Home > other >  Best way to rebase against a parent branch that performed a rebase?
Best way to rebase against a parent branch that performed a rebase?

Time:06-30

I have branch_A that is branched off master and branch_B that is branched off branch_A.

 Master----                        
           |                       
           |                       
           |Branch_A------         
                          |        
                          |        
                          |Branch_B

In my case, master updated and I rebased Branch_A. Now Branch_B has diverged. The only solution I've done is make a new branch from A and cherry-pick commits. It's very convoluted and gets confusing. Is there an easier way in this current state to get B up to date with A even with the divergent history?

CodePudding user response:

Yes, there is. If instead of rebasing, you

git checkout Branch_A
git merge master

Fix the merge conflicts that may arise, then you can update Branch_B via

git checkout Branch_B
git merge Branch_A

You may still have merge conflicts and similar difficulties, but at least up to the point when Branch_B merged out from Branch_A, things are perfectly in sync between the two. So, whatever was pushed into master and Branch_B afterwards may have diverged, which means that you may need to fix this, but, if the changes are not very close to each-other in the code, then you may end up merging without conflicts.

CodePudding user response:

You can use the optional --onto parameter to rebase:

git rebase <Branch_A-old> Branch_B --onto Branch_A

For <Branch_A-old> you need either a branch or a commit ID. So, before you rebase Branch_A you could do something like:

git branch Branch_A-old Branch_A
git rebase Branch_A master

Or, you could simply look at the current history of Branch_B and use the parent commit ID of the first commit you would have cherry-picked, which will represent the previous version of the commit on Branch_A. Note this "fancy" rebase is doing what you did with cherry-picks, but all in one shot and without necessitating creating a new branch.

Side Note: you can also cherry-pick a range of commits in a single command, starting with the parent ID of the first commit you want to cherry-pick, through the last commit, like this:

git switch -c Branch_B-new Branch_A
git cherry-pick <first-commit-id>^..<Branch_B>
# note the ^ symbol refers to the parent

This still isn't as efficient as the single rebase command because it requires a new branch first, but it's nice to know this command exists.

Way off to the side note: In general, I recommend trying to avoid working on something that depends on something else that isn't merged yet, especially when you use a rebase (or squash) strategy, for the exact reasons you have witnessed. Obviously you can't avoid it all the time, and you can just rebase --onto when it happens. Oftentimes though, you may find you can start working on something else while you're waiting.

CodePudding user response:

git rebase --fork-point Branch_A

is your ticket, or if this is purely local work and you did git checkout -t -b Branch_B while on Branch-A or otherwise told Git about the relationship, just plain git rebase will do it.

  • Related