Git - Undo推送提交

Man*_*olo 502 git

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

git*_*rik 609

您可以使用以下命令还原单个提交:

git revert <commit_hash>
Run Code Online (Sandbox Code Playgroud)

这将创建一个新的提交,它将恢复您指定的提交的更改.请注意,它只会还原该特定提交,而不会在此之后提交.如果要还原一系列提交,可以这样做:

git revert <oldest_commit_hash>..<latest_commit_hash>
Run Code Online (Sandbox Code Playgroud)

它还原指定提交之间的提交.

有关该命令的更多信息,请查看git-revert手册页git revert.有关还原提交的更多信息,请查看此答案.

  • 换句话说,它将恢复为<oldest_commit_hash>;) (16认同)
  • @mr_jigsaw使用`git log` (6认同)
  • 刚刚尝试过......最后一步被错过,在**“git revert &lt;commit_hash&gt;”**使用**“git push origin &lt;your_Branch&gt;”**之后 (4认同)
  • 在 git 文档中,它说 revert 命令恢复第一次和最后一次提交之间的提交(包括第一次和最后一次)。[查看文档](https://git-scm.com/docs/git-revert) (3认同)
  • @aod是正确的,这个答案需要更新.用于还原的当前git API将"<oldest_commit_hash>"包含在还原列表中 (3认同)
  • 与git 2.17.2还原&lt;旧&gt; .. &lt;新&gt;不包括旧,但包括&lt;新&gt; (3认同)
  • 恢复给我“错误:提交 zzz 是合并,但没有给出 -m 选项。致命:恢复失败` (2认同)

jo_*_*jo_ 297

一种不会留下"撤消"痕迹的解决方案.

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

做:

git reset <previous label or sha1>
Run Code Online (Sandbox Code Playgroud)

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

那么你"做你的工作"并重新提交你的更改(注意:这一步是可选的)

git commit -am "blabla"
Run Code Online (Sandbox Code Playgroud)

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

git push -f <remote-name> <branch-name>
Run Code Online (Sandbox Code Playgroud)

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

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

  • -a将跟踪所有跟踪的文件-m commit message (4认同)
  • 正是我搜索的内容.有人做了一个错误的提交并推送并在之后再次恢复它.因为这个而无法合并分支,我想让存储库再次处于正确状态(并且从历史记录中删除提交,因为它们都是错误的) (3认同)
  • 在错误提交之前的那一个 (3认同)
  • 正是我需要的。我错误地将一个分支推送到 master 。结果,我在所有提交历史记录中都有很多垃圾提交。我刚刚完成了“git push -f”以获得最后一次正确的提交并清除了远程历史记录!谢谢! (3认同)
  • 我应该使用哪个“以前的标签或 sha1”?我应该输入最后一个“正确”的还是之前的一个,然后重新执行最后一个正确的所有更改? (2认同)

fed*_*qui 157

我在这些情况下做的是:




查看my_new_branch我为此目的创建的分支上的完整示例:

$ git branch
my_new_branch
Run Code Online (Sandbox Code Playgroud)

这是添加一些东西后的近期历史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
Run Code Online (Sandbox Code Playgroud)

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

$ 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)
Run Code Online (Sandbox Code Playgroud)

太好了!现在我看到在commit(myfile.py)中更改的文件显示在"not staged 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")
Run Code Online (Sandbox Code Playgroud)

由于我不想要这些更改,我只是将光标移回本地:

$ git reset --hard b4zad078237fa48746a4feb6517fa409f6bf238e
HEAD is now at b4zad07 Initial commit
Run Code Online (Sandbox Code Playgroud)

所以现在HEAD在本地和远程的前一次提交中:

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

    Initial commit
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的答案!这正是我需要做的事情,感谢今天学到的东西:) (5认同)
  • 如果您想真正还原更改(好像您从未推送过更改),则此为正确答案。 (3认同)
  • +100 为最佳答案 (3认同)
  • 这是正确答案!这是关于推送(!)提交! (2认同)
  • 好!这应该是公认的答案. (2认同)

vib*_*006 66

如果您通过git命令行执行下面给出的步骤,您可以本地和远程 REVERT(或者您也可以将其命名为DELETE)Git Commit BOTH.

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

git log --oneline --decorate --graph
Run Code Online (Sandbox Code Playgroud)

您将获得如下截图 在此输入图像描述

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

在此输入图像描述

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

执行以下步骤以本地+远程执行DELETE/REVERT提交


首先在本地恢复提交id 030bbf6

git reset --hard 030bbf6
Run Code Online (Sandbox Code Playgroud)

其次是

git clean -f -d
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

现在,如果你运行git status,那么你将看到你是远程分支的两个提交者,如下所示 在此输入图像描述

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

git fetch --all
Run Code Online (Sandbox Code Playgroud)

完成后,您需要在分支前面使用+符号强制推送此提交,如下所示.我在这里用作主分支,你可以用任何替换它

在此输入图像描述

git push -u origin +master
Run Code Online (Sandbox Code Playgroud)

现在,如果您看到远程的Web界面然后提交,那么也应该还原.

在此输入图像描述

  • 是的,但是我刚刚解决了它。看来我的主分支受到了强制推送的保护,我需要暂时取消它的保护(在 gitlab 存储库设置下)。 (2认同)

Xys*_*Xys 40

2020 简单方法:

git reset <commit_hash>
Run Code Online (Sandbox Code Playgroud)

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

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

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

git push -f
Run Code Online (Sandbox Code Playgroud)


Sep*_*eha 36

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

    git reset --hard 61234
    git push -f origin master 
Run Code Online (Sandbox Code Playgroud)

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

注意:示例假定 master 分支位于 'origin' 远程。

  • 这工作完美!谢谢 (4认同)
  • 出色的。太感谢了。 (2认同)
  • 谢谢你!而且提交历史是无辜的!为了方便获取 sha-number,我使用了: $ git log --oneline &lt;feature-branch-name&gt;。 (2认同)

Mo *_*sis 21

这将删除您的推送提交

git reset --hard 'xxxxx'

git clean -f -d

git push -f
Run Code Online (Sandbox Code Playgroud)

  • “干净”是危险的。它删除不受版本控制的文件! (7认同)
  • 这个答案是 el magnifeco! (4认同)
  • 此方法正确重写历史记录以删除提交。太棒了 (3认同)
  • 只是为了清楚(我不确定):提交将是操作后的当前提交。不是最后一个删除的。 (3认同)
  • 如果您想在本地保留您的更改,请使用`git reset --soft 'xxxxx'`并继续使用剩余的命令! (2认同)

Sir*_*dda 20

git revert HEAD -m 1
Run Code Online (Sandbox Code Playgroud)

在上面的代码行中."最后一个论点代表"

  • 1 - 恢复一个提交.

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

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

您需要在此命令后按下以对远程执行效果.您还有其他选项,例如指定要还原的提交范围.这是一个选择.


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

  • 这不是真的 - -m参数指定要恢复的父级数(如果要还原传入的"他们的",更改,通常为1,而对于合并到的更改,则为"我们的" - 用于合并2)提交).它与恢复的提交数无关 - 如果要恢复提交范围,请使用`git revert ref1..ref2` (7认同)
  • 没有达到想要的效果 (2认同)

小智 15

重置对我来说很辛苦:谢谢@Mo D Genensis和@ vibs2006


git reset --hard 'your last working commit hash'

git clean -f -d

git push -f
Run Code Online (Sandbox Code Playgroud)

  • 这将覆盖更改的文件并删除添加的文件。 (2认同)

Sl4*_*4st 12

There are a number of ways like moving back commits by using git reset HEAD^, adding a ^ for every commit you want to go back, problem is the changes after that commit are then lost and can be added in a new commit. So I only do this when I only have to go one or two commits back.

To do it cleanly use the following:

git rebase -i <hash of last good commit, 9 chars is enough>
Run Code Online (Sandbox Code Playgroud)

Now you will get a list of the commits from the last good commit to the HEAD with options what to do with each commit, going from the most recent at the top to the one just before the commit of the hash you added to the command. It will look something like this:

在此输入图像描述

您可以将每次提交之前更改pick为选项列表中的任何其他选项。drop例如,将删除提交。然后,您保存文件,提交将被重新应用,执行您为每次提交选择的选项。

现在修复上游:

git push --force-with-lease
Run Code Online (Sandbox Code Playgroud)

使用租约,这样您就不会意外地给处理您推送的更新的其他人造成问题)

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

[编辑]:更多说明。和图像示例


Bál*_*ass 9

长话短说

\n
    \n
  1. git reset HEAD~1\n\xe2\x80\x93 返回 1 次提交,保留工作目录中的所有更改
  2. \n
  3. git status将向您显示保留的更改
  4. \n
  5. git add ...
  6. \n
  7. git commit
  8. \n
  9. git push --force-with-lease\xe2\x80\x93 覆盖原来的错误提交
  10. \n
\n


小智 7

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

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

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


bac*_*112 5

这是我的方法:

假设分支名称是develop.

# Checkout a new temp branch based on one history commit
git checkout <last_known_good_commit_hash>

# Delete the original develop branch 
git branch -D develop
# Create a new develop branch based on the temp branch
git checkout -b develop

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

Run Code Online (Sandbox Code Playgroud)