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