我正在处理一个处于以下状态的分支
A'--B'--C'--D'
/
A--B--C--D
发生了一些非常糟糕的事情,我必须在本地和远程回到B'
以便远程存储库是以下
A'--B'
/
A--B--C--D
对于我做的本地存储库
git reset --hard <sha>
但是如何为远程存储库执行此操作?
我应该可以做像
这样的事情git push origin mybranch --reset
但它不在手册页
我尝试创建一个会取消之前的提交但
的提交git add。
报告没有任何变化(预计因为我正好在之前的推动之后)
那么如何重置远程存储库呢?
答案 0 :(得分:4)
要覆盖跟踪的远程分支,请执行git push origin --force mybranch
。 (或使用-f
代替--force
,或使用+
git push origin +mybranch
作为分支名称的前缀。)
请注意,您应该警告任何可能已更改您的分支的远程更改的协作者,因此他们不会覆盖它。因为他们副本上的git push
将为远程分支执行快进 - 除非您至少对其进行了一次新提交,并且git pull
将不会更新其分支的本地版本。合作者应该这样做:
git fetch origin
git checkout mybranch
git rebase origin/mybranch
为完整性而更新:正如@CodeGnome建议的那样,要完全删除存在的提交,请在包含它们的所有Git存储库上运行git prune --expire now
。但请注意,此命令将从Git中删除所有悬空对象,并在运行之前阻止恢复您丢失的任何数据。通常没问题,但无论如何都需要加以警告。
更新:正如this页面建议的那样,git prune --expire now
不会清除reflog的提交。请参阅解决方案的链接。对于侵入性较小的解决方案,请尝试git reflog expire --all mybranch
。您必须在运行git prune
之前执行此操作。
有时更明智地生成一个“撤消”提交来删除更改(因此旧版本及其删除的事实在历史记录中可见)。它有一个git revert
命令。
答案 1 :(得分:3)
您真正需要做的就是在B'分支上,然后转到git push --force
来覆盖该分支的当前提交指针。如果您没有将遥控器设置为跟踪分支,则可能需要执行git push --force origin <branchname>
。
C'和D'将保留在reflog中,并作为存储库中的对象,直到它们最终被修剪,但不应该显示为任何日志历史记录的一部分,除非您开始深入挖掘管道。
如果您希望C'和D'完全不在存储库中,则可以在两个存储库中调用git prune --expire now
。这应该完全删除悬空物体。