user3929024
user3929024

Reputation:

Git merge strategy --ours use case

I read Pro Git book and came across the following use case of ours merge strategy:

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

Could someone please explain me how in this scenario a possible conflict between master and release branches occurs? And why do I need to fake that I have already merged bugfix branch to master?

Let's assume bugfix branch introduces 1 line change in a single file. If I already have this changed line on master branch, then merging in release branch containing the same changed line (because of merge with bugfix branch) won't cause any conflict.

Upvotes: 2

Views: 1950

Answers (1)

jthill
jthill

Reputation: 60443

The prose is a little hard to unpack, and I think the payload clause:

even though the fix is already there

should really really not be in parentheses.

The situation described is a bug fix that's already on master and also exists on some bugfix branch that hasn't been merged in to master. Perhaps it was cherrypicked as a hotfix "too important" to maintain a sane history for?

Whatever, the paragraph is attempting to illustrate one kind of situation where you'd want a -s ours merge, and now that I think about it I think it's a very good illustration of one such: confused, probably the result of some thoughtless cherrypicks/squash merges, you're just trying to figure out how to correct the record without disrupting all the work that's happened since, because what you've got now is lies:

  B1..B2         bugfix
 /
*...B'...        master
 \
  `--...         release

So what really happened here is, some thoughtless moron, probably me, squash-merged bugfix onto master because it was easiest or something. You came across this and just barely stopped yourself from calling me up and feeding me a choice selection of the thoughts crossing your mind, because even though I've horribly abused squash merging here, hey, there's an easy solution:

git checkout release; git merge bugfix
git checkout master; git merge -s ours bugfix

producing a history graph probably best drawn as

  ,--...*...o     release
 /         /
*--B1--B2-'       bugfix
 \         \
  `...B'...-Bx    master

Which is not quite right, but is as close to right as you're going to get short of having to force-push the history I should have made. The commit message for Bx should probably read "-s ours merge of bugfix recording the squash merge at B'" or something similar.

Now both humans and machines can easily see what happened and reason about the histories being merged: a subsequent merge from release to master won't try to apply the changes in B1 and B2 because it sees they've been merged.

Upvotes: 2

Related Questions