为什么Git变基不像Darcs那样花费指数时间?

时间:2019-06-08 00:28:27

标签: git git-merge rebase darcs

因此,根据this Wikipedia页面上有关版本控制中合并的信息,Darcs使用补丁换相,而Git在变基时也会使用补丁换相。

我很好奇为什么在某些情况下Git变基为什么不像Darcs那样花费指数时间?

This页列出了Darcs何时可能发生的一系列情况以及如何尝试解决这些问题。

2 个答案:

答案 0 :(得分:2)

我没有使用过darcs,可能在这里不合常规,但是在浏览Wikipedia文章时,我发现这里的说法令人误解:

  

补丁换行在Darcs中用于合并更改,并且也在git中实现(但称为“重新定级”)。补丁换向合并意味着更改补丁的顺序(即更改描述),以便它们形成线性历史记录。实际上,当在一种常见情况下制作两个补丁时,合并后,其中一个会被重写,以便看起来好像是在另一个情况下完成的。

Git既不存储补丁也不对其重新排序。 1 可以根据需要手动对补丁进行重新排序。当您使用git rebase将提交(即快照)转换为变更集时,转换本身是以worst-case O(nd)的简单方式完成的,其中n是行数,d是编辑的长度脚本。 (这是作为修补程序处理还是作为合并处理的cherry-pick处理程序,取决于您选择的rebase算法;合并案例在寻找树范围的重命名操作时会占用更多的CPU时间。)

因此,如果您的提交总数为C,则git rebase -i的最坏情况大约是O(Cnd)。 2 Git不会尝试其他任何提交顺序:由您决定是否要重新排序。如果重新设置失败,则可以尝试所有可能的重新排序,这将是提交次数的阶乘函数,但是Git不会为您这样做。


1 如果您对本身内部具有一个或多个合并的一组提交执行git rebase,则Git会“展平”它们并消除合并,但不会尝试许多命令,它只是对整个过程进行一次拓扑遍历。没有尝试对此精打细算,通常这将导致可怕的合并冲突,即,这通常是一个坏主意。如果您使用新的--rebase-merges标志,Git将尝试保留合并,但是会通过重新执行合并来保持。它只是使用小型脚本语言来构建相同的拓扑,然后根据需要手动对其进行编辑。

2 如果涉及重命名检测,则可以重命名检测的文件的数量为O(n 2 ) 。 Git尝试通过多种方式限制此限制,包括重命名队列的最大长度,当前默认值为4000个文件。

答案 1 :(得分:2)

您可以从一个地方回顾一下示例中发生的情况:从六行A B C D E F开始,在一个分支上插入三行G G G在前面,然后再在六行A B C D E F插入;在另一个分支(从第一个补丁/提交)开始,将C更改为C4。现在合并两个分支。

Git将产生A B C4 D E F G G G A B C D E F; darcs将基于其身份跟踪产生比Git的上下文和位置跟踪更好的结果的前提来更改第二个C。如果“ 4”是该块的初始化代码,则Git的结果是错误的。如果是函数或文件的初始化代码,则darcs是错误的。

身份跟踪会浪费时间。