简体   繁体   中英

what does git cherry-pick {commit-hash} do?

Given that I have 3 commits in order

c1
+ print("A")

c2
+ print("B")

c3
+ print("C")

then I checkout a new branch at c1.

git checkout -b br c1

then I cherry-pick c3.

git cherry-pick c3.

what I want is the file has

print("A")
print("C") 

-- I just pick c3 and c3 just add the line print("C")

but the fact is I got conflicts and the result is

print("A")
++<<<<<<< HEAD
++=======
+ print("B")
+ print("C")
++>>>>>>> f1383aa... C

my question are: 1. why conflicts? 2. what shall i do if I want print("A") and print("C")?

I also tried even I

git diff C^1 .. C > 1.patch
git apply 1.patch

I got

zhifan@zhifandeMacBook-Pro ~/g/demo> git apply 1.patch
error: patch failed: 1.py:1
error: 1.py: patch does not apply

Cherry-picking is essentially copying (the effects of) a commit. You can think of it the way you obviously are—ie, as diff the to-be-picked commit and its parent, then apply that diff to the current commit . However, it's more powerful than a mere diff-and-apply, because it has access to Git's full merge mechanism .

What this means is that git cherry-pick is really a full blown git merge internally, with the two commits being merged being your current commit—your HEAD —and the commit you are cherry-picking. The merge base for this operation is the parent of the commit you are cherry-picking.

The reason to do this is that, as you have seen, you can get a merge conflict if both your HEAD commit and the commit you are cherry-picking have changed "the same" lines. In this case, your HEAD commit added the line print("A") , probably at the end of the file, but in any case right before some other line. Meanwhile, the commit you are telling Git to cherry-pick—commit c3—adds the line print("C") at the same place (at the end of the file, or before the same existing line). Git does not know where to place the added print , so it declares a conflict and makes you choose the correct answer.

The solution is simple enough: open the conflicted file in your editor and adjust it to contain the correct resolution of the conflict, then write this out and use git add on the file so that you can run git cherry-pick --continue to finish up the cherry-picking process. Or, if you prefer, use a merge tool to obtain all three input files (base, "ours" or HEAD , and "theirs" or c3's version) and resolve the conflict that way.

For more about cherry-pick, see What does cherry-picking a commit with git mean?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM