Git hooks for automatic reference issues in commit
This hooks will remind you to reference task in your commit, and remember your task ref for branch. Your commit messages will have style "[reference] message"
[PROJECT_ROOT]/hooks/prepare-commit-msg.rb
and [PROJECT_ROOT]/hooks/post-checkout.rb
[PROJECT_ROOT]/hooks/prepare-commit-msg.rb
):#!/usr/bin/env ruby
require 'fileutils'
MESSAGE_WITH_ISSUE_PATTERN = /^\[(#\d+)\]/ # Regexp that matches messages with specified issue
# Remember that actual issue link will be taken from
# message.match(MESSAGE_WITH_ISSUE_PATTERN)[1]
# so currrent example is for github issues references
ISSUE_PATTERN = /^#\d+$/ # Regexp that matches issue reference
# e.g. if you want to reference github issues it will be /^#\d+$/
# or may be you want to reference trello -- /^https:\/\/trello.com/.+/
# Have no idea why STDIN.reopen is not working, so this
def read_stdin
open '/dev/tty' do |f|
input = f.gets.chomp
yield input
end
end
def save_issue(number)
File.write '.git/ISSUE', number
branch = File.read('.git/HEAD').match /^ref: refs\/heads\/(.+)/
FileUtils.mkdir_p '.git/refs/issues'
File.write ".git/refs/issues/#{branch[1]}", number if branch
end
def cache_issue(number, force: false)
if !force && File.exists?('.git/ISSUE')
return if number.to_s == File.read('.git/ISSUE')
puts "Do you want to update issue in branch? y(es)/anything else"
read_stdin do |input|
save_issue number if input.downcase.strip.match? /^y(es)?$/
end
else
save_issue number
end
end
msg = File.read(ARGV[0])
issue_match = msg.match MESSAGE_WITH_ISSUE_PATTERN
unless issue_match.nil?
cache_issue issue_match[1]
exit 0
end
issue = File.read('.git/ISSUE') if File.exists? '.git/ISSUE'
File.write(ARGV[0], "[#{issue}] #{msg}") && exit(0) if !issue.nil? && !issue.empty?
puts "Do you want to specify issue? Enter a reference if yes or anything else if no."
read_stdin do |input|
if input.match? ISSUE_PATTERN
File.write ARGV[0], "[#{input}] #{msg}"
cache_issue input, force: true
end
end
exit 0
MESSAGE_WITH_ISSUE_PATTERN
and ISSUE_PATTERN
which will satisfy your needs[PROJECT_ROOT]/hooks/post-checkout.rb
):#!/usr/bin/env ruby
heads = '.git/refs/heads/'
issues = '.git/refs/issues/'
branch = File.read('.git/HEAD').match /^ref: refs\/heads\/(.+)/
if !branch.nil? && File.exists?(issues + branch[1])
issue = File.read issues + branch[1]
puts "Current issue is #{issue}"
File.write '.git/ISSUE', issue
else
puts "Current issue is not specified yet"
File.write '.git/ISSUE', ''
end
exit 0
ln -s ../../hooks/prepare-commit-msg.rb .git/hooks/prepare-commit-msg
ln -s ../../hooks/post-checkout.rb .git/hooks/post-checkout
chmod u+x .git/hooks/prepare-commit-msg
chmod u+x .git/hooks/post-checkout
git commit -m "My awesome commit!"
you will be asked for issue. For next time, your commit in same branch will marked automatically.git commit -m "[#5] One more awesome commit"
. You will be asked if you want to update issue ref permanently or just for this commit.