-1

By using git cherry-pick, I've been trying to specifically merge the last commit from one branch to another. But it always results in a merge conflict, when it actually shouldn't. Following is what I've been doing, and it always results in conflicts.

  1. Initiate a new repository, and commit a fresh new file on master branch. The file would have the following content -
MASTER - 1st commit
  1. Checkout to a new branch called testing, and make the following changes to the file, and commit again.
MASTER - 1st commit : TESTING 1st commit

3.) Make further changes, on the same line of the file and commit again. So at the end, the file contents would look like the following.

MASTER - 1st commit : TESTING 1st commit : TESTING 2nd commit

Now, this would leave us with 1 commit on master branch, and 2 commits on testing. So if we were to checkout master and do a git merge testing, then since, there's a direct path between the last commit from master and the last commit to testing, therefore, git will use the fast forward technique, and without any merge conflicts, it will directly incorporate changes from testing to master. So my question is why this isn't the case when I try git cherry-pick testing (i.e merging the last commit from testing to master, which in turn has a direct path to it). If I'm being wrong here, then please suggest, what would be the correct way to do this.

ansme
  • 413
  • 2
  • 11
  • Git isn't clever enough to figure out where to put that added ` : TESTING 2nd commit` since the line was edited twice. – tkausl Jul 03 '22 at 15:29
  • @tkausl Yes, but if do `git merge testing`, then git recognises that there's a direct path between the commits, so it uses fast forward to merge testing into master, hence resulting in no conflicts. So what would be the way to achieve the same with cherry pick? I just want to only merge the last commit from testing into master, without including any other commits that I made before the last one. – ansme Jul 03 '22 at 15:36
  • 1
    You can't compare commit and cherry-pick. Cherry-pick _does_ recognize the path between master and testing, but it _can't_ know how to apply only the last change of the line without applying also the previous changes. – tkausl Jul 03 '22 at 15:38
  • Okay, I see. This is because of the absence of the previous commits. So it seems there's no choice but to resolve conflicts in such a case. – ansme Jul 03 '22 at 15:42
  • 2
    `cherry-pick` explicitly ignores the path to the commit you're picking. It considers only that commit and none of its ancestors. (You wrote "git cherry-pick testing (i.e merging the last commit from testing to master". But that's not what cherry-pick does. It does not merge anything. It takes a single commit, in isolation, and tries to apply it to the current branch.) – Raymond Chen Jul 03 '22 at 17:00
  • "I try git cherry-pick testing (i.e merging the last commit from testing to master)" you are not merging!! you are applying the second commit to master. You don't cherry-pick a branch, you are cherry picking the commit pointed by testing – Ôrel Jul 03 '22 at 18:12

1 Answers1

1

The patch that gets applied is different in both cases.
Additionally, git merge has this "fast forward" feature, where, if it determines that one way to produce the correct merge is to simply move branch A to where branch B stands, it just does this and this always results in a conflict free resolution.

In the example you describe :

  • it so happens that testing is ahead of master, so the merge can be resolved using a fast forward without conflict,
  • it so happens that the commit you selected in your cherry-pick command creates a patch which can't be applied as is on your current commit, hence the conflict

In the example you describe :

  • cherry-pick wouldn't conflict if you applied both commits :

    git chery-pick <1st commit> <2nd commit>
    

this would produce the same end result as running git merge testing : all the changes on testing would be added on top of master.

A more systematic way to apply all commits on a branch using cherry-pick is :

# you don't have to name the commits one by one :
# let git compute that for you
git cherry-pick master..testing
  • if you really need to apply only <2nd commit> and exclude <1st commit> :

<2nd commit> has a diff which says :

# replace the line that says 'MASTER ... 1st commit'
# with a line that says 'MASTER ... 2nd commit'
-MASTER - 1st commit : TESTING 1st commit
+MASTER - 1st commit : TESTING 1st commit : TESTING 2nd commit

you try to apply it on a branch where that file's content is :

# uh oh, no line saying 'MASTER - 1st commit : TESTING 1st commit'
MASTER - 1st commit

so you're bound to have a conflict.

LeGEC
  • 46,477
  • 5
  • 57
  • 104