版本控制中的二等分是否可以从使用rebaseif工作流程中受益?

时间:2012-10-08 17:50:19

标签: version-control mercurial branch dvcs bisect

只有在没有冲突的情况下自动完成合并时,rebaseif mercurial扩展才会自动执行该过程。 (如果存在要手动解决的冲突,则不会进行rebase,让您准备手动合并两个分支。)当开发人员在代码的不同部分工作时,这会简化并线性化历史记录,尽管任何rebase都会抛出当开发人员开始工作时,远离一些关于世界状况的信息。我倾向于同意像thisthis这样的论点,在一般情况下,变基不是一个好主意,但我发现rebase-if哲学对非冲突案件有吸引力。即使我理解在代码的不同部分(the author of rebaseif extension has come to feel it’s a bad idea.)发生变化时仍然存在逻辑错误的风险,我仍然会对此持开放态度。)

我最近经历了一个复杂而痛苦的二等分,我认为在我们的存储库中有大量的短分支合并是bisect没有达到其隐含的O(lg n)承诺的主要原因。我发现自己需要多次运行“bisect --extend”,将范围扩展到合并之外,一次进行几个变更集,主要是将二等分O(n)。我还发现,跟踪bisect的进展情况以及了解到目前为止我获得的信息非常复杂,因为在查看存储库的图表时我无法遵循分支。

是否有更好的方法来使用bisect(以及查看和理解修订历史记录),或者我是否正确,如果我们在开发中使用了更多的rebaseif,那么该过程会更顺畅。或者,您是否可以帮助我更具体地了解在非冲突情况下使用rebase可能出现的问题:是否可能导致应该避免的问题?

我更普遍地标记这个(不仅仅是mercurial)因为我认为rebaseif匹配更典型的git工作流:git用户可能已经看到了陷阱。

2 个答案:

答案 0 :(得分:5)

我认为答案很简单:你必须在硬 bisects 之间进行分类,或者冒险进行风险调整。

或者,介于两者之间:只有在不太可能无效地破坏事物的情况下才会进行反转。如果一个rebase只涉及一些变更集,这些变更集在语义上远离它们被重新定义的变化,那么通常可以安全地进行变基。

这是一个无冲突合并破坏事物的例子:

假设有两个分支从具有此内容的文件开始:

def foo(a):
    # do
    # something
    # with a (an integer)

...

foo(4)

在分支A中,这将更改为:

def foo(a):
    # now this function is 10 times faster, but only work with positive integers
    assert a > 0
    # do
    # something with
    # with a

...

foo(4)

在分支B中,它变为:

def foo(a):
    # do
    # something
    # with a (an integer)

...

foo(4)

...

foo(-1) # now we have a use case where we need to call foo with -1

从语义上讲,两种编辑都相互冲突。但是,Mercurial乐意合并它们而不会发生冲突(在两种情况下,在重新定位或进行常规合并时):

def foo(a):
    # now this function is 10 times faster, but only work with positive integers
    assert a > 0
    # do
    # something with
    # with a

...

foo(4)

...

foo(-1) # now we have a use case where we need to call foo with -1

合并的优势在于它可以让您在以后的某个时刻了解出现了什么问题,因此您可以相应地修复问题。 rebase可能会丢弃您需要的信息,以了解自动合并导致的错误。

答案 1 :(得分:2)

反对git rebase的主要论据似乎是围绕“失去历史”的哲学思考,但如果我真的关心这一点,我会将最后的构建步骤作为签到(或者是第一个跟踪所有步骤的构建步骤)失败的构建也是如此!)。

我对Mercurial或bisecting并不是特别熟悉(除了它有点像git),但在我和git的一个月里,我完全坚持使用rebase。我还使用git rebase -i --autosquashgit add -p lot

IME,在修复冲突时,rebase和merge之间也没有那么大的区别 - 你所链接的答案表明“rebaseif”是坏的,因为“if”条件是合并是否在没有冲突的情况下进行,而它应该取决于代码库构建和测试是否通过。

也许我的想法被git设计中固有的弱点所扭曲(它没有明确地跟踪分支的历史,即它实际指向的提交的子集),或者也许它就是我的工作方式(检查diff是否合理并且构建它,尽管在rebase之后我确实没有检查中间提交是否构建)。

(旁白:对于个人项目,我经常跟踪每个构建输出和相应的源快照,但我还没有找到任何擅长这样做的东西。)