Git称之为分离的头部最终会发生什么
我想通过SmartGit恢复到以前的提交。通过SmartGit,我选择了一个较早的提交并进行了签出。系统提示我输入分支名称。我选择不创建分支,因为当我只想在现有分支上“向后移动”时,创建分支似乎是不必要的,甚至是愚蠢的。这导致头部脱落。这似乎是一个坏主意,继续发展一个独立的头部,所以我没有继续 我切换到命令行,并做了一个Git称之为分离的头部最终会发生什么,git,smartgit,Git,Smartgit,我想通过SmartGit恢复到以前的提交。通过SmartGit,我选择了一个较早的提交并进行了签出。系统提示我输入分支名称。我选择不创建分支,因为当我只想在现有分支上“向后移动”时,创建分支似乎是不必要的,甚至是愚蠢的。这导致头部脱落。这似乎是一个坏主意,继续发展一个独立的头部,所以我没有继续 我切换到命令行,并做了一个git日志,以识别我感兴趣的早期提交的哈希代码。我做了一个git重置——硬0dfc994b23ea 现在,git log似乎是来自更早的时间,这就是我想要的。同样,SmartGi
git日志
,以识别我感兴趣的早期提交的哈希代码。我做了一个git重置——硬0dfc994b23ea
现在,
git log
似乎是来自更早的时间,这就是我想要的。同样,SmartGit看起来也不错。无论是git日志还是SmartGit日志(至少表面上看),都没有任何迹象表明我犯了错误(头部脱落)。分离的头部会发生什么情况?让我简单解释一下。分离头意味着您的工作树“指向”您要求git签出的修订版,从这里您可以“像往常一样”工作。你可以提交东西,合并东西,随便什么。唯一的问题是git不会移动任何“分支”(也称为修订指针),因为您没有签出“分支”,而是签出了修订(如果您要求使用--detach签出分支,也可以实现同样的效果)。如果你想快速完成某件事,但又不想有一个真正的指针指向它,分离头是非常有用的(比如……做一个快速测试,然后返回到你以前工作的地方。创建一个分支只是为了及时返回,然后返回到你以前工作的地方,然后“临时”删除你创建的分支有什么意义只是为了能够结帐?)。长话短说:你可以从“超脱的头”的位置搬到你喜欢的任何地方,这不会有什么不同
作为旁白。。。当您提供一个范围的修订时,git重置-难做什么?因为我只使用它提供了一个单一修订版。刚刚检查了git help reset,我没有看到它。这不是一个真正的错误,这里的一切仍然正常。你的头还在分离,只是在另一个地方分离了
不过,通常更明智的做法是使用git checkout
切换到所需的提交。要了解原因,请继续阅读
长描述
理解这一点的关键是多部分。首先,Git主要关注提交。正如您所看到的,提交具有大而难看的散列ID,0dfc…
等等,这对于人类来说很难使用,但是对于Git来说工作得很好。因此,这些散列ID是每次提交的“真实名称”
此外,每个提交通过其哈希ID记录一个父提交。此父提交是在它之前的提交。一些提交合并记录了多个父项,并且存储库中至少有一个提交没有父项,因为这是第一次提交,所以它不可能记录任何早期提交的ID:没有任何早期提交
所有这一切意味着,我们可以绘制一个提交图,使用它们的哈希ID或使用单个大写字母代表大而丑陋的哈希ID,只要我们不介意在26次提交后用完:
A <-B <-C
我们可以停止绘制内部箭头,因为(1)一旦提交,就永远不会更改;(2)它们都必须向后,因为当父级提交时,子级提交不存在,但当子级提交时,父级确实存在。我们仍然需要master
箭头,因为现在我们可以看到Git如何向存储库添加新提交
添加提交更改分支名称
如果我们签出master
并做一些工作,然后运行git add
,然后运行git commit
,git将构建一个新的commit,我们称之为D
,并将D
的哈希ID作为D
的父级:
A--B--C <-- master
\
D
现在我们有了一个新的承诺。让我们理顺这个链,并添加另一个指向commitD
的分支名称:
A--B--C--D <-- develop, master
Git现在需要将E
的散列ID写入两个分支名称中的一个,以对其进行更新。但是哪一个呢?这就是HEAD
的作用
头通常附加在分支名称上
让我们再画一次,但将标题附加到develope
:
A--B--C--D <-- develop (HEAD), master
\
E
现在Git知道使用develope
应该使用commitE
,而使用master
应该使用commitD
注意,对于这种附加头,HEAD
实际上只包含。我们稍后再讨论分离的头部案例
git reset
移动你的头
如果我们仍在develope
上并运行git reset
,则会发生以下情况:
A--B--C <-- develop (HEAD)
\
D <-- master
\
E <-- ???
然后运行git reset--hard HEAD
,我们将我们的HEAD(即名称develope
)从e
移动到e
,这样它就可以保持不变。git reset
的其他效果也适用,这大概就是为什么我们要做这个git reset
,因为我们的头部是自由运动的
你现在已经准备好去理解一个分离的头
分离的头仅仅意味着Git更改了头,因此它不包含分支的名称,而是直接包含原始提交哈希ID。我们可以这样画:
A--B--C--D <-- master
\
E <-- develop, HEAD
当头部被分离时,我们所做的任何其他git重置--hard
都将简单地移动HEAD
(再加上使用git重置--hard
,我们想要做的其他事情)
git checkout
命令也可以完成大部分工作
当您运行git checkout master
或git checkout develope
时,您要求git做两件事:
- 切换提交:使用名称
master
或develope
,找到要签出的提交,并提取该提交,以便
A--B--C--D <-- develop (HEAD), master
\
E
A--B--C--D <-- master
\
E <-- develop (HEAD)
A--B--C <-- develop (HEAD)
\
D <-- master
\
E <-- ???
A--B--C--D <-- master
\
E <-- develop (HEAD)
A--B--C--D <-- master
\
E <-- develop, HEAD
A--B--C <-- HEAD
\
D <-- master
\
E <-- develop