我对Git的分支复杂性很陌生。我总是在一个分支上工作,提交更改,然后定期推送到远程源。

最近的某个时候,我对一些文件进行了重置,以使它们脱离提交阶段,后来又进行了重新base-I,以消除最近的几个本地提交。现在我处于一种我不太理解的状态。

在我的工作区,git日志显示了我所期望的一切——我在正确的火车上,有我不想要的提交,还有新的提交,等等。

但我只是推到了远程存储库,这是不同的——我在rebase中删除的几个提交被推送了,而本地提交的新提交不在那里。

我认为“master/origin”与HEAD是分离的,但我不完全清楚这意味着什么,如何使用命令行工具将其可视化,以及如何修复它。


当前回答

简单地说,分离的HEAD状态意味着您没有签出任何分支的HEAD(或提示)。

通过示例了解

在大多数情况下,分支是多个提交的序列,如:

提交1:主-->分支_HEAD(123be6a76168aca712aea16076e971c23835f8ca)

提交2:主-->123be6a76168aca712aea16076e971c23835f8ca-->分支_HEAD

如上所述,在提交序列的情况下,分支指向最近的提交。因此,在这种情况下,如果您签出提交123be6a76168aca712aea16076e971c23835f8ca,那么您将处于分离的头部状态,因为分支的head指向100644a76168ca712aea16086e971c2 3835f8Ca,从技术上讲,您在没有分支的HEAT签出。因此,您处于分离的HEAD状态。

理论解释

在这个博客中,它清楚地指出Git存储库是一个提交树,每个提交都指向其祖先,每个提交指针都会更新,指向每个分支的这些指针都存储在.Git/refs子目录中。标记存储在.git/refs/Tags中,分支存储在.gt/refs/heads中。如果您查看任何文件,您都会发现每个标记对应一个文件,具有40个字符的提交哈希,正如@Chris Johnsen和@Yaroslav Nikitenko所解释的,您可以查看这些引用。

其他回答

我在搜索“You are in”separated HEAD“状态时发现了这个问题。

在分析了我在这里所做的事情之后,与我过去所做的相比,我发现我犯了一个错误。

我的正常流量是:

git checkout master
git fetch
git checkout my-cool-branch
git pull

这次我做到了:

git checkout master
git fetch
git checkout origin/my-cool-branch
# You are in 'detached HEAD' state.

问题是我无意中做到了:

git checkout origin/my-cool-branch

而不是:

git checkout my-cool-branch

修复方法(在我的情况下)只是运行上述命令,然后继续流程:

git checkout my-cool-branch
git pull

我今天遇到了这个问题,我更新了一个子模块,但没有在任何分支上。我已经承诺了,所以藏东西、结账、拆洗都不起作用。我最终选择了那个超然的脑袋。因此,在我提交后(推送失败时),我立即:

git checkout master
git cherry-pick 99fe23ab

我的想法是:我头脑冷静,但我想成为主人。假设我的分离状态与主状态没有太大的不同,如果我能将我的承诺应用于主状态,我就做好了。这正是樱桃树的作用。

这对我来说非常有效:

1.保存本地修改的git存储

如果要放弃更改git-clean-dfgit结帐--。gitclean会删除所有未跟踪的文件(警告:虽然它不会删除.gitignore中直接提到的忽略文件,但可能会删除驻留在文件夹中的忽略文件),gitcheckout会清除所有未标记的更改。

2.git checkout master切换到主分支(假设您想使用master)3.git pull从主分支提取最后一次提交4.git状态,以便检查一切是否正常

On branch master
Your branch is up-to-date with 'origin/master'.

查看此处了解分离头部的基本说明:

http://git-scm.com/docs/git-checkout

使其可视化的命令行:

git branch

or

git branch -a

您将得到如下输出:

* (no branch)
master
branch1

*(无分支)表示您处于分离状态。

您可以通过执行git checkout somecommit等来达到此状态,它会警告您以下内容:

您处于“分离HEAD”状态。你可以四处看看,做实验更改并提交它们,您可以放弃你在这方面的任何承诺状态而不影响任何分支通过执行另一次结账。如果要创建新分支到保留您创建的提交,您可以这样做所以(现在或以后)使用-b和再次执行checkout命令。例子:git checkout-b new_branch_name

现在,要让他们找到主人:

执行git reflog,甚至只执行git log,并记录您的提交。现在git checkout master和git合并提交。

git merge HEAD@{1}

编辑:

此外,使用gitrebase-i不仅可以删除/删除不需要的提交,还可以编辑它们。只需在提交列表中提到“edit”,您就可以修改提交,然后发出gitrebase——继续。这将确保你永远不会进入一个分离的头部。

当我个人发现自己处于这样一种情况时,当我发现自己在不在master中时做了一些更改(即HEAD被分离在master的正上方,并且中间没有提交),隐藏可能会有所帮助:

git stash # HEAD has same content as master, but we are still not in master
git checkout master  # switch to master, okay because no changes and master
git stash apply  # apply changes we had between HEAD and master in the first place