这个模块涵盖了 git 中最重要和最容易被误解的主题之一——git 中的分离头。 在本文中,我们将详细讨论什么是分离模式、它是如何工作的以及如何修复在分离模式下意外提交的提交。
git 中的 HEAD 和分支是什么?
在我们进入分离模式之前,我们需要更详细地了解什么是 HEAD,什么是分支。
git 中的每个提交都由一个 SHA-1 值表示。 这在现实生活中很难互动。 所以我们将引用命名为分支。 分支是指向提交链中最新提交的指针. 当我们在该分支上添加提交时,分支指针会更新到新的提交。
HEAD 是 git 中的符号指针。 从广义上讲,它指的是当前提交(代表目录当前状态的提交)。
HEAD 就是我们所说的符号指针,也就是说它指向一个引用,一般是分支指针。 HEAD 指向分支指针的状态称为附加模式。 可以使用 git checkout 命令将 HEAD 从一个提交移动到另一个提交。 例如:
# Points the HEAD pointer to reference/branch master git checkout master
注意:Git 仍然使用 master 作为默认分支,所以我们坚持使用 master 作为默认分支。
什么是 git 中的分离头?
分离头是一种情况,其中 HEAD 不再指向分支中的最新提交。 让我们用一个简单的图表来理解它
在这个图中,我们看到 HEAD 指向的提交不是该分支上的最新提交。 正如我们之前讨论的,HEAD 是一个符号引用。 在正常情况下,它会指向引用 master,后者又指向分支 master 上的最新提交。 但这里的情况并非如此,HEAD 与分支不对齐。 这种情况称为分离头情况。
注意: HEAD 不再是符号引用,它包含它指向的提交的 SHA-1 值。
你如何最终进入分离模式?
任何不是您的一个分支名称的提交的检出都会为您提供一个分离的 HEAD。 代表分支尖端的 SHA-1 仍然给出一个分离的 HEAD。 只有签出本地分支名称才能避免处于分离模式。 以下是一些使用 git checkout 的示例,用于显示我们的结帐结果是否处于分离模式。
# Go to the first commit in branch dev # Does not end up in the detached mode git checkout dev # Go to the previous commit # Swtiches to detached mode git checkout HEAD^ # Move 3 commit before the master reference # Swtiches to detached mode git checkout master~3
分离模式不是错误,而是一个功能。 它允许您通过恢复该状态的目录来访问旧提交。 Git rebase 是使用分离模式的主要示例之一。
如何重新连接头部?
在让我们考虑的假设情况下,您在分离模式下进行了一些提交,使得提交图如图 3 所示。
你不小心从分离的头上做了一些提交,导致了这种提交图。 您可能想做两件事:
- 忽略在分离模式下所做的提交并继续
- 将在分离模式下所做的这些更改提交到分支。
让我们看看如何做到这一点:
1. 忽略在分离模式下的提交
如果您想忽略在分离模式下进行的提交,您可以查看您正在处理的分支。 你可以这样做,
# Just checkout the branch where you want to place your head git checkout master
git 目录看起来像什么都没发生过。 这些提交仍将出现在图中,但不会对这个分支产生明显影响。 如果您没有提交并且只想切换回另一个分支,此方法也很有用。 如果您进行了意外更改,您可以将其隐藏(可选)并查看所需的分支。
2. 将分离模式下的更改提交到另一个分支
如果您不想无视您的努力,您可以将这些分离的提交附加到您的首选分支。 这可以通过将这些分离的 HEAD 转换为分支来完成。 这可以使用
# Convert the detached commits to a branch git branch temp
这些提交将不再分离,最近的提交将由分支名称引用,分支名称将由 HEAD 引用。 提交图将如下所示
- 现在签出您希望提交并合并新分支的分支。
# Merge the commits to master git checkout master git merge temp
注意:在某些情况下,基于旧提交合并分支可能会产生合并冲突。
结论
这将我们带到了这篇关于分离头的文章的结尾。 希望您能够理解并解决分离的 HEAD 中的问题。 我还想提一下我用来可视化 git 命令的这个开源工具。