progit2
progit2 copied to clipboard
Help with --ours merge strategy trick needed
Could someone please explain the last paragraph of book/07-git-tools/sections/advanced-merging.asc?.. I've tried a lot of variants, but however I merge the 'bugfix' branch to both 'master' and 'develop' branches, I get no conflict when I merge 'release' back to 'master'... What should I do to get this conflict?..
This [--ours merge strategy] can often be useful to basically trick Git into thinking that a branch is already merged when doing a merge later on. For example, say you branched off a release branch and have done some work on it that you will want to merge back into your master branch at some point. In the meantime some bugfix on master needs to be backported into your release branch. You can merge the bugfix branch into the release branch and also merge -s ours the same branch into your master branch (even though the fix is already there) so when you later merge the release branch again, there are no conflicts from the bugfix.
I'm currently translating the book to Ukrainian and would like to fully understand everything I translate.
Thanks in advance!
Before that paragraph, the book talks about resolving conflicts and how to set options for the default recursive merge strategy using '-X' (such as '-Xours') in order to get fewer conflicts.
In the paragraph you are referencing, the book talks about the "ours strategy" ('-Sours') which will never produce any conflicts because it simply takes "our side" as the merge result. In effect, this "marks the side branch as merged in" without even looking at its contents, and takes the contents of the main branch verbatim. No chance for conflicts there ;;)
Thank you very much for your time!
Yes, I understand that -Xours
leads to no conflicts :)
I don't understand how the situation described in the quoted paragraph leads to conflict if we don't "merge -s ours the same branch into your master branch (even though the fix is already there)".
I'm trying to do the following (as I understand this paragraph):
# 1. prepare repository
git init .
echo '1' > a.txt
echo '2' >> a.txt
echo '3' >> a.txt
echo '4' >> a.txt
echo '5' >> a.txt
git add a.txt
git commit -m 'Initial commit'
# 2. > For example, say you branched off a release branch
git checkout -b release
# 3. > and have done some work on it that you will want to merge back into your master branch at some point.
sed -i 's/2/2 release/' a.txt
git commit -a -m 'release commit'
# 4. > In the meantime some bugfix on master needs to be backported into your release branch. making bugfix git checkout
git checkout -b bugfix master
sed -i 's/5/5 bugfix/' a.txt
git commit -a -m 'bugfix commit'
git checkout master
git merge bugfix
# also add some changes so that there won't be fast-forward at item 7.
echo '6 additional line from master' >> a.txt
git commit -a -m 'master commit 2'
# 5. > You can merge the bugfix branch into the release branch
git checkout release
git merge bugfix
git checkout master
# 6. > and also merge -s ours the same branch into your master branch (even though the fix is already there)
git merge -Xours bugfix
# 7. > so when you later merge the release branch again, there are no conflicts from the bugfix.
git merge release
When I run 6, I get "Already up-to-date.", because "(...the fix is already there)". And 7 leads to no conflicts whether I run 6 or not.
Could you please tell me, what I miss?..
Thanks again, sorry for a LONG question...
I think what happens is:
- there is a release branch and a master branch
- a bug fix is made on the master branch
- the bug fix is backported (either by branch-merging or cherry-picking) to the release branch. But because the release branch is different from the master branch, modifications have to be made.
- fake merge the bug-fixed release branch into the master branch
- develop on the release branch
- merge the release branch into master Now if step 4 is not performed, during merging, the modified bug-fix is going to conflict with the original bug-fix already in master. But thanks to step 4, git will skip the bug-fix in the release branch when merging release into master.
@yushih I tried your scenario and it works :)
One thing that I still don't understand though is this sentence in the book:
that you will want to merge back into your master branch at some point
The above sentence signifies that we want the changes that are on the release
branch to be merged into the master
branch later on. The problem is, when we do git merge -s ours release
(step 4 in your comment), we are actually doing a fake merge, so all changes that were introduced before the backported bugfix commit (on release
) will not be merged when we later merge release
into master
(step 6), because these commits were "fake-merged" into master
already.
The sentence in the book:
and also merge -s ours the same branch into your master branch (even though the fix is already there)
should also be modified as it is not clear whether the same branch
refers to bugfix
or release
. Initially I thought it referred to the bugfix
branch.
I hope that one day I will make pull request with possible improvement of this section.
fix :
This [--ours merge strategy] can often be useful to basically trick Git into thinking that a branch is already merged when skipping specific commits in merging.
For example, say you branched off a release branch and have done some work on it that you will want to merge back into your master branch at some point.
step 1
In the meantime some bugfix on master needs to be backported into your release branch.
bug fix is made on the master branch
You can merge the master branch into the release branch
bugfix on master needs to be backported into your release branch
step 2
merge -s ours the master branch into your release branch
bugfix on master needs to be skipped into your release branch
step 3
some bugfix on master needs to be backported into your release branch.
merge the master branch into the release branch
step 4
merge release branch into master branch
In short: common ancestor. Whenever you do a merge, git will find a common ancestor of the current branch and the branch to be merged. Then git merges commits after the common ancestor from the other branch into current branch.
See :
https://stackoverflow.com/questions/5077688/why-would-one-use-git-merge-s-ours https://stackoverflow.com/questions/727994/git-skipping-specific-commits-when-merging/729723