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
There's no need to redo the same changes in a different branch when you can just copy the same commits to the other branch. Please note that cherry-picking commits will create a fresh commit with a new hash in the other branch, so please don't be confused if you see a different commit hash.
Cherry-pick using Git commit hash In order to cherry-pick changes, you will need to identify your commit hashes. In order to see the commit hashes for your current branch, simply run the “git log” command with the “–oneline” option in order to make it more readable.
The commit hash is an SHA-1 hash made up of a few properties from the commit itself. As mentioned above, it is a lot more complex than this post can go into, but understanding the fundamentals is a great first step. The git hash is made up of the following: The commit message. The file changes.
Cherry-pick a commit Similar to cherry-picking a merge request, you can cherry-pick the changes directly into the target branch or create a new merge request to cherry-pick the changes. When cherry-picking merge commits, the mainline is always the first parent.
Cherry-picking is essentially copying (the effects of) a commit. You can think of it the way you obviously are—i.e., 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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With