认识里程碑
里程碑就是Git中的tag,tag是与某个具体的提交(commit)关联的,使用里程碑的好处在于可以直观的看到版本的演变历史,而不是简单生硬的commit id。里程碑的命令是git tag
,可以创建、删除和查看里程碑。
在Git中还有一个git stash
命令,用于保存当前的工作进度,相比之下,git stash
可以在任何操作之后使用该命令,当需要处理其他操作的时候再接着上次的进度继续操作。里程碑所关联的commit是具有一定意义的,通常是在完成某个feature或者bug修复的时候使用,这也是称之为里程碑的原因。
以下创建里程碑的命令实例仍然基于上一篇文章使用的仓库进行。在正式开始之前,在user1和user2下的project目录执行
git pull
。
创建里程碑
git tag
创建里程碑的常用命令如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
轻量级里程碑
所谓轻量级里程碑是指在创建里程碑的时候无须输入描述信息。
在user2目录创建一个轻量级里程碑执行如下命令:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
在创建轻量级里程碑的时候会在版本库的.git/refs/tags
目录下创建一个新文件mytag
,该文件就是刚才创建的轻量级里程碑mytag
。该里程碑的信息可以使用如下命令查看:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
得到的结果是:
mytag
abb48d53ec4096f82e1014aa72e015610fa21415
可以发现是一个SHA-1的哈希值,那么该哈希值也就是该里程碑对应的什么类型的对象呢?使用如下命令:
- 1
- 2
- 1
- 2
输出结果为:
commit
发现刚才创建的mytag里程碑是一个commit,再继续查看该commit的内容。使用如下命令:
- 1
- 2
- 1
- 2
tree 026ce5f7b29dcd6e8760c1fd72fbd85536c98a49
parent 1e5c65640c4154866c87f20aa4fb78756cc49833
author rhwayfun rhwayfun@163.com 1461832874 +0800
committer rhwayfun rhwayfun@163.com 1461832874 +0800
blank commit.
显示了该commit对应的tree对象是026ce5f,父提交是1e5c656,还有提交的作者信息。
然而,在使用git tag
创建里程碑的时候不推荐创建轻量级里程碑,因为轻量级里程碑无法知道是谁创建的里程碑(上面显示了提交的作者信息,那是我配置过的原因),何时创建的。还有一点就是在使用git describe
命令(该命令可以显示生成的版本描述字符串)无法得到里程碑生成的字符串,而在创建里程碑时添加描述字符串的好处是对版本的开发流程一目了然,commit是无法做到这一点的。
带说明的里程碑
为了克服轻量级里程碑的缺点,在项目开发中使用较多的还是带说明的里程碑和带GnuPG签名的里程碑。带说明的里程碑就是在创建里程碑的时候提供一个关于该里程碑的说明。具体演示如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
执行git tag -l -n1
后输出的结果如下:
mytag blank commit.
mytag2 My first annotated tag.
这样就成功创建一个名为mytag2
的带说明的里程碑。要注意的是带说明的里程碑除了在创建里程碑的时候附带了说明字符串,而且mytag2不是一个commit了,而是一个tag对象。使用如下命令可以看到:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
依次输出:
tag
表明mytag2是一个tag类型的对象
object 6d095e6112f25444729ee8cddf8912c626dceca1
type commit
tag mytag2
tagger rhwayfun rhwayfun@163.com 1461833122 +0800
My first annotated tag.
由此可见,在创建带说明的里程碑的时候会在版本库中生成一个tag对象,这个对象记录了创建该里程碑的相关信息,这些信息包括创建的时间、作者和描述字符串。
带GnuPG签名的里程碑
该里程碑与带说明的里程碑本质是一样的,只不过在创建里程碑的时候还额外添加了GnuPG签名。具体创建带GnuPG签名的里程碑操作如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
执行以上的操作后就把本地所创建的里程碑推送到了远程仓库,而如果需要查看远端仓库的里程碑,可以执行如下命令:
- 1
- 2
- 1
- 2
显示结果如下:
abb48d53ec4096f82e1014aa72e015610fa21415 refs/tags/mytag
ec3edf736cd6e37431546b36d2623659995e005e refs/tags/mytag2
6d095e6112f25444729ee8cddf8912c626dceca1 refs/tags/mytag2^{}
可以看到,之前创建的两个里程碑mytag
和mytag2
都推送到了远端仓库。
下面开始创建带GnuPG签名的里程碑:
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
执行失败,信息如下:
gpg: directory
/home/rhwayfun/.gnupg' created
/home/rhwayfun/.gnupg/gpg.conf’ created
gpg: new configuration file
gpg: WARNING: options in/home/rhwayfun/.gnupg/gpg.conf' are not yet active during this run
/home/rhwayfun/.gnupg/secring.gpg’ created
gpg: keyring
gpg: keyring `/home/rhwayfun/.gnupg/pubring.gpg’ created
gpg: skipped “rhwayfun rhwayfun@163.com”: secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the data
error: unable to sign the tag
以上信息告诉我们找不到rhwayfun rhwayfun@163.com签名可用的公钥和私钥对,所以需要首先创建公钥。
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
生成key之后再次执行gpg --list-keys
就可以看到如下的输出:
/home/rhwayfun/.gnupg/pubring.gpg
———————————
pub 2048R/24694C17 2016-04-28 [expires: 2016-04-29]
uid user2 user2@163.com
sub 2048R/235AE980 2016-04-28 [expires: 2016-04-29]
这样就说明成功创建了公钥/私钥对。重新创建里程碑:
- 1
- 2
- 3
- 1
- 2
- 3
输出如下:
mytag blank commit.
mytag2 user2 update this annotated tag.
mytag3 My first GPG-signed tag.
这样就成功创建了带签名的里程碑。
删除里程碑
删除本地仓库的里程碑非常之简单,只需要执行如下命令就可以删除。
- 1
- 1
如果发现删除错误,可以使用如下命令进行补救:
- 1
- 2
- 1
- 2
而如果需要删除远端仓库的里程碑则需要使用如下的命令:
- 1
- 1
比如在user1工作区下,需要删除远端的mytag2里程碑,那么只需要执行如下命令:
- 1
- 1
这样,就完成了远端里程碑的删除。
小结
通过实际操作的方式演示了如何创建三种不同类型的里程碑,以及如何删除本地以及远程仓库的里程碑。不过虽然可以对里程碑进行删除更新等操作,但是里程碑不要应该随意修改,因为里程碑从概念上讲是对历史提交的一个标记,是具有一定意义的。而且,随意修改里程碑可能会造成里程碑管理的混乱。在实际的项目开发中只能允许部分人员具有推送远程里程碑的权限。
git分支关系查看,以及里程碑查看
提供两种方法:
1. 使用Git log命令
git log --graph --decorate --oneline --simplify-by-decoration --all
说明:
--decorate 标记会让git log显示每个commit的引用(如:分支、tag等)
--simplify-by-decoration 只显示被branch或tag引用的commit
--all 表示显示所有的branch,这里也可以选择,比如我指向显示分支ABC的关系,则将--all替换为branchA branchB branchC
2. 使用gitk工具
gitk --simplify-by-decoration --all
参考:
http://stackoverflow.com/questions/5298972/relationship-between-n-git-branches
git log --help