为什么 git cherry-pick 冲突包括来自上一次提交的更改

Why is git cherry-pick conflict including changes from a previous commit

我有一个暂存分支,我在其中对某个功能进行了一些提交,我需要改为从主分支进行这些提交。我尝试使用 master 分支签出一个分支 git checkout -b branch_name,然后进行了我想从暂存分支中挑选的第一个提交 git cherry-pick hash。由于某种原因,与 cherry pick 存在冲突,但冲突包括从之前的提交到 cherry-pick 的提交的更改,这是为什么?

TL;DR 与其他 VCS 相比,您所看到的内容与 Git 如何记录和存储文件历史直接相关。

基础知识

掌握它的最简单方法是考虑 revision(或 version)的概念。

传统上,版本控制系统通过存储文件现在和以前版本之间的差异来记录工作目录中文件的修订(这也称为 delta 或 Δ).

另一方面,

Git 通过存储当前工作目录中所有文件的 快照 来记录修订。

最好用 an image used in the Pro Git 书来说明:

在这里,您将看到传统的 VCS 如何只存储每个文件在修订之间的差异。

在 Git 中,它看起来更像这样(再次 from the Pro Git book):

您会看到每个修订都与工作目录中所有文件的 快照 相关联。但是,the documentation 指出:

To be efficient, if files have not changed, Git doesn’t store the file again—just a link to the previous identical file it has already stored.

但是,从概念上讲,您仍然可以认为每次提交都指向整个工作目录的快照。

摘樱桃

现在,考虑一下当您挑选一个提交时会发生什么。假设我们想要挑选对应于 Version 5:

的提交
git cherry-pick <version-5>

Git 将 HEAD 引用的提交关联的快照(即您工作目录中的文件)以及与 [=14= 关联的快照].

现在,如果 version-4 修改了 file B 中的一行(导致 file B1),其方式与 file B 在您的工作目录中的样子相冲突,你会遇到冲突。这是重要的部分:

The conflict is going to happen even if version-5 (the one you're cherry-picking) modified the same file B in a way that does not conflict with anything.

那是因为与 version-5 关联的快照包含 file B2,这是 file B 之前所有修订的结果。