将git存储库重置为特定分支的特定提交

时间:2012-06-29 04:10:07

标签: git reset

我正在处理一个处于以下状态的分支

        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。

报告没有任何变化(预计因为我正好在之前的推动之后)

那么如何重置远程存储库呢?

2 个答案:

答案 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。这应该完全删除悬空物体。