Search code examples
gitversion-controlbranchrebase

Automatically rebase Git sub-branches


Say I have a git history like this:

A--B--C--D <master>
   \--E--F <topic1>
         \--G <topic2>

That is, I have two topic branches, where one feature depends upon another. In the meantime, work has been done on master, so I want to rebase topic1. This results in:

A--B--C--D <master>
   |     \--E'--F' <topic1>
   \--E--F--G <topic2>

That is, topic1 was rebased but topic2 was not. I want to get to this:

A--B--C--D <master>
         \--E'--F' <topic1>
                \--G <topic2>

But if I simply do git rebase topic1 topic2, Git will try to replay commits E and F on top of E' and F', which will fail because they edit the same lines of the same files. So I have to run something unwieldy like this:

git rebase --onto topic1 <sha1-of-commit-F> topic2

... which requires doing a git log and copy-pasting something (using the mouse like some sort of loser!). I know this isn't exactly heartbreaking, but this usage pattern must be fairly common for Git. Can anyone think of a way to rebase topic1 and topic2 in one fell swoop?


Solution

  • As Nils_M pointed out in a comment, the rebase man page says Note that any commits in HEAD which introduce the same textual changes as a commit in HEAD..<upstream> are omitted (i.e., a patch already accepted upstream with a different commit message or timestamp will be skipped).

    The only reason Git would replay E and F during the rebase of topic2 onto topic1 is if E' or F' has been modified from their originals. In that case, when the rebase stops due the merge conflict, simply use git rebase --skip.