-
Notifications
You must be signed in to change notification settings - Fork 80
Merging between version branches
Once we create a version branch, let's say 2.0
, and keep pushing commits to that version branch, and in the meanwhile more commits are added to master
.
This wiki describes how to forward merge changes from 2.0 to master.
Apparently the solutions that avoid repeating conflict resolution is either merge or cherry-pick. Using rebase will inherently force to repeat conflicts on every rebase.
# fetch and update branches from origin
git fetch origin master:master 2.0:2.0
# create new branch from master
git checkout -b guy-cherry-from-2-0 master
# get list of commits to cherry pick (see https://git-scm.com/docs/git-cherry)
# every line with '+' should be picked, lines with '-' are already in master
git cherry -v HEAD 2.0
# cherry-pick commits from 2.0
git cherry-pick <commit-hash-1>
...
git cherry-pick <commit-hash-n>
# manually resolve conflicts for each commit ...
# push and PR
git push
While this method works pretty easily, merges behave a bit weird as the commits that merge brings are pushed in the middle of the commit stream and a final "merge commit" is created in the end to fix any automatic merging or manual conflicts. This is why we prefer to use cherry-picking instead, but merge will work too.
# fetch and update branches from origin
git fetch origin master:master 2.0:2.0
# create new branch from master
git checkout -b guy-merge-from-2-0 master
# merge that branch from 2.0
git merge 2.0
# manually resolve conflicts for the entire merge ...
# push and PR
git push
We tried to do it using a standard rebase as follows:
# fetch and update branches from origin
git fetch origin master:master 2.0:2.0
# create new branch from 2.0
git checkout -b guy-merge-from-2-0 2.0
# rebase that branch from master
git rebase master
# manually resolve conflicts per commit ...
# push and PR
git push
This method seems to work well for the first time, and all the commits from 2.0 are re-created on master, so they have different commit hashes.
However, when there are resolved conflicts and this method is repeated the problem is that git does not identify those commits on master as resolved conflicts, and the next rebase will ask to manually resolve the same conflict again without any real diff to apply.
Even starting with a merge, and then use rebase in order to remove all duplicated commits, the result is the same as the simple rebase option that repeats conflicts.
# fetch and update branches from origin
git fetch origin master:master 2.0:2.0
# create new branch from master
git checkout -b guy-merge-from-2-0 master
# merge that branch from 2.0
git merge 2.0
# manually resolve conflicts for the entire merge ...
# rebase the merged commits on top of master
# this will remove unneeded commits and potentially also the merge commit
git rebase master
# push and PR
git push