Cherry-pick with changes in a non-existent file

Viewed 602

I have two repos with similar architectures:

repo1:
 - file1
 - file2 *(this file is non-existent in repo2)
 - folder
    - file3
    - file4
    - file5

and

repo2:
 - file1
 - folder
    - file3
    - file4
    - file5

Repo1 is remote for repo2:

git remote add repo1 http://repo1.git

I need to cherry-pick commits from repo1 to repo2

git cherry-pick <commit_repo1>

Usually everything is ok. But I've faced with problem if I want to cherry-pick changes to non-existent file.

Changes look like:

 folder/file4    | 9 ---------
 folder/file5    | 5 -----
 file1           | 5 -----
 file2           | 5 -----
 4 files changed, 24 deletions(-)

In the end: Cherry-pick merge changes from non-existent file to file3. Only for deleting changes

Someone knows how avoid to merge change to wrong file if needed file non-existent?

Attempts:

git cherry-pick --strategy-option theirs <commit_repo1>
git cherry-pick --strategy-option ours <commit_repo1>

Give the same results:

Auto-merging folder/file3 !!! this file was not changes (instead changed in file2)
Auto-merging folder/file4
Auto-merging file1
2 Answers
Auto-merging folder/file3

This looks like a case of over-eager rename detection: Git thinks file3 is a match for the missing file, so it imports the change there.

You can disable rename detection:

-X no-renames

(i.e., git cherry-pick -X no-renames hash, rather than -X ours or -X theirs) to avoid this problem. Alternatively, use git cherry-pick -n so that Git does not commit the result, then fix the edited file by checking out the HEAD version:

git cherry-pick -n <hash>

inspect results, make any desired changes including:

git checkout HEAD -- folder/file3

and eventually:

git commit

to make the new commit.

Why you get this result

When cherry-picking a commit, you have to look at the changes introduced by the commit.

From what you describe, it looks like file2 was present in the parent commit, and somehow git computed that file2 was renamed to folder/file3.

And thus : cherry picking that commit dutifully tries to apply that change.


How to fix this

You can tell git to completely ignore renames (as @torek answered) :

git cherry-pick -X no-renames

You will probably have a conflict on folder/file3 (now git since that you are importing a commit which created folder/file3, but it already exists on your target branch), which you can fix.

Or you can manually fix the issue at hand after your cherry-pick :

# it looks like you want to revert `file3` to its previous state :
git checkout HEAD^ -- folder/file3
git commit --amend
Related