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.