当我检查远程git标签时,使用这样的命令。
git checkout -b local_branch_name origin/remote_tag_name
我得到了这样的错误。
error: pathspec `origin/remote_tag_name` did not match any file(s) known to git.
当我使用git tag命令时,我可以找到remote_tag_name。
标签是用来标示和标记历史中特定的**提交。
它通常用于标记发布点(如v1.0,等等)。
虽然标签可能看起来与分支相似,但标签并不会改变。
它直接指向历史中的一个**特定的提交。
如果标签不在你的版本库中,你将无法签出标签,所以首先你必须把标签 "取 "到你的本地版本库中。
**首先,确保标签在本地存在,方法是***
# --all will fetch all the remotes.
# --tags will fetch all tags as well
git fetch --all --tags --prune
然后通过运行来检查该标签。
git checkout tags/<tag_name> -b <branch_name>
用tags/
前缀代替origin
。
在这个例子中,你有2个标签,版本1.0 & 版本1.1,你可以用以下任何一种方法把它们检出来。
git checkout A ...
git checkout version 1.0 ...
git checkout tags/version 1.0 ...
以上所有的方法都是一样的,因为标签只是一个指向特定提交的指针。
![在此输入图片描述][3] 。 来源:https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png
# list all tags
git tag
# list all tags with given pattern ex: v-
git tag --list 'v-*'
有2种方法来创建标签。
# lightweight tag
git tag
# annotated tag
git tag -a
这两种方式的区别在于,创建注释标签时,你可以像在git提交中那样添加元数据。
姓名、电子邮件、日期、评论& 签名
# delete any given tag
git tag -d <tag name>
# Don't forget to remove the deleted tag form the server with push tags
为了抓取指定标签的内容,你可以使用checkout
命令。
如上所述,标签和其他提交文件一样,所以我们可以使用checkout
,而不是使用SHA-1,只需用tag_name替换它即可。
选项1:
# Update the local git repo with the latest tags from all remotes
git fetch --all
# checkout the specific tag
git checkout tags/<tag> -b <branch>
选项2:
由于git支持shallow clone,通过在clone命令中添加--branch
,我们可以使用标签名而不是分支名。Git知道如何将给定的SHA-1翻译成相关的提交。
# Clone a specific tag name using git clone
git clone <url> --branch=<tag_name>
git clone --branch=
*
--branch
也可以接受标签,并在生成的版本库中分离出该提交处的HEAD。
git push --tags
要推送所有标签。
git push --tags
要推送已注解的标签和当前的历史链标签,请使用:。
git push --follow-tags
这个标志--follow-tags
同时推送了commits和只有tag这两者。
从Git 2.4开始,你可以用配置来设置它
git config --global push.followTags true
不存在所谓的"远程 Git 标签"。 只有"标签"。 我指出这些并不是为了迂腐,1而是因为普通的Git用户对此有很大的困惑,而且Git文档对初学者的帮助不大2 。 (不清楚这种困惑是因为文档不完善,还是文档不完善是因为这本身就有一些困惑,还是什么)。
有*的"远程分支",更恰当的称呼是"远程跟踪分支",但值得注意的是,这些实际上是本地实体。 不过,没有远程标签(除非你(重新)发明它们)。 只有本地标签,所以你需要在本地获得标签,以便使用它。
特定提交的名称的一般形式--Git称之为references--是任何以refs/
开头的字符串。 以refs/heads/
开头的字符串命名一个分支;以refs/remotes/
开头的字符串命名一个远程跟踪的分支;以refs/tags/
开头的字符串命名一个标签。 refs/stash
是储藏库的引用(如git stash
所使用的;注意没有尾部斜线)。
有一些不寻常的特例名称不以refs/
开头:HEAD
、ORIG_HEAD
、MERGE_HEAD
,特别是CHERRY_PICK_HEAD
也都是可能指代特定提交的名称(尽管HEAD
通常包含一个分支的名称,即包含ref: refs/heads/
branch< /code>)。 但在一般情况下,引用以refs/
开头。
Git做了一件让人困惑的事,它允许你省略refs/
,通常还有refs/
后面的词。 例如,在引用本地分支或标签时,你可以省略refs/heads/
或refs/tags/
,事实上,在签出本地分支时,你必须省略refs/heads/
。 你可以在结果不明确的时候这样做,或者--正如我们刚刚指出的--当你必须这样做时(对于git checkout branch
)。
诚然,引用不仅存在于你自己的仓库,也存在于远程仓库。 然而,Git只在非常特定的时间让你访问远程仓库的引用:即在fetch
和push
操作期间。 你也可以使用git ls-remote
或git remote show
来查看它们,但fetch
和push
是更有趣的接触点。
在fetch
和push
过程中,Git使用它称之为refspecs的字符串在本地和远程仓库之间传输引用。 因此,正是在这些时候,通过refspecs,两个Git仓库可以相互同步。 一旦你们的名字同步了,你就可以使用远程的人所使用的名字了。 不过在fetch
上有一些特殊的魔法,它同时影响到分支名和标签名。
你应该把git fetch
看成是指导你的 Git 调用(或者文本消息)另一个 Git--"远程"--并与之进行对话。 在对话的早期,远程列出了它所有的引用:refs/heads/
中的所有内容和refs/tags/
中的所有内容,以及它的任何其他引用。 你的Git会扫描这些内容并(基于通常的fetch refspec)重命名它们的分支。
让我们来看看远程名为 "origin "的正常refspec。
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$
这个 refspec 指示你的 Git 将每一个与 refs/heads/*
匹配的名称--即远程的每一个分支--改成 refs/remotes/origin/*
,也就是说,保持匹配的部分不变,将分支名称(refs/heads/
)改为远程追踪的分支名称(refs/remotes/
,特别是refs/remotes/origin/
)。
正是通过这个 refspec,origin
'的分支成为你对远程origin
的远程跟踪分支。 分支名称成为远程跟踪的分支名称,其中包括远程的名称,在这里是origin
,。 refspec前面的加号+
设置了"force"标志,也就是说,你的远程跟踪分支将被更新为与远程的分支名相匹配,无论如何都要使其匹配。 (如果没有+
,分支的更新只限于"快进"修改,而标签的更新则从Git 1.8.2左右的版本开始就被忽略了--在此之前,同样的快进规则也适用。)
但是标签呢? 至少在默认情况下,没有标签的参考规范。 你可以设置一个,在这种情况下,Refspec的形式由你决定;或者你可以运行git fetch --tags
。 使用--tags
的效果是在 refspec 中添加refs/tags/*:refs/tags/*
,也就是说。它带来了所有的标签(但如果你已经有了这个名字的标签,则不会更新你的标签,不管远程的标签怎么说 2017年1月编辑:从Git 2.10,测试表明,--tags
会强制更新你的标签,就像refspec读作+refs/tags/*:refs/tags/*
;这可能是与早期版本的Git的行为不同)。
注意这里没有重命名:如果远程的origin
有标签xyzzy
,而你没有,并且你git fetch origin "refs/tags/*:refs/tags/*"
,你会得到refs/tags/xyzzy
添加到你的仓库(指向与远程相同的提交)。 如果你使用+refs/tags/*:refs/tags/*
,那么你的标签xyzzy
,如果你有的话,会被origin
的标签*替换。 也就是说,Refspec上的+
强制标志意味着"用我的Git从他们的Git上得到的值替换我的参考值"。
由于历史原因,3如果你既没有使用--tags
选项,也没有使用--no-tags
选项,git fetch
会采取特殊行动。 记得我们在上面说过,远程开始向你的本地Git显示所有的引用,无论你的本地Git是否想看到它们。4 你的Git在这时会记下它看到的所有标签。 然后,当它开始下载它需要处理的任何提交对象时,如果其中一个提交对象的ID与这些标签中的任何一个相同,Git就会把这个标签--或者这些标签,如果多个标签都有这个ID--添加到你的仓库里。
编辑,2017年1月:测试表明,现在Git 2.10中的行为是。如果他们的Git提供了一个名为T的标签,你没有名为T的标签,与T相关的提交ID是你的 "git fetch "正在检查的他们的一个分支的祖先,你的Git将T添加到你的标签,无论是否有--tags
。 添加--tags
会使你的Git获得**他们的所有标签,并强制更新。
你可能必须使用git fetch --tags
来获取他们的标签。 如果他们的标签名与你现有的标签名冲突,你可能*(取决于Git版本)甚至不得不删除(或重命名)你的一些标签,然后运行git fetch --tags
,来获得他们的标签。 因为标签--不同于远程分支--没有自动重命名功能,你的标签名必须与他们的标签名相匹配,这就是为什么你会遇到冲突的问题。
不过在大多数情况下,简单的 "git fetch "就能完成工作,带来他们的提交和匹配的标签,由于他们--不管他们是谁--会在发布提交的时候标记提交,你会跟上他们的标签。 如果你不做自己的标签,也不把他们的仓库和其他仓库混在一起(通过多个远程),你也不会有任何标签名称的冲突,所以你不必为了获得他们的标签而大费周章地删除或重命名标签。
我在上面提到,你几乎总是可以省略refs/
,以及refs/heads/
和refs/tags/
等大部分时间。 但是,什么时候可以39;不?
完整的(或接近完整的)答案在[gitrevisions
文档](https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html)。 Git 会使用链接中给出的六步序列将名称解析为提交 ID。 奇怪的是,标签会覆盖分支:如果有一个标签xyzzy
和一个分支xyzzy
,并且它们指向不同的提交,那么。
git rev-parse xyzzy
gitrevisions
所缺少的--git checkout
更倾向于分支名称,所以git checkout xyzzy
会把你放在分支上,而不考虑标签。
如果出现歧义,你几乎可以用全名来拼出参考文献的名称,refs/heads/xyzzy
或refs/tags/xyzzy
。 (注意,这是与git checkout
一起工作的,但可能是以一种意想不到的方式。git checkout refs/heads/xyzzy
会导致一个分离的前端检查,而不是一个分支检查。 这就是为什么你只需注意git checkout
会先使用短名称作为分支名称:这就是你如何签出分支xyzzy
,即使标签xyzzy
存在。 如果你想检出标签,你可以使用refs/tags/xyzzy
)。
因为(正如gitrevisions
所指出的)Git会尝试refs/name
,你也可以简单地写tags/xyzzy
来识别标记xyzzy
的提交。 (如果有人设法在$GIT_DIR
中写入一个名为xyzzy
的有效引用,这将被解析为$GIT_DIR/xyzzy
。 但通常只有各种 "*HEAD "的名字应该在"$GIT_DIR "中)。1好吧,好吧,"不是*只想迂腐"。 :-) 2有人会说"非常没有帮助",实际上,我倾向于同意。 3基本上,"git fetch",以及远程和refspecs的整个概念,是Git的一个迟到的补充,大约发生在Git 1.5的时候。 在那之前,只有一些临时的特殊情况,而标签获取就是其中之一,所以它通过特殊的代码得到了延续。 4如果有帮助的话,可以把远程Git想象成一个[flasher](http://www.dictionary.com/browse/flasher),在俚语中的意思。