views:

567

answers:

4

Everytime I read the git-rebase documentation, I get lost. It feels to me like a kind of a low-level operation (read: dark magic).

Quoting the docs:

Assume the following history exists and the current branch is "topic":

       A---B---C topic
      /
 D---E---F---G master
From this point, the result of either of the following commands:
git rebase master 
git rebase master topic
would be:
               A'--B'--C' topic
              /
 D---E---F---G master

The question is: Why would anyone want to do such a thing?

For one thing, it seems to "re-write" history, as if the branch started at a different point; essentially the commit history will be "a bunch of lies".

Another point, it doesn't feel safe. I tried it once, got a ton of conflicts, and all hell broke loose. I don't remember exactly how I resolved that hell, but IIRC it was on a temporary test branch or something like that.

The other question: Am I missing some really cool/time-saving set of features by not knowing how to utilize git-rebase?

EDIT:

Related question: Undoing a git rebase

+3  A: 

As soon as you merge "topic" back into "master" you will have those conflicts anyway. Thus, it is better to rebase "topic" onto "master" from time to time (it's easier if if you do small steps than if you do one big step - at least imo). If you rebase before you merge, all the "risky" stuff happens in the branch and the merge is easy afterwards.

bayer
+4  A: 

You need to use it for instance when you want to submit a patch to code that someone else's modified. For example if you branched from revision 1.56 of a software and in the meantime the maintainer moved to revision 1.57, he/she would probably accept patches only on revision 1.57.

You would rebase your branch to revision 1.57, correct all conflicts, verify and resubmit the patch.

Metiu
I haven't used git to submit patches, but what's wrong with fetching, merging and then diffing against the "remote" branch?
hasen j
+5  A: 

First, there are no unsafe operations in git. rebase has an abort operation, and all operations make it to the reflog, so you can undo anything. It is, in fact, quite the opposite.

It allows you to feel free to commit any time you want without having to have a "good" build while you're on the path to making one. The revisions you publish can be clean by squashing all of the steps you took along the way into a single commit.

I use rebase all the time (quite often via pull which I generally have configured to rebase after the fetch phase). Don't think of it as rewriting history -- think of it as providing a tool for you to clean up your rough draft before you publish it.

In a year from now, will it be important to anyone in your project to know that you really started this feature against revision E and not revision G?

Unnecessary recursive merges obscure the more important parts of history.

Dustin
could you expand a bit on the "undoing" thing? how do you undo a rebase for instance?
hasen j
Sorry, I think some of my comment was eaten. Pretty much every operation that changes the repository does so by adding something new and pointing to it. Reflog shows you all your previous HEAD states. You can always "reset --hard" to one or retroactively branch. Unless you try hard, none of this information is lost for 90 days.
Dustin
I see, Thanks! Maybe you should edit it into the answer :)
hasen j
It is not correct that "there are no unsafe operations in git". While "git rebase" doesn't throw any information away, "git gc" (which git, by default, calls by itself periodically) *does*. And even before "git gc" destroys information irrevocably, "git rebase" buries information in the reflog where some digging is required to get it back out again.Rebase is a very useful tool, but make no mistake about it: it is a sharp tool.
mhagger
+2  A: 

See git rebase: keeping your branches current blog post by James Bowes

Jakub Narębski