通过拉取请求撤消合并?

Wil*_*ill 139 git merge github pull-request

有人接受了他们不应该提出的拉动请求.现在我们已经合并了一堆破碎的代码.你如何撤消拉取请求?我只是要在合并之前将更改还原到提交,但我注意到它在一堆提交中合并.所以现在在合并之前几天就有来自这个人的所有这些提交.你怎么撤消这个?

err*_*per 133

对于这个问题有一个更好的答案,尽管我可以一步一步地解决这个问题.

您需要获取并检查最新的上游更改,例如:

git fetch upstream
git checkout upstream/master -b revert/john/foo_and_bar
Run Code Online (Sandbox Code Playgroud)

看一下提交日志,你应该找到类似的东西:

commit b76a5f1f5d3b323679e466a1a1d5f93c8828b269
Merge: 9271e6e a507888
Author: Tim Tom <tim@tom.com>
Date:   Mon Apr 29 06:12:38 2013 -0700

    Merge pull request #123 from john/foo_and_bar

    Add foo and bar

commit a507888e9fcc9e08b658c0b25414d1aeb1eef45e
Author: John Doe <john@doe.com>
Date:   Mon Apr 29 12:13:29 2013 +0000

    Add bar

commit 470ee0f407198057d5cb1d6427bb8371eab6157e
Author: John Doe <john@doe.com>
Date:   Mon Apr 29 10:29:10 2013 +0000

    Add foo
Run Code Online (Sandbox Code Playgroud)

现在,您希望还原整个拉取请求,并具有以后重新发送的功能.为此,您需要获取合并提交的ID .

在上面的例子中,合并提交是最顶层的,它表示"Merged pull request#123 ...".

这样做是为了恢复这两个更改("添加栏""添加foo"),最终会在一次提交中恢复整个拉取请求,您可以在以后重新保存,并保持更改历史记录清洁:

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

  • 这应该是正确的答案.git-revert手册页中有一个参考,来自git邮件列表的更多详细信息,请访问https://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge.文本 (6认同)
  • @Magne - 您正在创建一个新的分支来进行还原,然后您可以选择合并返回的位置.基本上只是让您更好地控制如何处理分支.在我的情况下,我从这个"固定"分支提交了一个新的pull请求,其中包含返回到我们的develop分支,这意味着我的新pull请求也可以在必要时恢复.这是为了发布我们决定撤出重新安排的功能的初稿.没有错误的代码,只是没有进入这个版本. (4认同)
  • 稍后如何“恢复”它? (4认同)
  • 我在这件事上学到了惨痛的教训。我们将一个功能推送到我们的开发分支,但意识到存在数据问题并直接在开发上恢复。后来事情解决了,我们想将新的开发特性添加回这个分支,以在推送之前测试它们与这个特性的兼容性,所以我将开发合并回特性分支。这也应用了还原提交,它取消了对功能分支所做的每个更改。&gt;&lt; (3认同)
  • 为什么`git checkout upstream/master -b revert/john/foo_and_bar`?它究竟做了什么? (2认同)

Paŭ*_*ann 85

查看您的提交图(使用gitk或类似程序).您将看到来自pull请求的提交,您将看到自己的提交和合并提交(如果它不是快进合并).您只需在合并之前找到自己的最后一次提交,并将分支重置为此提交.

(如果你有分支的reflog,那么在合并之前找到提交应该更容易.)


(在评论中的更多信息后编辑:)

好的,让我们看一下图表:

截图1

我假设最后(最右边)提交是你的错误合并拉请求,它合并了这里看到的蓝线.你最后一个好的提交将是黑线前的那个,这里用红色标记:

在此输入图像描述

重置为此提交,你应该没事.

这意味着,在您的本地工作副本中执行此操作(确保您没有更多未提交的内容,例如通过git stash):

git checkout master
git reset --hard 7a62674ba3df0853c63539175197a16122a739ef
gitk 
Run Code Online (Sandbox Code Playgroud)

现在确认你真的在我标记的那个提交上,你将看不到它的祖先中的任何东西.

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

(如果您的github遥控器已命名origin- 否则更改名称).

现在一切都应该在github上看起来正确.提交仍然在您的存储库中,但任何分支都无法访问,因此不应该在那里造成任何伤害.(当然,他们仍将在RogerPaladin的存储库中.)

(可能有一个Github特定的网络方式做同样的事情,但我不太熟悉Github及其拉取请求管理系统.)

请注意,如果其他人已经使用错误的提交已经撤消了您的主人,则他们会遇到与您目前相同的问题,并且无法真正回馈.在重置为新的主版本之前.

如果可能发生了这种情况,或者您只是想避免任何问题,请使用git revert命令代替git reset,以使用新提交还原更改,而不是设置回旧更改.(有些人认为你永远不应该使用已发布的分支重置.)请参阅此问题的其他答案,了解如何执行此操作.

为未来:

如果您只想要RogerPaladin分支的一些提交,请考虑使用cherry-pick而不是merge.或者与RogerPaladin通信以将它们移动到单独的分支并发送新的拉取请求.

  • 我认为这可能会有问题,如果有人提取了糟糕的提交,他们后来发送包含相同错误提交的拉取请求,因此他们偷偷进入回购.创建一个可以逆转糟糕提交的新提交会不会更安全?那样如果坏的提交被拉到其他分支/分叉,它们将被另一个分支/分支有效地删除?我不是说这是事实,这是我认为*可能是真的,与OP处于相同的位置并且花了一个小时左右考虑我的选择. (6认同)
  • @Will我会建议不接受这个答案.这对于尚未推送的代码来说很好(在这种情况下,[this](/sf/ask/167255301/ ?lq = 1)是一个更相关的SO问题,但对于公开共享的代码,执行重写历史记录的git命令(在这种情况下,`reset --hard`和强制推送是非常糟糕的做法).答案下面的@errordeveloper显示了一种方法,可以在没有任何历史记录重写或强制推送的情况下执行此操作. (4认同)

sam*_*est 33

如果拉力是他做的最后一件事

git reset --hard HEAD~1
Run Code Online (Sandbox Code Playgroud)

  • 请小心遵循此说明,它实际上让我退回了 2 个步骤,而不是一个。 (5认同)
  • @szeitlin 怎么可能让你后退两步,而不是一步?我知道这个评论是 4 多年前留下的,但我很好奇是否有人知道它是如何发生的。这对我来说非常重要。谢谢。 (2认同)

Von*_*onC 22

从2014年6月24日开始,您可以尝试轻松取消PR(请参阅" 恢复拉取请求 "):

介绍还原按钮

您可以通过单击"还原"轻松还原GitHub上的拉取请求:

https://camo.githubusercontent.com/0d3350caf2bb1cba53123ffeafc00ca702b1b164/68747470733a2f2f6769746875622d696d616765732e73332e616d617a6f6e6177732e636f6d2f68656c702f70756c6c5f72657175657374732f7265766572742d70756c6c2d726571756573742d6c696e6b2e706e67

系统将提示您使用恢复的更改创建新的拉取请求:

https://camo.githubusercontent.com/973efae3cc2764fc1353885a6a45b9a518d9b78b/68747470733a2f2f6769746875622d696d616765732e73332e616d617a6f6e6177732e636f6d2f68656c702f70756c6c5f72657175657374732f7265766572742d70756c6c2d726571756573742d6e65772d70722e706e67

如果该恢复是否使用仍然有待测试-m(也用于恢复合并)


Flu*_*rai 7

要通过您不希望删除的提交撤消github pull请求,您必须运行:

git reset --hard --merge <commit hash>

提交哈希是合并拉取请求的提交.这将从pull请求中删除所有提交,而不会影响历史记录中的任何提交.

找到这个的一个好方法是转到现在关闭的拉取请求并找到这个字段:

拉请求图像 拉请求图像

运行之后git reset,运行一个:

git push origin --force <branch name>

这应该在pull请求之前恢复分支,而不会影响分支中的任何提交,这些提交会在pull请求的提交之间进行提交.

编辑:

如果要单击拉取请求上的"还原"按钮,则会在分支上创建另一个提交.它不会解散或取消合并.这意味着,如果你点击[还原]按钮,就不能打开新的拉动请求重新添加所有代码.