SHIHUC

好记性不如烂笔头,还可以分享给别人看看! 专注基础算法,互联网架构,人工智能领域的技术实现和应用。
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

git tag知多少

Posted on 2016-01-21 10:20  shihuc  阅读(6073)  评论(0编辑  收藏  举报

这个命令,其实很有用,类似clearcase中的label,就是给一个版本设置一个标记(标签),方便后期查找特定的版本。

 

tag和commit的sha1那串字符串的关系,不是很大,但是还是要说一下的。

1. 每一次修改,在本地仓库中,只有commit了,在ref中有新的相关的记录,才可以做push到远端。否则会提示你Everything is up-to-date.

 1 [root@CloudGame mueas]# ll
 2 total 12
 3 -rw-r--r-- 1 root root 4132 Jan 21 09:28 pom.xml
 4 drwxr-xr-x 3 root root 4096 Jan 21 09:28 src
 5 [root@CloudGame mueas]# git status        #git status查看当前是否有新的修改发生,结果显示没有修改。
 6 On branch master
 7 Your branch is up-to-date with 'origin/master'.
 8 nothing to commit, working directory clean
 9 [root@CloudGame mueas]# git push         #push一个干净的工作目录,你会看到什么都是最新的,意思是没有必要push
10 Everything up-to-date

2. 没有commit得到的那个sha1的字符串,是不允许给执行git tag加标签的。否则,你会遇到错误!

 1 [root@CloudGame hello]# ll -al                #查看当前本地repo中的内容,显示什么都没有
 2 total 12
 3 drwxr-xr-x  3 root   root   4096 Jan 21 09:19 .
 4 drwxr-xr-x. 3 shihuc shihuc 4096 Jan 21 09:19 ..
 5 drwxr-xr-x  7 root   root   4096 Jan 21 09:20 .git
 6 [root@CloudGame hello]# git status              #查看当前repo的状态信息。也是说没有东西commit
 7 On branch master
 8 
 9 Initial commit
10 
11 nothing to commit (create/copy files and use "git add" to track)
12 [root@CloudGame hello]# git tag ht001            #创建轻量级标签ht001,提示错误
13 fatal: Failed to resolve 'HEAD' as a valid ref.
14 [root@CloudGame hello]# git tag -a ht001 -m "first one tag for initial repo"    #创建注解标签,同样报错
15 fatal: Failed to resolve 'HEAD' as a valid ref.

根据这个提示信息,很容易知道原因,就是没有东西commit,所以不让做tag。只有commit了,才可以打标签。我们可以看看下面:

 1 [root@CloudGame hello]# touch README.txt      #创建一个文件
 2 [root@CloudGame hello]# git status          #查看状态信息。显示有意个没有被跟踪的文件
 3 On branch master
 4 
 5 Initial commit
 6 
 7 Untracked files:
 8   (use "git add <file>..." to include in what will be committed)
 9 
10     README.txt
11 
12 nothing added to commit but untracked files present (use "git add" to track)
13 [root@CloudGame hello]# git add README.txt               #添加README.txt到本地repo
14 [root@CloudGame hello]# git commit -m "README is created"      #commit这个文件
15 [master (root-commit) d4e04d6] README is created
16  1 file changed, 0 insertions(+), 0 deletions(-)
17  create mode 100644 README.txt
18 [root@CloudGame hello]# git status                    #再次查看当前repo的信息,显示当前没有东西可以commit。工作目录是干净的。
19 On branch master
20 Your branch is based on 'origin/master', but the upstream is gone.
21   (use "git branch --unset-upstream" to fixup)
22 nothing to commit, working directory clean
23 [root@CloudGame hello]# vim .git/refs/heads/master           
24 [root@CloudGame hello]# cat .git/refs/heads/master           #由于当前在master分支,所以查看这个分支文件的内容,显示为当前的commit的sha1字符串
25 d4e04d68c5aa5b316167a1c3baa63faabb06cf80
26 [root@CloudGame hello]# 
27 [root@CloudGame hello]# git log
28 commit d4e04d68c5aa5b316167a1c3baa63faabb06cf80
29 Author: chengsh <shihu.cheng@000000.com>
30 Date:   Thu Jan 21 09:39:03 2016 +0800
31 
32     README is created

 

最后,在有了这个commit的内容后,先检查下.git/refs/tags/目录下有没有内容!从下面的日志看,是什么都没有的,空的。

1 [root@CloudGame hello]# ll .git/refs/
2 total 8
3 drwxr-xr-x 2 root root 4096 Jan 21 09:40 heads
4 drwxr-xr-x 2 root root 4096 Jan 21 09:19 tags
5 [root@CloudGame hello]# ll .git/refs/tags/
6 total 0

那么,这个时候添加tag,会是什么样子呢?往下看:

1 [root@CloudGame hello]# git tag -a ht001 -m "first tag"    #添加一个注解类型的标签,添加基本类型(轻量级)的也同样可以。
2 [root@CloudGame hello]# 
3 [root@CloudGame hello]# ll .git/refs/tags/            #查看tags目录下有没有东西,显示有一个标签命名的文件  
4 total 4
5 -rw-r--r-- 1 root root 41 Jan 21 09:48 ht001
6 [root@CloudGame hello]# 
7 [root@CloudGame hello]# cat .git/refs/tags/ht001         #查看这个标签文件内容是什么,一串字符
8 6e032b380494c7a230686a00533ea4ad1ab2961a

 

到此,可以看出tag和commit的关系了吧。要想tag,必须先有commit。clearcase当中,可以给一个节点添加多个label,那git里面能否给一个commit号(sha1字符串)添加多个标签呢?我们往下看:

 1 [root@CloudGame hello]# git tag ht002
 2 [root@CloudGame hello]# 
 3 [root@CloudGame hello]# ll -al .git/refs/tags/
 4 total 16
 5 drwxr-xr-x 2 root root 4096 Jan 21 09:53 .
 6 drwxr-xr-x 4 root root 4096 Jan 21 09:19 ..
 7 -rw-r--r-- 1 root root   41 Jan 21 09:48 ht001
 8 -rw-r--r-- 1 root root   41 Jan 21 09:53 ht002
 9 [root@CloudGame hello]# cat .git/refs/tags/ht002
10 d4e04d68c5aa5b316167a1c3baa63faabb06cf80
11 [root@CloudGame hello]# 

上面的操作日志显示,给同一个commit后的操作,添加多个tag是可以的,每次的tag标签对应的sha1字符串不同。

 

下面看看,操作tag后,gitk显示的内容是什么?

 

再来看看ht002标签的信息对应的内容:

 

从上图,可以发现,基本类型的tag对应的信息,那个sha1串头是tree字样。而注解类型的tag中sha1串头对应的字样是object。这也是一个小区别。

 

下面,列举一下tag常见的操作指令:

切换到标签 git checkout <tagname>
查看标签的版本信息 git show <tagname>
删除标签 git tag -d <tagname>
给指定的commit打标签 git tag -a <tagname> [-m <your comment>] <commit-sha1-id>
发布指定的标签到远程仓库 git push origin <tagname>
将本地的标签全部发布到远程仓库 git push origin --tags
查看当前分支下的所有标签信息 git tag
删除远程tag  

git tag -d <tagname>;

git push origin :<tagname>

最后补充说明一下,通常git push的时候,标签信息是不会被一起发布到远程仓库的。删除远程分支和标签类似,都是先删除本地的分支或则标签,然后push这个分支或则标签到远程仓库。都要注意的一点就是origin与冒号之间有一个空格。否则会出错的。