git - 樱桃选择问题 : changes from previous commits are also applied

标签 git cherry-pick git-cherry-pick

在我的项目中,我几个月前发布了一个版本。在那个版本之后,我在 master 分支上做了很多改动。

如果我遇到上一个版本中存在的一些错误,我会在主分支上修复它们,然后将它们挑选到我在上一个版本中创建的分支。然后我可以提供一个只修复错误的新版本,而不会在 master 分支上发布未完成的工作。

当我尝试为发布分支挑选某个错误修复时,我遇到了 merge 冲突。

据我了解,樱桃选择某个提交会向目标分支引入一个新的提交,并在樱桃选择的提交中完成更改。

但是,当我尝试修复 merge 冲突时,似乎 git 已经在 master 分支上应用了更改,这些更改不是由cherry选择的提交引入到我的发布分支。 cherry-pick 的提交只向冲突文件引入了几行。但是,当我尝试解决冲突时,我看到文件中还引入了其他几行,这些行已添加到具有不同提交的 master 分支。

有人可以解释为什么我的发布分支中引入了除樱桃选择提交之外的其他提交的更改吗?

最佳答案

As I understand, cherry picking a certain commit introduces a new commit to the target branch, with the changes done in the cherry picked commit.



那是正确的。但是,这些更改可能不会完全适用,在这种情况下:

... I encountered a merge conflict.



此时,git cherry-pick正在做三路 merge ,这需要选择一个 merge 基。

我记得,哪些文件或提交用作 merge 基础部分取决于您的 Git 版本。现代 Git,如果你运行 git cherry-pick , 使用精选提交的 parentmerge base ,但至少有一种形式(使用 git amgit apply--3way 选项,git rebase 仍然可以这样做)可以使用 index 挑选出更早版本的文件git diff 行输出。最后,这可能不会太重要。

在任何情况下, merge 实际上都会运行 git diff从基本提交到两个“提示”中的每一个(樱桃选择的提交,以及您尝试应用樱桃选择的 HEAD 提交)。为了直观地看到发生了什么,您应该像往常一样从绘制提交图开始。 (我没有你的存储库,所以我会画一个不同的图,希望它足够接近。但你应该画你自己的——或者让 Git 来做,或者使用 gitk 或类似的东西。)
          o--@         <-- branch (HEAD)
         /
...--o--o
         \
          I--P--C--o   <-- otherbranch

我在这里为各种提交提供了单字母名称:C是我们将要挑选的提交,以及 P是它的父级。我将我们当前的 (HEAD) 提交标记为 @在这里,虽然所有真正的工作都将发生在索引和工作树中。 (幸运的是 git cherry-pick 要求索引和工作树是“干净的”,除非您使用 -n 将多个樱桃组装成一个大选择,因此索引和工作树无论如何都会匹配提交 @。)而且,我标记了提交 I作为“重要”。

现在,考虑如果我们对 P 进行三向 merge 会发生什么为基础,C作为提交之一,和 @作为另一个提交。当我们计算更改指令时 P进入 C ,我们得到了我们想要应用的差异:这非常简单。但是当我们计算改变指令时 P进入 @ ,嗯,呃。

我们在 I 中做了一些重要的更改.这些更改是 P 的一部分,即它们在我们的 merge 基础中。但它们不在 @ . merge 的含义是 Git 会将这些重要的更改视为我们试图取消的事情。事实上,他们是!我们没有挑剔I本身,所以我们必须撤消这些 I更改以应用来自 C 的更改.

凡是那些I我们正在“撤消”的更改不在 @ 中开始并且不影响来自 C 的任何更改,我们很好:它们已经被撤消了。如果出于某种机会或目的,其中之一 I更改在 @ (也许通过 @ 的父级),那些甚至不在我们首先试图撤消的集合中,所以我们再次很好。当这些变化与 P 冲突,甚至只是与(上下文)相冲突时-至- C变化,我们有问题。

在这种情况下,Git 将在两个 merge 冲突区域之一中显示一些 I变化。这些是我们试图挑选的部分。它们不一定被应用,它们只是我们必须解决的冲突的一部分。如果你设置 merge.conflictStylediff3 ——我通常推荐的东西——I更改将显示为 merge 基的一部分,因为 merge 基是提交 P ,它本身基于 I (即, P 的快照包含来自 I 的代码,除了我们在制作 P 时对其进行了更改)。

所以,我并不完全清楚你在问什么,但在 merge 冲突区域看到与你挑选的位无关的变化是正常的。

关于git - 樱桃选择问题 : changes from previous commits are also applied,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42530381/

相关文章:

git - 读取 git 的最后一次提交和提交编号

git - 你能从 git 提交中挑选一个或多个大块头吗?

git - 在这些场景下使用 git cherry-pick 是否合适?

git - 强制 git 接受 cherry-pick 的更改

git 比较两个分支,其中包含一些具有不同哈希值的公共(public)提交

git - 在 merge 了精选提交的分支上 pull 请求

linux - 删除了一个存储库,现在遇到严重问题,重新提交到我创建的新存储库

git - 是否可以将 git 提交消息保存到预提交 Hook 中的文件中?

git - 你如何保持 git 下游的 Perforce repo 更新?

eclipse - 如何在没有历史记录的系统上从分支 A 挑选到分支 B?