Git分离头部 - 返回到之前的提交并应用更改

3

我把我的git仓库搞砸了,希望有解决方法。我试图升级一个库依赖项,但失败了。我找不到撤消它们的方法,所以我决定回到早期提交,然后从那里开始工作,认为以后会合并。然而,我最终让origin/master与head分离开来,现在无法将任何内容推送到远程仓库。以下是当前状态的屏幕截图:

enter image description here

我对那个分支毫不在意,我只希望它回到它爬出来的洞里。但我无法让它发生。

我尝试像这样还原提交:

git revert 7921869

错误:无法还原,因为您有未合并的文件。
提示:在工作树中修复它们,然后使用“git add/rm”适当地标记解决方案,并进行提交。
致命错误:还原失败

我也尝试推送更改:

git push origin HEAD:master

对于https://xxx@bitbucket.org/xxx/xxx.git,出现了以下错误:! [rejected] HEAD -> master (non-fast-forward)
error: failed to push some refs to 'https://xxx@bitbucket.org/xxx/xxx.git'
提示:因为已推送的分支与远程分支的最新提交不同而被拒绝
提示: 请在再次推送之前检查该分支并与远程更改进行整合
提示:(例如'git pull ...')
如需了解详情,请参阅'git push --help'中有关快进的注释。

git push origin master --force

错误:源引用规范master与任何匹配项都不符。
错误:未能推送一些引用到'https://xxx@bitbucket.org/xxx/xxx.git'

然后我执行了以下操作:

git show-ref

79218694bc34715b3d632dc0057f01fc2df2c842 refs/remotes/origin/master

有人能帮我解决这个问题,让我不再处于分离头状态吗?我需要origin/master与ddf4a1f提交保持一致,就好像f0dd017和7921869从未发生过一样。如果我只是执行git checkout mastergit checkout e416f24,那么我会失去4个后续提交,我不能让这种情况发生。

谢谢。

编辑

如果我没有解释清楚,左侧的行是完美的。我只需要使主分支指向该最终提交,以便我可以再次推送到远程。忘记粉色分支。那是垃圾,我不想使用它。

编辑2

我已经按照Tim Biegeleisen的建议进行了操作,我认为我已经接近成功了。现在我有了这个状态:

enter image description here

现在当我执行git push origin master时,会得到以下结果:

https://xxx@bitbucket.org/xxx/xxx.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'https://xxx@bitbucket.org/xxx/xxx.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

但是,如果我按照消息所说的执行git pull ...,那么我不会打败整个目的,并且会将来自origin/master的垃圾带回来吗?
我可以只执行git push origin master --force吗?

你有未合并的文件。这意味着你进行了一次合并,但只完成了一半。你可能需要运行 git merge --abort - ryenus
git push origin master --force会丢弃origin/master超前于分支点的两个提交,并将master超前于分支点的四个提交推送到origin。这正是您想要实现的目标。 - cmaster - reinstate monica
是的。它起作用了。现在我完全修好了。谢谢! - AndroidDev
1个回答

3

结束这种疯狂的一种方法是提交您在此分离头状态下的任何工作,创建一个新的真正的分支,然后将您想要的提交选取到master中。以下是您可以执行此操作的方法:

git commit -m 'final commit detached HEAD'  # save any remaining work
git checkout -b master_detached             # create new branch (perhaps optional)

git checkout master                         # switch to master
git cherry-pick <SHA-1 detached #1>         # cherry-pick 1st commit
git cherry-pick <SHA-1 detached #2>         # cherry-pick 2nd commit
...

命令 git cherry-pick <SHA-1> 告诉Git将单个哈希值为SHA-1的提交应用于当前分支,这种情况下的分支是master。 换句话说,使用cherry-pick命令,您可以有效地将您在分离的HEAD状态下进行的提交移植到master分支中以进行安全保护。 Cherry-pick可以被视为合并一个提交,因此,您可能需要针对每个cherry-pick操作进行合并冲突的审核。
更新: 看起来您在分离状态下进行的四项提交之外还有一些错误的提交,这些提交在master分支顶部。 在这种情况下,您可以从master中删除这两个提交。 因此,在上面的git checkout master步骤之后,您可以尝试以下操作:
git reset --hard HEAD~2

这将把master7921869提交回滚到e416f24提交。之后,通过挑选分离的提交,简单地继续如上操作。

由于您重写了master分支的历史记录,因此您现在需要通过以下方式将其推送到远程:

git push --force origin master

请记住,如果master在许多人之间共享,则可能不希望这样做。

谢谢,但我想继续使用“master”分支。我不想要那两个提交,因为它们把一切都搞砸了。我能不能只做 git checkout e416f24 然后像你建议的那样挑选提交?这样做会达到同样的效果吗? - AndroidDev
嗯...我可能误读了你的问题,或者你没有理解我的答案。我说的和你一样。只需检出master分支,然后进行cherry-pick操作。在分离HEAD状态下所做的提交不会在master分支中出现。 - Tim Biegeleisen
很可能是后者。当我执行 git checkout master 时,会跳转到7921869提交。我不想在那里。我想要开始应用的提交是e416f24。我要丢弃f0dd017和7921869。 - AndroidDev
我会更新我的答案,以考虑这些信息。 - Tim Biegeleisen
非常感谢您的帮助,现在我已经把本地的 master 分支放到了正确的位置。但是我仍然无法将更改推送回远程仓库。您能否看一下我的第二次编辑?再次感谢您,我非常感激! - AndroidDev
我明白了。最后一步只是 git push origin master --force 然后跟着 git pull origin master。非常感谢你的帮助。尽管我犯了错误,但我正在逐渐地变得更加熟练掌握 git。 - AndroidDev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接