为什么挑选樱桃会使回购不稳定?

Cer*_*sei 4 git github cherry-pick

我不是开发人员。在我们的一个项目中,由于很多票需要时间来完成,我们一直在挑选我们的提交,现在我们必须经常这样做。一位开发人员告诉我,应该避免挑选,因为它会使回购不稳定。这是什么意思,它如何使回购不稳定? 换句话说,采摘樱桃的负面后果是什么?

Sch*_*ern 7

需要明确的是,挑选不会损害您的存储库。Git 擅长挑选。精挑细选可能会让你的代码不稳定。

樱桃选择基本上是将提交复制到另一个分支。仔细使用,这是一个非常有用的工具。如果使用不当,你就会复制未经测试的代码。如果您发现自己必须经常使用cherry-pick,那么您的流程可能存在一些次优的情况。


一个典型的例子是,当您有一个大型功能分支时,它也修复了一个错误。该功能需要很长时间才能完成,但您现在需要修复该错误。(更深层次的问题是为什么该功能分支需要这么长时间?它太大了吗?可以将其分割成一系列较小的功能吗?)

你的存储库看起来像这样。

A - B - C - D - E [master]
     \
      1 - 2 - bugfix - 3 - 4 - 5 [feature]
Run Code Online (Sandbox Code Playgroud)

接下来发生的事情取决于您的工作流程。你可以直接把它挑选出来master

git cherry-pick bugfix

A - B - C - D - E [master]
     \
      1 - 2 - bugfix - 3 - 4 - 5 [feature]
Run Code Online (Sandbox Code Playgroud)

这存在将未经测试的代码直接提交到master. 它可能取决于其他一些部分feature。这可能行不通。它可能会引入更多微妙的错误。它可能不完整。这可能就是他们所说的“使代码不稳定”。


更好的是遵循“功能分支”工作流程。不允许直接提交master。一切都必须在一个分支中完成。分支在合并之前要经过质量检查。这确保master始终保持已知的良好状态,并且没有人共享未经测试的低质量代码。

您将打开一个新分支来修复错误,然后将其挑选出来。

git checkout -b fix/bug
git cherry-pick bugfix

                  bugfix' [fix/bug]
                 /
A - B - C - D - E [master]
     \
      1 - 2 - bugfix - 3 - 4 - 5 [feature]
Run Code Online (Sandbox Code Playgroud)

然后fix/bug运行正常的 QA 流程。任何问题都已解决。当它通过 QA 时,它会合并到master. 假设出现了问题,所以还有另一个提交。

git checkout master
git merge fix/bug
git branch -d fix/bug

                  bugfix' - F
                 /           \
A - B - C - D - E ----------- G [master]
     \
      1 - 2 - bugfix - 3 - 4 - 5 [feature]
Run Code Online (Sandbox Code Playgroud)

现在feature应该进行自我更新master以确保它具有完整的错误修复。错误修复的 master 版本与其自己的版本之间可能存在冲突。像平常一样修复它们。

git checkout feature
git merge master

                  bugfix' ---- F
                 /              \
A - B - C - D - E -------------- * [master]
     \                            \ 
      1 - 2 - bugfix - 3 - 4 - 5 - * [feature]
Run Code Online (Sandbox Code Playgroud)

然后一旦完成就可以正常feature合并。masterGit 并不关心历史记录中有两个版本的错误修复,任何问题都已在更新合并中得到解决。

git checkout master
git merge feature
git branch -d feature

                  bugfix' ---- F
                 /              \
A - B - C - D - E -------------- * --------- * [master]
     \                            \         /
      1 - 2 - bugfix - 3 - 4 - 5 - * - 6 - 7
Run Code Online (Sandbox Code Playgroud)

旁注:如果您不使用合并rebase来更新分支(我的偏好),Git 甚至可能完全删除错误修复提交(如果它认为它是多余的)。

git checkout feature
git rebase master

                  bugfix' - F
                 /           \
A - B - C - D - E --------- - * [master]
                               \
                                1 - 2 - 3 - 4 - 5 [feature]
Run Code Online (Sandbox Code Playgroud)


Tim*_*sen 5

Git 挑选的一个典型用例是将提交从一个分支带到另一个分支,因为执行此操作的通常方法(例如通过合并或变基)不可用。通常的合并选项可能不可用,因为功能分支尚未准备好合并到其源。然而,可能需要立即在源分支中进行某个提交,例如对于错误或其他热修复,因此挑选是一种方法来做到这一点。

Cherry-picking 并没有真正使存储库不稳定,但是这样做会冒着到处重复提交的风险。回到具有需要立即返回源的提交的功能分支的示例,如果我们稍后合并此功能分支,那么我们可能会引入相同的提交,该提交是精心挑选的。结果,源分支可能会以多个提交结束,每个提交在功能上都应该做同样的事情。这并没有真正使 repo 不稳定,但它确实使历史难以阅读。将来,历史的读者可能会发现很难弄清楚贡献者在做什么导致重复提交出现。

这个问题的根源在于,每次使用时,Git cherry-pick 实际上都会创建一个新的提交,并带有一个新的 SHA-1 哈希值。因此,从功能分支中挑选单个提交到源实际上会给存储库留下两个提交,功能相同,但具有完全不同的 SHA-1 哈希值。