什么是git标签,如何创建标签&如何结帐git remote tag(s)

时间:2016-03-14 04:38:51

标签: git git-checkout git-tag

当我签出远程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。

5 个答案:

答案 0 :(得分:776)

让我们首先解释一下git中的标签是什么

enter image description here

  

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

     

虽然标签可能与分支类似,但标签不会改变   它将直接指向历史记录中的特定提交

enter image description here

如果标签不在您的存储库本地,那么您将无法签出标签,因此首先,您必须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只是指向给定提交的指针。

enter image description here
来源: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;签名

enter image description here

如何删除标签?

# 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/开头: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-remotegit remote show查看这些内容,但fetchpush是更有趣的联系点。

Refspecs

fetchpush期间,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/xyzzygit 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。

相关问题