Git-撤消推送的提交


607

我在远程存储库中有一个项目,与本地存储库(开发)和服务器(产品)同步。我一直在进行一些已提交的更改,这些更改已推送到服务器并已从服务器拉出。现在,我要撤消那些更改。因此,我可以只git checkout在更改之前提交并提交新更改,但是我猜测将它们再次推到远程将存在一些问题。关于如何进行的任何建议?


Answers:


734

您可以使用以下方法还原单个提交:

git revert <commit_hash>

这将创建一个新的提交,该提交将还原您指定的提交的更改。请注意,它仅还原特定的提交,之后不提交。如果要还原一定范围的提交,可以这样进行:

git revert <oldest_commit_hash>..<latest_commit_hash>

它还原指定提交之间(包括指定提交)的提交。

查看git-revert手册页以获取有关该git revert命令的更多信息。另请参阅此答案以获取有关还原提交的更多信息。


22
换句话说,它恢复为<oldest_commit_hash>;)
David

7
@mr_jigsaw使用git log
gitaarik

2
在git文档中,它说revert命令还原第一次和最后一次提交之间的提交(包括第一次和最后一次提交)。 参见文档
Onur Demir

4
@aod是正确的,此答案需要更新。当前的用于还原的git API已<oldest_commit_hash>包含在还原列表中
JHixson,

4
与git 2.17.2恢复<旧> .. <新>不包括旧,但包括<新>
chingis

353

一种不保留“撤消”痕迹的解决方案。

注意:如果有人已经撤回了您的更改,请不要这样做(我只会在我的个人仓库中使用它)

做:

git reset <previous label or sha1>

这将在本地重新签出所有更新(因此git status将列出所有更新的文件)

然后您“完成工作”并重新提交更改(注意:此步骤是可选的)

git commit -am "blabla"

此时,您的本地树与远程树不同

git push -f <remote-name> <branch-name>

将推送并强制远程考虑此推送,并删除上一个推送(指定remote-name和branch-name不是强制性的,但建议避免使用update标志更新所有分支)。

!! 当心一些标签可能仍指向删除提交!如何删除远程标签


4
-a所有跟踪的文件都将被提交-m提交消息如下
jo_15年

3
正是我搜索的内容。有人进行了错误的提交,然后推送并随后将其还原。树枝不能因为这个合并,我想获得资源库是在正确的状态再次(和删除,因为他们是错误的那些反正从历史提交)
byemute

1
我应该使用哪个“上一个标签或sha1”?我应该输入最后一个“正确”的字符还是之前的那个,然后重新执行最后一个正确的字符所做的所有更改?
elysch '16

3
在犯错之前的那一刻
jo_16,2016年

1
正是我所需要的。我误把分支推到了主人。结果,在所有提交历史中,我都有很多垃圾提交。我刚刚完成git push -f了最后一次正确的提交,并清除了远程历史记录!谢谢!
安东·里巴尔科

192

在这些情况下,我要做的是:

  • 在服务器中,将光标移回上一个已知的良好提交:

    git push -f origin <last_known_good_commit>:<branch_name>
    
  • 在本地,执行相同的操作:

    git reset --hard <last_known_good_commit>
    #         ^^^^^^
    #         optional
    



请参阅my_new_branch我为此创建的分支上的完整示例:

$ git branch
my_new_branch

这是向中添加一些内容后的最近历史记录myfile.py

$ git log
commit 80143bcaaca77963a47c211a9cbe664d5448d546
Author: me
Date:   Wed Mar 23 12:48:03 2016 +0100

    Adding new stuff in myfile.py

commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

我想摆脱已经被推送的最后一次提交,所以我运行:

$ git push -f origin b4zad078237fa48746a4feb6517fa409f6bf238e:my_new_branch
Total 0 (delta 0), reused 0 (delta 0)
To git@github.com:me/myrepo.git
 + 80143bc...b4zad07 b4zad078237fa48746a4feb6517fa409f6bf238e -> my_new_branch (forced update)

真好!现在,我看到在该commit(myfile.py)上更改的文件显示为“ notstaged for commit”:

$ git status
On branch my_new_branch
Your branch is up-to-date with 'origin/my_new_branch'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   myfile.py

no changes added to commit (use "git add" and/or "git commit -a")

由于我不需要这些更改,因此我也只需将光标移回本地:

$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit

因此,现在HEAD在本地和远程的上一次提交中:

$ git log
commit b4zad078237fa48746a4feb6517fa409f6bf238e
Author: me
Date:   Tue Mar 18 12:46:59 2016 +0100

    Initial commit

10
这是正确的答案!这正是我需要做的事情,谢谢今天学到的新知识:)
Egli Becerra

2
这是正确的答案!它与push(!)提交有关!
powtac

3
如果您想真正还原更改(好像您从未推送过更改),这正确的答案。
雅各布

1
完美的答案。效果不错!
拉菲·阿尔罕默德

2
有人给这个男人买啤酒!
Jay Nebhwani

72

如果您通过git命令行执行以下步骤,则可以本地(或远程)禁止(或也可以将其称为DELETE)Git提交。

运行以下命令以查看要还原的提交ID

git log --oneline --decorate --graph

您将获得以下屏幕截图 在此处输入图片说明

如果您还通过“ Web Interface”(Web界面)检查“远程”,则可以看到如下所示

在此处输入图片说明

按照目前的截图你在提交ID e110322但是要恢复到030bbf6 BOTH 本地和远程

执行以下步骤以本地/远程删除/删除提交


第一次本地还原以提交ID 030bbf6

git reset --hard 030bbf6

其次是

git clean -f -d

这两个命令清除强制重置以提交阶段030bbf6,如下快照所示

在此处输入图片说明

现在,如果您运行git status,那么您将看到您是来自远程分支的两次提交行为,如下所示 在此处输入图片说明

运行以下命令更新索引(如果有任何更新)。建议您要求所有开发人员不要在主远程分支上接受任何拉取请求。

git fetch --all

完成后,需要使用分支前面的+符号强行推送此提交,如下所示。我在这里用作主分支,您可以将其替换为

在此处输入图片说明

git push -u origin +master

现在,如果您看到远程的Web界面,则提交也应还原。

在此处输入图片说明


61

这将删除您的推送提交

git reset --hard 'xxxxx'

git clean -f -d

git push -f

7
此方法正确重写历史记录以删除提交。很棒
Jesse Reza Khorasanee

2
这个答案是el magnifeco!
trueadjustr

3
喜欢答案,谢谢:)
Dzenis H.

1
只是要清楚一点(我不确定):提交将是操作后的当前提交。不是要删除的最后一个。
Maik639

22
git revert HEAD -m 1

在上面的代码行中。“最后一个参数代表”

  • 1-恢复一次提交。

  • 2-恢复最后两次提交。

  • n-恢复最后n次提交。

您需要按此命令后才能在远程上生效。您还有其他选项,例如指定要还原的提交范围。这是选项之一。


以后使用git commit -am "COMMIT_MESSAGE" ,然后git pushgit push -f


8
这是不正确的--m参数指定要还原为的父级数目(如果要还原传入的“它们的”更改,通常为1,而不是合并到更改的2,“我们的”-用于合并2提交)。它与还原的提交数量无关-如果要还原提交范围,请使用git revert ref1..ref2
空引用

1
没有达到预期的效果
Sam Tuke

2

2020简单方法:

git reset <commit_hash>

(您要保留的最后一次提交的哈希值)。

您将在本地保留未提交的更改。

如果要再次推送,则必须执行以下操作:

git push -f

0

这是我的方式:

假设分支名称为develop

# Create a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>
git checkout -b develop-temp

# Delete the original develop branch and 
# create a new branch with the same name based on the develop-temp branch
git branch -D develop
git checkout -b develop

# Force update this new branch
git push -f origin develop

# Remove the temp branch
git branch -D develop-temp

0

你可以做类似的事情

git push origin +<short_commit_sha>^:<branch_name>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.