3

I have a question with regard to gits rebase --onto functionality.

My problem is very similar to the one described here

Where the author of that page has a branch history of:

master ---A---B---C
           \
feature1    D---E---F
                 \
feature2          G---H

and is looking to rebase both branches onto master so that the branch history looks like:

master ---A---B---C
                   \
feature1            D'--E'--F'
                             \
feature2                      G'--H'

This is achievable as described in the linked article via the command:

git rebase --onto feature1 feature1@{1} feature2

I have a similar problem, however I have two dependent feature branches instead of one.

My current branch history looks like this:

master       ---A---B---C
                 \
intermediate      D---E---F
                       \
feature1                G---H
                         \
feature2                  I---J

I am wondering if it is possible to perform a rebase such that my my history is transformed into:

master       ---A---B---C
                         \
intermediate              D'---E'---F'
                                     \
feature1                              G'---H'
                                       \
feature2                                I'---J'

Can I perform a dependent rebase of two branches simultaneously?

If so, what would the syntax be for such an operation?

Thanks in advance for any responses!!

Dalaigh88
  • 392
  • 3
  • 13
  • As a simple workaround you could just rebase `intermediate` in first step, then `feature1` and finally `feature2` – Michał Walenciak Dec 05 '17 at 11:58
  • 1
    Does that not run into an issue where feature 1 has the same history as intermediate, but different commit hashes? Rebasing feature 1 onto intermediate would result in multiple duplicate commits being applied, which might be difficult to resolve. Or am I misunderstanding how things work in that case? – Dalaigh88 Dec 05 '17 at 12:01
  • you are right, I havn't considered that. – Michał Walenciak Dec 05 '17 at 12:19
  • @Dalaigh88: git is good at recognizing same commits even with different SHA IDs, so it's worth a shot just rebasing individually. Might work, might not work depending on merge conflicts. – tkruse Dec 05 '17 at 13:22
  • Wouldn't `H'` be the parent of `I'`? – evolutionxbox Dec 05 '17 at 14:37
  • @tkruse, that's a fair enough answer, and it might work for 99% of cases. I just want to be able to have a method that a can be confident *will* work, every time. Processes that 'might' work scare the hell out of me, that unpredictability tends to manifest on important deploy or demo days... :) – Dalaigh88 Dec 05 '17 at 15:27
  • @evolutionxbox, I am specifically looking to preserve the divergence of feature1 and feature2 while having both rebased onto their parent branches. However, a solution that ends up with H' as a parent of I' would probably be a good start to the above... – Dalaigh88 Dec 05 '17 at 15:29
  • This is a fairly hard problem to solve in general. I started on a Python script to do it at one point, but gave up because the crappy 90+% method was working and I did not have time to write a 100% version. – torek Dec 05 '17 at 16:46
  • @Dalaigh88: There are no guarantees of end quality in either rebases or merges. What I said is, you might be lucky and this just passes without manual intervention, else you will have to resolve conflicts and clean up duplicate commits. But in the latter case, any other approach would likely also cause merge conflicts to resolve manually. So there is benefit in taking the simplest approach that you can understand rather than trying to find an even better approach that very complex to understand. – tkruse Dec 06 '17 at 00:44

1 Answers1

0

Git rebase branch with all parent branches (or dependent sub-branches) gets you close, but is a slightly different problem. The linked question has a top-level branch which fully contains all other branches.

For your use case, you have to manually rebase branch after branch:

git rebase master intermediate
git rebase intermediate feature1
git rebase "G'" feature2

Git is usually smart enough to figure out when two commits contain the same patch and will skip those commits. This can be controlled via the --reapply-cherry-picks option.

If this does not work for you, you can be fully explicit when running git rebase and always fully specify which commit range you want to rebase and where you want to rebase it to:

git rebase --onto master master intermediate
git rebase --onto intermediate E feature1
git rebase --onto "G'" G feature2

This is cumbersome, but should work in 100% of the cases.

knittl
  • 246,190
  • 53
  • 318
  • 364