Home > Software design >  Cherry picking a later commit from a previous commit does not ask for resolving merge conflicts
Cherry picking a later commit from a previous commit does not ask for resolving merge conflicts

Time:12-22

With the following sequence of commands:

#!/bin/bash

git init

# Below is first commit
touch a.txt
echo "first commit in a" > a.txt
git add a.txt
touch b.txt
echo "first commit in b" > b.txt
git add b.txt
git commit -m "first commit"

# below is second linear commit
echo "second main change to a in master" > a.txt
echo "second main change to b in master" > b.txt
git add a.txt b.txt
git commit -m "second commit"

# create branch from first 
git checkout -b branch_for_a HEAD~1

I am setup like so:

enter image description here

So, at present HEAD = branch_for_a and HEAD and master are completely different in that both a.txt and b.txt are changed between the two commits.

When I now issue: git cherry-pick master, I would expect that I would have to resolve merge conflicts for both a.txt as well as b.txt. However, git replaces my working directory with the a.txt and b.txt from master with no requirement to resolve the conflict. I would like to understand why this is so.


However, instead of issuing git cherry-pick master, if I instead create a new commit with changed a.txt and b.txt onward from branch_for_a like so:

echo "branch a" > a.txt
echo "branch b" > b.txt
git add a.txt b.txt
git commit -m "branch commit"

I am in this situation now:

enter image description here

If I issue git cherry-pick master now, git indicates that I have to resolve merge conflicts in a.txt and b.txt which I can understand as correct.


I am unable to understand why no merge conflicts were required to be resolved in the first case.

CodePudding user response:

For context, when you cherry-pick a commit and get a conflict, it's because you are attempting to "merge" that commit by itself.

In the first case, no merge is necessary at all because master is already exactly in the position you're trying to place it. In other words, if you have branch_for_a checked out, the following commands would result in the identical state afterwards:

  1. git merge master
  2. git cherry-pick master

Using cherry-pick in this instance will still rewrite the commit and change the ID, but it's not possible to have a merge conflict because the commit you are picking already has branch_for_a as its parent.

In order to have a conflict, the commits must have different parents, and the changes to the file must overlap near the same lines of the file. In the second example both of those conditions were met. A more detailed explanation can be found here.

  •  Tags:  
  • git
  • Related