'git log –graph'或'hg graphlog'是如何工作的?

我知道Git中的历史存储在一个名为DAG的数据结构中。 我听说过DFS,知道这有点相关。

我很好奇,程序如git log --graph或者hg graphlog绘制历史? 我一直认为用这样一个好方法来画道和一切都是相当复杂的。

有人可以写一些伪代码来演示它吗?

注意:我试着环顾Git或者Hg的代码,但是很难跟踪并得到一个大概的想法。

我试着环顾Git或者Hg的代码,但是很难跟踪并得到一个大概的想法。

对于hg,你是否试图按照hg本身的代码或者graphlog?

因为graphlog的代码很短。 你可以在hgext / graphlog.py中find它, 其实重要的部分是200行,其余的是扩展的引导,并findselect的修订图。 代码生成函数是ascii ,最后一个参数是调用asciiedge的结果(调用本身是在最后一行generate ,函数是通过graphlog generate的)

首先,获得提交列表(与git rev-list )以及每个提交的父项。 内存中保存“列预约列表”。

然后对于每个提交:

  • 如果提交没有为其保留列,则将其分配给空闲列。 这是分支机构将如何开始。
  • 根据列预定列表打印树graphics,然后提交提交消息
  • 当前列/提交的保留列表条目用当前提交的第一个父代进行更新,以使父代打印在同一列中。
  • 其他家长则获得新的免费专栏。
  • 如果这是一个合并,下一行将尝试将第二个父代链接到预期提交的列(这使得循环和“≡桥”)

显示aufs2-util上的git-forest输出的例子,额外的提交有多个分支)。

例

随着outlook,人们可以预测合并点将会向下多远,并且将木材挤压在两列之间以给出更美观的结果。

与一般的graphics显示相比,这个特殊的问题并不难。 因为你想保持节点按照他们提交的顺序,问题变得更简单。

另请注意,显示模型是基于网格的,行是提交,列是过去/未来的边缘。

虽然我没有读过git源代码,但是你可能只是从最新的版本开始提交提交列表,并且保留一个开放的边缘列表。 沿着边缘自然导致分割/合并列,并最终得到树的git / hg显示。

合并边缘时,要避免穿越其他边缘,因此您必须尝试提前对列进行sorting。 这实际上是唯一可能不那么简单的部分。 例如,可以执行两遍algorithm,在第一遍中为边缘构成列顺序,在第二遍中进行绘制。