2011-06-26 87 views
101

有人接受了他们不应该有的拉请求。现在我们合并了一堆破碎的代码。如何撤消一个请求?我只是想在合并之前恢复对提交的更改,但我注意到它合并在一堆提交中。所以现在这个人在合并之前的几天就有这些提交。你如何解决这个问题?通过拉取请求撤消合并?

+3

尽管接受的答案是建议,但如果回购与其他人共享,请勿强制推送到存储库。你冒着破坏别人已经完成的工作的风险,并且GitHub可能会继续显示pull请求已被合并。这个问题的另一个答案解释了一个更安全的方法来撤消拉取请求。 – alxndr

+2

注意:至少现在(2014年6月),GitHub在其Pull Request Web GUI中提出了“恢复”按钮。请参阅[我的答案](http://stackoverflow.com/a/24459309/6309) – VonC

+0

回复按钮的问题是,它创建一个新的提交作为与拉请求相反的方式,这意味着如果您想要最终合并这些更改,使用“还原”按钮可能会使这变得更加困难。 – FluffySamurai

回答

88

有一个better answer这个问题的最后一件事,虽然我可以打破这一步一步的。

您将需要获取和结帐,像这样的最新上游的变化,例如:

git fetch upstream 
git checkout upstream/master -b revert/john/foo_and_bar 

在提交日志以一看,你会发现一些与此类似:

commit b76a5f1f5d3b323679e466a1a1d5f93c8828b269 
Merge: 9271e6e a507888 
Author: Tim Tom <[email protected]> 
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 <[email protected]> 
Date: Mon Apr 29 12:13:29 2013 +0000 

    Add bar 

commit 470ee0f407198057d5cb1d6427bb8371eab6157e 
Author: John Doe <[email protected]> 
Date: Mon Apr 29 10:29:10 2013 +0000 

    Add foo 

现在您想要恢复整个拉取请求,并具有稍后恢复的能力。 为此,您需要取合并提交的ID。

在上面的例子中合并提交是最上面的一个地方说:“合并拉请求#123 ......”

这样做是为了恢复两个变化(“添加栏”“添加富”),你会最终在一个提交回复整个拉入请求,你可以unrevert以后,保持历史改变清洁:

git revert -m 1 b76a5f1f5d3b323679e466a1a1d5f93c8828b269 
+6

这应该是正确的答案。 git-revert手册页提供了git邮件列表的更多详细信息https://www.kernel.org/pub/software/scm/git/docs/howto/revert-a-faulty-merge .txt –

+0

为什么'git checkout upstream/master -b revert/john/foo_and_bar'?它究竟做了什么? – Magne

+2

@Magne - 您正在创建一个新分支来执行还原操作,然后您可以选择合并还原的位置。基本上只是给你更多的控制如何处理分支。在我的情况中,我从这个“固定”分支提交了一个新的请求,包含返回到我们的开发分支,这意味着我的新的请求也可以在必要时恢复。这是为了发布我们决定推出已重新计划的功能的初稿而完成的。没有错误的代码,只是不会在这个版本。 –

84

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

(如果有分支的引用日志,它应该是更容易找到在合并之前提交。)


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

Okay, lets look at the graph:

screenshot 1

我假设最后(最右边)的提交是你的错误通过拉请求合并,它合并了这里看到的蓝线。 你最后承诺会前的一个上黑线,这里以红色标记:

enter image description here

重置为这个承诺,你应该罚款。

这意味着,在您的本地工作副本做到这一点(确保以后你有没有更多的未提交的东西,例如通过git的藏匿处):

git checkout master 
git reset --hard 7a62674ba3df0853c63539175197a16122a739ef 
gitk 

现在确认您是真的在提交标志着我那里,你会看到它的血统中没有任何东西。

git push -f origin master 

(如果你的github remote被命名为origin - 否则更改名称)。

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

(可能存在Github特定的仅限于Web的方式,但我不太熟悉Github及其请求管理系统)

注意注意,如果其他人已经可能用错误的提交拉了你的主人,他们就会遇到和你现在一样的问题,并且不能真正回馈。在重置为新的主版本之前。

如果可能发生这种情况,或者您只是想避免任何问题,请使用git revert命令而不是git reset,以便使用新的提交来恢复更改,而不是将其更改为旧的提交。 (有些人认为你永远不应该用已发布的分支进行重置。)请参阅关于如何执行此操作的此问题的其他解答。

对于未来:

如果你想只有一些RogerPaladin的分公司提交的,可以考虑使用的cherry-pick代替merge。或与RogerPaladin沟通,将他们移动到单独的分支并发送新的拉取请求。

+0

但是我们在合并和他的第一次提交之间有很多提交。所以就像我们有合并提交,我们自己的提交,然后是他的另一个提交。它似乎融入了他真正的老承诺。 – Will

+0

是的,它会合并到所有合并提交的祖先(并且已经不是您的提交的祖先)。这不应该妨碍你重置 - 如果你以后没有重新绑定,那么这些提交不会自行重新排序。 –

+0

嗯,我真的不太了解git,我使用tortoisegit,所以我不知道你是否可以用它做到这一点。当我尝试重置到最后一次提交时,仍然有旧的提交。 – Will

25

若拉是他做那么

git reset --hard HEAD~1 
+1

按照这条指示要小心,它实际上让我回到2步,而不是一个。 – szeitlin

+0

@szeitlin这怎么可能发生,它把你带回了2个步骤,而不是一个?我知道这个评论是在4年前留下的,但我很好奇,如果有人知道答案会如何发生。这对我来说非常重要。谢谢。 – Haradzieniec

+0

我现在不记得了,但我猜如果我尝试重置时做了新的提交,可能会发生这种情况。如果您担心,我会用虚拟回购测试它。 – szeitlin

19

开始2014年6月24日,你可以尝试轻松取消PR(请参阅 “Reverting a pull request”)与:

Introducing the Revert Button

,你可以很容易地通过点击还原恢复在GitHub上拉请求:

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

你会被提示创建一个还原变化的新的拉动请求:

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

它仍然有待测试,但如果该r evert使用-m或不(也用于还原合并)

+0

我试过这个,它创建了一个新的分支,而不是撤销主人的PR? – Tsar

+0

奇怪。你能否问一个新问题来说明这种行为? – VonC

0

我一直都在使用这个地方,谢谢。

我正在寻找如何撤消拉请求,并在这里。

我刚刚在git reset --hard“很久以前”和 做一个快速回到我之前做拉请求的地方。

除了看这里,我也问我的同事他会做什么, 他有一个典型的很好的答案:使用示例输出 第一个答案以上:

git reset --hard 9271e6e 

与大多数Git中的东西,如果你这样做并不容易, 你可能做错了。

4

要撤消在整个你不想删除提交一个github上拉的要求,你必须运行:

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

与提交哈希被提交前合并拉请求。这将从pull请求中移除所有提交而不影响历史记录中的任何提交。

一个很好的方法来发现这是去现在关闭拉请求,并发现这一领域:

Pull Request Image Pull Request Image

运行git reset后,运行:

git push origin --force <branch name>

这应该在拉取请求之前恢复分支,而不会影响分支中的任何提交进入commi t提取请求提交之间的历史记录。

编辑:

如果你点击就拉请求恢复按钮,这造成在树枝上的额外承诺。它不会拒绝或取消合并。这意味着如果您要点击回复按钮,则无法打开新的拉取请求来重新添加所有这些代码。

+0

将事情理顺的好方法,无需任何疯狂的还原或樱桃采摘 –

+0

谢谢!这正是我计划要做的事情,但那大约会有大约200次提交樱桃挑选。 – FluffySamurai