如何签出远程git标签

当我签出远程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命令时,我可以findremote_tag_name。

让我们先解释一下git中的标签

标签用于标记和标记历史logging中的特定提交
它通常用来标记释放点(例如v1.0等)。

虽然标签可能会出现类似于分支, 但是标签不会改变
直接指向历史上的具体提交


如果标签不在本地存储库中,则无法检出标签,因此首先必须将标签fetch到本地存储库。

首先确保标签在本地存在

 # --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> 

而不是origin使用tags/前缀。


在这个示例中,您有两个标签版本1.0和版本1.1,您可以使用以下任意一项将它们签出:

 git checkout A ... git checkout version 1.0 ... git checkout tags/version 1.0 ... 

以上所有都会做同样的事情,因为标签只是一个指向给定提交的指针。

在这里输入图像说明


如何创build标签?

有两种方法可以创build标签:

 # normal tag git tag # anotated tag git tag -a 

2之间的区别是,创build注释标签时,你可以添加元数据像你在一个混帐提交:
姓名,电子邮件,date,评论和签名

(这个答案需要一段时间才能写出来, 代码向导的答案在目标和本质上是正确的,但是并不完全完整,所以我会发布这个。)


没有像“远程Git标签”这样的东西。 只有“标签”。 我指出所有这一切都不是迂腐, 1,但是因为对于随便的Git用户而言,这个问题有很多困惑,Git文档对初学者来说并不是很有帮助。 (目前还不清楚是由于文档质量差造成了混淆,还是因为这本质上有些混乱,或者说什么而导致文档质量差)。

有“远程分支机构”,更恰当地称为“远程跟踪分支”,但值得注意的是,这些实际上是本地实体。 没有远程标签,但(除非你(重新)发明)。 只有本地标签,所以你需要在本地获取标签才能使用它。

特定提交的名称(Git调用引用)的一般forms是任何以refs/开头的string。 以refs/heads/名称开头的string; 一个以refs/remotes/名字开头的string,一个远程追踪分支; 和一个以refs/tags/命名一个标签的string。 名称refs/stash是存储引用(由git stash ;注意缺less结尾的斜线)。

有一些不寻常的特殊名称不以refs/开始: HEADORIG_HEADMERGE_HEADCHERRY_PICK_HEAD尤其都是可以引用特定提交的名称(虽然HEAD通常包含分支名称,即包含ref: refs/heads/ branch )。 但一般来说,引用以refs/开头。

Git所做的一件事情就是让它混淆,就是允许你忽略refs/ ,经常是refs/之后的单词。 例如,在引用本地分支或标签时,您可以省略refs/heads/refs/tags/ ,实际上在签出本地分支时,您必须省略refs/heads/ ! 只要结果是明确的,或者正如我们刚刚提到的那样,您可以做到这一点,当您必须执行此操作时(对于git checkout branch )。

确实,引用不仅存在于您自己的存储库中,而且存在于远程存储库中。 但是,Git只允许您在非常特定的时间访问远程存储库的引用:即在fetchpush操作期间。 你也可以使用git ls-remote或者git remote show来查看它们,但是fetchpush是更有趣的联系点。

Refspecs

fetchpush期间,Git使用它调用refspecs的string在本地和远程存储库之间传输引用。 因此,正是在这个时候,通过refspecs,两个Git仓库可以相互同步。 一旦你的名字同步,你可以使用与远程使用者相同的名字。 虽然在这里有一些特殊的魔术,它会影响分支名称和标签名称。

你应该把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/* -ie,远程的每个分支 – 并将其名称更改为refs/remotes/origin/* ,即保持匹配的部分相同,更改分支名称( refs/heads/ )到远程追踪分行名称( refs/remotes/ ,特别是refs/remotes/origin/ )。

通过这个refspec origin分支成为远程origin远程追踪分支。 分行名称变为远程跟踪分行名称,包括远程的名称,在本例中为origin 。 refspec前面的加号设置“强制”标志,即远程跟踪分支将被更新以匹配远程的分支名称,而不pipe使其匹配的是什么。 (没有+ ,分支更新被限制为“快进”更改,自从Git版本1.8.2左右,标签更新被简单地忽略 – 然后应用相同的快进规则。)

标签

但是标签呢? 对他们来说没有什么特别的规定,至less不是默认的。 你可以设置一个,在这种情况下,refspec的forms取决于你; 或者你可以运行git fetch --tags 。 使用--tags的作用是在--tags中添加refs/tags/*:refs/tags/* ,即它带来了所有的标签( 但是不会更新标签,如果你已经有了这个名字的标签,什么是远程的标签说:编辑,2017年1月:从Git 2.10,testing表明, --tags强制更新您的标签从远程的标签,就像--tags阅读+refs/tags/*:refs/tags/* ;这可能与早期版本的Git有所不同)。

请注意,这里没有重命名:如果远程origin有标签xyzzy ,而你不这样做,你git fetch origin "refs/tags/*:refs/tags/*" ,你可以将refs/tags/xyzzy添加到你的存储库(指向与远程服务器相同的提交)。 如果你使用+refs/tags/*:refs/tags/*那么你的标签xyzzy (如果有的话) 来自origin标签replace 。 也就是说,refspec上的+ force标志意味着“用我的Git从他们的Git中获得的值来replace我的引用值”。

提取过程中的Automagic标签

由于历史原因, 3如果您既不使用--tags选项也不使用--no-tags选项, git fetch会采取特殊的措施。 请记住,我们上面说过,远程服务器是通过向本地Git显示其所有引用来开始的,无论您的本地Git是否希望看到它们。 4你的Git注意到了这个时候看到的所有标签。 然后,当它开始下载任何提交对象时,它需要处理提取的任何内容,如果其中一个提交与这些标记具有相同的ID,git将添加该标记或那些标记(如果多个标记具有该标识)你的仓库

编辑,2017年1月:testing显示现在在Git 2.10中的行为是:如果他们的Git提供了一个名为T的标签, 并且没有名为T的标签, 并且T相关的提交ID是其分支之一的祖先你的git fetch正在检查,你的Git将T添加到你的标签有或没有 – --tags 。 添加 – --tags会导致你的Git获得他们所有的标签,并强制更新。

底线

你可能不得不使用git fetch --tags来获取他们的标签。 如果他们的标签名称与您现有的标签名称冲突,则可能 (取决于Git版本)甚至需要删除(或重命名)一些标签,然后运行git fetch --tags来获取标签。 由于标签(不同于远程分支)不具有自动重命名function,因此标签名称必须与其标签名称相匹配,这就是为什么您可能遇到冲突问题。

大多数正常情况下,一个简单的git fetch将完成这项工作,提交他们的提交和匹配的标签,而且由于他们(无论他们是谁)将在发布提交时标记提交,所以您将继续标签。 如果您不制作自己的标签,也不会混合他们的存储库和其他存储库(通过多个遥控器),您也不会有任何标签名称冲突,所以您不必大惊小怪地删除或重命名标签获取他们的标签。

当你需要有限的名字

我在上面提到过,你几乎总是可以忽略refs/ ,并且大部分时间都是refs/heads/refs/tags/等等。 但是,当你不能

完整的(或接近完整的)答案在gitrevisions文档中 。 Git将使用链接中给出的六步序列将名称parsing为提交ID。 奇怪的是,标签覆盖分支:如果有一个标签xyzzy和一个分支xyzzy ,他们指向不同的提交,那么:

 git rev-parse xyzzy 

会给你标签指向的ID。 然而 – 这是从gitrevisions缺less的gitrevisionsgit checkout更喜欢分支名称,所以git checkout xyzzy会把你放在分支上,不pipe标签。

如果含糊不清,几乎总是可以使用其全名拼写ref名称, refs/heads/xyzzyrefs/tags/xyzzy 。 (请注意,这与git checkout一起工作,但是可能是出乎意料的: git checkout refs/heads/xyzzy会导致一个分离的HEAD checkout而不是一个分支checkout,这就是为什么你只需要注意到git checkout将会使用短名称作为第一个分支名称:即使标签xyzzy存在,也是如此检出分支xyzzy 。如果要检出标签,可以使用refs/tags/xyzzy 。)

因为(如gitrevisions注释)Git会尝试refs/ name ,你也可以简单地写tags/xyzzy来标识标签为xyzzy的提交。 (如果有人设法将一个名为xyzzy的有效引用写入$GIT_DIR ,那么这将被parsing为$GIT_DIR/xyzzy ,但是通常只有不同的*HEAD名字应该在$GIT_DIR


1好的,好吧,“不要只是迂腐”。 🙂

2有些人会说“非常没有帮助”,实际上我倾向于同意。

3基本上, git fetch ,以及remotes和refspecs的整个概念,在Git 1.5的时代发生了一些Git的延迟。 在此之前,只有一些特殊的特殊情况,取标签就是其中之一,所以它通过特殊的代码得到了盛行。

4如果有帮助的话,可以把远程的Git看作是一个闪光器 ,用俚语来表示。