0

I have two repositories with a similar structure, but no common commits. I've added them as remotes of each other to be able to cherry-pick commits between them.

Recently, I've noticed that git correctly applies the commit's changes even if the files' paths in the repositories differ (and the files themselves differ). How does git find the file(s) to apply the changes to? Does it look through all the files in the current snapshot?

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
  • Possible duplicate of [How do cherry-pick and revert work?](https://stackoverflow.com/questions/34572096/how-do-cherry-pick-and-revert-work) – phd Mar 16 '18 at 12:22

2 Answers2

0

git cherry-pick eacf32b will take the patch which describes commit eacf32b, and try to apply it on top of your current commit.

So yes : if looks through all the files in the "snapshot" described by the cherry picked commit.


A more complete answer is : git cherry-pick does a merge-like operation to apply the patch.

Starting from :

--*--*--A--B--C--D
         \
          \
           D--E--F <- HEAD

If you run git cherry-pick D, it will apply a merge-like operation, using C as the "base content", D as "theirs" and F as "ours", as if you were merging something with the following history to build D' :

..*..*..A..B   C--D
         .      \  .
          .      \  .
           D..E   F..D'

So git also looks at the diff between C and F, and may detect file renaming or trigger conflicts when applying the patch C..D on top of C..F

LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • It' can't be `the "snapshot" described by the cherry picked commit` because, as I mentioned, the paths of the corresponding files may differ and `cherry-pick` would still work. – Eugene Yarmash Mar 16 '18 at 12:27
0

See phd's suggested duplicate, How do cherry-pick and revert work? as cherry-pick really does use git merge.

Note that git merge runs git diff --find-renames (well, the internal equivalent of it anyway). This is the step that discovers which files are renamed from which other files. To see how that works, see my answers to Trying to understand `git diff` and `git mv` rename detection mechanism and Git Diff of same files in two directories always result in "renamed". The rename-detector is run on both diffs:

  • git diff parent child, where child is the commit being cherry-picked and parent is its parent; and
  • git diff parent HEAD, which finds the changes on "our" side of the merge operation. Note that parent here is the parent commit of the commit being cherry-picked, not the parent of HEAD itself.

Typically, the parent-vs-child has few renames to find (most people don't cherry-pick a massive-rename operation), but the parent-vs-HEAD may have a large number of renames to detect.

torek
  • 448,244
  • 59
  • 642
  • 775