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:
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:
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:
git merge master
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.