这个问题有两个部分。一个很简单:从Git中获取图的边和顶点。另一个很难:画一个“漂亮的”(平面,最小的线交叉)图。
你似乎在问容易的部分,所以答案是:使用
git cat-file -p
从一些已知的Git哈希ID开始,获取每个Git对象的内容。(使用
git rev-parse
以获取初始ID。)
例如:
$ git rev-parse HEAD
d35688db19c9ea97e9e2ce751dc7b47aee21636b
$ git cat-file -p HEAD
tree 242af4b1a902347da2ff144516fb40c4a28ca257
parent 43c9e7e365d7a8961767d0bd4a305ca378800a2a
author Junio C Hamano <gitster@pobox.com> 1507361343 +0900
committer Junio C Hamano <gitster@pobox.com> 1507361343 +0900
Prepare for -rc1
Signed-off-by: Junio C Hamano <gitster@pobox.com>
(the
git cat-file
这里的示例旨在表明您可以使用
任何一个
象征性名称,
或
一个哈希ID,用于启动进程)。检查提交对象将得到一个
tree
线,以及零或更多
parent
线,为父边提供散列ID(请注意,这是一个DAG,如果您想在边上绘制箭头,这些是输出弧)。
A.
树
git cat文件-p
:
$ git cat-file -p 242af4b1a902347da2ff144516fb40c4a28ca257
100644 blob 611ab4750bd21e77d0fec41c8b2e115574c692ff .clang-format
100644 blob 8ce9c6b8888fe6c12949d30e3e8b461cb67bb43f .gitattributes
040000 tree 7ba15927519648dbc42b15e61739cbf5aeebf48b .github
100644 blob 833ef3b0b783b8180d0dad1ce336713bddf09b26 .gitignore
100644 blob cbeebdab7a5e2c6afec338c3534930f569c90f63 .gitmodules
100644 blob ab85e0d16d6383b13954220a0b41202bd68d5d73 .mailmap
100644 blob fead995eddd15460b6be81e6a5f7c8f0648368ca .travis.yml
100644 blob 8c85014a0a936892f6832c68e3db646b6f9d2ea2 .tsan-suppressions
100644 blob 536e55524db72bd2acf175208aef4f3dfc148d42 COPYING
040000 tree 3957dfa63966e1efd20481ebd61311397a34e8ab Documentation
100755 blob ab04c977be0cfdb6f282b7911d3fe630d5f70c65 GIT-VERSION-GEN
100644 blob ffb071e9f03a79a052beaa4372fa790ecbabbb7b INSTALL
[more, snipped]
每个输出线都以“模式”开始,即
040000
如果具有此名称的对象本身是另一棵树,或
100644
100755
如果是普通文件。(还有两种模式,一种用于符号链接,另一种用于“gitlink”,这是Git存储子模块哈希ID的方式。另请参阅
https://github.com/chris3torek/scripts/blob/master/githash.py
例如。)遵循编码模式,
git cat文件-p
打印底层Git对象类型,然后是哈希ID,然后是选项卡,然后是要在其下提取blob或子树的文件名组件。
每个哈希ID都是唯一的,因此,如果哈希ID出现多次,则有一个共享子节点。示例图中的几个blob对象就是这种情况。请注意,顶级树也可以重用。例如,如果您有以下提交序列:
A <-B <-C <--master
C
git revert
的提交
B
,很可能
A
C
使用相同的顶级树(这自动意味着它们使用所有相同的子树和blob)。