如果我们在Git中将提交压缩为一并重新设置基数,那么重新设置基数或合并是否真的很重要?

时间:2020-04-24 02:47:29

标签: git merge rebase

我们重新设置基准的原因是历史都是线性的。但是,如果我们将提交压缩为一个,那么是否只合并然后忽略任何分支就无关紧要了吗?

我正在与一位同事讨论如果历史是线性的,并且如果一个开发人员有7次提交,而7次提交中有1次提交引入了错误,则可以进行二进制搜索,我们可以使用自动二进制文件确切地找到它是哪个提交搜索(和自动测试)。但是他说,如果某些中间提交实际上还不好,那可能会破坏构建或破坏测试。然后,他提到能够将所有提交压缩为一个并重新设置基准,这样就不会遇到捕获尚未准备好的提交的问题。

如果我们真的可以使用二进制搜索来查找哪个提交引入了新的错误,那就太好了,并且我们不必担心历史记录的提交数是原来的7倍,因为O(log n)并不是问题当n增加7倍时–仅意味着再进行3次构建和测试。但是,实际上我们是否使用自动构建和自动测试进行二进制搜索来查找新的错误?看来确实很耗时。

如果我们只是合并然后完全忽略任何分支,那与壁球和重新设置基准一样吗?与我们只将所有提交压缩为一个并重新设置基准相比,忽略任何分支(只是一条直线)时,具有一个额外的合并提交的形状相同。

3 个答案:

答案 0 :(得分:0)

您要问的一个问题是,合并营和重组营之间的争论确实很漫长。在我看来,这里的理想答案是倾向于使用rebasing,但要始终确保所推送的每个提交都具有完整的功能(即所有单元测试和集成测试都通过了)。

从发现错误的角度来看,无论您使用合并还是变基类型的工作流,实际上并没有太大的区别。无论哪种情况,自引入错误提交以来,很可能已经进行了许多提交。在这两种工作流程中,您都可以通过提交一个或多个提交来解决问题,从而修复该错误。正如您已经正确指出的那样,rebase的优点是git bisect可用于深入探查引入该错误的确切提交。对于合并工作流,git bisect仍会告诉您哪个提交引入了该错误。但是,在这种情况下,您可能会失去很多分辨率。您可能会有一个较大的合并提交,而不是具有较小的更改集的较小的功能提交,而该合并提交是由包含许多提交的功能分支生成的。因此,可能很难立即准确地找出合并提交中导致问题的什么

我更喜欢尽可能地进行变基工作流,因为它可以清晰地记录构建功能所采取的确切步骤。

答案 1 :(得分:0)

如果您的工作流程是压缩一次提交然后重新设置基准,则最好也合并一下,以便保留分辨率。使用“第一父级”视图(这就是您所说的“忽略任何分支”的正式名称),每个合并提交之间的差异应与压榨/重新设置历史记录相同。如果您的工作流程在功能分支合并到母版(或开发)中后将其删除,则保留开发人员在其功能分支中的首选提交历史记录特别有价值。当然,您不需要额外的提交,但是有时能够遵循开发过程的思路是很好的。

通常,错误更可能是在破损的代码行而不是 commit 处发现的,因此我不会仅出于其他目的来评估其他提交除非是自动进行的,否则都将查找错误。如果您打算通过检出并构建特定的提交来自动化git bisect(或其他二进制搜索),则从最简单到最难实现自动化的排名是:最好是不压扁的基线,合并将是第二好的,而压扁/重新基线将是最佳最糟糕(因为每个提交都将包含许多更改,而无法解析为单个提交)。请注意,您仍然可以使用merge自动实现单个提交的隔离,除了它比较复杂之外,因为您导航第一个父对象直到找到中断的合并提交,然后向下跟踪第二个父对象直到找到特定的损坏的提交。 / p>

我个人更喜欢合并,而不是合并,但略有改动。合并的一个缺点(虽然很少见)是在功能分支中可能没有错误,实际上是合并提交引入了该错误,即使合并发生时也没有冲突。为避免这种情况,我建议我的团队始终先将其功能分支重新建立到目标上,然后再与--no-ff合并以强制执行合并提交。 (有时称为半线性合并。)

答案 2 :(得分:0)

如果您压榨提交,则重新设置基础还是合并都无关紧要。它们将产生相同的树,因为更改将相同。如果您使用功能齐全的Git服务器(例如GitHub),则会发现squash工作流被称为“ squash and merge”,但行为是相同的。

正如您所注意到的,不压扁的好处是您可以将引入错误的变更一分为二。但是,您也可以使用不压缩的常规合并工作流来执行此操作,因为git bisect知道如何处理合并提交。

为了从此额外的历史记录中获得真正的好处,通常必须使工作流具有合理,逻辑和二等分的提交。如果您有很多我们所谓的“修正提交”,它们可以修复语法错误或其他错误并且不执行理智,逻辑的提交,那么git bisect将很难跟踪有问题的提交,因为赢得了一些提交甚至没有建立。因此,如果您要采用此策略,则必须在代码审查中甚至在CI中强制执行此策略。压扁的好处是,开发人员可以懒惰,但代价是作为单个提交的潜在巨大,难以理解的代码转储。

在使用Git时,我们确实确实经常使用git bisect来跟踪有问题的提交。我还在以前的工作场所中使用过它来追踪引入回归的位置,因此这是一种广泛使用的方法。但是,有些项目并不关心什么地方坏了,也不使用还原,因此它们并没有太多使用git bisect。这取决于您的项目和工作流程以及团队的文化。

我见过的方法一旦奏效,就需要进行理性的,逻辑的,可二等分的提交或压缩。如果您是一个谨慎,有条不紊的开发人员,愿意在合并之前重新设置基础并获得提交,则可以将其完全合并;否则,您可以将它们完全合并。如果你想偷懒,那你得壁球。这样可以保留分支的二分法,同时使要求较低的开发人员更轻松地进行操作。如果愿意,也可以使用rebase来完成此方法。

我的一般方法是Git方法(这并不奇怪,因为我为Git做出了贡献):将功能重新划分为理智的逻辑提交,然后创建合并提交。但最终,您必须选择适合您团队的工作流程。