Understanding Git Cherry Pick conflict

2020-06-06 07:04发布

问题:

We recently switched from SVN to GIT, and I'm having some trouble converting our previous workflow. Mostly everything works, but today I got a weird cherry-pick conflict.

I'm able to resolve the conflict, but I would like to know where this came from, because to my understanding there shouldn't be a conflict in this situation.

Setup

In our repository we have a master branch on which we develop. Four times a year we release a new version. We branch of of master into Release-x and this gets shipped after testing.

We have several release-versions in production at the same time. If a bug is found, this has to be fixed on all (supported) release branches. So a single release branch using tags to identify the different releases isn't a valid workflow.

So we currently have these branches: master, Release-15Q1, Release-15Q2 and Release-15Q3

Say for example we found a typo causing a bug in master, we would fix it and then cherry-pick it onto Release-15Q1, Release-15Q2 and Release-15Q3

So, now onto the conflict I'm facing:

The file properties.dat was changed in master, after branching Release-15Q3

Properties.dat (Release-15Q3)

serverip=1.1.1.1
serverport=11
name=MyApp

Properties.dat (master)

serverip=2.2.2.2
serverport=22
name=BetterName

Development went on... all good. Then we noticed a bug where we needed to add an extra property to the file to disable the bug.

Properties.dat (master)

  serverip=2.2.2.2
  serverport=22
  name=BetterName
+ allowBug=false

This fix-commit also needs to be applied to the three other branches. So I go to each branch and use the cherry-pick command.

This is giving me conflicts on the first three lines, but I don't really understand why.

I was under the assumption that with cherry-picking you would only replay that specific commit, so only add the allowBug=false line at the right spot. It shouldn't matter if other changes were made, right?, because I'm not merging the branches?

Why is this giving a conflict? Shouldn't these other changes be ignored?

回答1:

When cherry-pick is issued, first git computes the differences with its parent. This results in a diff-file (a.k.a. patch). This patch not only contains what has changed (i.e., + allowBug=false) but also the surrounding context of the changed line(s). Hence, the patch file would look something like:

@@ -1,7 +1,7
serverip=2.2.2.2 
serverport=22  
name=BetterName
+ allowBug=false

Once the patch is computed, git will try to apply it into your release branch. The context lines of the patch files (those without +/-) tells git where to apply the + allowBug=false. Since the surrounding context cannot be found in the Properties.dat on release branches, the patch cannot be applied and git raises a conflict.

A bit late, but hope it helps :)

EDIT: you might have a look at git cherry-pick: how consider only lines modified by the commit (i.e., not the surrounding context)?