views:

120

answers:

2

In this article, the author explains rebasing with this diagram:

alt text

Rebase: If you have not yet published your branch, or have clearly communicated that others should not base their work on it, you have an alternative. You can rebase your branch, where instead of merging, your commit is replaced by another commit with a different parent, and your branch is moved there.

while a normal merge would have looked like this:

alt text

So, if you rebase, you are just losing a history state (which would be garbage collected sometime in the future). So, why would someone want to do a rebase at all? What am I missing here?

+1  A: 

Rebasing allows you to pick up merges in the proper order. The theory behind merging means you shouldn't have to worry about that. The reality of resolving complicated conflicts gets easier if you rebase, then merge new changes in order.

You might want to read up on Bunny Hopping

glowcoder
+6  A: 

There are variety of situations in which you might want to rebase.

  • You develop a few parts of a feature on separate branches, then realize they're in reality a linear progression of ideas. Rebase them into that configuration.

  • You fork a topic from the wrong place. Maybe it's too early (you need something from later), maybe it's too late (it actually applies to previous versions as well). Move it to the right place. The "too late" case actually can't be fixed by a merge, so rebase is critical.

  • You want to test the interaction of a branch with another branch, but for some reason don't want to merge. For example, you might want to see what conflicts crop up commit-by-commit, instead of all at once.

The general theme here is that excessive merging clutters up the history, and rebasing is a way to avoid it if you didn't get your branch/merge plan right at first. Too many merges can make it hard for a human to follow the history, and also can make it harder to use tools like git-bisect.

There are also all the many cases which prompt an interactive rebase:

  • Multiple commits should've been one commit.

  • A commit (not the current one) should've been multiple commits.

  • A commit (not the current one) had a mistake in it or its message.

  • A commit (not the current one) should be removed.

  • Commits should be reordered (e.g. to flow more logically).

While it's true that you "lose history" doing these things, the reality is that you want to only publish clean work. If something is still unpublished, it's okay to rebase it in order to transform it to the way you should have committed it. This means that the final version in the public repository will be logical and easy to follow, not preserving any of the hiccups a developer had along the way.

Jefromi
Darned: no more upvote for today. I would add: http://stackoverflow.com/questions/1241720/git-cherry-pick-vs-merge-workflow, http://stackoverflow.com/questions/457927/git-workflow-and-rebase-vs-merge-questions, http://stackoverflow.com/questions/1751534/is-there-a-significance-in-merge-directions-between-upstream-topic-integration-in/1764180#1764180 (for Linus's comment)
VonC
And I would also mention as an aside: http://utcc.utoronto.ca/~cks/space/blog/tech/GitNewHistory: "git's design means that by its very nature you cannot rewrite history"
VonC
@VonC: As always, your research into previous questions shows me up. Thanks for the links. The point about "rewriting history" is also a very good one. To everyone else: the summary is that you don't actually rewrite, you create new history and update the ref to point to it instead of the old history. There are plenty of questions here about that sort of thing too - going back to find the history you've "lost" by rebasing/amending.
Jefromi
"you create new history and update the ref to point to it instead of the old history": YES! Exactly. More power to reflog and `git log -g` ;)
VonC
And... the +1 from yesterday I couldn't give at the time;)
VonC