tag的实现
在git中,常见的tag有两种,一种是轻量级的tag,一种是带说明的tag。要创建一个新的tag是一个很简单的操作,创建轻量级tag只需git tag [tagname] 创建带说明的tag只需git tag [tagname] -m [message]。看似两者差别很小,但背后,在git内部,二者的实现却差别很大。
首先通过创建两个tag来开始今天的讨论:
gewang@LM-SHC-00355679@17:01:40:~/test/TryOurInternalGithub => git log --oneline -1 # 查看当前所在commit ab2d6ee 2nd commit gewang@LM-SHC-00355679@16:34:14:~/test/TryOurInternalGithub => find .git/objects/ .git/objects/ .git/objects//info .git/objects//info/packs .git/objects//pack .git/objects//pack/pack-37b8c10ba135fb7e9166a0ea483ab9597b15d039.idx .git/objects//pack/pack-37b8c10ba135fb7e9166a0ea483ab9597b15d039.pack gewang@LM-SHC-00355679@16:34:17:~/test/TryOurInternalGithub => git tag tag1 # 创建轻量级的tag1 gewang@LM-SHC-00355679@16:34:23:~/test/TryOurInternalGithub => find .git/objects/ # 没有新的object生成 .git/objects/ .git/objects//info .git/objects//info/packs .git/objects//pack .git/objects//pack/pack-37b8c10ba135fb7e9166a0ea483ab9597b15d039.idx .git/objects//pack/pack-37b8c10ba135fb7e9166a0ea483ab9597b15d039.pack gewang@LM-SHC-00355679@16:34:26:~/test/TryOurInternalGithub => git tag tag2 -m "tag2" # 创建一个带说明的提交 gewang@LM-SHC-00355679@16:34:42:~/test/TryOurInternalGithub => find .git/objects/ # 生成了一个新的object 84458d .git/objects/ .git/objects//84 .git/objects//84/458d8d078307134b8f6712d84c07f438ba6657 .git/objects//info .git/objects//info/packs .git/objects//pack .git/objects//pack/pack-37b8c10ba135fb7e9166a0ea483ab9597b15d039.idx .git/objects//pack/pack-37b8c10ba135fb7e9166a0ea483ab9597b15d039.pack
可以看到,二者深层次的差别在于是否会创建一个object来记录这个tag。到git repo中的tag命名空间查看:
gewang@LM-SHC-00355679@16:59:23:~/test/TryOurInternalGithub => ls .git/refs/tags/ tag1 tag2接着查看两者的内容:
gewang@LM-SHC-00355679@17:00:34:~/test/TryOurInternalGithub => cat .git/refs/tags/tag1 ab2d6eea3cde6b1fac1784a6afb19a552a78689e gewang@LM-SHC-00355679@17:01:14:~/test/TryOurInternalGithub => cat .git/refs/tags/tag2 84458d8d078307134b8f6712d84c07f438ba6657
可以看到轻量级的tag1的内容直接指向了当前的commit id。而带提交的tag2则指向了那个新生成的object。让我们来看看这个新object的真面目。
gewang@LM-SHC-00355679@17:04:17:~/test/TryOurInternalGithub => git cat-file -t 84458d8d078307134b8f6712d84c07f438ba6657 tag gewang@LM-SHC-00355679@17:04:22:~/test/TryOurInternalGithub => git cat-file -p 84458d8d078307134b8f6712d84c07f438ba6657 object ab2d6eea3cde6b1fac1784a6afb19a552a78689e type commit tag tag2 tagger Michael Wang可以看到新生成的object的类型是tag(这是git四个基本object类型中的一种,其他三种是commit,tree,blob)。可以看到这个object记录的5条信息,它指向了一个id为ab2d6eea3的对象,这个对象的类型为commit,这个tag的名字叫tag2,打tag的username是Michael,当天给的message是“tag2”。Tue Aug 14 16:34:42 2012 +0800 tag2
至此,基本可以看出git中tag的实现方式,轻量级的tag直接通过一个tag文件指向一个commit id。带说明的tag会生成一个特定的tag对象,记录一系列和tag相关的信息。
那么实际操作中我们该使用哪种tag呢?一般情况下推荐使用带提交的tag,因为它除了基本的信息外,还记录了谁在什么时间创建这个tag,以及一些说明,这对以后查阅历史提供了更详尽的信息。
与server端交互
现在尝试将新创建的tag推送到server:gewang@LM-SHC-00355679@17:04:25:~/test/TryOurInternalGithub => git push Everything up-to-dategit提示我们所有的refs都已经up-to-date,表示git默认不会推送本地tag到server端,必须明确指定要推送的tag:
gewang@LM-SHC-00355679@17:16:24:~/test/TryOurInternalGithub => git push origin tag1 Total 0 (delta 0), reused 0 (delta 0) To git@github.scm.corp.ebay.com:gewang/TryOurInternalGithub.git * [new tag] tag1 -> tag1 gewang@LM-SHC-00355679@17:17:38:~/test/TryOurInternalGithub => git push origin tag2 Counting objects: 1, done. Writing objects: 100% (1/1), 158 bytes, done. Total 1 (delta 0), reused 0 (delta 0) To git@github.scm.corp.ebay.com:gewang/TryOurInternalGithub.git * [new tag] tag2 -> tag2在上边的例子中可以看到推送tag2时,向server端写了1个object,而tag1则没有,这也印证了2者的区别。
那么要如何才能从server获得tag呢?我们删除本地tag,执行git pull看看:
gewang@LM-SHC-00355679@17:20:45:~/test/TryOurInternalGithub => git tag -d tag1 Deleted tag 'tag1' (was ab2d6ee) gewang@LM-SHC-00355679@17:20:54:~/test/TryOurInternalGithub => git tag -d tag2 Deleted tag 'tag2' (was 84458d8) gewang@LM-SHC-00355679@17:20:54:~/test/TryOurInternalGithub => git pull remote: Counting objects: 1, done. remote: Total 1 (delta 0), reused 1 (delta 0) Unpacking objects: 100% (1/1), done. From github.scm.corp.ebay.com:gewang/TryOurInternalGithub * [new tag] tag1 -> tag1 * [new tag] tag2 -> tag2可以看到默认清空下,git pull会将server端的tag获取到本地。
以上就是关于git中tag的简要分析,有问题的朋友可以留言说明,我会尽快update。
没有评论:
发表评论