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.
