撤消’git push’

Undoing a 'git push'

这是我在我应该是稳定的分支上所做的…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
% git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded alpha-0.3.0 to master.
% git status
# On branch alpha-0.3.0
# Your branch is ahead of 'origin/alpha-0.3.0' by 53 commits.
#
nothing to commit (working directory clean)
% git push
Fetching remote heads...
  refs/
  refs/heads/
  refs/tags/
  refs/remotes/
'refs/heads/master': up-to-date
updating 'refs/heads/alpha-0.3.0'
  from cc4b63bebb6e6dd04407f8788938244b78c50285
  to   83c9191dea88d146400853af5eb7555f252001b0
    done
'refs/heads/unstable': up-to-date
Updating remote server info

我后来才意识到,这完全是个错误。我想撤消整个过程,并将alpha-0.3.0分支恢复到原来的状态。

我该怎么办?


您需要确保此存储库的其他用户不会获取不正确的更改,或者尝试在要删除的提交之上进行构建,因为您将要倒带历史记录。

然后你需要"强制"推旧的参考。

1
git push -f origin last_known_good_commit:branch_name

或者在你的情况下

1
git push -f origin cc4b63bebb6:alpha-0.3.0

您可能在远程存储库上设置了receive.denyNonFastForwards。如果是这种情况,那么您将得到一个错误,其中包括短语[remote rejected]

在这种情况下,您必须删除并重新创建分支。

1
2
git push origin :alpha-0.3.0
git push origin cc4b63bebb6:refs/heads/alpha-0.3.0

如果这不起作用-可能是因为设置了receive.denyDeletes,那么您必须直接访问存储库。在远程存储库中,您随后必须执行类似以下管道命令的操作。

1
git update-ref refs/heads/alpha-0.3.0 cc4b63bebb6 83c9191dea8


我相信你也可以这样做:

1
2
3
git checkout alpha-0.3.0
git reset --hard cc4b63bebb6
git push origin +alpha-0.3.0

这与最后一种方法非常相似,只是在远程回购中不需要到处乱搞。


git revert比这里建议的一些方法危险性小:

1
2
3
4
5
6
7
8
9
prompt> git revert 35f6af6f77f116ef922e3d75bc80a4a466f92650
[master 71738a9] Revert"Issue #482 - Fixed bug."
 4 files changed, 30 insertions(+), 42 deletions(-)
prompt> git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)
prompt>

将35F6AF6F77F116EF922E3D75BC80A4466F92650替换为您自己的提交。


如果您在共享回购中工作,那么(来自@charles bailey)接受的解决方案非常危险。

作为最佳实践,推送到共享的远程回购的所有提交都应被视为"不可变"。改用"git revert":http://www.kernel.org/pub/software/scm/git/docs/user manual.html修复错误

https://git-scm.com/book/be/v2/git-basics-undoing-things


一种不丢失所需更改的方法:

1
2
3
4
git reset cc4b63b
git stash
git push -f origin alpha-0.3.0
git stash pop

然后您可以选择要推送的文件


另一种方法是:

  • 创建另一个分支
  • 使用"git checkout"签出该分支上的上一次提交
  • 推动新的分支。
  • 删除旧分支并推动删除(使用git push origin --delete )
  • 将新分支重命名为旧分支
  • 再推一次。

  • 1
    git push origin +7f6d03:master

    这将使您的repo恢复到提到的提交编号。


    撤消多次提交git reset——硬0AD5A7A6(只提供commit sha1哈希)

    撤消上次提交

    git reset--硬头~1(将删除对上次提交的更改)git reset--软头~1(对上次提交的更改将作为未提交的本地修改提供)


    场景1:如果您想撤销最后一次提交,比如8123B7e04b3,下面是命令(这对我有效):

    1
    git push origin +8123b7e04b3^:<branch_name>

    输出如下:

    1
    2
    3
    Total 0 (delta 0), reused 0 (delta 0)
    To https://testlocation/code.git
     + 8123b7e...92bc500 8123b7e04b3^ -> master (forced update)

    其他信息:场景2:在某些情况下,您可能希望通过前面的命令恢复刚才撤消的操作(基本上是撤消撤消操作),然后使用下面的命令:

    1
    git reset --hard 8123b7e04b3

    输出:

    1
    HEAD is now at cc6206c Comment_that_was_entered_for_commit

    更多信息请访问:https://github.com/blog/2019-how-to-undo-most-anything-with-git


    如果要忽略刚刚在远程分支中推送的最后一次提交:这不会删除提交,而是通过将git指针移到前面的提交指针(由head^或head^1引用)来忽略它。

    1
    git push origin +HEAD^:branch

    但是,如果你已经推动了这一承诺,而其他人已经拉下了分支。在这种情况下,重写分支的历史记录是不可取的,您应该改为恢复此提交:

    1
    2
    git revert <SHA-1>
    git push origin branch