今天早上我们从我们的回购中抽出来,然后git把我们拉上了(没有分支)。
我不明白这一点,为什么会这样?如何摆脱它而不会失去我们的变化?
答案 0 :(得分:95)
“当前不在任何分支上”意味着您有detached head,即您的HEAD指针直接引用提交而不是象征性地指向分支的名称。
您可以通过检查SHA1的提交,或者当您处于rebase的中间或合并失败时进入这种情况。很难说你为偶然进入这种情况做了什么。
据说,当您从分离的HEAD切换到某个分支时,您可能会丢失更改,但是reflog将始终跟踪HEAD移动的位置。实际上,当从一个独立的HEAD切换时,Git 1.7.5会警告你。您真正失去工作的唯一时间是您有未提交的更改,您可能想要提交或存储。
查看发生了什么的简单方法是git reflog
或git log -g --decorate
,以获得更详细的列表。 --decorate
选项将为每个SHA1标记指向它的所有分支的名称。如果当前HEAD的SHA1与master完全相同,那么除了git checkout master
之外,您不必执行任何操作即可恢复正常运行。否则,查看某个其他分支是否指向SHA1。如果没有,您可能希望创建一个分支来挂起它。
另一个好的命令是git branch -av
,它同样会列出所有分支及其指向的内容,因此您可以看到(no branch)
真正应该是什么。
答案 1 :(得分:32)
没有更多详细信息很难说清楚。
git pull
从远程存储库中获取更改,然后进行合并。它可以配置为执行rebase而不是合并(通过执行git pull --rebase
,或者为您要提取的分支配置branch.<branch_name>.rebase
的真值。)
如果你开始分支,任何合并类型拉动总会让你离开那个分支。另一方面,rebase命令总是通过使用临时分离的HEAD(也称为“无分支”)来工作。如果你在rebase类型拉动期间处于这种状态,那么这是因为拉动的rebase部分遇到了冲突,它正等着你解决它们并使用rebase --continue
(或--skip
,或--abort
)。
默认情况下,reflog存储对HEAD进行的每次更新(每个分支也可以有一个)。您可以使用git reflog show
(或git log -g
查看reflog以获得更详细的视图)。它可能会帮助您确定如何进入这种状态。
如果你正处于一个rebase的中间(你有一个.git/rebase-apply
目录),那么它可能会停止让你解决一些冲突。使用git status
检查“未合并”条目。任何此类条目都应在文件中嵌入冲突标记(假设它们是纯文本文件)。您应该编辑它们以解决冲突,并通过在它们上运行git add
将它们标记为合并。然后运行git rebase --continue
继续使用rebase。您可能会遇到更多应以类似方式处理的冲突(编辑,添加,继续)。如果您决定不再需要特定提交,则可以使用git rebase --skip
跳过它。您可以使用git rebase --abort
中止整个rebase。当rebase由于任何冲突而停止时,所有这些rebase命令都会在错误消息中列出。一旦所有挂起的提交都被应用(或跳过),您的原始分支将使用最终的新提交进行更新,并且您的HEAD将重新连接到它(如果您中止,您的HEAD将被重新连接而不更新分支)。
如果您的分离HEAD不是由于在rebase中间发生冲突,那么您的HEAD在拉动之前的某个时刻被分离。您需要评估树的当前状态以确定您要执行的操作。您可以使用git show-branch --current --all
或git log --graph --oneline --decorate --all
或图形工具(如gitk
)来了解当前(分离的)HEAD与其他分支的关系。如果您决定要保留HEAD的内容,那么您可以使用git branch new_branch_name
为它们创建一个新分支。如果要覆盖现有分支,请使用git branch --force existing_branch_name
。然后使用git checkout branch_name
将存储库的HEAD重新附加到分支。
答案 2 :(得分:2)
请注意,如果在分离git pull --rebase
时运行“HEAD
”,Git会尝试查找分离的HEAD
的上游分支(根据定义,它不存在)并发出不必要的错误消息。
Git1.8.0.1(2012年11月26日)不再是这种情况
请参阅this commit。