如何恢复已经推送到远程分支的合并提交?

单独的git revert <commit_hash>将不起作用。 '-m'必须指定,我对此很困惑。

任何人都经历过这个?

-m选项指定父代码 。 这是因为合并提交具有多个父代,并且Git不会自动知道哪个父代是主线,哪个父代是您想要合并的分支。

当你在git log的输出中查看一个合并提交时,你会看到它的父母列在以Merge开头的行上:

 commit 8f937c683929b08379097828c8a04350b9b8e183 Merge: 8989ee0 7c6b236 Author: Ben James <ben@example.com> Date: Wed Aug 17 22:49:41 2011 +0100 Merge branch 'gh-pages' Conflicts: README 

在这种情况下, git revert 8f937c6 -m 1会像8989ee0那样得到树,而git revert -m 2会像7c6b236那样恢复树。

这里有一个完整的例子,希望能帮助别人:

 git revert -m 1 <commit-hash> git commit -m "Reverting the last commit which messed the repo." git push -u origin master 

其中<commit-hash>是你想要恢复的合并的提交散列,正如在这个答案的解释中指出的那样, -m 1表示你想要在第一个父代之前恢复到第一个父代的树。合并。

git commit ... line实质上是提交你的改变,而第三行是通过把你的改变推送到远程分支来公开你的改变。

Ben已经告诉过你如何恢复一个合并提交,但是你意识到这样做是非常重要的 ,“声明你永远不会想要合并引入的树更改,所以后面的合并只会引入由承诺不是先前恢复合并的祖先,这可能是也可能不是你想要的。 (混帐手册页) 。

从手册页链接的文章/邮件列表消息详细介绍了涉及的机制和考虑因素。 只要确保你明白,如果你恢复合并提交,你不能只是稍后再次合并分支,并期望相同的变化回来。

您可以按照这些步骤恢复不正确的提交或将您的远程分支重置为正确的HEAD /状态。

  1. 检查远程分支到本地回购。
    git checkout development
  2. 从git log git log -n5复制提交哈希(即错误提交之前提交的id)

    输出:

    提交7cd42475d6f95f5896b6f02e902efab0b70e8038“合并分支”错误提交“到”开发“中
    提交f9a734f8f44b0b37ccea769b9a2fd774c0f0c012“这是一个错误的提交”
    提交3779ab50e72908da92d2cfcd72256d7a09f446ba“这是正确的提交”

  3. 将分支重置为在上一步中复制的提交哈希
    git reset <commit-hash> (ie 3779ab50e72908da92d2cfcd72256d7a09f446ba)

  4. 运行git status来显示错误提交的所有更改。
  5. 只需运行git reset --hard即可恢复所有这些更改。
  6. 强行推送你的本地分支到远程,并注意你的提交历史是干净的,因为它是污染之前。
    git push -f origin development

有时回滚最有效的方法是退后一步,取而代之。

git log

在列出的错误之前,使用第二个提交哈希(完全哈希,你想恢复的哈希),然后从那里重新分支。

git checkout -b newbranch <HASH>

然后删除旧的分支,在其位置复制新分支,并从那里重新启动。

 git branch -D oldbranch git checkout -b oldbranch newbranch 

如果已经广播,则从所有存储库中删除旧的分支,将重新分支推到最中心,并将其重新拉回到全部。

我发现在两个已知的端点之间创build一个反向修补程序,然后应用该修补程序。 这假定你已经创build了主分支的快照(标签),甚至是主分支的备份,说master_bk_01012017。

说你合并到master的代码分支是mycodebranch。

  1. 结帐大师。
  2. 在主服务器和备份之间创build完整的二进制反向修补程序 git diff --binary master..master_bk_01012017 > ~/myrevert.patch
  3. 检查你的补丁git apply --check myrevert.patch
  4. 用签名git am --signoff < myrevert.patch应用补丁
  5. 如果您需要在修复后再次引入此代码,则需要分离已恢复的主服务器并检出修复分支git branch mycodebranch_fix git checkout mycodebranch_fix
  6. 在这里你需要find恢复的SHA键,并恢复恢复git revert [SHA]
  7. 现在你可以使用你的mycodebranch_fix来解决这个问题,提交并重新合并到master中。
 git revert -m 1 <merge-commit> 

正如Ryan所说的, git revert可能会让合并变得困难,所以git revert可能不是你想要的。 我发现使用git reset --hard <commit-hash-prior-to-merge>命令在这里更有用。

一旦完成硬复位部分,就可以强制推送到远程分支,即git push -f <remote-name> <remote-branch-name> ,其中<remote-name>通常被命名为origin 。 从这一点上,你可以重新合并,如果你想。