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

如果我们在Git和rebase中将提交压缩成一个,那么我们重新设置或合并是否真的很重要?,git,merge,rebase,Git,Merge,Rebase,我们重新设定基准的原因是历史都是线性的。但是,如果我们将提交压缩为一个,那么我们只是合并然后忽略任何分支是否重要 我和一位同事谈过,如果历史是线性的,并且如果一个开发人员有7次提交,并且7次提交中有1次提交引入了一个bug,那么我们可以使用自动二进制搜索(和自动测试)准确地找到哪个提交。但他说,如果一些中间提交实际上还不好,可能会破坏构建或破坏测试,该怎么办。然后他提到可以将所有提交压缩成一个,然后重新设置基址,这样就不会有捕获不太准备好的提交的问题 如果我们真的可以使用二进制搜索来查找哪个提交

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

我和一位同事谈过,如果历史是线性的,并且如果一个开发人员有7次提交,并且7次提交中有1次提交引入了一个bug,那么我们可以使用自动二进制搜索(和自动测试)准确地找到哪个提交。但他说,如果一些中间提交实际上还不好,可能会破坏构建或破坏测试,该怎么办。然后他提到可以将所有提交压缩成一个,然后重新设置基址,这样就不会有捕获不太准备好的提交的问题

如果我们真的可以使用二进制搜索来查找哪个提交引入了新的bug,那就好了,我们不必担心历史上有7倍多的提交,因为当n增加7倍时,O(log n)不是一个问题——它只意味着还有3次构建和测试。但实际上,我们真的使用自动构建和自动测试进行二进制搜索来发现新的bug吗?看起来真的很费时


如果我们只是合并,然后忽略任何分支,这难道不是和挤压和重基一样吗?当我们忽略任何分支(只是一条直线)时,有一个额外的合并提交是相同的形状,而不是将所有提交压缩成一个并重新设置基础。

您提出的问题在合并阵营和重新设置基础阵营中确实是一个长期争论的问题。在我看来,这里的理想答案是倾向于使用重定基址,但要努力始终确保推送的每个提交都是完全功能的(即所有单元和集成测试都通过)

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


如果可能的话,我更喜欢使用重基工作流,因为它可以清晰地记录构建功能所采取的确切步骤。

如果您的工作流要压缩为一个提交,然后重基,那么您最好只合并,这样您就可以保留分辨率。使用“第一个父级”视图(这是您所谓的“忽略任何分支”的正式名称),每个合并提交之间的差异应该与挤压/重基历史相同。如果您的工作流在功能分支合并到master(或development)中后删除了这些功能分支,那么从它们的功能分支中保留开发人员首选的提交历史记录尤其有价值。当然,您不需要额外的提交,但有时能够遵循开发过程的思路是很好的

通常,错误更可能在代码的断行而不是提交时被发现,因此我不会将额外提交的价值仅仅用于查找错误,除非它是自动的。如果您打算通过签出并构建特定的提交来自动化git对分(或另一个二进制搜索),那么从最容易到最难自动化的排序将是:不使用挤压的重基最好,合并次之,挤压/重基最差(因为每次提交都会包含许多更改,而不会解析为单个提交)。请注意,您仍然可以使用“合并”自动隔离单个提交,但这更复杂,因为您要导航第一个父级,直到找到中断的合并提交,然后跟踪第二个父级,直到找到特定的中断提交


我个人更喜欢合并而不是重设基础,但有一点扭曲。合并的一个缺点,虽然很少,但可能是功能分支中没有bug,实际上是合并提交引入了bug,即使合并发生时没有冲突。为了防止这种情况,我建议我的团队始终重设其功能分支的基础首先将h合并到目标上,然后使用--no ff合并以强制合并提交(有时称为半线性合并)

如果挤压提交,则重定基址还是合并无关紧要。它们将生成相同的树,因为更改将是相同的。如果使用功能齐全的Git服务器,如GitHub,您会发现挤压工作流称为“挤压和合并”,但行为是相同的

正如您所注意到的,不挤压的好处是,您可以非常精确地平分引入错误的更改。但是,您也可以使用不挤压的常规合并工作流来进行平分,因为
git bisect
知道如何处理合并提交

为了从这个额外的历史中获得真正的好处,您通常必须拥有一个具有合理、逻辑、可平分提交的工作流如果修复语法错误或其他错误,并且不强制执行合理的逻辑提交,那么
git bisect
将很难跟踪有问题的提交,因为有些提交甚至无法生成。因此,您必须在代码审阅中强制执行此策略,如果需要,甚至可能在CI中强制执行此策略