为什么采摘樱桃会使回购交易不稳定?

时间:2019-08-19 05:09:19

标签: git github cherry-pick

我不是开发人员。 在我们的一个项目中,由于许多票证需要花费时间才能完成,因此我们一直在挑选承诺,现在我们不得不经常这样做。 一位开发人员告诉我,应避免采摘樱桃,因为这会使回购协议变得不稳定。 这是什么意思,它如何使回购交易不稳定? 换句话说,摘樱桃的负面后果是什么?

2 个答案:

答案 0 :(得分:3)

Git挑选樱桃的典型用例是将一个分支中的提交带入另一个分支,因为这样做的通常方法是:通过合并或变基,不可用。通常的合并选项可能不可用,因为功能分支尚未准备好被合并到其源中。但是,可能需要立即在源分支中进行某些提交,例如来修复错误或其他即时修复程序,因此摘樱桃是实现此目的的一种方法。

Cherry-picking并没有真正使存储库不稳定,但是这样做是为了冒着在各处复制提交的风险。回到具有提交需要立即返回到源的提交的功能分支的示例,如果以后再合并此功能分支,则可能会引入 same 提交,该提交是樱桃选择。结果,源分支最终可能会出现多个提交,每个提交在功能上都应该做同样的事情。这并没有真正使回购协议变得不稳定,但确实使历史记录难以阅读。将来,历史的读者可能会发现很难弄清贡献者的所作所为,从而导致重复提交。

此问题的根源在于,每次使用Git cherry-pick时,实际上都会创建一个带有新SHA-1哈希的 new 提交。因此,从特征分支向源代码中挑选单个提交实际上会使存储库具有两个提交,它们在功能上是相同的,但是具有完全不同的SHA-1散列。

答案 1 :(得分:3)

要清楚,挑选樱桃不会损害您的存储库。 Git采摘樱桃很好。采摘樱桃可能会使您的 code 不稳定。

基本上是将提交复制到另一个分支。仔细使用,这是一个非常有用的工具。随意使用,您正在复制未经测试的代码。如果您发现自己不得不大量使用“自动选择”功能,则可能是您的过程不太理想。


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

您的存储库如下所示。

A - B - C - D - E [master]
     \
      1 - 2 - bugfix - 3 - 4 - 5 [feature]

接下来会发生什么取决于您的工作流程。您可以将其直接摘到master上。

git cherry-pick bugfix

A - B - C - D - E [master]
     \
      1 - 2 - bugfix - 3 - 4 - 5 [feature]

这具有直接将未经测试的代码提交到master的所有问题。它可能取决于feature的其他部分。它可能不起作用。它可能会引入更多细微的错误。可能不完整。这可能是他们通过“使代码不稳定”所指的。


最好遵循"feature branch" work flow。不允许直接提交给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]

然后fix/bug将通过常规质量检查流程运行。任何问题都已解决。通过质量检查后,它会合并到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]

现在feature应该从master进行更新,以确保它具有完整的错误修正。修正版本的主版本与其自身版本之间可能存在冲突。正常修复它们。

git checkout feature
git merge master

                  bugfix' ---- F
                 /              \
A - B - C - D - E -------------- * [master]
     \                            \ 
      1 - 2 - bugfix - 3 - 4 - 5 - * [feature]

然后feature完成后就可以正常合并到master中了。 Git不在乎历史记录中有两个版本的错误修正,任何问题已在更新合并中得到解决。

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

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

git checkout feature
git rebase master

                  bugfix' - F
                 /           \
A - B - C - D - E --------- - * [master]
                               \
                                1 - 2 - 3 - 4 - 5 [feature]