Many of us at Rally like to Pair-Program because it offers continuous code reviews and many other benefits. We also like using Git, because it’s fast and makes branching and merging far easier than Subversion.

Unfortunately, pair programming can often make interacting with a version control system difficult. Who officially makes the commit? How do you make sure the other half of the pair gets credit/blame when needed?

Luckily, Bryan Helmkamp wrote a script that allows pairs to update the usernames of commits to reflect the involvement of both people.

We’ve been using this script, but we’ve made some changes and figured we’d let others use the modified script as well.

The changes are as follows:

1. E-mail addresses use the plus-style subaddressing to specify pairs as part of the e-mail address. So if a pair switches using pair ck pp, the e-mail address will show up as something like “pair+ck+pp@company.com”. This has a number of advantages, not the least of which is that you can set up Gravatars with those addresses to actually show pictures of the pair.
2. Names are sorted alphabetically. Thus, pair ck pp and pair pp ck yield the same results. This makes searching a bit easier should the need arise.
3. The authors are no longer stored in the script. Instead, a .authors file is required in the project directory (the same one with the .git directory) that contains the authors. This allows different projects to have different lists of authors, and it also makes it easier to version control the .authors file, such that when a new person joins the company you don’t have to push new copies of the script to all of the pairing stations.
4. As with the other script, put this script in your executable path and use it by typing “pair” followed by the initials of everyone pairing at the station, such as pair js ta. If “js” and “ta” are defined in a .authors file in your project directory like so:

js John Smith
ta Tom Anderson

Then git will update the author e-mail to contain both sets of initials and set the name to be “John Smith and Tom Anderson”.

The source code for the modified script is here:

#!/usr/bin/env ruby

# Configures the git author to a list of developers when pair programming
#
# Usage: pair lm bh (Sets the author to 'Luke Melia and Bryan Helmkamp')
#        pair       (Unsets the author so the git global config takes effect)
#
# Author: Bryan Helmkamp (http://brynary.com)
# Author: Rod Hilton and Adam Esterline (http://www.rallydev.com)

#######################################################################
## Configuration

EMAIL_PREFIX = "developers"
EMAIL_SUFFIX = "@company.com"
AUTHORS = {}

@pair_initials = ARGV.sort

## End of configuration
#######################################################################

unless File.exists?(".git")
puts "This doesn't look like a git repository."
exit 1
end

unless File.exists?(".authors")
puts "You do not have an .authors file in the repository."
puts "Repository needs a file named .authors in the following format:"
puts "  ck Clark Kent"
puts "  bw Bruce Wayne"
puts "  pp Peter Parker"
exit 1
end

# Read the local .authors file, parsing to get the AUTHORS map
File.open('.authors').each_line do |line|
initials, name = line.match(/^(\w+)\s+(.*)\$/).captures
if(AUTHORS.has_key?(initials))
puts "Duplicate initials for #{initials}"
exit 1
end
AUTHORS[initials] = name
end

authors = @pair_initials.map do |initials|
if AUTHORS[initials.downcase]
AUTHORS[initials.downcase]
else
puts "Couldn't find author name for initials: #{initials}"
exit 1
end
end

if authors.any?
if authors.size == 1
authors = authors.first
elsif authors.size == 2
authors = authors.join(" and ")
else
authors = authors[0..-2].join(", ") + " and " + authors.last
end

email="#{EMAIL_PREFIX}+#{@pair_initials.join("+")}#{EMAIL_SUFFIX}"

git config user.name '#{authors}'
git config user.email '#{email}'

puts "user.name = #{authors}"
puts "user.email = #{email}"
else
git config --unset user.name
git config --unset user.email

puts "Unset user.name and user.email"
end

Copy the plain text to your clip board and save it in a executable file called ‘pair’ in the path of your pairing machines.