While the git cherry-pick operation is common in Git, it's usually not the best solution. Sometimes this is the lesser of two evils, but I have not yet seen a situation where it would be appropriate.
This is the first part in a series that starts with explaining why copying is bad, continues with why itβs terrible, and then describes how to get the same result using merge. I'll show you how to apply this technique when you need to do a retroactive merge and when you want to fix copy-to-merge before something bad happens.
Two branches are involved in copying: the donor (where the commit comes from) and the receiving (where it is copied). Let's call them master and feature respectively. For simplicity, let's assume that the commit you are copying contains the change in only one line of a single file. In this diagram, each commit is marked with the contents of that line, and the dashed arrow indicates the copy (operation git cherry-pick
) itself.
Note that the shaded arrow does not physically exist in the repository, it is only in our heads to keep track of timeline.
There is some common ancestor of A with the "apple" line commit. Then the branches diverge, the F1 commit is in the feature branch, and M1 is in master. These commits do not affect the line in question, so they are still labeled "apple". We then commit F2 to the feature branch, which changes the content of our line to "berry", and then copy F2 to the master branch called M2.
So far, nothing unusual has happened.
Time goes by, the repository tree is enriched with new commits:
We committed M3 to master and F3 to feature. Both commits bypass our line, so it's still "berry".
feature master. , , "berry".
, , , .
. F2 3 master F3 feature, F3 "cherry". , feature, , "cherry". , :
feature master . (three-way merge) "apple", feature "cherry", β "berry".
<<<<<<<<<< HEAD (master) berry ||||||||| merged common ancestors apple ========= cherry >>>>>>>>>> feature
, , . , .
, , , feature.
( , .). ?
, "apple". victim A V1, . V1 feature : F1 , "apple". master 1, .
. feature "berry" F2, master M2. "cherry" feature F3. master 3, , master "berry".
victim "-" feature master. V2 V3, "apple".
- , feature victim, V4 , "cherry" feature.
"" victim, master. ! : "" F2 M2. , , , () , .
In short, the problem: when git cherry-pick
two copies of one commit appear in the tree. If at least one of its lines changes before merging its copies, then an unforced collision will arise. Moreover, this can happen in a week or a year. This means that the one who will resolve it may simply not have the resources to make the right decision (he did not copy, the team completely changed, etc.).
However, all of this Santa Barbara could get worse if the conflict doesn't happen!
Why? Read on in the next part.