progit2 icon indicating copy to clipboard operation
progit2 copied to clipboard

Help with --ours merge strategy trick needed

Open hedrok opened this issue 9 years ago • 5 comments

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!

hedrok avatar Sep 30 '15 17:09 hedrok

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 ;;)

mjg avatar Oct 06 '15 15:10 mjg

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...

hedrok avatar Oct 07 '15 10:10 hedrok

I think what happens is:

  1. there is a release branch and a master branch
  2. a bug fix is made on the master branch
  3. 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.
  4. fake merge the bug-fixed release branch into the master branch
  5. develop on the release branch
  6. 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 avatar Apr 18 '22 03:04 yushih

@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.

admksh avatar May 21 '22 07:05 admksh

I hope that one day I will make pull request with possible improvement of this section.

KZiemian avatar Aug 27 '22 14:08 KZiemian

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

devLiuGit avatar Dec 27 '23 05:12 devLiuGit