Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 701
zhihuifan Avatar asked Oct 22 '18 12:10

zhihuifan


People also ask

Does cherry pick Create a new commit hash?

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.

How do you cherry pick a 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.

What is a commit hash?

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.

What happens when you cherry pick a merge commit?

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.


1 Answers

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?

like image 86
torek Avatar answered Sep 30 '22 12:09

torek