第17章 Git里程碑

里程碑即Tag,是人为对提交进行的命名。这和Git的提交ID是否太长无关,使用任何数字版本号无论长短,都没有使用一个直观的表意的字符串来得方便。例如:用里程碑名称"v2.1"对应于软件的2.1发布版本就比使用提交ID要直观得多。

对于里程碑,实际上我们并不陌生,在第2篇的“第10章Git基本操作”中,就介绍了使用里程碑来对工作进度“留影”纪念,并使用git describe命令显示里程碑和提交ID的组合来代表软件的版本号。本章将详细介绍里程碑的创建、删除和共享,还会介绍里程碑存在的三种不同形式:轻量级里程碑、带注释的里程碑和带签名的里程碑。

接下来的三章,将对一个名为"Hello World"的示例版本库进行研究,这个版本库不需要我们从头建立,可以直接从Github[1]上克隆。先使用下面的方法在本地创建一个镜像,用作本地用户的共享版本库。

进入本地版本库根目录下。


$mkdir-p/path/to/repos/

$cd/path/to/repos/


从Github上镜像hello-world.git版本库。

如果Git是1.6.0或更新的版本,可以使用下面的命令建立版本库镜像。


$git clone—mirror git://github.com/ossxp-com/hello-world.git


否则使用下面的命令建立版本库镜像。


$git clone—bare\

git://github.com/ossxp-com/hello-world.git hello-world.git


完成上面的操作后,就在本地建立了一个裸版本库/path/to/repos/hello-world.git。接下来用户user1和user2分别在各自的工作区克隆这个裸版本库。使用如下命令即可:


$git clone file:///path/to/repos/hello-world.git\

/path/to/user1/workspace/hello-world

$git clone file:///path/to/repos/hello-world.git\

/path/to/user2/workspace/hello-world

$git—git-dir=/path/to/user1/workspace/hello-world/.git\

config user.name user1

$git—git-dir=/path/to/user1/workspace/hello-world/.git\

config user.email user1@sun.ossxp.com

$git—git-dir=/path/to/user2/workspace/hello-world/.git\

config user.name user2

$git—git-dir=/path/to/user2/workspace/hello-world/.git\

config user.email user2@moon.ossxp.com


17.1 显示里程碑

里程碑可以使用git tag命令来显示,里程碑还可以在其他命令的输出中出现,下面分别对这些命令加以介绍。

1.命令git tag

不带任何参数执行git tag命令,即可显示当前版本库的里程碑列表。


$cd/path/to/user1/workspace/hello-world

$git tag

jx/v1.0

jx/v1.0-i18n

jx/v1.1

jx/v1.2

jx/v1.3

jx/v2.0

jx/v2.1

jx/v2.2

jx/v2.3


里程碑创建的时候可能包含一个说明。在显示里程碑的时候同时显示说明,使用-n<num>参数,显示最多<num>行里程碑的说明。


$git tag-n1

jx/v1.0 Version 1.0

jx/v1.0-i18n i18n support for v1.0

jx/v1.1 Version 1.1

jx/v1.2 Version 1.2:allow spaces in username.

jx/v1.3 Version 1.3:Hello world speaks in Chinese now.

jx/v2.0 Version 2.0

jx/v2.1 Version 2.1:fixed typo.

jx/v2.2 Version 2.2:allow spaces in username.

jx/v2.3 Version 2.3:Hello world speaks in Chinese now.


还可以使用通配符对输出进行过滤。只显示名称和通配符相符的里程碑。


$git tag-l jx/v2*

jx/v2.0

jx/v2.1

jx/v2.2

jx/v2.3


2.命令git log

在查看日志时使用参数—decorate可以看到提交对应的里程碑及其他引用。


$git log—oneline—decorate

3e6070e(HEAD,tag:jx/v1.0,origin/master,origin/HEAD,master)Show version.

75346b3 Hello world initialized.


3.命令git describe

使用命令git describe将提交显示为一个易记的名称。这个易记的名称来自于建立在该提交上的里程碑,若该提交没有里程碑则使用该提交历史版本上的里程碑并加上可理解的寻址信息。

如果该提交恰好被打上一个里程碑,则显示该里程碑的名字。


$git describe

jx/v1.0

$git describe 384f1e0

jx/v2.2


若提交没有对应的里程碑,但是在其祖先版本上建有里程碑,则使用类似<tag>-<num>-g<commit>的格式显示。

其中<tag>是最接近的祖先提交的里程碑名字,<num>是该里程碑和提交之间的距离,<commit>是该提交的精简提交ID。


$git describe 610e78fc95bf2324dc5595fa684e08e1089f5757

jx/v2.2-1-g610e78f


如果工作区对文件有修改,还可以通过后缀-dirty表示出来。


$echo hacked>>README;git describe—dirty;git checkout—README

jx/v1.0-dirty


如果提交本身没有包含里程碑,可以通过传递—always参数显示精简提交ID,否则会出错。


$git describe master^—always

75346b3


命令git describe是非常有用的命令,可以将该命令的输出用作软件的版本号。

在此之前曾经演示过这个应用,马上还会看到。

4.命令git name-rev

命令git name-rev和git describe类似,会显示提交ID及其对应的一个引用。默认优先使用分支名,除非使用—tags参数。还有一个显著的不同就是,如果提交上没有相对应的引用,则会使用最新提交上的引用名称并加上向后回溯的符号~<num>。

默认优先显示分支名。


$git name-rev HEAD

HEAD master


使用—tags优先使用里程碑。

之所以在对应的里程碑引用名称后面加上后缀^0,是因为该引用指向的是一个tag对象而非提交。用^0后缀指向对应的提交。


$git name-rev HEAD—tags

HEAD tags/jx/v1.0^0


如果提交上没有对应的引用名称,则会使用新提交上的引用名称并加上后缀~<num>。后缀的含义是第<num>个祖先提交。


$git name-rev—tags 610e78fc95bf2324dc5595fa684e08e1089f5757

610e78fc95bf2324dc5595fa684e08e1089f5757 tags/jx/v2.3~1


命令git name-rev可以对标准输入中的提交ID进行改写,使用管道符号对前一个命令的输出进行改写,会显示神奇的效果。


$git log—pretty=oneline origin/helper/master|\

git name-rev—tags—stdin

bb4fef88fee435bfac04b8389cf193d9c04105a6(tags/jx/v2.3^0)Translate for Chinese.

610e78fc95bf2324dc5595fa684e08e1089f5757(tags/jx/v2.3~1)Add I18N support.

384f1e0d5106c9c6033311a608b91c69332fe0a8(tags/jx/v2.2^0)Bugfix:allow spaces in username.

e5e62107f8f8d0a5358c3aff993cf874935bb7fb(tags/jx/v2.1^0)fixed typo:-help to—help

5d7657b2f1a8e595c01c812dd5b2f67ea133f456(tags/jx/v2.0^0)Parse arguments using getopt_long.

3e6070eb2062746861b20e1e6235fed6f6d15609(tags/jx/v1.0^0)Show version.

75346b3283da5d8117f3fe66815f8aaaf5387321(tags/jx/v1.0~1)Hello world initialized.


[1]https://github.com/ossxp-com/hello-world/