17.2.2 带说明的里程碑

带说明的里程碑,就是使用参数-a或-m<msg>调用git tag命令,在创建里程碑的时候提供一个关于该里程碑的说明。下面来看看如何创建带说明的里程碑:

(1)还是先创建一个空提交。


$git commit—allow-empty-m "blank commit for annotated tag test."

[master 8a9f3d1]blank commit for annotated tag test.


(2)在刚刚创建的空提交上创建一个带说明的里程碑,名为mytag2。

下面的命令使用了-m<msg>参数,在命令行给出了新建里程碑的说明。


$git tag-m "My frst annotated tag." mytag2


(3)查看里程碑,可以看到该里程碑已经创建。


$git tag-l my*-n1

mytag blank commit.

mytag2 My first annotated tag.


下面来看看带说明里程碑的奥秘。当创建了带说明的里程碑mytag2后,会在版本库的.git/refs/tags目录下创建一个新的引用文件。

查看一下这个引用文件的内容:


$cat.git/refs/tags/mytag2

149b6344e80fc190bda5621cd71df391d3dd465e


用git cat-file命令检查该里程碑(带说明的里程碑)指向的对象,会发现指向的不再是一个提交,而是一个tag对象。


$git cat-file-t mytag2

tag


查看该提交的内容,会发现mytag2对象的内容不是之前我们熟悉的提交对象的内容,而是包含了创建里程碑时的说明,以及对应的提交ID等信息。


$git cat-file-p mytag2

object 8a9f3d16ce2b4d39b5d694de10311207f289153f

type commit

tag mytag2

tagger user1<user1@sun.ossxp.com>Sun Jan 2 14:10:07 2011+0800

My first annotated tag.


由此可见使用带说明的里程碑,会在版本库中建立一个新的对象(tag对象),这个对象会记录创建里程碑的用户(tagger),创建里程碑的时间,以及为什么要创建里程碑。这就避免了轻量级里程碑因为匿名创建而无法追踪的缺点。

带说明的里程碑是一个tag对象,在版本库中以一个对象的方式存在,并用一个40位的SHA1哈希值来表示。这个哈希值的生成方法和前面介绍的commit对象、tree对象、blob对象一样。至此,Git对象库的四类对象我们就都已经研究到了。


$git cat-file tag mytag2|wc-c

148

$(printf "tag 148\000";git cat-file tag mytag2)|sha1sum

149b6344e80fc190bda5621cd71df391d3dd465e-


虽然mytag2本身是一个tag对象,但在很多Git命令中,可以直接将其视为一个提交。下面的git log命令,显示mytag2指向的提交日志。


$git log-1—pretty=oneline mytag2

8a9f3d16ce2b4d39b5d694de10311207f289153f blank commit for annotated tag test.


有时,需要得到里程碑指向的提交对象的SHA1哈希值。

直接用git rev-parse命令查看mytag2得到的是tag对象的ID,并非提交对象的ID。


$git rev-parse mytag2

149b6344e80fc190bda5621cd71df391d3dd465e


使用下面几种不同的表示法,则可以获得mytag2对象所指向的提交对象的ID。


$git rev-parse mytag2^{commit}

8a9f3d16ce2b4d39b5d694de10311207f289153f

$git rev-parse mytag2^{}

8a9f3d16ce2b4d39b5d694de10311207f289153f

$git rev-parse mytag2^0

8a9f3d16ce2b4d39b5d694de10311207f289153f

$git rev-parse mytag2~0

8a9f3d16ce2b4d39b5d694de10311207f289153f