'git cherry-pick' 如何找到要应用更改的文件?

How does 'git cherry-pick' find the file(s) to apply the changes to?

我有两个结构相似的存储库,但没有共同的提交。我已将它们添加为彼此的遥控器,以便能够 cherry-pick 在它们之间提交。

最近,我注意到 git 正确地应用了提交的更改,即使存储库中的文件路径不同(并且文件本身也不同)。 git 如何找到要应用更改的文件?它会查看当前快照中的所有个文件吗?

git cherry-pick eacf32b 将获取描述提交 eacf32b 补丁 ,并尝试将其应用到当前提交之上。

所以是的:如果查看 cherry picked 提交描述的 "snapshot" 中的所有文件。


更完整的答案是:git cherry-pick 执行 merge-like 操作来应用补丁。

开始于:

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

如果你 运行 git cherry-pick D,它将应用 merge-like 操作,使用 C 作为 "base content",D 作为 "theirs" 和 F 为 "ours",就像您将某些内容与以下历史记录合并以构建 D' :

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

所以 git 也会查看 CF 之间的差异,并且可能会检测文件重命名或在 C..D 上应用补丁 C..D 时触发冲突=24=]

参见 phd's suggested duplicate, How do cherry-pick and revert work?,因为 cherry-pick 确实使用了 git merge

请注意 git merge 运行s git diff --find-renames(好吧,无论如何,它的内部等效项)。这是发现哪些文件是从哪些其他文件重命名的步骤。要了解 that 的工作原理,请参阅我对 and 的回答。 rename-detector 在 上 运行 差异:

  • git diff <em>parent</em> <em>child</em>, where child 是被 cherry-picked 的提交,parent 是它的父级;和
  • git diff <em>parent</em> HEAD,找到合并操作的 "our" 侧的变化。请注意,这里的 parent 是被 cherry-pick 提交的父提交,而不是 HEAD 本身的父提交。

通常,parent-vs-child 几乎没有重命名(大多数人不会 cherry-pick massive-rename 操作),但是 parent-vs-HEAD 可能有大量重命名需要检测。