Archives

Creative Commons License
This blog is licensed under a Creative Commons License.

The saga of rebase versus merge

| 3 Comments | No TrackBacks

Following on my last entry, where I built a better pre-commit hook to ensure every commit in my Git history passed make check with flying colors, I realized something today about my good friend, rebase.

git rebase is a brilliant tool for editing history you haven’t pushed yet. If I have a set of ten commits, and realize the 3rd commit has an oversight I’d like to smooth out, I can make a new commit to fix the problem and then merge it with that old commit, resulting in a nice, clean set of commits for pushing.

However, using rebase at any time invalidates the work of my pre-commit hook. Why? Because any time I use rebase, I throw away whatever I’ve confirmed in the past about those commits. A rewritten commit is really a new commit, which means it hasn’t been tested, may never have existed as a working tree, and certainly isn’t the same as the previous commit, however similar its diff output may be.

What this goes to show is that immutability is a requirement of sane integration. Not only does code go into a commit, plus a date and a description, but also the work that went into verifying that commit. All of these details are bound up in the immutable state of that commit. If the state is change, and the immutability guarantee broken, all bets are off.

Thus the only way I could use rebase in confidence would be to run the same pre-commit again on every changed commit during the rebase operation – which is something Git doesn’t do. It thinks that if you rewrite a series of commits, the final HEAD will have the same contents as the previous HEAD, which is true. But the rebased commits leading up to that head, especially if their order was changed, now represent a fictitious history behind that new HEAD.

It makes me think more and more about the virtues of merging.

No TrackBacks

TrackBack URL: http://www.newartisans.com/mt/mt-tb.cgi/2541

3 Comments

This is a good point as well (and I felt smart when I realised I were thinking about the original pre-commit problem, before you mentioned it!).

I get the feeling though, that this is the conflict of git being used as a practical tool, and the way git “can” be used to do everything the right way – or at least pretend it was.

It makes my head hurt… It sure sounds a noble goal to keep every commit being “perfect”, but there are obvious limits to that. For example, to go extreme, it should mean every commit which changes behaviour (even when you can’t see it does!) should change the tests as well, otherwise your commit might be untested. This is compared to the current situation, when you want all commits to be tested against some, possibly trivial testing suite. And to do that right obviously hinders outside development.

Is it as dirty as I think to acknowledge, that testing boundary is different from commits? Or is it that git should have a way to force us to do it perfectly? :)

My current thinking is to use merge on the topic branch, and then do a rebase just after the final merge to master (before pushing the updated master).

E.g., to merge to master: “git merge $BRANCH; git rebase ORIG_HEAD”

[If there’s tweaking that needs to be done for “perfection”, use rebase -i of course]

I dunno what downsides this approach entails, but at least it concentrates the rebasing to where it’s easier to focus on potential problems… Since it seems to take forever for my topic branches to reach master, that should hopefully mean a lot less work for me.

The one annoying I do know, is that it means I’ll probably have to re-resolve any merge conflicts (rerere won’t catch them because they happen in a different context).

Leave a comment

About this Entry

This page contains a single entry by John Wiegley published on February 26, 2009 12:30 AM.

Building a better pre-commit hook for Git was the previous entry in this blog.

Hello Haskell, Goodbye Lisp is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Recent Comments

  • yoman: “Barfin”? “Slurping”? “Slime” “Hunchentoot” ??? What in the T.F. world read more
  • Bjorn Tipling: Why would you add instructions for installing an editor when read more
  • Mark Aufflick: sudo port install sbcl +threads If you previously installed sbcl read more
  • Alexander Lehmann: Thank. You. So. Much. – Clisp caused a lot of read more
  • Vetle: Btw, to get support for threading in SBCL, you have read more
  • ifade: I tried the same and get the same answer, but read more
  • Martial Boniou: Hi, I tried to install slime with MacPorts and I read more
OpenID accepted here Learn more about OpenID
Powered by Movable Type 4.261