I am trying to learn how to use git cherry pick, I read the manual pages that git
returns by doing git cherry-pick --help
but that did not seem to help. I will try and explain the problem below. I have two branches master
and other
.
On branch master
The commit history is
0x2 Second commit from master branch
0x1 Initial commit
And the only file in the repository that I am tracking readme
has the following contents
Some text
On branch other
The commit history is
0x5 CHECKPOINT, going to cherry-pick onto master
0x4 second commit from branch other
0x3 first commit from other branch:
0x2 Second commit from master branch
0x1 Initial commit
And the contents of the readme
file are
Some text.
Adding some text from other branch. Adding some more text.
Going to cherry-pick this commit.
The working directory is clean on both branches with no untracked changes. From this point on when I switch to the master branch and merge with git merge other
the merge happens gracefully with no merge conflicts. But when I try git cherry-pick 0x5
there is a merge conflict, I get the following output from git
error: could not apply 0x5... CHECKPOINT, going to cherry-pick onto master
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
And the readme
file has the following contents
<<<<<<< HEAD
Some text
=======
Some text.
Adding some text from other branch. Adding some more text.
Going to cherry-pick this commit.
>>>>>>> 0x5... CHECKPOINT, going to cherry-pick onto master
Why is there this merge conflict? I am trying to understand why it occurs. Shouldn't cherry-pick
ing be the same as trying to make all the edits made on the commit that is to be cherry-pick
ed yourself and then commiting that change onto the branch (master
in this case)?
Also when exactly is there a merge conflict in git
? I seem to get them at weird times. Is this implementation dependent (for example dependent on the algorithm used to merge)?
Thank you!
I just tested that scenario, after reading:
If the modification to the first line (Some text.
instead of Some text
) was done immediately after 0x2, as in 0x3, then git cherry-pick 0x3
works without conflict.
But if that same change is done a few commits later, the git cherry-pick
won't generate a patch compatible with the content of 0x2.
There is no notion of "common ancestor" here (as incorrectly stated here): only of "patch".
A git cherry-pick
, even if it uses merging strategies, is not a git merge
.
git merge
will look for a common ancestor (going back in the history of commits of 0x5, to find a common commit with 0x2: here 0x2 itself)git cherry-pick
only creates a patch by doing a unified diff between two commits (by default, the commit you mention and its immediate parent 0x4)The point is: that patch won't be able to be applied on top of 0x2.
Try if for yourself: a git cherry-pick 0x5
is like doing a git diff -p 0x4..0x5
.
You will see in that patch lines which are not part of 0x2, and reflect changes coming from 0x3 or 0x4.
Such a patch cannot be applied on 0x2, as it is based on a content which does not exist for 0x2.
I have created a test repo in which I made from master two modifications.
Here what my patch looks like:
C:\Users\vonc\prog\git\tests\cp>git diff -p dev~..dev
diff --git a/f b/f
index 2b6dd7b..1c4bb79 100644
--- a/f
+++ b/f
@@ -1,4 +1,4 @@
-"Some text"
+"Some text."^M
Adding some text from other branch. Adding some more text.
I cannot apply (cherry-pick) that commit onto 0x2, as 0x2 has no line "Adding some text from other branch
" yet. It only has one line "Some text"
.
That is why git reports a conflict: the content has diverged, and that patch is supposed to change line 1 on top of a file including "Adding some text from other branch
", which 0x2 does not have.
This differs from a git merge
of course, as a git merge will look for a common ancestor (here 0x2) and reports all modifications since 0x2 onto 0x2 without any issue.