【问题标题】:Undoing a 'git push'撤消“git push”
【发布时间】:2010-11-19 05:20:29
【问题描述】:

这是我在 supposed-to-be-stable 分支上所做的...

% 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 分支恢复到原来的样子。

我该怎么办?

【问题讨论】:

  • 这个stackoverflow帖子也许? stackoverflow.com/questions/134882/undoing-a-git-rebase
  • 实际情况不一样,撤消 rebase 是本地存储库方案,撤消 git push 涉及远程存储库,根据您的访问权限可能会更加棘手。
  • Steen - 你是对的 - 我想我可能应该有。我认为所有从中提取的受祝福的存储库更像是一项管理任务,因此属于这里,一般客户端 git 是一个 stackoverflow 问题。
  • 快速澄清-我猜如果您通过 partial 哈希值引用 git 提交,git 会假设您正在谈论哈希以该哈希开头的提交字符串?

标签: git git-push


【解决方案1】:

您需要确保此存储库的其他用户没有获取不正确的更改或尝试在您想要删除的提交之上构建,因为您即将回滚历史记录。

那么你需要“强制”推送旧的引用。

git push -f origin last_known_good_commit:branch_name

或者在你的情况下

git push -f origin cc4b63bebb6:alpha-0.3.0

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

在这种情况下,您将不得不删除并重新创建分支。

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

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

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

【讨论】:

  • 完美且解释清楚的回复 - 非常感谢。对于遇到此问题的任何其他人,出于学术原因,我尝试了前两种方法,并且都有效 - 显然,如果第一种有效,它是最干净的方法。如果我让你 10 次查尔斯,我会的。 :)
  • 为了快速参考,这里的第一行是git push -f origin last_known_good_commit:branch_name
  • git push -f origin cc4b63bebb6:alpha-0.3.0 => 这个对我有帮助,注意 alpha-0.3.0 是分支名称,而 cc4b63bebb6 是我们希望恢复的提交 ID。因此,执行此命令后,我们将在 cc4b63bebb6 commit id 中。
  • 如果您在共享存储库中工作,此解决方案非常危险。作为最佳实践,所有推送到共享的远程仓库的提交都应该被认为是“不可变的”。改用“git revert”:kernel.org/pub/software/scm/git/docs/…
  • jww - 与其他一切相比,git 是可用的功能最丰富和最高效的源代码控制工具。每个团队都以不同的方式使用它。值得花一个周末来玩一个新的存储库并经历所有常见的场景。一旦你花一些时间使用它,开发的压力就会小很多。
【解决方案2】:

我相信你也可以这样做:

git checkout alpha-0.3.0
git reset --hard cc4b63bebb6
git push origin +alpha-0.3.0

这与最后一种方法非常相似,只是您不必在远程仓库中乱七八糟。

【讨论】:

  • 这对我也有用,但值得注意的是,这将在遥控器上“重写”历史记录。这可能是您想要的,但可能不是!
  • +1 这个答案真的帮助了我。我还想补充(并明确说明)提交 ID(位于“--hard”参数之后)应该是您要将分支重置为的任何提交的 ID。
  • 很好地改写了历史......任何可以取消更改的人,我只是确保他们做了git reset --hard [commit_id],所以我们没有弄乱时空连续体。
  • “git push origin +alpha-0.3.0”中的+是什么?
  • @jpierson + 强制推送发生,类似于-f(但略有不同:stackoverflow.com/a/25937833/1757149)。没有它,如果你尝试git push origin alpha-0.3.0,推送将失败:Updates were rejected because the tip of your current branch is behind
【解决方案3】:

git revert 的危险性低于此处建议的一些方法:

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>

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

【讨论】:

  • 我如何想出 35f6af6f77f116ef922e3d75bc80a4a466f92650 ID?如果你能解释一下,这个答案会更好。
  • @Volomike(以及未来的谷歌开发者),这个问题描述了许多获取它的方法:version control and hash question on SO
  • 这是正确的答案,因为使用“git reset”您应该无法推送(更新被拒绝,因为您当前分支的尖端位于其远程对应部分之后)或者您需要强制pull 这不是很干净。
  • 这对我有用。但是,请小心,因为 revert 会还原本地文件中的所有更改。
  • 我多次选择这种方法,但我也使用 git rebase -i 进行交互式 rebase 并按照此处的建议清理历史记录,stackoverflow.com/questions/5189560/… .
【解决方案4】:

在不丢失您想要的更改的情况下做到这一点的方法:

git reset cc4b63b 
git stash
git push -f origin alpha-0.3.0
git stash pop

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

【讨论】:

  • 这拯救了我的一天!
  • 谢谢!
【解决方案5】:

如果您在共享存储库中工作,接受的解决方案(来自@charles bailey)是非常危险的。

作为最佳实践,所有推送到共享的远程存储库的提交都应被视为“不可变”。 改用“git revert”: http://www.kernel.org/pub/software/scm/git/docs/user-manual.html#fixing-mistakes

https://git-scm.com/book/be/v2/Git-Basics-Undoing-Things

【讨论】:

  • 您的处方具体是什么?您似乎只有旧链接。
【解决方案6】:
git push origin +7f6d03:master

这会将您的 repo 恢复为提到的提交号

【讨论】:

  • 这是最直接的答案。你是一个活生生的救星。
  • 记住,这不会重置您的本地文件。
  • 这正是我所需要的,因为我想在不丢失本地更改的情况下简单地撤消推送。
【解决方案7】:

另一种方法:

  1. 创建另一个分支
  2. 使用“git checkout”签出该分支上的先前提交
  3. 推送新分支。
  4. 删除旧分支并推送删除(使用git push origin --delete <branch_name>
  5. 将新分支重命名为旧分支
  6. 再推一次。

【讨论】:

  • 当您在 repo 中已经有错误提交时,这看起来像是一个真正的解决方案
【解决方案8】:

撤消多个提交 git reset --hard 0ad5a7a6(只需提供提交 SHA1 哈希)

撤消上次提交

git reset --hard HEAD~1(对上次提交的更改将被删除)git reset --soft HEAD~1(对上次提交的更改将作为未提交的本地修改提供)

【讨论】:

    【解决方案9】:

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

    git push origin +8123b7e04b3^:<branch_name>
    

    输出如下:

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

    注意:要更新对本地代码的更改(同时在本地删除提交):

    $ git reset --hard origin/<branchName>
    Message displayed is :    HEAD is now at 8a3902a comments_entered_for_commit
    

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

    git reset --hard 8123b7e04b3
    git push
    

    输出:

    HEAD is now at cc6206c Comment_that_was_entered_for_commit
    

    更多信息在这里:https://github.com/blog/2019-how-to-undo-almost-anything-with-git

    【讨论】:

    • 场景 1 应该是接受的答案,因为问题没有指定要删除哪个提交。接受的答案仅删除 last 提交。这个答案会删除 any 提交。
    【解决方案10】:

    你可以使用命令reset

    git reset --soft HEAD^1
    

    然后:

    git reset <files>
    git commit --amend
    

    git push -f
    

    【讨论】:

      【解决方案11】:
      git reset --hard HEAD^
      git push origin -f
      

      这将从您的本地设备以及 Github 中删除最后一次提交

      【讨论】:

        【解决方案12】:

        现有的答案是好的和正确的,但是如果您需要撤消push 但是:

        1. 您希望将提交保留在本地,或者您希望保留未提交的更改
        2. 你不知道你刚刚推送了多少次提交

        使用此命令恢复对 ref 的更改:

        git push -f origin refs/remotes/origin/<branch>@{1}:<branch>
        

        【讨论】:

          【解决方案13】:

          恢复推送

          git reset --hard HEAD@{1}
          git push -f
          git reset --hard HEAD@{1}
          

          现在您的本地将领先于远程

          git reset --hard origin/master
          

          或其他方式

          1. 重置推送:git reset --soft HEAD^1

          2. 会出现修改文件所以重置它们:git reset &lt;files&gt;

          3. git commit --amend

          4. git push -f

          【讨论】:

            【解决方案14】:

            如果你想忽略你刚刚推送到远程分支的最后一个提交:这不会删除提交,而只是通过将 git pointer 移动到更早的提交来忽略它,由 HEAD^ 或 @ 引用987654323@

            git push origin +HEAD^:branch
            

            但是如果你已经推送了这个提交,而其他人已经拉了分支。在这种情况下,重写你的分支的历史是不可取的,你应该恢复这个commit

            git revert <SHA-1>
            git push origin branch
            

            【讨论】:

            • 问题是关于“推送”然后它涉及远程分支。不移动 HEAD 关于一个提交,这意味着忽略最后一次提交的提交,只需执行以下操作: git push origin +HEAD^:your_branch
            猜你喜欢
            • 2015-09-03
            • 2014-11-03
            • 2012-10-31
            • 2017-12-10
            • 2012-02-29
            • 2020-08-23
            • 2016-10-03
            • 2013-01-06
            相关资源
            最近更新 更多