如何签出远程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/
开始: HEAD
, ORIG_HEAD
, MERGE_HEAD
和CHERRY_PICK_HEAD
尤其都是可以引用特定提交的名称(虽然HEAD
通常包含分支名称,即包含ref: refs/heads/ branch
)。 但一般来说,引用以refs/
开头。
Git所做的一件事情就是让它混淆,就是允许你忽略refs/
,经常是refs/
之后的单词。 例如,在引用本地分支或标签时,您可以省略refs/heads/
或refs/tags/
,实际上在签出本地分支时,您必须省略refs/heads/
! 只要结果是明确的,或者正如我们刚刚提到的那样,您可以做到这一点,当您必须执行此操作时(对于git checkout branch
)。
确实,引用不仅存在于您自己的存储库中,而且存在于远程存储库中。 但是,Git只允许您在非常特定的时间访问远程存储库的引用:即在fetch
和push
操作期间。 你也可以使用git ls-remote
或者git remote show
来查看它们,但是fetch
和push
是更有趣的联系点。
Refspecs
在fetch
和push
期间,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的gitrevisions
– git checkout
更喜欢分支名称,所以git checkout xyzzy
会把你放在分支上,不pipe标签。
如果含糊不清,几乎总是可以使用其全名拼写ref名称, refs/heads/xyzzy
或refs/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看作是一个闪光器 ,用俚语来表示。