325

假设我是一个 repo 的维护者,并且我想从贡献者那里获取更改,有一些可能的工作流程:

  1. cherry-pick每次都从远程提交(按顺序)。在这种情况下,git 将提交记录为与远程分支无关。
  2. merge是分支,拉入所有更改,并添加一个新的“冲突”提交(如果需要)。
  3. merge从远程分支单独提交每个提交(再次按顺序),允许为每个提交记录冲突,而不是全部组合在一起。
  4. 为了完整起见,您可以做一个rebase(与cherry-pick选项相同?),但是我的理解是这可能会给贡献者造成混淆。也许这消除了选项1。

在情况 2 和 3 中,git 记录提交的分支历史记录,与 1 不同。

cherry-pick使用所描述的任何一种或merge方法之间的优点和缺点是什么?我的理解是方法 2 是规范,但我觉得通过单个“冲突”合并解决大型提交并不是最干净的解决方案。

4

3 回答 3

320

两者rebase(和cherry-pickmerge都有其优点和缺点。我在这里争论merge,但两者都值得理解。(在这里寻找一个替代的、有充分理由的答案,列举了首选的案例rebase。)

merge出于几个原因,cherry-pick它是首选。rebase

  1. 稳健性。提交的 SHA1 标识符不仅可以识别它本身,还可以识别它之前所有其他提交。这为您提供了一个保证,即给定 SHA1 的存储库状态在所有克隆中都是相同的。(理论上)不可能有人做了看起来相同的更改,但实际上正在破坏或劫持您的存储库。您可以挑选个别更改,它们可能相同,但您不能保证。(作为一个次要的次要问题,如果其他人再次在同一个提交中进行挑选,那么新挑选的提交将占用额外的空间,因为即使您的工作副本最终相同,它们也会出现在历史记录中。)
  2. 易于使用。人们倾向于merge相当容易地理解工作流程。 rebase往往被认为更高级。最好同时了解两者,但是不想成为版本控制专家的人(根据我的经验,其中包括许多非常擅长他们所做的工作但不想花额外时间的同事)更容易时间刚刚合并。

即使使用大量合并的工作流程rebase,并且cherry-pick对于特定情况仍然有用:

  1. 一个缺点merge是混乱的历史。 rebase防止一长串提交分散在您的历史记录中,就像您定期合并其他人的更改一样。这实际上是我使用它的主要目的。您要非常小心的是,永远不要rebase编写您与其他存储库共享的代码。一旦一个提交被push编辑,其他人可能已经在它之上提交了,并且变基最多会导致上面讨论的那种重复。在最坏的情况下,您可能会得到一个非常混乱的存储库和细微的错误,这将需要您很长时间才能找出来。
  2. cherry-pick对于从您基本上决定丢弃的主题分支中抽取一小部分更改很有用,但意识到有几个有用的部分。

至于更喜欢合并多个更改而不是一个:它只是简单得多。一旦您开始拥有大量单个变更集,合并单个变更集可能会变得非常乏味。git(以及 Mercurial 和 Bazaar)中的合并分辨率非常好。大多数时候,即使是长分支,您也不会遇到重大问题。我通常一次合并所有内容,只有我遇到大量冲突时,我才会备份并重新运行合并。即便如此,我还是大块地做。作为一个非常真实的例子,我有一位同事需要合并 3 个月的更改,并且在 250000 行代码库中遇到了大约 9000 个冲突。我们要解决的是一次合并一个月的价值:冲突不会线性累积,并且分段执行会导致很远少于 9000 个冲突。这仍然是很多工作,但不如尝试一次提交一个提交。

于 2009-08-06T22:14:19.000 回答
102

在我看来,樱桃采摘应该保留在需要它的极少数情况下,例如,如果您直接在“主”分支(主干,主开发分支)上进行了一些修复,然后意识到它也应该应用于“维护” '。您应该将工作流基于合并或 rebase(或“git pull --rebase”)。

请记住,从 Git 的角度来看,cherry-picked 或 rebased 提交与原始提交不同(具有不同的 SHA-1 标识符),因此它与远程存储库中的提交不同。(Rebase 通常可以处理这个问题,因为它检查补丁 id 即更改,而不是提交 id)。

同样在 git 中,您可以一次合并多个分支:所谓的octopus merge。请注意,章鱼合并必须成功而不会发生冲突。尽管如此,它可能很有用。

HTH。

于 2009-08-08T12:22:19.410 回答
-16

Rebase 和 Cherry-pick 是保持干净提交历史的唯一方法。避免使用合并,避免产生合并冲突。如果您正在使用 gerrit,请将一个项目设置为 Merge(如有必要),并将一个项目设置为樱桃挑选模式并尝试自己。

于 2017-12-13T06:10:38.177 回答