3

Consider the situation created by the following commands:

git init
git commit --allow-empty -m "Initial commit"
git branch first
git branch second
git checkout first
echo 1 > file
echo 2 >> file
echo 3 >> file
echo 4 >> file
git add file
git commit -m "Commit file 1 to 4"
git checkout second
echo 1 > file
echo 2 >> file
echo 3 >> file
echo 4 >> file
echo 5 >> file
echo 6 >> file
git add file
git commit -m "Commit file 1 to 6"
git checkout first
git cherry-pick second

The file on branch first contains numbers from 1 to 4 (each in its own line). The same file on the branch second contains numbers from 1 to 6. The file has been added in both branches as a new one.

Now, if I try to cherry-pick one branch onto another, my dreamed result would be (the file contents):

1
2
3
4
5
6

An acceptable result would be

1
2
3
4
<<<<<<< HEAD
=======
5
6
>>>>>>> 5c9d53e... Commit file 1 to 6

However, git always gives me:

<<<<<<< HEAD
1
2
3
4
=======
1
2
3
4
5
6
>>>>>>> 5c9d53e... Commit file 1 to 6

And I have to do all of the conflict resolution myself.

How to cherry-pick two commits that add the same file (with possibly similar content) on each other? How to make git try to analyze their contents and run into conflict only if it needs to?

Now it behaves like Hey! These commits add the same file so I will throw a whole file conflict here! I'm too lazy to look inside them.

fracz
  • 20,536
  • 18
  • 103
  • 149
  • I think this is supposed to be improved in Git 2.9. It's a bit tricky to implement, basically one must invent a common base, but there *is* a chunk of script code in Git to do that, I just don't know where or if it's invoked. It was modified recently (just before 2.9) though! :-) – torek Jun 23 '16 at 22:04
  • Git 2.9 [has been released almost 2 weeks ago](https://github.com/git/git/blob/master/Documentation/RelNotes/2.9.0.txt). Let me give it a try. – fracz Jun 23 '16 at 22:10

2 Answers2

2
git init
git commit --allow-empty -m "Initial commit"
git branch first
git branch second
git checkout first
echo 1 > file
echo 2 >> file
echo 3 >> file
echo 4 >> file
git add file
git commit -m "Commit file 1 to 4"
git checkout second
echo 1 > file
echo 2 >> file
echo 3 >> file
echo 4 >> file
echo 5 >> file
echo 6 >> file
git add file
git commit -m "Commit file 1 to 6"
git checkout first

#Here is where I did edits:

git cherry-pick --strategy resolve second
git diff HEAD..second
git add file
git commit -C second

You are using the default merge strategy: recursive. The resolve merge strategy will produce the conflict in the state you might want.

$ git diff HEAD..second
diff --git a/file b/file
index 94ebaf9..b414108 100644
--- a/file
+++ b/file
@@ -2,3 +2,5 @@
 2
 3
 4
+5
+6

$ cat file
1
2
3
4
5
6
Bryce Drew
  • 5,777
  • 1
  • 15
  • 27
  • I get the same conflict with the `resolve` strategy (i.e. whole files, not compared at all). – fracz Jun 24 '16 at 18:59
  • Then please update your example to include that. Does doing this to your example data produce files in the format you want? – Bryce Drew Jun 24 '16 at 19:14
  • I mean: when you run my example and replace the last command with `git cherry-pick --strategy resolve second`, the result is the same as with `git cherry-pick second`. The output of the command is different, indeed, but the result is the same. – fracz Jun 24 '16 at 20:21
  • Try running `cat file` this will show the file being in the format as your `dream result`, but also shows that there is a conflict, because there is. The resolve method will put it in the style you want it to be in. If you do a `git diff HEAD..second` it will show up as your `acceptable result`. – Bryce Drew Jun 24 '16 at 20:28
  • In Git 2.5 the `file` contents after `git cherry-pick --strategy resolve second` are the same as without the strategy specified. In Git 2.9, however, the `file` contents after it are `1 2 3 4` (in newlines) which is even more weird. However, I find another nice solution. I'll post it in a while. – fracz Jun 24 '16 at 20:33
  • Please do. For reference, my box is running `git version 1.9.1` – Bryce Drew Jun 24 '16 at 20:37
  • 1
    So, apparently, there are big differences in this behavior between different versions. Thank you! – fracz Jun 24 '16 at 20:40
2

After the cherry-pick one needs to run

git checkout --conflict=merge file

in order to get the acceptable content of the file, i.e.:

1
2
3
4
<<<<<<< ours
=======
5
6
>>>>>>> theirs

Neither --strategy resolve nor the Git 2.9 solved the problem for me, as suggested by @BryceDrew and @torek respectively.

fracz
  • 20,536
  • 18
  • 103
  • 149
  • I like the train of thought you are on. After updating to 2.9: `git diff HEAD..second`, if there are only additions to thiers: `git cherry-pick -X theirs second` if there are only additions to ours, there is no need for a cherry-pick. – Bryce Drew Jun 24 '16 at 21:47