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

Rya*_*nqy 468 git git-checkout git-tag

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

git checkout -b local_branch_name origin/remote_tag_name
Run Code Online (Sandbox Code Playgroud)

我得到这样的错误:

error: pathspec `origin/remote_tag_name` did not match any file(s) known to git.
Run Code Online (Sandbox Code Playgroud)

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

Cod*_*ard 992

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

在此输入图像描述

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

虽然标签可能看起来与分支类似,但标签不会改变.
直接指向历史中的特定提交.

在此输入图像描述


如果标签不在您的存储库中本地,您将无法签出标签,因此首先,您必须fetch将标签添加到本地存储库.

首先,确保标签存在于本地

# --all will fetch all the remotes.
# --tags will fetch all tags as well
git fetch --all --tags --prune
Run Code Online (Sandbox Code Playgroud)

然后通过运行检查标签

git checkout tags/<tag_name> -b <branch_name>
Run Code Online (Sandbox Code Playgroud)

而不是origin使用tags/前缀.


在此示例中,您有2个标签版本1.0和版本1.1,您可以使用以下任何一个签出它们:

git checkout A  ...
git checkout version 1.0  ...
git checkout tags/version 1.0  ...
Run Code Online (Sandbox Code Playgroud)

以上所有内容都是相同的,因为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-*'
Run Code Online (Sandbox Code Playgroud)

如何创建标签?

有两种方法可以创建标记:

# lightweight tag 
git tag 

# annotated tag
git tag -a
Run Code Online (Sandbox Code Playgroud)

2之间的区别在于,在创建带注释的标签时,您可以像在Git提交中一样添加元数据:
名称,电子邮件,日期,注释和签名

在此输入图像描述

如何删除标签?

# delete any given tag
git tag -d <tag name>

# Don't forget to remove the deleted tag form the server with push tags
Run Code Online (Sandbox Code Playgroud)

如何克隆特定标签?

为了获取给定标记的内容,您可以使用该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>
Run Code Online (Sandbox Code Playgroud)

选项2:

使用clone命令

由于git 通过添加到clone命令支持浅克隆,--branch我们可以使用标记名称而不是分支名称.Git知道如何将给定的SHA-1"翻译"到相关的提交

# Clone a specific tag name using git clone 
 git clone <url> --branch=<tag_name>
Run Code Online (Sandbox Code Playgroud)

git clone --branch =

--branch 也可以在结果存储库中的提交处获取标记并分离HEAD.

  • 不错.`git checkout A`.什么是'A`?你是怎么创造'A`的? (3认同)
  • @Honey`A`是一个提交哈希 (3认同)
  • @CodeWizard好流程图!你用它来制作它的软件? (2认同)
  • @GiovanniLovato流程图是第三方流程图.图像的链接是https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png,该页面来自此页面https://backlog.com/git-tutorial/stepup/stepup4_1.html of该网站名为Git Beginner's Dummies指南(backlog.com). (2认同)
  • 值得注意的是,`git checkout tags/<tag_name> -b <branch_name>`确实需要`-b <branch_name>`.`git checkout tags/<tag_name>`给了我一个超然的头.根据[关于分离头的文章](https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit),您可以通过临时创建和删除a来避免分离头科.这是一个非常外来的工作流程.很明显,我作为一个git用户需要习惯于创建和删除分支以获得乐趣和利润. (2认同)

tor*_*rek 186

(这个答案花了一些时间来编写,codeWizard的答案在目标和本质上是正确的,但并不完全完整,所以无论如何我都会发布这个.)


没有"远程Git标签"这样的东西.只有"标签".我点出这一切并非是迂腐,1但因为混乱的这个搭配休闲的Git用户带来了极大的交易,Git的文件是不是非常有帮助2至初学者.(目前尚不清楚是否由于文档较差或文档较差而导致混淆,因为这本质上有点令人困惑,或者是什么.)

这里 "远程分支",更恰当地称为"远程跟踪分支",但值得注意的是,这些其实都是当地实体.但是,没有远程标签(除非您(重新)发明它们).只有本地标签,因此您需要在本地获取标签才能使用它.

特定提交的名称的一般形式--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/branchrefs/

Git做的一件令人困惑的事情是,它允许你省略refs/,通常是后面的单词refs/.例如,您可以省略refs/heads/refs/tags/在引用本地分支或标记时 - 事实上,在签出本地分支时必须省略refs/heads/!只要结果明确无误,或者我们刚才注意到 - 当你必须这样做时(for ),你就可以这样做.git checkout branch

确实,引用不仅存在于您自己的存储库中,还存在于远程存储库中.但是,Git只允许您在非常特定的时间访问远程存储库的引用:即,在操作期间fetchpush操作期间.您还可以使用git ls-remotegit remote show看到他们,但fetchpush有接触的更有趣点.

Refspecs

fetch和中push,Git使用字符串,它调用refspecs来传输本地和远程存储库之间的引用.因此,在这些时候,通过refspecs,两个Git存储库可以相互同步.一旦您的名称同步,您可以使用与远程用户相同的名称.fetch但是,这里有一些特殊的魔法,它会影响分支名称和标记名称.

您应该考虑git fetch指导您的Git调用(或者可能是文本消息)另一个Git - "远程" - 并与之进行对话.在这个对话的早期,远程列出了它的所有引用:所有内容refs/heads/和所有内容refs/tags/,以及它具有的任何其他引用.你的Git扫描这些并(基于通常的fetch refspec)重命名它们的分支.

让我们来看看名为的远程的正常refspec origin:

$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$ 
Run Code Online (Sandbox Code Playgroud)

此refspec指示您的Git将每个名称匹配refs/heads/*-ie,远程上的每个分支 - 并将其名称更改为refs/remotes/origin/*,即保持匹配的部分相同,将分支名称(refs/heads/)更改为远程跟踪分支名称(refs/remotes/具体而言) ,refs/remotes/origin/).

正是通过这样的Refspecorigin的分支成为远程远程跟踪分支origin.分支名称变为远程跟踪分支名称,包括远程名称(在本例中origin).+refspec前面的加号设置"force"标志,即远程跟踪分支将更新以匹配远程的分支名称,无论使其匹配需要什么.(如果没有+,分支更新仅限于"快进"更改,并且自Git版本1.8.2左右之后,标签更新将被忽略,然后应用相同的快进规则.)

标签

但标签怎么样?它们没有refspec - 至少,默认情况下不是.您可以设置一个,在这种情况下,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上的force标志意味着"用我的Git从他们的Git获取的值替换我的引用值".

获取期间的自动标记

由于历史的原因,3,如果您既不用--tags选项也没有--no-tags选择,git fetch采取专项行动.请记住,我们上面说过,远程启动时会向您的本地Git显示其所有引用,无论您的本地Git是否想要查看它们.4 你的Git会记录它此时看到的所有标签. 然后,当它开始下载任何提交对象时,它需要处理它所提取的任何内容,如果其中一个提交具有与任何这些标记相同的ID,git将添加该标记 - 或者那些标记,如果多个标记具有该ID-to你的存储库.

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

底线

您可能必须使用它git fetch --tags来获取标签.如果他们的标签名称与您现有的标签名称冲突,您可能(取决于Git版本)甚至必须删除(或重命名)您的某些标签,然后运行git fetch --tags,以获取其标签.由于标签(与远程分支不同)没有自动重命名,因此标签名称必须与其标签名称匹配,这就是您可能遇到冲突问题的原因.

但是,在大多数正常情况下,一个简单git fetch的工作人员会完成工作,提交他们的提交和匹配的标签,因为他们 - 无论他们是谁 - 将在他们发布这些提交时标记提交,你将跟上他们的标签.如果你没有制作自己的标签,也没有混合他们的存储库和其他存储库(通过多个遥控器),你也不会有任何标签名称冲突,所以你不必为删除或重命名标签而烦恼获得他们的标签.

当您需要合格的名字时

我上面提到的,你可以省略refs/几乎总是和refs/heads/refs/tags/等大部分的时间.但是什么时候不能

完整(或接近完整反正)答案是gitrevisions文件.Git将使用链接中给出的六步序列将名称解析为提交ID.奇怪的是,标签覆盖分支:如果有标签xyzzy和分支xyzzy,并且它们指向不同的提交,则:

git rev-parse xyzzy
Run Code Online (Sandbox Code Playgroud)

将为您提供标签指向的ID.然而 - 这就是缺少的gitrevisions- git checkout更喜欢分支名称,因此git checkout xyzzy会将您放在分支上,忽略标记.

如果含糊不清,您几乎可以使用其全名来拼写引用名称,refs/heads/xyzzy或者refs/tags/xyzzy.(请注意,这确实有效git checkout,但可能以一种意想不到的方式:git checkout refs/heads/xyzzy导致分离-HEAD结帐而不是分支结账.这就是为什么你必须注意首先git checkout使用短名称作为分支名称:这就是你的方式xyzzy即使标签xyzzy存在,也要检查分支.如果要查看标签,可以使用refs/tags/xyzzy.)

因为(作为gitrevisions笔记)Git会尝试,你也可以简单地写一下来识别标记的提交.(如果有人已经成功地编写了一个名为一个有效的参考到,但是,这将解决的,但通常只不同的名称应该是.)refs/nametags/xyzzyxyzzyxyzzy$GIT_DIR$GIT_DIR/xyzzy*HEAD$GIT_DIR


1好吧,好吧," 不仅仅是为了迂腐".:-)

2有些人会说"非常有帮助",实际上我倾向于同意.

3基本上,git fetch以及遥控器和refspecs的整个概念,对Git来说是一个迟到的补充,发生在Git 1.5的时候.在此之前,只有一些特殊的特殊情况,而标记抓取就是其中之一,因此它通过特殊代码得到了认可.

4如果它有所帮助,可以将远程Git视为傻瓜的意思.


man*_*ani 15

为了签出一个 git 标签,你需要执行以下命令

git checkout tags/tag-name -b branch-name
Run Code Online (Sandbox Code Playgroud)

例如如下所述。

 git checkout tags/v1.0 -b v1.0-branch
Run Code Online (Sandbox Code Playgroud)

要获取所有标签,请使用命令

git fetch --all --tags
Run Code Online (Sandbox Code Playgroud)


moo*_*oom 5

当我想要标签处的代码时,我可能不想创建分支(通常,如果我要对其进行热修复,我只需要一个完整的分支)。

要暂时将分支退回到标记处的代码,请执行以下操作:

git reset --hard tags/1.2.3
Run Code Online (Sandbox Code Playgroud)

我可以根据需要简单地使用它,然后在完成后返回到分支的 HEAD,使用一个简单的git pull.