a.txt git add a.txt git commit -mbase # create branch" /> a.txt git add a.txt git commit -mbase # create branch" /> a.txt git add a.txt git commit -mbase # create branch"/>

How can I disable git cherry-pick from applying the diff of one file to another?

76 Views Asked by At

The steps to reproduce my case,

git init foo
cd foo

# add initial a.txt on "master"
echo hello > a.txt
git add a.txt
git commit -mbase

# create branch "new"
git branch new

# on "master", rename a.txt to b.txt
git mv a.txt b.txt
git commit -m'rename a.txt to b.txt'

# on "master", modify b.txt
echo world >> b.txt
git commit -am'world b'

# on "new" rename a.txt to c.txt
git switch new
git mv a.txt c.txt
git commit -m'rename a.txt to c.txt'   # Anchor 1

# apply the commit in which b.txt is modified
git cherry-pick master

As on branch new, b.txt does not exist and it has only c.txt, I expected git cherry-pick to fail due to conflicts. However, it succeeded and applied the diff of b.txt to c.txt.

I guess it's related to the fact that b.txt and c.txt are considered as being copied from the same origin a.txt, and maybe also some git merge strategy. I had a try to solve the issue,

# remove foo, run the commands again, and pause at # Anchor 1

# introduce b.txt from "master" to "new"
git checkout master -- b.txt
git commit -m'add b.txt from master'

# apply the commit in which b.txt is modified
git cherry-pick master

This way, it complains nothing to commit, working tree clean as expected. But, in one of my projects the situation is very common, and I cannot abandon git cherry-pick in the workflow. As the creation and renaming are not under my control, I cannot ask other team members to always apply all new files to other branches where they are not necessary at all.

Is there any solution to disable git cherry-pick from applying the diff of one file to another without any bad side effect? Thanks.

I tried git 2.19.2, 2.24.1 and 2.39.0 on Ubuntu.

1

There are 1 best solutions below

2
grg On BEST ANSWER

The ‘resolve’ merge strategy…

[…] does not handle renames.

https://git-scm.com/docs/git-merge#Documentation/git-merge.txt-resolve

Use --strategy to choose ‘resolve’.

https://git-scm.com/docs/git-cherry-pick#Documentation/git-cherry-pick.txt---strategyltstrategygt

Continuing from anchor 1 as an example:

$ git cherry-pick --strategy=resolve master
Trying simple merge.
Simple merge failed, trying Automatic merge.
ERROR: b.txt: Not handling case … ->  -> …
fatal: merge program failed
error: could not apply …... world b

$ git status
On branch new
You are currently cherry-picking commit ….

Unmerged paths:
    deleted by us:   b.txt

no changes added to commit