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

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

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

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

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


当前回答

git checkout checksum  # You could use this to peek previous checkpoints
git status # You will see HEAD detached at checksum
git checkout master # This moves HEAD to master branch

其他回答

如果您想保存在分离头上所做的更改,只需执行以下操作:创建临时分支并在完成更改后将其提交,然后转到your-branch并将临时分支与之合并。最后,删除临时分支。

git checkout -b temp
git add . && git commit -m 'save changes'
git checkout YOUR-BRANCH
git merge temp
git branch -d temp

如果你有一个主分支,想回到“开发”或功能,就这样做:

git checkout origin/develop

注意:检查起源/发展。

您处于分离HEAD状态。你可以四处看看,做实验更改并提交它们,您可以放弃在此过程中所做的任何提交通过执行另一个签出,状态而不影响任何分支。。。

then

git checkout -b develop

它有效:)

如果您想推送当前分离的HEAD(之前检查gitlog),请尝试:

git push origin HEAD:master

将您分离的HEAD发送到原点的主分支。如果您的推送被拒绝,请首先尝试git pull-origin-master从origin获取更改。如果您不关心源代码的更改,并且它被拒绝,因为您做了一些有意的重基,并且您想用当前分离的分支替换源代码/主代码,那么您可以强制它(-f)。如果您失去了对以前提交的一些访问权限,您可以始终运行git-relog来查看所有分支的历史记录。


要返回主分支,同时保留更改,请尝试以下命令:

git rebase HEAD master
git checkout master

请参见:Git:“当前不在任何分支上。”有没有一种简单的方法可以在保留更改的同时返回分支?

我遇到了这个问题,当我读到最热门的答案时:

HEAD是当前签出提交的符号名称。

我想:啊哈!如果HEAD是当前签出提交的符号名称,我可以通过对master重新设置基址来将其与master进行协调:

git rebase HEAD master

此命令:

签出主机标识HEAD的父提交返回到HEAD从master分支的点在master之上播放这些提交

最终的结果是,所有在HEAD中而不是在master中的提交都在master中。master仍处于检出状态。


关于遥控器:

我在rebase中杀死的几个提交被推送了,而本地提交的新提交不在那里。

远程历史记录不能再使用本地历史记录快速转发。您需要强制push(gitpush-f)来覆盖远程历史记录。如果你有任何合作者,与他们进行协调通常是有意义的,这样每个人都在同一页上。

将master推送到远程源之后,远程跟踪分支origin/master将被更新为指向与master相同的提交。

首先,让我们澄清HEAD是什么,以及当它被分离时它意味着什么。

HEAD是当前签出提交的符号名称。当HEAD未分离时(“正常”1情况:您签出了一个分支),HEAD实际上指向分支的“ref”,而分支指向提交。因此,HEAD“连接”到分支。当您进行新的提交时,HEAD指向的分支将更新为指向新的提交。HEAD会自动跟随,因为它只指向分支。

git符号ref HEAD产生refs/heads/master将签出名为“master”的分支。git rev parse refs/heads/master产量17a02998078923f2d62811326d130de991d1a95a该提交是主分支的当前提示或“头”。git-rev-parse HEAD还生成17a02998078923f2d62811326d130de991d1a95a这就是“符号引用”的含义。它通过其他引用指向对象。(符号引用最初是作为符号链接实现的,但后来改为具有额外解释的普通文件,以便可以在没有符号链接的平台上使用。)

我们有头→ 参考/主管/主管→ 17a02998078923f2d62811326d130代码991d1a95a

分离HEAD时,它直接指向提交,而不是通过分支间接指向提交。你可以把一个独立的HEAD看作是在一个未命名的分支上。

git符号ref HEAD失败,出现致命错误:ref HEAD不是符号refgit-rev-parse HEAD生成17a02998078923f2d62811326d130de991d1a95a由于它不是符号引用,因此必须直接指向提交本身。

我们有头→ 17a02998078923f2d62811326d130代码991d1a95a

使用分离的HEAD需要记住的重要一点是,如果它指向的提交是未被引用的(没有其他引用可以访问它),那么当您签出其他提交时,它将变为“悬空”。最终,这些悬空的提交将通过垃圾收集过程被删除(默认情况下,它们至少保留2周,并且可以通过HEAD的reflog引用而保留更长时间)。

1.使用分离的HEAD进行“正常”工作是非常好的,您只需跟踪正在进行的操作,以避免从重新记录中提取掉的历史。


交互式rebase的中间步骤是用分离的HEAD完成的(部分是为了避免污染活动分支的reflog)。如果您完成了完全重基操作,它将使用重基操作的累积结果更新原始分支,并将HEAD重新附加到原始分支。我的猜测是,你从未完全完成重新启动过程;这将留下一个分离的HEAD,指向rebase操作最近处理的提交。

要从您的情况中恢复,您应该创建一个分支,该分支指向分离的HEAD当前指向的提交:

git branch temp
git checkout temp

(这两个命令可以缩写为gitcheckout-b temp)

这将把HEAD重新连接到新的临时分支。

接下来,您应该将当前提交(及其历史记录)与预期要处理的正常分支进行比较:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(您可能希望尝试使用日志选项:add-p、off--pretty=…查看整个日志消息等)

如果新的临时分支看起来不错,您可能需要更新(例如)master以指向它:

git branch -f master temp
git checkout master

(这两个命令可以缩写为git checkout-B master temp)

然后可以删除临时分支:

git branch -d temp

最后,您可能希望推动重建的历史:

git push origin master

如果远程分支无法“快速转发”到新提交(即,您删除或重写了一些现有提交,或以其他方式重写了一些历史记录),则可能需要在该命令的末尾添加--force以进行推送。

如果你正在进行一个重设基操作,你可能应该清理它。您可以通过查找目录.git/rebasemerge/来检查是否正在进行重基。您可以通过删除该目录来手动清理正在进行的重基(例如,如果您不再记得活动重基操作的目的和上下文)。通常您会使用gitrebase--abort,但这会进行一些您可能希望避免的额外重置(它会将HEAD移回原始分支,并将其重置回原始提交,这将撤消我们上面所做的一些工作)。