Git知识点:利用git-draw绘制仓库的对象关系图

417 阅读4分钟

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}"]
}

image.png

派生项目

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

image.png

参考资料

Git - External Links

sensorflo/git-draw: draws nearly the full content of a tiny git repository as a graph

Git 底层原理:Git 对象

graphviz绘图学习