Appending Pivotal Tracker story Ids to git commits

At work, we've adopted the habit of using Pivotal Tracker's hooks to keep a track of Git commit messages in the form of comments corresponding to their relevant pivotal stories. The advantage of this is that all other developers are aware of what is going on and the clients can also get a rough estimate of which features are currently in progress. Comments of the git commits are added by appending the pivotal story id in the git commit messages. e.g.

[#pivotal_id]: git message

This workflow proved to be rather annoying as I'd be forced to look at the pivotal story id from Pivotal Trackers website before I'd prepend it to the git commit message. I decided to automate this procedure so that I shouldn't be worrying about such trivial tasks.

Here is the solution that I came up with. It makes use of git hooks to prepend the pivotal story id to the git message right after I make my commit.(the commit-msg hook)

#!/usr/bin/env ruby
#
# Script for appending the pivotal id of a story to the commits
# Branches must begin with st{pivotal_story_id}_description_here
#
# Reads the pivotal story from the branch name and appends it to the
# commit messages. Supports the following formats
#
# Examples:
#     st{#pivotal_id}_commit_description_here
#     hotfix/st{#pivotal_id}_commit_description_here
#     feature/st{#pivotal_id}_commit_description_here
#
# Sohaib Talaat Bhatti -- sohaibbbhatti@gmail.com
# sohaibbbhatti.wordpress.org


def blank?(message)  
  message.nil? || message.empty?
end

# Detects whether any string prepends the git message.
#
# Example
#
#  message.exists? "My first commit
#  # Please enter the commit message for your changes. Lines starting" => true
#
def message_exists?(message)  
  blank? message.rpartition(commit_msg_start).first
end

def commit_msg_start  
  "# Please enter the commit message for your changes. Lines starting"
end

branch_name = `git branch`[/\* (.+)/]  
story_subset = branch_name[/\* ((feature\/)|(hotfix\/)){0,1}st(\d+)/]

# Regex for detecting pivotal story id
pivotal_story_id = "[##{story_subset[/\d+/]}]" if story_subset

message_file = ARGV[0]  
message = File.read(message_file)

message = if pivotal_story_id  
            # Only commit if commit message exists
            message_exists?(message) ? [pivotal_story_id, message].join(' ') : false
          else
            message
          end

File.open(message_file, 'w') { |f| f.write message } if message  

This script relies on the fact that when the git branch command is used, the current branch name has an asterisk right before the branch name. The regular expression being used to assign branch_name a value is responsible for detecting the asterisk branch.

Once the branch name is found, a simplistic format is used to embed the pivotal id into the branch name(Shown in the beginning comments). Since we're using a fixed format a regular expression for extracting the pivotal story id can easily be extracted. If the pivotal story id is found, the script then joins it with the git commit message.

This script is proving to be a great time saver. Currently it doesnt support multiple pivotal story id's. e.g.

[#pivotal_id_1, #pivotal_id_2]: commit_msg

I'll add this functionality whenever I find the need for it. But for now I'm happy with the functionality as it is.

This script can be found on github along with usage instructions over here.

comments powered by Disqus