我的Senoir编码器希望我每周在开发服务器上签出发布标签
我之前没有得到,所以我所做的只是
git pull
所以我总是在主分支上
现在他做到了,当我检查时,他不在任何一个分支上。
当我问他为什么代码在no branch
时,他告诉我那应该是什么。
我不明白。任何人都可以解释他做了什么,他想要什么以及我做错了什么
答案 0 :(得分:2)
<强>背景强>
标签只是与提交相对应的标签。
分支类似于标记,但随着工作的进展,它会从提交转移到提交。通常,分支被称为它指向的提交,并且所有祖先都会提交。
多个分支在其历史记录中可以具有相同的提交。 (例如master
和branch-a
都提交了哈希abcdef123456
。)
<强>答案强>
假设提交哈希位于master
分支上,并且您没有任何未推送的更改,那么您和您的朋友所做的事情之间并没有太大的区别,除了方式更容易。
区别:
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找到B
,B
让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 commit
或git 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}}与您的结帐不会移动分支,而是签出代码。