Fraser Speirs Cocoa and Photos

Posted
22 September 2008 @ 9am

Tagged
Tech

Add:     

Git committing workflow with BBEdit

Now that I’m committed to using Git, I’m trying to streamline (and improve) my workflow a bit. Here’s what I’m doing in a git commit right now.

I use the following script to open up individual diffs of each changed file in BBEdit:

#!/bin/sh

# Open each diff in a separate BBEdit buffer, inside one window
for f in `/usr/local/bin/git ls-files \
	-d -m -o --exclude-per-directory=.gitignore`; do

	/usr/local/bin/git diff $f | /usr/bin/bbedit --front-window

done

# Open the list of changed files in BBEdit
/usr/local/bin/git ls-files -d -m -o -t --exclude-per-directory=.gitignore \
	| /usr/bin/bbedit

This gets me two BBEdit windows. One window contains several buffers, each with a diff of a file that changed. The second window contains a Subversion-style list of changed file paths:

C ExposureTouch/Classes/EXLocalController.m
C ExposureTouch/Classes/ExposureAppDelegate.m

I then apply a BBEdit Text Factory to this window, which converts these lines into:

== CHANGED: ExposureTouch/Classes/EXLocalController.m ==

Comment: <# Change Comment #>

== CHANGED: ExposureTouch/Classes/ExposureAppDelegate.m ==

Comment: <# Change Comment #>

The <# Change Comment #> things are BBEdit placeholders. Incidentally, the manual is a little vague on how you create your own placeholders in BBEdit. The format is <##> and you can insert them by any text manipulation (from the manual, I had initially thought that you could only add them by inserting a clipping).

Having done this, I can tab through the placeholders (thanks, BBEdit 9!) and write a comment about each changed file while looking at the individual diffs in a second window.

At the top of the file, I write a single line that summarises the changes in the commit. I try to write this in the style of a user-visible release note, which I later extract in another script to produce the release notes (for example).

Usually, I then do git commit -a and paste my completed change form into the top of the commit message editor and I’m done.

The release note generator is a simple script around git log:

#!/bin/sh
/usr/local/bin/git log --pretty=format:"- %s (%h, %ci)" $1..

I invoke this by naming the last release tag: gitnotes Exposure-1.0.3. This gives me the first line of every commit message since the tag Exposure-1.0.3 was created.

It’s not perfect (particularly when you cherry-pick) but it generally does the job on a single branch. Usually the notes need some massaging to make total sense to users, but I much prefer doing it this way to maintaining a separate file of changes. I’m also working on ways to tag commits as user-visible or internal, so that I could mark internal changes as “not for release” and exclude them in the gitnotes script.


1 Comment

Posted by
Mark
22 September 2008 @ 5pm

Frasier,

Do you really like looking at raw diff output. It gives me a headache.

I like to send my diffs to a GUI before submitting my changes. This is pretty easy to do in git.

Edit your ~/.gitconfig and add the following lines:

[diff]
external = “/Users/mark/bin/git-diff-driver.sh”

Then /Users/mark/bin/git-diff-driver.sh should contain:

#!/bin/sh

/usr/local/bin/compare -title1:”$1 (repo version)” -title2:”$1 ” -max -wait $2 $5
echo “All Done!”

This is necessary to convert the paramaters git-diff sends to the external comparison application to a form that the external app expects.

I am using Araxis Merge Pro, but this should not be to difficult to adapt to other GUI diff clients that have a command line component. The first thing to do is to drop the -title[12] flags and their parameters.

Good Luck.