我的场景:我有一个分支 B,它是从分支 A 创建的。我在分支 B 中做了一些提交,我想将其挑选到分支 C(类似于 A)中。我不想将 B merge 到 C 中,因为我不想让 A 中的某些东西进入其中。
我的问题:当我对 B 的提交进行 cherry-pick 时,我在分支 C 中发现了一些冲突点。这不是解决它们的问题,除了在分支 B 的冲突更改 block 中,那里有一些来自 A 的东西。
那么为什么我看到 A 中的任何内容都没有直接添加到 B 中却出现在 C 中并且我正在挑选提交?我猜这与冲突有关,因为没有其他来自 A 的东西过来,只有冲突线周围的东西。
在我下面的屏幕截图中,红色括号中的所有内容最初都在 A 中,但在 C 中不存在。我真正想要的唯一一行是最后一行。这也发生在另一个文件中。
最佳答案
当要挑选的 Material 存在冲突时,Git 会做它总是做的同样的事情:
- 查看 merge 基础版本;
- 查看
HEAD
版本;和 - 查看待 merge 的版本。
如果你设置merge.conflictStyle
至 diff3
(我愿意),您将在冲突区域看到所有三个版本,而不仅仅是这三个版本中的两个。我发现这有助于了解 Git 所看到的内容。
So why am I seeing anything from A show up in C when it wasn't directly added in B and I'm cherry picking the commits? I'm guessing this is related to the conflict because nothing else from A is coming over, just the stuff around the conflict line.
这是正确的:问题是 Git 必须找到一个 merge 基础 提交来决定“你改变了什么”——这是将 merge 基础与你当前的或 HEAD
进行比较的结果。提交——以及“他们更改了什么”,这是将 merge 基础与“他们的”提交进行比较的结果。
你在所有这一切的开头提到了“分支”:
I have branch B which was created off of branch A. I make a few commits in branch B that I want to cherry-pick into branch C (which is similar to A).
但事实上,Git 基本上根本不关心分支。 Git 只关心提交——分支对 Git 很重要,因为分支名称允许 Git 找到单独的提交。它有助于绘制出实际的提交(并且,如果您愿意,还可以包括让我们和 Git 找到这些提交的分支标签):
H--I--J <-- branch-B
/
...--E--F--G <-- branch-A
\
K--L <-- branch-C
我用整 block 布制作了这张图,它看起来可能与你的图很不一样,但它现在让我们可以用奇怪的方式来说明 git cherry-pick
识别 Git 中的 merge 基础提交。
如果我们“在分支 C”上为 git status
可能会说,我们的HEAD
提交是提交 L
,分支C的尖端。如果我们然后运行 git cherry-pick <hash-of-commit-I>
, Git 进行这些分配:
- merge-base = commit H
- 负责人或
--ours
= 提交 L -
--theirs
= 提交我
然后 Git 将比较(如 git diff
)提交 H
反对提交 I
看看他们做了什么——那是我们想要采摘的樱桃——但也是 diff commit H
反对提交 L
,看看我们改变了什么并寻找冲突。
如果存在 冲突,Git 会向我们展示双方对 merge 基础版本所做的操作 H
,实际上并没有向我们展示 merge 基础版本 H
本身。这可能包括我们不想要的东西:我们通过从 H
“向后”“删除”的东西至 L
. Git 是否显示了 merge 基础版本 H
同样,我们可以看到我们“删除”了我们不想要的东西,因此在解决 merge 冲突时我们应该“保持删除”。
关于git cherry-pick 冲突包括不需要的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46588120/