当我签出远程git标签使用命令像这样:

git checkout -b local_branch_name origin/remote_tag_name

我得到了这样的错误:

错误:pathspec origin/remote_tag_name不匹配git已知的任何文件。

当我使用git tag命令时,可以找到remote_tag_name。


当前回答

当我想要标记上的代码时,我可能不想创建一个分支(通常,如果我要热修复它,我只需要一个完整的分支)。

要临时倒回你的分支到标记处的代码,可以这样做:

git reset --hard tags/1.2.3

我可以根据需要简单地使用它,然后当我完成时回到分支的HEAD,使用简单的git拉。

其他回答

让我们从解释git中的标签开始

标记用于标记历史记录中的特定提交。 它通常用来标记释放点(例如。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>

使用标签/前缀代替origin。


在这个例子中,你有2个标签版本1.0和版本1.1,你可以检查他们与任何以下:

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

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

来源: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-*'

如何创建标签?

有两种方法来创建一个标签:

# lightweight tag 
$ git tag 

# annotated tag
$ git tag -a

两者的区别在于,当创建一个带注释的标签时,你可以添加元数据,就像在git提交中一样: 姓名,电子邮件,日期,评论和签名

如何删除标签?

删除本地标签

$ git tag -d <tag_name>
Deleted tag <tag_name> (was 000000)

注意:如果你试图删除一个不存在的Git标签,将会看到以下错误:

$ git tag -d <tag_name>
error: tag '<tag_name>' not found.

删除远程标签

# Delete a tag from the server with push tags
$ git push --delete origin <tag name>

如何克隆一个特定的标签?

为了获取给定标记的内容,可以使用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:

使用clone命令

因为git通过在clone命令中添加——branch来支持浅克隆,所以我们可以使用标记名而不是分支名。Git知道如何将给定的SHA-1“转换”到相关的提交

# Clone a specific tag name using git clone 
$ git clone <url> --branch=<tag_name>

Git克隆——branch= ——branch也可以在最终的存储库中使用标记并分离提交时的HEAD。


如何推送标签?

Git push—标签

推送所有标签:

# Push all tags
$ git push --tags 

使用refs/标签,而不是仅仅指定<tagname>。

Why?

建议使用refs/tags,因为有时候标签可能与你的分支有相同的名称,简单的git push将会推送分支而不是标签

要推送带注释的标签和当前历史链标签,请使用:

Git push—follow-tags

这个标志——follow-tags同时推送提交和同时推送的标签:

注释标记(因此您可以跳过本地/临时构建标记) 来自当前分支(位于历史记录上)的可达标记(祖先)

在Git 2.4中,您可以使用配置来设置它

$ git config --global push.followTags true

Cheatsheet:


(这个答案花了一些时间来写,codeWizard的答案在目的和本质上是正确的,但不完全完整,所以我还是把它贴出来。)


没有所谓的“远程Git标记”。只有“标签”。我指出这一切并不是为了卖弄学问,1而是因为普通Git用户对此有很多困惑,而Git文档对初学者并不是很有帮助2。(目前还不清楚这种混乱是由于糟糕的文档造成的,还是因为文档本身就有些混乱,或者其他什么原因。)

存在“远程分支”,更恰当的说法是“远程跟踪分支”,但值得注意的是,这些实际上是本地实体。但是没有远程标记(除非您(重新)发明它们)。只有本地标记,因此需要在本地获取标记才能使用它。

特定提交(Git称之为引用)的名称的一般形式是任何以refs/开头的字符串。以refs/heads/ names开头的字符串;以refs/remotes/开头的字符串命名一个远程跟踪分支;以refs/tags/开头的字符串命名一个标签。名称refs/stash是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分支)。

的确,引用不仅存在于您自己的存储库中,还存在于远程存储库中。但是,Git只允许您在非常特定的时间访问远程存储库的引用:即在获取和推送操作期间。你也可以使用git ls-remote或git remote show来查看它们,但是fetch和push是更有趣的接触点。

参考规格

在获取和推送期间,Git使用它称为refspecs的字符串在本地和远程存储库之间传输引用。因此,正是在这些时候,通过refspecs,两个Git存储库可以相互同步。一旦你的名字是同步的,你可以使用相同的名字与远程使用的人。不过,这里的取回有一些特殊的魔力,它同时影响分支名称和标记名称。

您应该将git取回看作是指示您的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/)。

It is through this refspec that origin's branches become your remote-tracking branches for remote origin. Branch name becomes remote-tracking branch name, with the name of the remote, in this case origin, included. The plus sign + at the front of the refspec sets the "force" flag, i.e., your remote-tracking branch will be updated to match the remote's branch name, regardless of what it takes to make it match. (Without the +, branch updates are limited to "fast forward" changes, and tag updates are simply ignored since Git version 1.8.2 or so—before then the same fast-forward rules applied.)

Tags

But what about tags? There's no refspec for them—at least, not by default. You can set one, in which case the form of the refspec is up to you; or you can run git fetch --tags. Using --tags has the effect of adding refs/tags/*:refs/tags/* to the refspec, i.e., it brings over all tags (but does not update your tag if you already have a tag with that name, regardless of what the remote's tag says Edit, Jan 2017: as of Git 2.10, testing shows that --tags forcibly updates your tags from the remote's tags, as if the refspec read +refs/tags/*:refs/tags/*; this may be a difference in behavior from an earlier version of Git).

注意,这里没有重命名:如果远程origin有标签xyzzy,而你没有,并且你git获取origin "refs/tags/*:refs/tags/*",你会得到refs/tags/xyzzy添加到你的存储库中(指向与远程相同的提交)。如果你使用+refs/tags/*:refs/tags/*,那么你的标签xyzzy,如果你有一个,被替换为一个从原点。也就是说,refspec上的+ force标志意味着“将我的引用值替换为我的Git从他们的Git中获得的值”。

在获取期间自动标记

For historical reasons,3 if you use neither the --tags option nor the --no-tags option, git fetch takes special action. Remember that we said above that the remote starts by displaying to your local Git all of its references, whether your local Git wants to see them or not.4 Your Git takes note of all the tags it sees at this point. Then, as it begins downloading any commit objects it needs to handle whatever it's fetching, if one of those commits has the same ID as any of those tags, git will add that tag—or those tags, if multiple tags have that ID—to your repository.

编辑,2017年1月:测试显示,Git 2.10中的行为现在是这样的:如果他们的Git提供了一个名为T的标记,而你没有一个名为T的标记,并且与T关联的提交ID是你的Git取回正在检查的一个分支的祖先,你的Git将T添加到你的标记中,无论是否有——标记。添加——tags会导致Git获取它们所有的标签,并强制更新。

底线

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

不过,在大多数正常情况下,简单的git获取就可以完成这项工作,带来它们的提交和匹配的标记,因为它们(无论它们是谁)将在发布这些提交时标记提交,所以您将跟上它们的标记。如果您不创建自己的标记,也不混合它们的存储库和其他存储库(通过多个远程),您也不会有任何标记名称冲突,因此您不必为了获取它们的标记而删除或重命名标记。

当您需要限定名称时

我上面提到过,你几乎总是可以省略refs/,大多数时候也可以省略refs/heads/和refs/tags/等等。但你什么时候不能呢?

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

git rev-parse xyzzy

将为您提供标记所指向的ID。然而——这是gitrevision中所缺少的——git checkout更喜欢分支名称,因此git checkout xyzzy将把您放在分支上,忽略标签。

In case of ambiguity, you can almost always spell out the ref name using its full name, refs/heads/xyzzy or refs/tags/xyzzy. (Note that this does work with git checkout, but in a perhaps unexpected manner: git checkout refs/heads/xyzzy causes a detached-HEAD checkout rather than a branch checkout. This is why you just have to note that git checkout will use the short name as a branch name first: that's how you check out the branch xyzzy even if the tag xyzzy exists. If you want to check out the tag, you can use refs/tags/xyzzy.)

因为(正如gitrevisions指出的那样)Git会尝试refs/name,你也可以简单地写标签/xyzzy来识别带有xyzzy标签的提交。(但是,如果有人设法将名为xyzzy的有效引用写入到$GIT_DIR中,则这将解析为$GIT_DIR/xyzzy。但是通常只有不同的*HEAD名称应该在$GIT_DIR中。)


好吧,好吧,“not just to be pedantic”。: -)

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

基本上,git取回,以及遥控器和refspecs的整个概念,都是git的晚期添加,大约发生在git 1.5的时候。在此之前,只有一些特别的情况,标记抓取是其中之一,所以它通过特殊代码得到了扩展。

4如果有帮助的话,可以把远程Git想象成一个flasher(俚语)。

这有点断章取义,但如果你在这里,因为你想标记一个特定的提交,就像我做的

这里有一个这样做的命令:-

例子:

git tag -a v1.0 7cceb02 -m "Your message here"

其中7cceb02是提交id的开始部分。

然后,您可以使用git push origin v1.0推送标记。

你可以使用git log来显示当前分支中所有的提交id。

要获得特定的标记代码,请尝试创建一个新分支,并在其中添加标记代码。 我已经通过命令完成了:$git checkout -b newBranchName tagName

当我想要标记上的代码时,我可能不想创建一个分支(通常,如果我要热修复它,我只需要一个完整的分支)。

要临时倒回你的分支到标记处的代码,可以这样做:

git reset --hard tags/1.2.3

我可以根据需要简单地使用它,然后当我完成时回到分支的HEAD,使用简单的git拉。