We're migrating from SVN, and also merging a bunch of branches. To massively simplify, we have a branch B which was forked a long time ago, and has a little bit of development, let's say 8 files modified, out of hundreds. Meanwhile, huge changes have happened on master:
A
|
X---(a few changes)--- B
|
|(hundreds of changes)
|
HEAD/master
If I do "git merge master" from the branch, many merge conflicts are shown, because B and HEAD are very different now. But this seems (naively, to me) wrong: B is not that far from the trunk, it's just a long way back in time.
Is there a way to take advantage of this fact? Should I try and first merge B back to X, then from there to HEAD? What would be the commands to:
Is there another approach that people use in these situations?
(Quite possibly I have said some very stupid and un-git-like things in the preceding - feel free to point them out. :))
Rebase the old branch against the master branch. Solve the merge conflicts during rebase, and the result will be an up-to-date branch that merges cleanly against master. Merge your branch into master, and resolve the merge conflicts. Merge master into your branch, and resolve the merge conflicts.
In a good workflow, the feature branch is deleted once its merged back into master. New branches should be created for each new feature(s) that you work on.
The message “Already up-to-date” means that all the changes from the branch you're trying to merge have already been merged to the branch you're currently on. More specifically it means that the branch you're trying to merge is a parent of your current branch.
Git rebase compresses all the changes into a single “patch.” Then it integrates the patch onto the target branch. Unlike merging, rebasing flattens history. It transfers the completed work from one branch to another. In the process, unwanted history is eliminated.
Creating a new branch "X" from the point where B and master diverged and then merging B into X won't help you. That would simply be a fast-forward merge; there would be literally no change to the conflicts caused by merge B into master. Your only option is to perform the merge of B into master and address the conflicts. Conflicts are what they are, and there is no way "around" them.
If it's bad enough, you might want to just manually rewrite the patch against HEAD or at least a more recent version. This will not only help deal with the conflicts, and leave you a history you'll probably like better, but also help you avoid bugs that aren't part of merge conflicts. There's quite a lot of potential for problems due to code changing underneath the change, and not all of it would actually present as a merge conflict.
That said, if you do want to try to do it solely in merge-y ways, you're going to have to deal with these conflicts one way or another. It's possible that you could spare yourself some pain by doing it incrementally, stepping forward in time in smaller increments. I might do this by progressively rebasing the branch forward:
git rebase version-2 old-branch
# deal with conflicts if they happen
git rebase version-3 old-branch
# and so on...
# until old-branch is based on a recent version
git checkout master
git merge old-branch
This would effectively let you deal with smaller changes in each step, instead of dealing with it all at once.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With