checkout标签在git中意味着什么

时间:2014-04-14 03:20:14

标签: git version-control

我的Senoir编码器希望我每周在开发服务器上签出发布标签

我之前没有得到,所以我所做的只是

  1. git pull
  2. 查找该标记的提交哈希
  3. git reset --hard hashcode
  4. 所以我总是在主分支上

    现在他做到了,当我检查时,他不在任何一个分支上。

    当我问他为什么代码在no branch时,他告诉我那应该是什么。

    我不明白。任何人都可以解释他做了什么,他想要什么以及我做错了什么

3 个答案:

答案 0 :(得分:2)

<强>背景

标签只是与提交相对应的标签。

分支类似于标记,但随着工作的进展,它会从提交转移到提交。通常,分支被称为它指向的提交,并且所有祖先都会提交。

多个分支在其历史记录中可以具有相同的提交。 (例如masterbranch-a都提交了哈希abcdef123456。)


<强>答案

假设提交哈希位于master分支上,并且您没有任何未推送的更改,那么您和您的朋友所做的事情之间并没有太大的区别,除了方式更容易。

区别:

  • 你在提交,但是git也知道你正在分支master上工作(所以如果你做了提交,那么它将在分支master上)。此外,如果自标记后master发生了更改,则--hard会从master中删除这些更改。如果你没有推动它们,你就有可能永远失去它们。
  • 他在同一个提交,但没有特定的分支(没有提交可能)。此外,checkout不会更改历史记录。

因此,检查标签更容易,更清洁,更不容易出错(丢失任何当前工作,意外提交等),但为了您的目的,基本上是相同的。

答案 1 :(得分:1)

要正确理解这一点,请从这开始:那些哈希码(SHA-1值,如5f95c9f...)是&#34;真实的名称&#34;提交。所有其他名称 - 分支和标签 - 只是别名,但当然更容易记住和关联。让我们称这些用户友好名称为#34;。例如,标记v1.9.0告诉您这是git版本1.9.0的提交,而5f95c9f850b19b368c43ae399cc831b17a26a5ac 1 并不意味着什么明显。分店还有一个特殊的财产。

每个提交也记录其先前(父)提交的(原始)SHA-1。 2 这意味着我们可以将提交绘制为链,最新的提交在右边,每个提交一个指向左边的父母:

A <- B <- C

(这里的每个字母代表一些SHA-1。)分支标签&#34;指向&#34;通过包含提交的原始SHA-1,在该分支上提交最多提交。例如,如果分支标签dev包含提交C的SHA-1,则分支dev 提交C。同时C让git找到BB让git找到A,这样A <- B <- C也是&#34;分支&#34; -this令人困惑,确定:git调用整个序列&#34;分支&#34;并且最尖端提交&#34;分支&#34;。 (但是,从上下文中通常可以清楚地知道&#34;分支foo&#34;是指&#34;最尖端的提交&#34;或者#34;通过启动形成的分支在最顶端提交并向后工作。)

此外,git reset 您要在此处使用的命令;我们马上就会谈到这一点。

现在,如果你创建一个标签名称,那么git将帮助你强制执行的约定是标签名称指向一个特定的提交, 3 并且永远不会移动。换句话说,给定标签名称的提交SHA-1始终是&#34;真实名称&#34;一个特定的提交。

但是,如果创建分支名称,则约定是分支名称​​ 移动。像master这样的分支名称会解析为该分支的当前提示,因此master可能会解析为5f95c9f...。每当您向分支添加新提交时(通过运行git commitgit merge,通常,虽然还有一些情况也会添加新的提交),但分支名称会更新为指向新的提交你刚刚添加。也就是说,它现在解析为 new 分支提示。你做了一个git commit,所以你得到了一个新的提交,所以分支标签是&#34;移动&#34;到新的提交。

这是git reset的用武之地。reset命令就是你如何制作一个非标准的&#34;移动。特别是,它允许您移动分支名称&#34;向后&#34;。

假设您有这一系列提交:

... <- E <- F <- G <- H   <-- master

其中,提交H是分支master的当前提示。提交H时,提交G一直是master的提示,即master已解决为9c8ce73...之类的问题。但随后git commit创建了5f95c9f...,因此master现在已解决此问题。

如果出于某种原因,您想要从分支H 删除提交master,您可以使用git reset来移动标签向后&#34;,即将其指向提交G而不是:

git reset --hard 9c8ce73

这使得分支标签master解析为提交G。提交H已被有效删除(它还没有真正删除 - git会保留所有内容,以便您可以&#34;不会删除&#34;它们会暂时 - 但它会看起来就像它已经消失了),如果你现在进行新的提交,你会得到一个新的,不同的提交,使用一个新的,不同的SHA-1。那肯定不是你想要的。


如果您已有一些标记名称,则可以执行git checkout tagname。这告诉git得到&#34; off&#34;当前分支,导致git调用&#34;分离的HEAD&#34;。当你处于这种状态时,如果你进行了新的提交,git会像往常一样添加它们,但是没有&#34;用户友好的名字&#34;对于这些:你不是&#34;在分支&#34;,所以git不会分支移动到新的提示。它不能:没有分支可以移动。但是如果你没有做出新的提交,那么无论如何这并不重要。你可以回到&#34; on&#34; git checkout branchname的分支。

所以:

  • git checkout tagname带你离开分支,进入&#34;分离的HEAD&#34;州。在这里,您可以查看树,因为它是 tagname 是别名的原始SHA-1。 (如果您只想查看SHA-1,请使用git rev-parse tagname。)
  • git checkout branchname将您带到指定的分支,检查分支提示。 (如果您只想查看分支提示的SHA-1,请使用git rev-parse branchname。)
  • git checkout SHA-1的工作原理与git checkout tagname完全相同。事实上, git checkout tagname的工作原理是:它将标记名称解析为原始SHA-1,并检出该提交。那个也是 git checkout branchname如何工作,除了git认识到 branchname 是一个分支名称,所以它会让你&# 34;在分支上&#34;因此,未来git commit将为您移动分支提示。

可是:

  • git reset --hard commit接受您所依赖的任何分支,并使分支名称指向您提供的提交。换句话说,它会剥离&#34;来自当前branch-tip-commit的分支标签和&#34;粘贴在&#34;你给git的SHA-1。如果你给git另一个标签或分支名称,它只是将名称解析为正确的原始SHA-1,然后使其成为当前分支的新分支。 (当然,它还会检查出与该提交一致的树。)

1 实际上,标记v1.9.0指向带注释的标记对象,但这又指向我上面引用的提交。但原则是一样的。

2 或者,在合并提交的情况下,它会记录所有其父提交ID。但是,对于本次讨论的其余部分而言,这些都不重要。

3 或者,就像在git本身中一样,带注释的标签,反过来又指向提交。当然,该提交指向其父提交,指向其父级,依此类推;所以标签是&#34;同样好的&#34;从某种意义上说,作为一个分支。

答案 2 :(得分:0)

听起来您的高级开发人员希望您这样做:

git checkout <tag>

当您这样做时,您会看到no branch,因为您正在检查标记引用,而不是分支引用。

您之前所做的可能是 您的资深开发人员希望您做的事情。 git reset用于将您当前的分支引用移至其他提交,当您使用--hard时, 实际上会导致您丢失工作

当您使用no branch时,您没有看到git reset --hard的原因是因为重置会使您的结帐移动分支。与git checkout <tag>形成鲜明对比,{{1}}与您的结帐不会移动分支,而是签出代码。