17.2.3 带签名的里程碑

    带签名的里程碑和上面介绍的带说明的里程碑本质上是一样的,都是在创建里程碑的时候在Git对象库中生成一个tag对象,只不过带签名的里程碑多做了一个工作:为里程碑对象添加GnuPG签名。

    创建带签名的里程碑也非常简单,使用参数-s或-u<key-id>即可。还可以使用-m<msg>参数直接在命令行中提供里程碑的描述。创建带签名的里程碑的一个前提是需要安装GnuPG,并且建立相应的公钥/私钥对。

    GnuPG可以在各个平台上安装。

    在Linux如Debian/Ubuntu上安装,执行:


    $sudo aptitude install gnupg

    在Mac OS X上可以通过Homebrew安装:


    $brew install gnupg

    在Windows上可以通过cygwin安装gnupg。

    为了演示创建带签名的里程碑,还是事先创建一个空提交:


    $git commit—allow-empty-m "blank commit for GnuPG-signed tag test." [master ebcf6d6]blank commit for GnuPG-signed tag test.

    直接在刚刚创建的空提交上创建一个带签名的里程碑mytag3很可能会失败:


    $git tag-s-m "My frst GPG-signed tag." mytag3 gpg:"user1<user1@sun.ossxp.com>"已跳过:私钥不可用 gpg:signing failed:私钥不可用 error:gpg failed to sign the tag error:unable to sign the tag

    之所以签名失败,是因为找不到签名可用的公钥/私钥对。使用下面的命令可以查看当前可用的GnuPG公钥。


    $gpg—list-keys /home/jiangxin/.gnupg/pubring.gpg ————————————————- pub 1024D/FBC49D01 2006-12-21[有效至:2016-12-18] uid Jiang Xin<worldhello.net@gmail.com> uid Jiang Xin<jiangxin@ossxp.com> sub 2048g/448713EB 2006-12-21[有效至:2016-12-18]

    可以看到GnuPG的公钥链(pubring)中只包含了Jiang Xin用户的公钥,尚没有uesr1用户的公钥。

    实际上在创建带签名的里程碑时,并非一定要使用签名者本人的公钥/私钥对进行签名,使用-u<key-id>参数调用就可以用指定的公钥/私钥对进行签名,对于此例可以使用FBC49D01作为<key-id>。但如果没有可用的公钥/私钥对,或者希望使用提交者本人的公钥/私钥对进行签名,就需要为提交者:user1<user1@sun.ossxp.com>创建对应的公钥/私钥对。

    使用命令gpg—gen-key来创建公钥/私钥对。


    $gpg—gen-key

    按照提示一步一步操作即可。需要注意的有:

    在创建公钥/私钥对时,会提示输入用户名,输入User1,提示输入邮件地址,输入user1@sun.ossxp.com,其他可以采用默认值。

    在提示输入密码时,为了简单起见可以直接按下回车,即使用空口令。

    在生成公钥/私钥对过程中,会提示用户做一些随机操作以便产生更好的随机数,这时不停的晃动鼠标就可以了。

    创建完毕,再查看一下公钥链。


    $gpg—list-keys /home/jiangxin/.gnupg/pubring.gpg ————————————————- pub 1024D/FBC49D01 2006-12-21[有效至:2016-12-18] uid Jiang Xin<worldhello.net@gmail.com> uid Jiang Xin<jiangxin@ossxp.com> sub 2048g/448713EB 2006-12-21[有效至:2016-12-18] pub 2048R/37379C67 2011-01-02 uid User1<user1@sun.ossxp.com> sub 2048R/2FCFB3E2 2011-01-02

    很显然用户user1的公钥/私钥对已经建立。现在就可以直接使用-s参数来创建带签名的里程碑了。


    $git tag-s-m "My frst GPG-signed tag." mytag3

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


    $git tag-l my*-n1 mytag blank commit. mytag2 My first annotated tag. mytag3 My first GPG-signed tag.

    和带说明的里程碑一样,在Git对象库中也建立了一个tag对象。查看该tag对象可以看到其中包含了GnuPG签名。


    $git cat-file tag mytag3 object ebcf6d6b06545331df156687ca2940800a3c599d type commit tag mytag3 tagger user1<user1@sun.ossxp.com>1293960936+0800 My first GPG-signed tag. ——-BEGIN PGP SIGNATURE——- Version:GnuPG v1.4.10(GNU/Linux) iQEcBAABAgAGBQJNIEboAAoJEO9W1fg3N5xn42gH/jFDEKobqlupNKFvmkI1t9d6 lApDFUdcFMPWvxo/eq8VjcQyRcb1X1bGJj+pxXk455fDL1NWonaJa6HE6RLu868x CQIWqWelkCelfm05GE9FnPd2SmJsiDkTPZzINya1HylF5ZbrExH506JyCFk//FC2 8zRApSbrsj3yAWMStW0fGqHKLuYq+sdepzGnnFnhhzkJhusMHUkTIfpLwaprhMsm 1IIxKNm9i0Zf/tzq4a/R0N8NiFHl/9M95iV200I9PuuRWedV0tEPS6Onax2yT3JE I/w9gtIBOeb5uAz2Xrt5AUwt9JJTk5mmv2HBqWCq5wefxs/ub26iPmef35PwAgA= =jdrN ——-END PGP SIGNATURE——-

    要验证签名的有效性,如果直接使用gpg命令会比较麻烦,因为需要将这个文件拆分为两个,一个是不包含签名的里程碑内容,另外一个是签名本身。还好可以使用命令git tag-v来验证里程碑签名的有效性。


    $git tag-v mytag3 object ebcf6d6b06545331df156687ca2940800a3c599d type commit tag mytag3 tagger user1<user1@sun.ossxp.com>1293960936+0800 My first GPG-signed tag. gpg:于2011年01月02日星期日17时35分36秒CST创建的签名,使用RSA,钥匙号37379C67