2

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
SwissCodeMen
  • 4,222
  • 8
  • 24
  • 34
Lola
  • 2,591
  • 6
  • 24
  • 49
  • 2
    Does this answer your question? [How to copy commits from one Git repo to another?](https://stackoverflow.com/questions/37471740/how-to-copy-commits-from-one-git-repo-to-another) – Liam Jun 11 '21 at 12:18
  • 1
    @Liam this ticket is not answer for me. I tried --strategy-option and other. but still have problem with deleting changes in non-existing files – Lola Jun 11 '21 at 12:26
  • @liam This ticket does not describe my problem at all – Lola Jun 11 '21 at 12:28
  • Put what you have tried (the actual commands and their outputs) into your question. – torek Jun 11 '21 at 12:30
  • I guess it would make sense to ask: what is the history of `file2` in the _branches_ involved? Was it renamed to file3 in the branch that is in repo2? Because I can't think of a straight answer why git would confuse file3 (which appears to be present in both branches) with file2 which is only present in the branch of repo1. – eftshift0 Jun 11 '21 at 12:37
  • What I would expect from git in this case is to get a tree conflict because of the missing file in the branch of repo2. – eftshift0 Jun 11 '21 at 12:39
  • @eftshift0 File2 was in repo2 a year ago – Lola Jun 11 '21 at 12:50
  • I would like to git hadn't done anything in this case. When new changes are added, the git creates a file. If changes are deleted, it would be logical not to do anything – Lola Jun 11 '21 at 12:50

2 Answers2

7
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.

torek
  • 448,244
  • 59
  • 642
  • 775
  • 1
    I didn't know about `--no-renames`. @tokek knows all the good stuff, as usual. – eftshift0 Jun 11 '21 at 12:58
  • 1
    @eftshift0: `-X` or `--strategy-option` and then `no-renames`: it's one of the options to the merge strategy. If you have an old Git you have to use the old `rename-threshold` control knob and lower it to zero. – torek Jun 11 '21 at 13:05
4

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
LeGEC
  • 46,477
  • 5
  • 57
  • 104