git DAG的增量线性化

时间:2009-03-31 15:03:50

标签: objective-c git visualization directed-acyclic-graphs

我是GitX的作者。 GitX的一个功能是分支的可视化,可以看到here

此可视化目前通过读取以正确顺序从git发出的提交来完成。对于每次提交,父母都是已知的,因此以正确的方式构建通道相当容易。

我想通过使用自己的提交池并自行线性化提交来加快此过程。这允许我重用现有的已加载提交并允许git更快地发出提交,因为它不必以正确的顺序发出它们。

但是,我不确定使用什么算法来完成此任务。重要的是建筑物是增量的,因为提交的加载可能需要很长时间(100,000次提交的时间> 5秒,应该全部显示)。

Gitk已经走了同样的道路,并且有一个补丁here,展示了它是如何实现的,但是我的TCL技能很弱,并且补丁没有得到很好的评论,也有点难以理解。

我也希望这个算法高效,因为它必须处理数十万次提交。它也必须显示在表中,因此访问特定行很快很重要。

我将描述我到目前为止的输入,我想要的输出和一些观察。

输入:

  • 我有一个哈希表形式的当前提交池,它将提交ID映射到提交对象。此池不必完整(必要的所有提交)
  • 我在git的新提交中有一个单独的线程加载,每次加载新提交时都可以调用一个回调。提交没有保证顺序,但在大多数情况下,下一次提交是前一次提交的父级。
  • 提交对象有自己的修订版ID和所有父级的修订版ID
  • 我有一个应列出的分支头列表。也就是说,不应该显示DAG的单个“顶部”。也没有一个图形根。

输出:

  • 我需要按拓扑顺序线性化这些提交。也就是说,在列出其父项后,无法列出提交。
  • 我还需要在上面的屏幕截图中看到的“分支线”。这些可能需要预先计算,因为大多数都依赖于他们的孩子。

一些评论:

  • 有必要重新定位提交列表。例如,我们可能必须提交(分支头)不相关的内容,直到提交显示使一个头成为另一个头的祖先。
  • 必须显示多个分支提示
  • 此过程非常重要,因此在数据仍在加载时至少可以使用部分视图。这意味着必须在中途插入新数据,并且必须重新调整分支线。

4 个答案:

答案 0 :(得分:6)

标准topological sort是O(n)(OK,O(V + E)),即你应该能够在几分之一秒内对内存中的一百万次提交进行排序。不需要像Tcl那样的增量黑客。

顺便说一句,我每天都使用GitX(看起来比OS X上的Gitk要好得多)并且没有任何问题(也许是因为我在我的存储库中没有那些疯狂的合并):))

答案 1 :(得分:3)

好的,所以我也有同样的困难时间阅读整个补丁,但是让我们看看我是否可以从我所弄清楚的东西中把它拼凑起来。

首先,gitk通过将一串提交压缩为一个弧来简化事物,其中包含一系列提交,每个提交只有一个父项和一个子项。除此之外,这样做可以大大减少您必须考虑的排序节点数量,这将有助于您使用的任何算法。作为奖励,相关提交将最终组合在一起。

在读取新提交时,这确实会在查找弧时引入一些复杂性。有几种情况:

  • 新提交有一个父母,或没有父母。它扩展了一个(可能是空的)弧。大多数情况下,您只需延长最近的弧线。有一些有趣的子句:
    • 如果现有的弧已经有一个子节点(也就是它的父节点是一个分支点,我收集的你不知道提前知道),它可能导致现有的弧被拆分。
    • 它可能是将两个弧连接在一起的“缺失链接”。
    • 您可能已经知道此提交有多个孩子
  • 新提交有多个父项(合并提交)。

您可能希望在弧中包含多子或多父提交,或者将它们分开可能更有意义。无论哪种方式,逐步建立这组弧都不应该太难。

一旦你有了这些弧线,你仍然会尝试线性化它们。在您的情况下,上述Wikipedia page中描述的第一个算法听起来很有用,因为您有一组已知的分支点用作初始集合S.

其他说明:

  • 重新定位提交应该是可管理的。首先,只需通过新的合并提交,新发现的分支点或将两个弧组合成一个弧,即可连接两个弧。任何给定的弧都可以很容易地保持其当前行号范围(假设您在顺序行上放置弧线很好),因此遍历树检查所有新祖先后来显示应该非常快。
  • 我不太了解绘制图形线条的内容,但我认为它与现在的图形不会太差异。

无论如何,我希望有所帮助。至少在思考这个问题时很有意思。

答案 2 :(得分:0)

你真的需要一次显示100k提交吗?什么样的用户可以吸收这种信息?

您是否考虑过分页?我只计算~100次提交或其他东西。如果分支线返回(离页),你可以使用类似Github的后向箭头来显示。

答案 3 :(得分:-2)

我没有使用GitX,所以也许我错过了一些东西,但似乎你可以从每个当前分支的头部从孩子走到父母,直到你可以画出几个图形的屏幕。

这可能无法为您提供以前根植的分支的最佳视觉布局。但似乎响应性比等待绘制最少交叉的图表更重要,因为大多数用户可能对最近的活动感兴趣。