Git底层实际上是由一个个对象组成的,一个仓库里面的所有对象会组成一个图(Graph),按照指向关系可以简单的这么理解:refs –> tag对象 –> commit对象 –> tree对象 –> blob对象
,对象之间通过对方的SHA-1哈希值来确定指向关系。git-draw可以将Git仓库的对象和引用关系绘制成图形,让我们更加直观地了解Git仓库的结构,对于学习Git的内部原理很有帮助。
git-draw is a small tool that draws nearly the full content of a tiny git repository as a graph. It helps people with an engineering background learning Git's internals.
下载安装
# 如果仅生成.dot文件(--print-only),不生成和显示图片,graphviz和imagemagick是可选的
$ sudo apt-get install perl graphviz imagemagick
$ git clone https://github.com/sensorflo/git-draw.git
$ export PATH=$PATH:`pwd`/git-draw
$ git-draw -h
Usage: git-draw [options]
-h|--help Print help message & exit
-p|--print-only Only print .dot to stdout
-i|--image-only Only create an image, and a .dot file beforehand
-g|--git-dir Git repository directory to use
-w|--work-dir Top level git working directory
--dot-filename <filename> Name of the dot file to generate
--image-filename <filename> Name of the image file to generate
--display-cmd <command> Command to use to display image
--sha1-length <length> Number of sha1 digits to display
--hide-legend Don't display the legend
--hide-objects Don't display git objects
--hide-refs Don't display references
--hide-reflogs Don't display reflogs
--hide-index Don't display the index
--hide-commitcontent Don't display commit content
--hide-tagcontent Don't display tag content
--hide-treecontent Don't display tree content
--hide-blobcontent Don't display blob content
--color-scheme <color scheme> Choose color scheme. Can be one of: default,
set312, spectral11, blues9, brbg11, bupu9,
dark28, paired12, pastel19, set19
--color-commit <color> Set color for commit objects
--color-tag <color> Set color for tag objects
--color-tree <color> Set color for tree objects
--color-blob <color> Set color for blob objects
--color-default <color> Set default color
--orientation <orientation> Change the graph orientation.
<orientation> must be one of the following:
TB top to bottom, the default
BT bottom to top
LR left to right
RL right to left
The primary documentation is at the top of the git-draw script itself.
- Perl是高阶、通用、解释型、动态的编程语言家族(Perl 5和Perl 6)。最初设计者拉里·沃尔为了让在UNIX上进行报表处理的工作变得更方便,决定开发一个通用的脚本语言,而在1987年12月18日发表。Perl语言应用广泛,涵盖CGI、图形编程、系统管理、网络编程、金融、生物等领域。由于其灵活性,Perl被称为脚本语言中的瑞士军刀。
- Graphviz(Graph Visualization Software,图形可视化软件)是一个由AT&T实验室启动的开源工具包,用于绘制DOT语言脚本描述的图形。DOT语言是一种文本图形描述语言。它提供了一种简单的描述图形的方法,并且可以为人类和计算机程序所理解。DOT语言文件通常是具有.gv或是.dot的文件扩展名。
$ dot -V
dot - graphviz version 2.43.0 (0)
$ vim graph.dot
graph graphname {
a -- b -- c;
b -- d;
}
$ dot -Tpng -ograph.png graph.dot
- ImageMagick是一个用于查看、编辑位图文件以及进行图像格式转换的开放源代码软件套装。使用ImageMagick可以调整图像大小,翻转,镜像,旋转,变形,剪切和变换图像,调整图像颜色,应用各种特殊效果或绘制文本,线条,多边形,椭圆和贝塞尔曲线。
代码示例
$ git init example
$ cd example
$ for i in {1..3}; do echo "version${i}" > index.html; git add --all; git commit -m "version${i}"; done
$ git tag -a -m "version 1.0" v1.0 HEAD
$ find .git/objects -type f
.git/objects/df/7af2c382e49245443687973ceb711b2b74cb4a
.git/objects/5f/93d5a82ad52c796504fd79f26964b7df128c13
.git/objects/55/db589dc3c5ca9f6229fa01bf36146db423a6ef
.git/objects/50/54691d2503e57be5d909bc5be22e03fd5b331d
.git/objects/f4/f78ca3c685d827abb69d066d3356d361089948
.git/objects/5b/dcfc19f119febc749eef9a9551bc335cb965e2
.git/objects/86/7f64f9d8747d30ed757bc31d02327490ba6685
.git/objects/e6/afec40a2008e592028a16be3fd6a495778e75a
.git/objects/cc/fd6a902b05e1e08ef6e2c331b8466a839b5f07
.git/objects/77/7d3c2b51e73cc9177c34d14d9b6079b7c3ae7d
$ git-draw --image-only
$ ls -t
git-draw.png git-draw.dot index.html
说明:如果无法安装graphviz和imagemagick,可以将.dot文件打印到控制台,然后通过GraphvizOnline在线查看GraphViz图形。
$ git-draw --print-only
digraph structs {
node [shape=record,fontsize=11];
rankdir="TB";
subgraph cluster_0 {
color=gray80;
label = "legend\l";
legend_node [label="{{type:subtype|id/name}|content\l|metadata from config\l}"]
}
_df7a [fillcolor="white", style="filled,rounded", label="{{obj:blob|df7a}|version2\l}"] _5f93 [fillcolor="lightyellow", style="filled,rounded", label="{{obj:tree|5f93}|100644\ blob\ 777d\ index\.html\l}"] _5f93 -> _777d
_55db [fillcolor="lightyellow", style="filled,rounded", label="{{obj:tree|55db}|100644\ blob\ df7a\ index\.html\l}"] _55db -> _df7a
_5054 [fillcolor="palegreen1", style="filled,rounded", label="{{obj:commit|5054}|tree\ 55db\lparent\ f4f7\lauthor\ leitiannet\ \<347341200\@qq\.com\>\ 1721635598\ \+0800\lcommitter\ leitiannet\ \<347341200\@qq\.com\>\ 1721635598\ \+0800\l\lversion2\l}"] _5054 -> _55db
_5054 -> _f4f7
_f4f7 [fillcolor="palegreen1", style="filled,rounded", label="{{obj:commit|f4f7}|tree\ 867f\lauthor\ leitiannet\ \<347341200\@qq\.com\>\ 1721635598\ \+0800\lcommitter\ leitiannet\ \<347341200\@qq\.com\>\ 1721635598\ \+0800\l\lversion1\l}"] _f4f7 -> _867f
_5bdc [fillcolor="white", style="filled,rounded", label="{{obj:blob|5bdc}|version1\l}"] _867f [fillcolor="lightyellow", style="filled,rounded", label="{{obj:tree|867f}|100644\ blob\ 5bdc\ index\.html\l}"] _867f -> _5bdc
_e6af [fillcolor="white", style="filled,rounded", label="{{obj:tag|e6af}|object\ ccfd\ltype\ commit\ltag\ v1\.0\ltagger\ leitiannet\ \<347341200\@qq\.com\>\ 1721635610\ \+0800\l\lversion\ 1\.0\l}"] _e6af -> _ccfd
_ccfd [fillcolor="palegreen1", style="filled,rounded", label="{{obj:commit|ccfd}|tree\ 5f93\lparent\ 5054\lauthor\ leitiannet\ \<347341200\@qq\.com\>\ 1721635598\ \+0800\lcommitter\ leitiannet\ \<347341200\@qq\.com\>\ 1721635598\ \+0800\l\lversion3\l}"] _ccfd -> _5f93
_ccfd -> _5054
_777d [fillcolor="white", style="filled,rounded", label="{{obj:blob|777d}|version3\l}"] _refs___heads___master [style=filled, fillcolor=gray, label="{{ref:local branch|refs\/heads\/master}|ccfd\l}"]
_refs___heads___master -> _ccfd
_refs___tags___v1___0 [style=filled, fillcolor=lightyellow, label="{{ref:tag|refs\/tags\/v1\.0}|e6af\l}"]
_refs___tags___v1___0 -> _e6af
_HEAD [style=filled, fillcolor=gray30, fontcolor=white, label="{{ref|HEAD}|refs\/heads\/master\l}"]
_HEAD -> _refs___heads___master
reflog_refs___heads___master -> _ccfd [color=gray90]
reflog_refs___heads___master -> _5054 [color=gray90]
reflog_refs___heads___master -> _f4f7 [color=gray90]
reflog_refs___heads___master [color=gray90, fontcolor=gray, label="{{reflog|logs/refs/heads/master}|ccfd\ refs\/heads\/master\@\{0\}\:\ commit\:\ version3\l5054\ refs\/heads\/master\@\{1\}\:\ commit\:\ version2\lf4f7\ refs\/heads\/master\@\{2\}\:\ commit\ \(initial\)\:\ version1\l}"]
reflog_refs___tags___v1___0 [color=gray90, fontcolor=gray, label="{{reflog|logs/refs/tags/v1.0}|\l}"]
reflog_HEAD -> _ccfd [color=gray90]
reflog_HEAD -> _5054 [color=gray90]
reflog_HEAD -> _f4f7 [color=gray90]
reflog_HEAD [color=gray90, fontcolor=gray, label="{{reflog|logs/HEAD}|ccfd\ HEAD\@\{0\}\:\ commit\:\ version3\l5054\ HEAD\@\{1\}\:\ commit\:\ version2\lf4f7\ HEAD\@\{2\}\:\ commit\ \(initial\)\:\ version1\l}"]
index -> _777d
index [style=filled, fillcolor=lightcyan, label="{{index}|100644\ 777d\ 0\ index\.html\l}"]
}
派生项目
git-draw-ext新增--show-commitgraph选项用来显示提交图
- 仅显示commit和tag对象,不显示blob和tree对象
- 仅显示提交或标签消息,不显示其他信息
- 自动设置默认值,简化命令行参数
$ git clone git@github.com:leitiannet/git-draw-ext.git
$ cd git-draw-ext
$ vim git-draw # 代码修改详见https://github.com/leitiannet/git-draw-ext/commit/ad46997a7b5f2b76392e0609771695e599f72f21
$ git add git-draw
$ git commit -m "added option --show-commitgraph, Only show commit graph, hiding blob, tree and tag"
$ git mv git-draw git-draw-ext
$ git add --all
$ git commit -m "renamed git-draw -> git-draw-ext"
$ git push origin master
$ git-draw-ext --print-only --sha1-length 7 --hide-legend --hide-reflogs
$ git-draw-ext --show-commitgraph
参考资料
sensorflo/git-draw: draws nearly the full content of a tiny git repository as a graph