这个命令,其实很有用,类似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与冒号之间有一个空格。否则会出错的。