3

rebaseif mercurial 扩展在拉取时自动执行 rebase 的过程,前提是合并可以自动完成而没有冲突。(如果有需要手动解决的冲突,它不会变基,让您准备好手动合并两个分支。)当开发人员在代码的不同部分工作时,这会简化和线性化历史记录,尽管任何变基都会抛出当开发人员工作时,会删除一些有关世界状态的信息。我倾向于同意这样的论点这个在一般情况下,rebase 不是一个好主意,但我发现 rebase-if 哲学对非冲突情况很有吸引力。我对此持谨慎态度,尽管我知道当代码的不同部分发生更改时仍然存在逻辑错误的风险(并且rebaseif 扩展的作者已经觉得这是一个坏主意。..

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

是否有更好的方法来使用 bisect(以及查看和理解修订历史),或者如果我们在开发中更多地使用 rebase,这个过程会更顺利,我是对的。或者,您能否帮助我更具体地理解在非冲突情况下使用 rebase 可能会出现什么问题:是否足以引起应该避免的问题?

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

4

2 回答 2

5

我认为答案很简单:你必须在硬平分或有风险的 rebase 之间做出区分。

或者,介于两者之间:仅当变基不太可能静默破坏事物时才变基。如果一个 rebase 只涉及几个变更集,这些变更集在语义上与它们 rebase 的更改相距甚远,那么 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

合并的优点是它允许在稍后的某个时间点了解出了什么问题,因此您可以相应地修复问题。变基可能会丢弃您需要了解由自动合并引起的错误的信息。

于 2012-10-08T19:30:48.337 回答
2

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

我对 Mercurial 或二分法不是特别熟悉(除了它有点像 git),但是在我使用 git 的一个月和一点点中,我完全坚持使用 rebase。我也用git rebase -i --autosquashgit add -p很多

IME,在解决冲突方面,变基和合并之间也没有太大区别-您链接到的答案表明“rebaseif”很糟糕,因为“如果”条件是合并是否在没有冲突的情况下进行,而应该是取决于代码库构建和测试是否通过。

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

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

于 2012-10-08T19:03:47.433 回答