我不小心用 DEV 分支重新定位了我的分支,然后将其推送到远程存储库。使用变基,我选择了当前更改,因此我的本地更改被覆盖。
我在变基中丢失了我之前的提交,但通过运行找到了它git log
。然后我跑了git checkout commitId
,甚至git reset --hard commitId
。但是,在这两种情况下,我的代码库仍然在我的分支上显示最新的重新定位代码。
如何将我的分支恢复到之前的状态?
我不小心用 DEV 分支重新定位了我的分支,然后将其推送到远程存储库。使用变基,我选择了当前更改,因此我的本地更改被覆盖。
我在变基中丢失了我之前的提交,但通过运行找到了它git log
。然后我跑了git checkout commitId
,甚至git reset --hard commitId
。但是,在这两种情况下,我的代码库仍然在我的分支上显示最新的重新定位代码。
如何将我的分支恢复到之前的状态?
我怀疑这里的命令顺序有点混乱。如果你做了
git checkout <commitId>
它会分离你的HEAD
然后你的后续
git reset --hard <commitId>
没有任何效果,因为当前没有签出分支。
在重置之前检查您的分支,它会没事的:
git checkout <yourBranchName>
git reset --hard <commitId>
检查提交的哈希或对象名称会输入 git 文档所指的detached HEAD state。
有时能够检出不在任何命名分支顶端的提交,甚至创建一个未被命名分支引用的新提交,这有时很有用。让我们看看当我们检出提交b时会发生什么(这里我们展示了 [三种] 可能完成的方式):
$ git checkout v2.0 # or $ git checkout master^^ # or $ git checkout b HEAD (refers to commit 'b') | v a---b---c---d branch 'master' (refers to commit 'd') ^ | tag 'v2.0' (refers to commit 'b')
请注意,无论我们使用哪个 checkout 命令,
HEAD
现在都直接指向 commit b。这被称为处于分离的 HEAD 状态。它的意思只是HEAD
指一个特定的提交,而不是指一个命名的分支。
正如您所观察到的,git 会很高兴地使用分离的 HEAD 创建新的提交、变基、合并等等,但是因为没有标签或分支引用生成的未命名分支,所以很容易丢失它。您可以使用git log
. 当你做了更剧烈的手术时,输出git reflog
是另一个值得关注的地方。
如您的问题中所述修复您的分支将涉及以下顺序。
HEAD
到您的分支(以下称为topic/my-branch
)topic/my-branch
到之前的位置origin/topic/my-branch
从较早的推送中
修复。重新连接 HEAD
而不是通过它的 SHA-1 哈希,按名称检查您的分支
git checkout topic/my-branch
修复您的本地分支
接下来,将它放回原来的位置git reset --hard
。您将使用相同的命令,但上下文不同:HEAD
aftergit checkout
指向topic/my-branch
而不是直接指向commitId。
git reset --hard commitId
修复远程分支
您说您推送了重新定位的分支,因此更新远程存储库以反映您的更改。在一个命令中完成所有操作的方法是
git push --force origin topic/my-branch
远程存储库的管理员可能已经采取了非常合理的步骤来拒绝强制推送(原因见下文)。如果是这样,请尝试一系列
在过去糟糕的日子里,我们不得不删除不明显的远程分支
git push origin :topic/my-branch
但现在,它的拼写
git push --delete origin topic/my-branch
扫清道路后,现在推动您的分支将事物恢复到以前的位置。
git push origin topic/my-branch
如果您的遥控器上同时禁用了强制推送和删除,请向对该存储库具有管理访问权限的人寻求帮助。
大多数时候,你必须非常努力地说服 git 破坏工作。但是,git reset --hard
删除远程分支,git push --force
都是利器——在需要时有用,但在不小心使用时很危险。与 一样rm -rf
,暂停以考虑您是否真的指的是您将要运行的命令。