fingernails in oatmeal

Lisp has all the visual appeal of oatmeal with fingernail clippings mixed in.

— Larry Wall

Authors

The Unsightliness of Merge Commits

I hate unnecessary merge commits. That is, I hate navigating a git tree of commits littered with merge commits. It is like eating a cupcake in which a small amount of sand was accidentally mixed into the batter. It may still be edible but no one is going to enjoy eating such a thing. Inadvertent mistakes like these may seem minor at first, but eventually one finds her focus drawn to the mistakes rather than the content.

Merge commits are necessary in some cases, such as merging two divergent branches. When one finds himself new to the ideas of git and coming from a system such as SVN, it can be difficult to grok the horrors he wreaks on his fellow developers by not understanding the differences between SVN and git.

The good news is that unnecessary merge commits are easy to avoid once we embrace rebasing. Let’s play through a scenario and see how we can improve our approach. If you don’t understand what we’re doing here just remember Tony Harrison and his incredulity toward unnecessary merge commits.

Git is decidedly not SVN. This kind of workflow leads to overly complex git trees (even though they may look pretty in GitX) and smells of a misunderstanding about the tools we’ve chosen. Next time, instead of refusing to understand why git is different from SVN, we can try the following:

Now that is an awful lot of work requiring us to find the SHA hash of our original commit or use special git notation for denoting parents of a commit. Seems like we could avoid that simply by pulling down the latest changes before we commit.

But this kind of technique is only useful when we are planning on pushing changes out immediately. This workflow actually tends to treat git more like SVN than the first one. Most of the time, I would not recommend the above workflow, but it will avoid merge commits. However, I think we can still do better thanks to a git configuration tip from @kEND.

git config branch.<branch>.rebase true
Whenever we pull changes down then our commits will automatically be rebased on top of those changes rather than merged together. Our workflow will end up looking like the first one, which is much more intuitive (commit*n => pull => push). The technique of automatic rebasing leaves less room for error in trying to remember all the steps and guidelines above.

From my limited understanding of git, I would prefer it to work this way by default, but I am guessing there are reasons why this is not the case. What kind of git workflow tricks do you use?

Adam