Barrison Twitter

Manipulate History for Meaningful Commits

Quantum leap

One of git's most powerful features is the ability to rewrite history.

While developing, I commit after every step of the red-green-refactor cycle. I prepend them with the word 'wip' as a reminder not to share them with the world.

 ~/code/paleospots/ [venues] gl
5bdc625 - wip - refactoring
7733fc7 - wip - passing unit test
acfd9dc - wip - failing unit test
2e14ec9 - wip - failing acceptance spec
1d65cf1 - Added Ability for Users to Create Tips [completes #14]

These commits are meaningful while developing a feature.

5 weeks from now, I am not going to care about the commit that introduced a failing unit test.

Because git is decentralized, I can make these micro-commits locally and worry about squashing them into one commit later.

For example, if I want to try a completely different implementation, I can create a new branch and revert to that failing spec in seconds:

 ~/code/paleospots/ [venues]  git checkout 5bdc625
You are in 'detached HEAD' state. [...]

HEAD is now at 5bdc625...  failing acceptance tests

>  git checkout -b different-implementation

p Now, once that feature is complete, it's time to think about the future audience. Two months from now no one's going to care about a commit with just a failing spec. You might want to revert an entire feature, or look at the files involved in a feature. That's where git rebase comes in. Run git rebase -i SHA-BEFORE-ALL-THE-COMMITS-TO-SQUASH

 ~/code/paleospots/ [venues] git rebase -i 1d65cf1

Then you'll see this screen.

Pick the first commit, and change the word "pick" to "s" to squash all the other commits into it.

Save and exit.

Now you'll be presented with a chance to edit your commit message. You'll see a list of your previous commit messages and all the files changed, so you have no excuse to document exactly what you did, packing as many searchable keywords in that first line as possible. (You're not going to search for "fixed the issue" a month from now, so use as precise wording as possible.)

 ~/code/paleospots/ [venues] git log
498a02f - (HEAD, venues) Users create Venues, Venues update their lat/long from an address [completes #23421] (7 hours ago) Len Smith
1d65cf1 - Added Ability for Users to Create Tips [completes #14] (2 weeks ago) Len Smith

And bam. Your history is meaningful.

Before you push, take a second look at your commit. You're not going to be able to change it once its published. Use "git commit –amend" if you need to reword your commit.

* Once you push to a remote branch that other people might use, you can no longer change history without mucking up the time stream.