当我签出远程git tag时使用这样的命令:
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。
答案 0 :(得分:776)
标记用于标记和标记历史记录中的特定提交 它通常用于标记释放点(例如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/
前缀。
在此示例中,您有2个标签版本1.0&amp;版本1.1您可以使用以下任何一项结帐:
git checkout A ...
git checkout version 1.0 ...
git checkout tags/version 1.0 ...
以上所有内容都是相同的,因为tag只是指向给定提交的指针。
来源: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-*'
有两种方法可以创建标记:
# normal tag
git tag
# annotated tag
git tag -a
2之间的区别在于,在创建带注释标签的时候,你可以像在git commit中一样添加元数据:
姓名,电子邮件,日期,评论&amp;签名
# 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支持浅克隆通过将--branch
添加到克隆命令,我们可以使用标记名称而不是分支名称。 Git知道如何翻译&#34;给定的SHA-1到相关的提交
# Clone a specific tag name
git clone <url. --branch=<tag_name>
git clone --branch =
--branch
也可以在生成的存储库中获取标记并分离该提交的HEAD。
答案 1 :(得分:168)
(这个答案花了一些时间来写,而codeWizard's answer在目标和本质上是正确的,但并不完全完整,所以无论如何我都会发布这个。)
没有&#34;远程Git标签&#34;。只有&#34;标签&#34;。我指出这一切不是迂腐, 1 但是因为对于休闲的Git用户存在很多混淆,而且Git文档不是很有用 2 对于初学者。 (目前尚不清楚是否由于文档较差而引起的混淆,或者文档较差,因为这本身就有点令人困惑,或者是什么。)
&#34;远程分支&#34;,更恰当地称为&#34;远程跟踪分支&#34;,但值得注意的是,这些实际上是本地的实体。但是,没有远程标签(除非您(重新)发明它们)。只有本地标签,因此您需要在本地获取标签才能使用它。
特定提交的名称的一般形式--Git称之为引用 - 是以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
)。但一般来说,引用以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-the&#34;遥控器&#34; - 和它进行对话。在此对话的早期,远程列出了所有引用: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前面的加号+
设置&#34; force&#34;标记,即您的远程跟踪分支将更新以匹配远程的分支名称,无论使其匹配所需的内容。 (如果没有+
,分支更新仅限于&#34;快进&#34;更改,并且自Git版本1.8.2左右之后,标签更新将被忽略,然后应用相同的快进规则。 )
但是标签怎么样?对它们没有任何反对意见 - 至少,不是默认情况下。您可以设置一个,在这种情况下,refspec的形式由您决定;或者你可以运行git fetch --tags
。使用--tags
会将refs/tags/*:refs/tags/*
添加到refspec中,即它会带来所有标记(但如果您已经有标记,则不会更新您的标记使用该名称,无论遥控器的标签是什么 编辑,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上的+
强制标志意味着&#34;将我的引用值替换为我的Git从Git获得的值&#34;。
由于历史原因, 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无论有没有--tags
,都会将 T 添加到您的代码中。添加--tags
会导致您的Git获取所有标记,并强制更新。
您可能必须使用git fetch --tags
来获取其代码。如果他们的标记名称与您现有的标记名称冲突,那么可能(取决于Git版本)甚至必须删除(或重命名)某些标记,然后运行git fetch --tags
,以获取他们的标签。由于标签(与远程分支不同)没有自动重命名,因此标签名称必须与其标签名称相匹配,这就是您可能遇到冲突问题的原因。
在大多数正常情况下,一个简单的git fetch
将完成这项工作,带来他们的提交及其匹配的标签,因为他们 - 无论他们是谁 - 将标记提交他们发布这些提交的时间,你会跟上他们的标签。如果你没有制作自己的标签,也没有混合他们的存储库和其他存储库(通过多个遥控器),你也不会有任何标签名称冲突,所以你不必大惊小怪地删除或重命名标签以获取其标签。
我上面提到过,您几乎可以省略refs/
,而refs/heads/
和refs/tags/
等等大部分时间都可以省略xyzzy
。但是当不能你的时候?
完整(或接近完成)答案在the gitrevisions
documentation。 Git将使用链接中给出的六步序列将名称解析为提交ID。奇怪的是,标签会覆盖分支:如果有标记xyzzy
和分支git rev-parse xyzzy
,并且它们指向不同的提交,那么:
gitrevisions
将为您提供标记所指向的ID。但是 - 这是git checkout
- git checkout xyzzy
中缺少的分支名称,因此refs/heads/xyzzy
会将您放在分支上,而忽略标记。
如果含糊不清,您几乎可以使用其全名refs/tags/xyzzy
或git checkout
拼出引用名称。 (请注意,此 可以与git checkout refs/heads/xyzzy
一起使用,但是可能会以一种意想不到的方式:git checkout
导致分离的HEAD结帐而不是分支结帐。这就是为什么你只有请注意xyzzy
将首先使用短名称作为分支名称:即使标记xyzzy
存在,您也可以查看分支refs/tags/xyzzy
。如果您愿意检查标记,您可以使用gitrevisions
。)
因为(作为refs/name
注释)Git会尝试tags/xyzzy
,您也可以简单地编写xyzzy
来识别标记为xyzzy
的提交。 (如果有人设法将一个名为$GIT_DIR
的有效引用写入$GIT_DIR/xyzzy
,则会将其解析为*HEAD
。但通常只有$GIT_DIR
个名称应该在{ {1}}。)
1 好的,好的,&#34; 只是才是迂腐的#34;。 : - )
2 有人会说&#34;非常有帮助&#34;,我倾向于同意,实际上。
3 基本上,git fetch
,以及遥控器和refspecs的整个概念,对于Git来说是一个迟到的补充,发生在Git 1.5的时候。在此之前,只有一些临时的特殊情况,而标记抓取就是其中之一,所以它通过特殊代码得到了很好的效果。
4 如果有帮助,可以将远程Git视为flasher,用俚语表示。
答案 2 :(得分:5)
为了签出git标签,您将执行以下命令
git checkout tags/tag-name -b branch-name
例如,如下所述。
git checkout tags/v1.0 -b v1.0-branch
要获取所有标签,请使用命令
git fetch --all --tags
答案 3 :(得分:0)
要获取特定的标记代码,请尝试创建一个新分支,然后在其中添加标记代码。
我已经通过命令完成了操作:$git checkout -b newBranchName tagName
答案 4 :(得分:0)
这有点脱离上下文,但如果你在这里是因为你想像我一样标记一个特定的提交
这是执行此操作的命令:-
示例:
match_words = match.split(" ")
match = " ".join(match_words[:-1]) + "\n" + match_words[-1]
其中 git tag -a v1.0 7cceb02 -m "Your message here"
是提交 ID 的开始部分。
然后您可以使用 7cceb02
推送标签。
您可以执行 git push origin v1.0
以显示当前分支中的所有提交 ID。