如何使用git撤消推送提交?

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

1601242 次浏览

您可以使用以下命令恢复单个提交:

git revert <commit_hash>

这将创建一个新的提交,它将恢复您指定的提交的更改。请注意,它只恢复该特定提交,而不是之后的提交。如果您想恢复一系列提交,您可以这样做:

git revert <oldest_commit_hash>..<latest_commit_hash>

它会还原<oldest_commit_hash>之后的所有提交,直到并包括<latest_commit_hash>。在某些版本的git上,它还会还原<oldest_commit_hash>,因此请仔细检查该提交是否被还原。您始终可以使用g reset --hard HEAD~删除最新的还原提交(它会还原最旧的提交)。

要找出提交的哈希值,您可以使用git log

有关git revert命令的更多信息,请参阅git恢复手册页。此外,有关恢复提交的更多信息,请参阅这个答案

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

注意:如果有人已经提取了您的更改,请不要这样做(我只在我的个人存储库中使用它。

运行:

git reset <previous label or sha1>

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

然后你“做你的工作”并重新提交你的更改(注意:这一步是可选的)

git commit -am "blabla"

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

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

将强制远程分支接受此推送并删除前一个推送(指定远程名称和分支名称不是强制性的,但建议避免使用更新标志更新所有分支)。

!!注意一些标签可能仍然指向删除提交!!如何删除远程标签

git revert HEAD -m 1

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

  • 1-恢复一个提交。

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

  • n-恢复最后一个n提交。

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


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

我在这些情况下做的是:

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

    git push -f origin <last_known_good_commit>:<branch_name>
  • Locally, do the same:

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



See a full example on a branch my_new_branch that I created for this purpose:

$ git branchmy_new_branch

这是向myfile.py添加一些东西后的最近历史:

$ git logcommit 80143bcaaca77963a47c211a9cbe664d5448d546Author: meDate:   Wed Mar 23 12:48:03 2016 +0100
Adding new stuff in myfile.py
commit b4zad078237fa48746a4feb6517fa409f6bf238eAuthor: meDate:   Tue Mar 18 12:46:59 2016 +0100
Initial commit

我想删除已经推送的最后一次提交,所以我运行:

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

不错!现在我看到在该提交上更改的文件(myfile.py)显示在“未为提交暂存”中:

$ git statusOn branch my_new_branchYour 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 b4zad078237fa48746a4feb6517fa409f6bf238eHEAD is now at b4zad07 Initial commit

所以现在HEAD在之前的提交中,无论是本地还是远程:

$ git logcommit b4zad078237fa48746a4feb6517fa409f6bf238eAuthor: meDate:   Tue Mar 18 12:46:59 2016 +0100
Initial commit

如果您按照下面通过git命令行给出的步骤进行操作,您可以REVERT(或者您也可以将其称为删除)Git Commit本地和远程

运行以下命令以查看要恢复的提交ID

git log --oneline --decorate --graph

您将获得以下屏幕截图输入图片描述

如果您还检查远程(通过Web界面),那么您可以看到如下所示

在此处输入图片描述

根据屏幕截图,目前您的提交ID为e110322,但您想恢复到030bbf6本地和远程

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


首次本地恢复以提交id030bbf6

git reset --hard 030bbf6

其次是

git clean -f -d

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

在此处输入图片描述

如果你跑git状态,然后你会看到你是远程分支后面的两个提交,如下所示输入图片描述

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

git fetch --all

一旦你完成了它,那么你需要通过在分支前面使用+符号来推送这个提交有力,如下所示。我在这里使用了大师分支,你可以用任何

在此处输入图像描述代码

git push -u origin +master

现在,如果您看到远程的Web界面,那么提交也应该被恢复。

在此处输入图片描述

这将删除您的推送提交

git reset --hard 'xxxxx'
git clean -f -d
git push -f

做个备份以防万一

评论中出现了两个注释:

  • 'xxxxx'是您要保留的最后一次提交的哈希代码。

  • clean很危险。它删除文件,而不是版本控制!

这是我的方式:

假设分支名称为develop

# Checkout a new temp branch based on one history commit(cmd to get history: git log)git checkout <last_known_good_commit_hash>
# Delete the original develop branchgit branch -D develop# Create a new develop branch based on the temp branchgit checkout -b develop
# Force update this new branchgit push -f origin develop

你可以这样做

git push origin +<short_commit_sha>^:<branch_name>

2020简单方法:

git reset <commit_hash>

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

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

如果你想再推一次,你必须这样做:

git push -f

重置对我来说很困难:谢谢@Mo D Genensis和@vibs2006

git reset --hard 'your last working commit hash'
git clean -f -d
git push -f

另一种不还原的方法(撤消的痕迹):

如果其他人已经推送了其他提交,请不要这样做

创建分支的备份,位于分支my-branch中。因此,如果出现问题,您可以重新启动流程而不会丢失任何已完成的工作。

git checkout -b my-branch-temp

回到你的分支。

git checkout my-branch

重置,丢弃你的最后一次提交(撤消它):

git reset --hard HEAD^

删除远程分支(例如origin远程)。

git push origin :my-branch

将您的分支(没有不需要的提交)重新推送到远程。

git push origin my-branch

成交!

希望有帮助!;)

假设61234是您想要保留的最后一个好的提交的sha-号。

git reset --hard 61234git push -f


将完全删除所有错误的提交,没有任何痕迹。

注意:如果你想推送(你重置的提交)到一个特定的分支,你应该使用git push -f origin branch-name代替。

干净利落地做:

git rebase -i <hash of last good commit, 9 chars is enough>

现在,您将获得从最后一个好提交到HEAD的提交列表,其中包含如何处理每个提交的选项。DROP将丢弃该提交。保存文件。

现在要修复上游做:

git push --force-with-lease

有租赁,这样你就不会意外地给其他正在处理你的推送更新的人带来问题)

这通过删除错误的提交而不是引入新的提交来修复早期的错误提交来保持日志清洁。

git reset <commit_hash>(获取使用git log--oneline)

git restore .将所有更改的文件恢复到yout目标提交的版本

git push origin master --force强制推送到您的远程主分支。但是如果有人在同一个分支中与您一起工作,使用强制推送时要小心