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"
- Create two files in your repo - e.g.
[PROJECT_ROOT]/hooks/prepare-commit-msg.rb
and[PROJECT_ROOT]/hooks/post-checkout.rb
- Copy to first file (here will assume that this is a
[PROJECT_ROOT]/hooks/prepare-commit-msg.rb
):
#!/usr/bin/env ruby
# frozen_string_literal: true
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 branch
branch = File.read('.git/HEAD').match /^ref: refs\/heads\/(.+)/
branch[1] if branch
end
def save_issue(number)
return unless branch
issue_number = number =~ /^TN-\d+$/ ? number : "TN-#{number}"
File.write '.issues/ISSUE', issue_number
issue_folder = ".issues/"
subfolder = branch.split('/').to_a
issue_folder += subfolder[0..(subfolder.size - 2)].join('/') if subfolder.size >= 2
FileUtils.mkdir_p issue_folder
File.write ".issues/#{branch}", issue_number
end
def cache_issue(number, force: false)
if !force && File.exist?('.issues/ISSUE')
return if number.to_s == File.read('.issues/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 =~ /^y(?:es)?$/
end
else
save_issue number
end
end
def check_issue(file)
msg = File.read(file)
issue_match = msg.match MESSAGE_WITH_ISSUE_PATTERN
unless issue_match.nil?
cache_issue issue_match[1]
exit 0
end
issue = File.read('.issues/ISSUE') if File.exist? '.issues/ISSUE'
# after rebase we lose .issues/ISSUE
if !branch.nil? && File.exist?(".issues/#{branch}") && (issue.nil? || issue.empty?)
issue = File.read(".issues/#{branch}")
end
File.write(file, "[#{issue}] #{msg}") && exit(0) if !issue.nil? && !issue.empty?
puts "Do you want to specify issue? Enter issue number (without TN- prefix) if yes " \
"or anything else if no."
read_stdin do |input|
if input =~ ISSUE_PATTERN
File.write file, "[TN-#{input}] #{msg}"
cache_issue input, force: true
end
end
end
check_issue ARGV[0]
exit 0
- Specify your own regexp in
MESSAGE_WITH_ISSUE_PATTERN
andISSUE_PATTERN
which will satisfy your needs - Copy to second file (assume that this is
[PROJECT_ROOT]/hooks/post-checkout.rb
):
#!/usr/bin/env ruby
issues = '.issues/'
branch = File.read('.git/HEAD').match /^ref: refs\/heads\/(.+)/
if !branch.nil? && File.exist?(issues + branch[1])
issue = File.read issues + branch[1]
puts "Current issue is #{issue}"
File.write '.issues/ISSUE', issue
else
puts "Current issue is not specified yet"
File.write '.issues/ISSUE', ''
end
exit 0
- Create links:
ln -s ../../hooks/prepare-commit-msg.rb .git/hooks/prepare-commit-msg
ln -s ../../hooks/post-checkout.rb .git/hooks/post-checkout
- Add permissions:
chmod u+x .git/hooks/prepare-commit-msg
chmod u+x .git/hooks/post-checkout
- When you will run
git commit -m "My awesome commit!"
you will be asked for issue. For next time, your commit in same branch will marked automatically. - If you want to redefine issue in branch, you just need to ref new issue. E.g. with default values (reference to GitHub)
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.
Fix for
#save_issue
to take into account branch names like"fix/bla/bla/bla"
: