Wes Gibbs github twitter linked in ruby5 archives
Rebases all the way down

You have a long-running topic branch off of master. Every day or two you rebase the topic branch on top of master to keep it up-to-date.1 You have another branch off of topic in which you are doing incremental work that periodically gets committed to the topic branch. When you rebase topic on master, that incremental branch gets “orphaned”. You want to rebase it cleanly back on top of the topic branch.

Now with pictures. Here’s what you start with.

  A---B---C  master
       \
        D---E  topic origin/topic
             \
              F  incremental

Your topic and incremental branches are missing commit C. Use rebase --onto to correctly rewrite the history2 for topic and incremental.3


(topic)$ git rebase master

  A---B---C  master
      |    \
      |     D'--E'  topic
       \      
        D---E  origin/topic
             \
              F  incremental

(incremental)$ git rebase --onto topic origin/topic

  A---B---C  master
           \
            D'--E'  topic
                 \ 
                  F  incremental

You may be thinking that rebasing topic on master then rebasing incremental on topic would accomplish the same goal, like this:


(topic)$ git rebase master

  A---B---C  master
      |    \
      |     D'--E'  topic
       \      
        D---E  origin/topic
             \
              F  incremental

(incremental)$ git rebase topic

  [UH-OH]

UH-OH means that you’re going to rewind to E', then try replaying D, E, and F on top of E'. That’s probably not what you want, and in all but the most trivial cases you’re going to wind up with messy conflicts. What you want is to permanently drop D and E. D' and E' have replaced them. Using rebase --onto accomplishes that.

 

1. And you're using rerere to avoid reliving the same conflicts each time.
2. Assume all the usual caveats about rewriting git history.
3. In these examples, note the branch from which these commands are run in the prompt. There are alternate invocations of these commands that take that branch as an argument and so don't care what branch is current when the command is run. I prefer the context provided by switching branches.
blog comments powered by Disqus
Comments