第五课 Git标签

内容提要:创建有签名,无签名、轻量级标签来永久的标记项目历史中的关键点
 
跟大多数的VCS工具一样,git也有在历史状态的关键点“贴标签”的功能--一般人们用这个功能来标记发布点(例如'v1.0')。这节课我们学习如何使用标签列表,创建新标签,以及在git中有哪些不同类别的标签。
 
列出git中现有标签
 
要想列出git中现有的所有标签,输入'git tag'命令运行即可:
$ git tag
v0.1
v1.3
这个列表是按照字母表顺序给出的,其实排名先后跟重要程度没有直接联系。
当然,你也可以按照特定表达式搜索某些标签。假如在一个git仓库中有超过240个标签,而你只想得到1.4.2序列的标签,那么你可以:
$ git tag -l v1.4.2.*
v1.4.2.1
v1.4.2.2
v1.4.2.3
v1.4.2.4
创建标签
在git中有两种最主要的标签--轻量级标签(lightweight)和带注释的标签(annotated)。轻量级标签跟分枝一样,不会改变--它就是针对某个特定提交的指针。然而,带注释的标签是git仓库中的对象。它是一组校验和,包含标签名、email、日期,标签信息,GPG签名和验证。一般情况下,建议创建带注释的标签,这样就会保留这些信息,但是如果你只是需要临时性标签或者某些原因你不想在标签中附带上面说的这些信息,lightweight标签更合适些。
带注释的标签

在git中创建带注释的标签非常简单,在运行'tag'命令时加上-a就可以了。
$ git tag -a v1.4 -m 'version 1.4'
$ git tag
v0.1
v1.3
v1.4

'-m'指明标签信息,跟标签一起存储。如果你不使用-m指明标签信息,git会自动启动文本编辑器让你输入。
可以使用 git show 命令查看相应标签的版本信息,并连同显示打标签时的提交对象。
$ git show v1.4
tag v1.4
Tagger: Scott Chacon <
schacon@gmail.com>
Date:   Mon Feb 9 14:45:11 2009 -0800
my version 1.4
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <
schacon@gmail.com>
Date:   Sun Feb 8 19:02:46 2009 -0800
    Merge branch 'experiment'
我们可以看到,在提交对象信息上面,列出了此标签的提交者和提交时间,以及相应的标签信息。
有签名的标签

如果你有GPG私钥的话,你也可以用GPG来给你的标签签名,把-a换成-s就可以了:
[master]$ git tag -s v1.5 -m 'my signed 1.5 tag'
You need a passphrase to unlock the secret key for
user: "Scott Chacon <
schacon@gmail.com>"
1024-bit DSA key, ID F721C45A, created 2009-02-09

然后,如果你对某个标签运行'git show'的话,你就会看到你的GPG前面附加上去了。
[master]$ git show v1.5
tag v1.5
Tagger: Scott Chacon <
schacon@gmail.com>
Date:   Mon Feb 9 15:22:20 2009 -0800
my signed 1.5 tag
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.8 (Darwin)
iEYEABECAAYFAkmQurIACgkQON3DxfchxFr5cACeIMN+ZxLKggJQf0QYiQBwgySN
Ki0An2JeAVUCAiJ7Ox6ZEtK+NvZAj82/
=WryJ
-----END PGP SIGNATURE-----
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <
schacon@gmail.com>
Date:   Sun Feb 8 19:02:46 2009 -0800
    Merge branch 'experiment'
稍后,我们会介绍如何验证签名标签。
轻量级标签

轻量级标签实际上就是存在一个文件中的提交校验和--没有附加任何其他信息。创建轻量级标签的方法就是把上面'-a','-s','-m'这些选项都去掉。
$ git tag v1.4-lw
$ git tag
v0.1
v1.3
v1.4
v1.4-lw
v1.5
如果现在对这个标签使用'git show'命令,不会看到像上面那种标签显示的那么多内容,仅仅显示这次提交的有关信息。
$ git show v1.4-lw
commit 15027957951b64cf874c3557a0f3547bd83b3ff6
Merge: 4a447f7... a6b4c97...
Author: Scott Chacon <schacon@gmail.com>
Date:   Sun Feb 8 19:02:46 2009 -0800

    Merge branch 'experiment'
验证标签
使用'git tag -v (tag)'就可以验证一个签名标签了。这个命令会用到GPG来验证签名。前提是:你必须在密钥环中存放着签名者的公钥。
$ git tag -v v1.4.2.1
object 883653babd8ee7ea23e6a5c392bb739348b1eb61
type commit
tag v1.4.2.1
tagger Junio C Hamano <
junkio@cox.net> 1158138501 -0700
GIT 1.4.2.1
Minor fixes since 1.4.2, including git-mv and git-http with alternates.
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Good signature from "Junio C Hamano <
junkio@cox.net>"
gpg:                 aka "[jpeg image of size 1513]"
Primary key fingerprint: 3565 2A26 2040 E066 C9A7  4A7D C0C6 D9A4 F311 9B9A
如果你没有这个公钥的话,你会看到这样的信息:
gpg: Signature made Wed Sep 13 02:08:25 2006 PDT using DSA key ID F3119B9A
gpg: Can't check signature: public key not found
error: could not verify the tag 'v1.4.2.1'
后期贴标签

这种情况是说你想对以前的某次提交贴个标签,如果整个提交历史是这样的:
$ git log --pretty=oneline
15027957951b64cf874c3557a0f3547bd83b3ff6 Merge branch 'experiment'
a6b4c97498bd301d84096da251c98a07c7723e65 beginning write support
0d52aaab4479697da7686c15f77a3d64d9165190 one more thing
6d52a271eda8725415634dd79daabbc4d9b6008e Merge branch 'experiment'
0b7434d86859cc7b8c3d5e1dddfed66ff742fcbc added a commit function
4682c3261057305bdd616e23b64b0857d832627b added a todo file
166ae0c4d3f420721acbb115cc33848dfcc2121a started write support
9fceb02d0ae598e95dc970b74767f19372d61af8 updated rakefile
964f16d36dfccde844893cac5b347e7b3d44abbc commit the todo
8a5cbc430f1a9c3d00faaeffd07798508422908a updated readme

忘记在那个提交信息为'updated rakefile'的点上贴一个'v1.2'的标签了,我可以现在贴一个上去。你可以在执行创建标签的语句后面跟上那次提交的校验和(或者部分校验和)。
$ git tag -a v1.2 9fceb02
现在我们可以列出所有的标签:
$ git tag
v0.1
v1.2
v1.3
v1.4
v1.4-lw
v1.5
$ git show v1.2
tag v1.2
Tagger: Scott Chacon <
schacon@gmail.com>
Date:   Mon Feb 9 15:32:16 2009 -0800
version 1.2
commit 9fceb02d0ae598e95dc970b74767f19372d61af8
Author: Magnus Chacon <
mchacon@gmail.com>
Date:   Sun Apr 27 20:43:35 2008 -0700
    updated rakefile
...
共享标签

默认情况下,'git push'命令不会将标签上传到远程服务器上。为了共享这些标签,你必须在'git push'命令后明确添加-tags选项
[master]$ git push --tags
Counting objects: 50, done.
Compressing objects: 100% (38/38), done.
Writing objects: 100% (44/44), 4.56 KiB, done.
Total 44 (delta 18), reused 8 (delta 1)
To
git@github.com:schacon/simplegit.git
 * [new tag]         v0.1 -> v0.1
 * [new tag]         v1.2 -> v1.2
 * [new tag]         v1.4 -> v1.4
 * [new tag]         v1.4-lw -> v1.4-lw
 * [new tag]         v1.5 -> v1.5
现在,如果有人克隆或者在线同步你的git仓库的话,标签也会一并同步了。