“git log --graph”如何实现?或“hg graphlog”工作?
我知道 Git 中的历史记录存储在称为 DAG 的数据结构中。我听说过 DFS 并且知道它有些相关。
我很好奇,git log --graph
或 hg graphlog
等程序如何绘制历史记录?我一直认为以如此漂亮的方式绘制车道和所有东西是相当复杂的。
有人可以写一些伪代码来演示它吗?
注意:我尝试查看 Git 或 hg 的代码,但很难理解并大致了解正在发生的事情。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
首先,获取提交列表(与 git rev-list 一样)以及每个提交的父项。内存中保存有“列保留列表”。
对于每个提交,然后:
显示 git-forest 输出的示例> 在 aufs2-util 上进行额外提交以拥有多个分支)。
通过前瞻,人们可以预测合并点将有多远,并在两根柱子之间挤压木材,以获得更美观的结果。
First, one obtains a list of commits (as with
git rev-list
), and parents of each commit. A "column reservation list" is kept in memory.For each commit then:
Example showing output of
git-forest
on aufs2-util with an extra commit to have more than one branch).With lookahead, one can anticipate how far down the merge point will be and squeeze the wood between two columns to give a more aesthetically pleasing result.
对于 hg,您是否尝试遵循 hg 本身或 graphlog 中的代码?
因为graphlog的代码很短。您可以在 hgext/graphlog.py 中找到它,实际上,最重要的部分是前 200 行,其余部分是扩展的引导和查找选定的修订图。代码生成函数是
ascii
,其最后一个参数是调用asciiedge
的结果(调用本身在generate
的最后一行执行) code>,由graphlog
提供给generate
的函数)For hg, did you try to follow the code in hg itself, or in graphlog?
Because the code of graphlog is pretty short. You can find it in hgext/graphlog.py, and really the important part is the top ~200 lines, the rest is the extension's bootstrapping and finding the revision graph selected. The code generation function is
ascii
, with its last parameter being the result of a call toasciiedge
(the call itself is performed on the last line ofgenerate
, the function being provided togenerate
bygraphlog
)与一般的图形显示相比,这个特殊问题并不难。因为您希望保持节点的提交顺序,所以问题变得更加简单。
另请注意,显示模型是基于网格的,行是提交,列是过去/未来的边缘。
虽然我没有阅读 git 源代码,但您可能只是从最新的开始遍历提交列表,并维护过去的开放边缘列表。沿着边缘自然会导致拆分/合并列,最终会得到树 git/hg 显示的类型。
合并边时,您希望避免交叉其他边,因此您必须尝试提前对列进行排序。这实际上是唯一可能不简单的部分。例如,可以执行双遍算法,在第一遍中为边缘制定列顺序,并在第二遍中进行绘图。
This particular problem isn't that hard, compared to graph display in general. Because you want to keep the nodes in the order they were committed the problem gets much simpler.
Also note that the display model is grid based, rows are commits and columns are edges into the past/future.
While I didn't read the git source you probably just walk the list of commits, starting from the newest, and maintain a list of open edges into the past. Following the edges naturally leads to splitting/merging columns and you end up with the kind of tree git/hg display.
When merging edges you want to avoid crossing other edges, so you'll have to try to order your columns ahead of time. This is actally the only part that may not be straightforward. For example one could do a two-pass algorithm, making up a column order for the edges in the first pass and doing the drawing in the second pass.
注意:Git 2.18(2018 年第 2 季度)现在会预先计算祖先遍历所需的信息并将其存储在单独的文件中,以优化图形遍历。
提交图的概念确实改变了“
git log --graph
”的工作方式。正如此处提到:
请参阅提交 7547b95,提交 3d5df01,< a href="https://github.com/git/git/commit/049d51a2bb9a03d2f2c2cce1ae41e57dbbf42244" rel="nofollow noreferrer">提交 049d51a, 提交 177722b,提交 4f2542b< /a>, 提交 1b70dfd, 提交 2a2e32b(2018 年 4 月 10 日),以及 提交 f237c8b,提交 08fd81c, 提交 4ce58ee,提交 ae30d7b, 提交 b84f767 ,提交cfe8321,提交 f2af9f5(2018 年 4 月 2 日),作者:德里克·斯托利 (
derrickstolee
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 b10edb2,2018 年 5 月 8 日)您现在拥有命令
git commit-graph
:编写并验证 Git 提交图形文件。设计文档指出:
在 Git 2.39(2022 年第 4 季度)中,添加了“提交图文件”和“可达性位图”的术语表条目。
请参阅提交8fea12a,提交 4973726,提交fa8e8d5,提交 776ba91(2022 年 10 月 29 日),作者:菲利普·奥克利 (
PhilipOakley
)。(由 Taylor Blau --
ttaylorr
-- 合并于 提交 4b6302c,2022 年 11 月 8 日)glossary-content
现在包含在其 手册页:和:
glossary-content
现在包含在其 手册页:Git 2.19(2018 年第 3 季度)将处理锁定文件:
请参阅 commit 33286dc ( 2018 年 5 月 10 日),提交 1472978,提交 7adf526,提交 04bc8d1,提交 d7c1ec3,提交f9b8908,提交 819807b,提交 e2838d8, 提交 3afc679,提交 3258c66 (2018 年 5 月 1 日),以及 提交 83073cc,提交 8fb572a(2018 年 4 月 25 日)作者:Derrick Stolee (
derrickstolee
)。帮助者:Jeff King (
peff
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 a856e7d,2018 年 6 月 25 日)注意:当核心对象
从未知类型提升到提交(例如,提交是
通过引用它的标签访问)涉及,这已经
使用 Git 2.21 更正(2019 年 2 月)
请参阅 commit 4468d44(2019 年 1 月 27 日) SZEDER Gábor (
szeder
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 2ed3de4,2019 年 2 月 5 日)该算法正在 Git 2.23 中重构( 2019 年第三季度)。
请参阅提交238def5,提交 f998d54, 提交014e344,提交b2c8306,提交 4c9efe8, 提交 ef5b83f,提交 c9905be,提交 10bd0be,提交 5af8039,提交 e103f72 (2019 年 6 月 12 日),以及提交 c794405(2019 年 5 月 9 日),作者:Derrick Stolee (
derrickstolee
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 e116894,2019 年 7 月 9 日)Commit 10bd0be 解释范围的变化。
在 Git 2.24(2109 年第 3 季度)中,通过给定提交对象名称编写
commit-graph
的代码变得更加健壮。请参阅 提交 7c5c9b9、提交 39d8831, 提交9916073(2019 年 8 月 5 日),作者:SZEDER Gábor (
szeder
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 6ba06b5,2019 年 8 月 22 日)而且,仍然使用 Git 2.24(2019 年第 4 季度 ) ),解析和使用提交图文件的代码针对损坏的输入变得更加健壮。
请参阅 提交 806278d、提交 16749b8, 提交23424ea(2019 年 9 月 5 日),作者:Taylor Blau (
ttaylorr
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 80693e3,2019 年 10 月 7 日)因此:
在 Git 2.26(2020 年第一季度)中,计算提交图的代码已被教导使用更强大的方法来判断两个对象目录是否引用同一事物。
请参阅提交a7df60c,提交 ad2dd5b, 提交13c2499(2020 年 2 月 3 日),提交 0bd52e2(2020 年 2 月 4 日) ,以及 提交 1793280(2020 年 1 月 30 日),作者:泰勒·布劳 (
ttaylorr
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 53c3be2,2020 年 2 月 14 日)在 Git 2.28(2020 年第 3 季度)中,
commit-graph write --stdin-commits
得到了优化。请参阅 提交 2f00c35、提交 1f1304d, 提交 5b6653e,提交 630cd51,提交 d335ce8(2020 年 5 月 13 日),提交 fa8953c (2020 年 5 月 18 日),以及 提交 1fe1084(2020 年 5 月 05 日),作者:泰勒·布劳 (
ttaylorr
)。(由 Junio C Hamano --
gitster
-- 合并于 提交 dc57a9b,2020 年 6 月 9 日)用GIT 2.28(Q3 2020)对此进行了测试。
参见 commits 6334c5f (03 Jun 2020)(03 Jun 2020) nofollow noreferrer“> taylor blau(
ttaylorr
)。(由 Junio C Hamano --
gitster
-- 合并于使用GIT 2.29(Q4 2020),IN_Merge_Bases_Many()是一种查看一组提交中任何提交是否可以达到提交的方法,当使用了提交订单 - 格拉普功能(已纠正)时,已完全破坏。
参见 noreflowl noreferrer“> commit github.com/derrickstolee“ rel =“ nofollow noreferrer”> derrick stolee(
derrickstolee
)。(由 Junio C Hamano --
gitster
-- 合并于在GIT 2.32(Q1 2021)之前,当存储库中使用的某些功能(例如移植物)与使用提交图的使用不符时,我们过去曾默默关闭提交图形;现在,我们告诉用户我们在做什么。
参见 johannes schindelin(
dscho
)。(由 Junio C Hamano --
gitster
-- 合并于 noreflow noreferrer“> ,但是
警告将是:
Note: Git 2.18 (Q2 2018) does now pre-compute and store information necessary for ancestry traversal in a separate file to optimize graph walking.
That notion of commits graph does change how '
git log --graph
' does work.As mentioned here:
See commit 7547b95, commit 3d5df01, commit 049d51a, commit 177722b, commit 4f2542b, commit 1b70dfd, commit 2a2e32b (10 Apr 2018), and commit f237c8b, commit 08fd81c, commit 4ce58ee, commit ae30d7b, commit b84f767, commit cfe8321, commit f2af9f5 (02 Apr 2018) by Derrick Stolee (
derrickstolee
).(Merged by Junio C Hamano --
gitster
-- in commit b10edb2, 08 May 2018)You now have the command
git commit-graph
: Write and verify Git commit graph files.The design document states:
With Git 2.39 (Q4 2022), the glossary entries for "commit-graph file" and "reachability bitmap" have been added.
See commit 8fea12a, commit 4973726, commit fa8e8d5, commit 776ba91 (29 Oct 2022) by Philip Oakley (
PhilipOakley
).(Merged by Taylor Blau --
ttaylorr
-- in commit 4b6302c, 08 Nov 2022)glossary-content
now includes in its man page:And:
glossary-content
now includes in its man page:Git 2.19 (Q3 2018) will take care of the lock file:
See commit 33286dc (10 May 2018), commit 1472978, commit 7adf526, commit 04bc8d1, commit d7c1ec3, commit f9b8908, commit 819807b, commit e2838d8, commit 3afc679, commit 3258c66 (01 May 2018), and commit 83073cc, commit 8fb572a (25 Apr 2018) by Derrick Stolee (
derrickstolee
).Helped-by: Jeff King (
peff
).(Merged by Junio C Hamano --
gitster
-- in commit a856e7d, 25 Jun 2018)Note: The commit-graph facility did not work when in-core objects that
are promoted from unknown type to commit (e.g. a commit that is
accessed via a tag that refers to it) were involved, which has been
corrected with Git 2.21 (Feb. 2019)
See commit 4468d44 (27 Jan 2019) by SZEDER Gábor (
szeder
).(Merged by Junio C Hamano --
gitster
-- in commit 2ed3de4, 05 Feb 2019)That algorithm is being refactored in Git 2.23 (Q3 2019).
See commit 238def5, commit f998d54, commit 014e344, commit b2c8306, commit 4c9efe8, commit ef5b83f, commit c9905be, commit 10bd0be, commit 5af8039, commit e103f72 (12 Jun 2019), and commit c794405 (09 May 2019) by Derrick Stolee (
derrickstolee
).(Merged by Junio C Hamano --
gitster
-- in commit e116894, 09 Jul 2019)Commit 10bd0be explain the change of scope.
With Git 2.24 (Q3 2109), the code to write
commit-graph
over given commit object names has been made a bit more robust.See commit 7c5c9b9, commit 39d8831, commit 9916073 (05 Aug 2019) by SZEDER Gábor (
szeder
).(Merged by Junio C Hamano --
gitster
-- in commit 6ba06b5, 22 Aug 2019)And, still with Git 2.24 (Q4 2019), the code to parse and use the commit-graph file has been made more robust against corrupted input.
See commit 806278d, commit 16749b8, commit 23424ea (05 Sep 2019) by Taylor Blau (
ttaylorr
).(Merged by Junio C Hamano --
gitster
-- in commit 80693e3, 07 Oct 2019)Hence:
With Git 2.26 (Q1 2020), the code to compute the commit-graph has been taught to use a more robust way to tell if two object directories refer to the same thing.
See commit a7df60c, commit ad2dd5b, commit 13c2499 (03 Feb 2020), commit 0bd52e2 (04 Feb 2020), and commit 1793280 (30 Jan 2020) by Taylor Blau (
ttaylorr
).(Merged by Junio C Hamano --
gitster
-- in commit 53c3be2, 14 Feb 2020)With Git 2.28 (Q3 2020), the
commit-graph write --stdin-commits
is optmized.See commit 2f00c35, commit 1f1304d, commit 0ec2d0f, commit 5b6653e, commit 630cd51, commit d335ce8 (13 May 2020), commit fa8953c (18 May 2020), and commit 1fe1084 (05 May 2020) by Taylor Blau (
ttaylorr
).(Merged by Junio C Hamano --
gitster
-- in commit dc57a9b, 09 Jun 2020)This is tested with Git 2.28 (Q3 2020).
See commit 94fbd91 (01 Jun 2020), and commit 6334c5f (03 Jun 2020) by Taylor Blau (
ttaylorr
).(Merged by Junio C Hamano --
gitster
-- in commit abacefe, 18 Jun 2020)With Git 2.29 (Q4 2020), in_merge_bases_many(), a way to see if a commit is reachable from any commit in a set of commits, was totally broken when the commit-graph feature was in use, which has been corrected.
See commit 8791bf1 (02 Oct 2020) by Derrick Stolee (
derrickstolee
).(Merged by Junio C Hamano --
gitster
-- in commit c01b041, 05 Oct 2020)Before Git 2.32 hopefully (Q1 2021), when certain features (e.g. grafts) used in the repository are incompatible with the use of the commit-graph, we used to silently turned commit-graph off; we now tell the user what we are doing.
See commit c85eec7 (11 Feb 2021) by Johannes Schindelin (
dscho
).(Merged by Junio C Hamano --
gitster
-- in commit 726b11d, 17 Feb 2021)That will show what was intended for Git 2.31, but it has been reverted, as it is a bit overzealous in its current form.
The warnings will be: