【问题标题】:Why does cherry-picking make the repo unstable? [closed]为什么挑选樱桃会使回购不稳定? [关闭]
【发布时间】:2019-12-24 07:42:30
【问题描述】:

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

【问题讨论】:

  • 需要明确的是,挑选樱桃不会损害回购协议。但这可能会混淆您的开发过程。
  • 通常当出现问题时需要进行挑选,例如,一旦一些开发人员将一些错误/不完整的代码合并到生产分支而不考虑三思而后行,所以我不得不从错误提交中挑选好的提交,那是我唯一一次使用cherry pick,但如果你经常使用它,那就意味着这个过程中有一些问题。

标签: git github cherry-pick


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    需要明确的是,挑选樱桃不会损害您的存储库。 Git 很适合挑选樱桃。樱桃采摘可能会使您的代码不稳定。

    cherry-pick 基本上是将提交复制到另一个分支。仔细使用这是一个非常有用的工具。使用草率,您正在复制未经测试的代码。如果您发现自己不得不经常使用cherry-pick,那么您的流程可能存在一些次优问题。


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

    您的存储库如下所示。

    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。一切都必须在一个分支中完成。分支在合并之前要经过 QA。这可确保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 通过正常的 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]
    

    现在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]
    

    【讨论】:

    • and you're copying untested code around ... 为什么樱桃采摘与是否测试代码有任何关系?
    • @TimBiegeleisen 草率地使用... 即。从分支中获取提交并将其粘贴到我概述的主场景中。
    猜你喜欢
    • 2016-12-16
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-21
    • 2017-02-26
    • 1970-01-01
    相关资源
    最近更新 更多