プルリクエストでマージを元に戻しますか?


159

誰かがすべきではないプルリクエストを受け入れました。これで、一連の壊れたコードがマージされました。プルリクエストを元に戻すにはどうすればよいですか?マージの直前にコミットの変更を元に戻すつもりでしたが、大量のコミットでマージされていることに気付きました。そのため、マージの前日からのこの人物からのこれらすべてのコミットがあります。これをどのようにして元に戻しますか?


7
受け入れられた回答のアドバイスにもかかわらず、リポジトリが他の誰かと共有されている場合は、リポジトリに無理にプッシュしないでください。あなたは他の人が行った仕事を台無しにする危険を冒します、そしてGitHubはマージされたものとしてそのプルリクエストを示し続けるかもしれません。この質問に対する別の回答は、プルリクエストを元に戻す安全な方法を説明しています。
alxndr 2014年

2
注:少なくとも現在(2014年6月)、GitHubはプルリクエストWeb GUIに「元に戻す」ボタンを提案しています。以下の私の答えを
VonC '27

1
元に戻すボタンの問題は、プルリクエストの逆として新しいコミットを作成することです。つまり、これらの変更を最終的にマージしたい場合、「元に戻す」ボタンを使用すると、はるかに困難になる可能性があります。
FluffySamurai 2017

回答:


159

より良い答えがありますこの問題に私はこれを段階的に分解することができました。

次のように、最新のアップストリームの変更をフェッチしてチェックアウトする必要があります。

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

コミットログを見ると、次のようなものが見つかります。

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

次に、プルリクエスト全体を元に戻し、後で元に戻すことができるようにします。そのためには、マージコミットの IDを取得する必要があります。

上記の例では、マージコミット「マージされたプルリクエスト#123 ...」と表示されている一番上のコミットです。

これを行って両方の変更を元に戻し("Add bar""Add foo")、1つのコミットでプルリクエスト全体を元に戻し、後で元に戻して変更の履歴をクリーンに保つことができます。

git revert -m 1 b76a5f1f5d3b323679e466a1a1d5f93c8828b269

6
これが正解です。git-revertのmanページに、gitメーリングリストの詳細への参照があります。kernel.org
pub / software /

2
なぜgit checkout upstream/master -b revert/john/foo_and_bar?それは正確に何をしますか?
マグネ14

4
@Magne-復帰を実行するための新しいブランチを作成します。その後、復帰をマージする場所を選択できます。基本的には、ブランチをどう処理するかをより詳細に制御できます。私の場合、この「修正済み」ブランチから、開発ブランチへの復帰を含む新しいプルリクエストを送信しました。つまり、必要に応じて、私の新しいプルリクエストも復帰できます。これは、再スケジュールされた機能の最初のドラフトを引き出すことにしたリリースで行われました。悪いコードはなく、今回のリリースではありません。
Daniel Nalbach 2014年

3
私はこれについて難しい教訓を学びました。機能を開発ブランチにプッシュしましたが、データの問題があることに気付き、開発時に直接戻りました。物事が修正された後、プッシュする前にこのブランチに新しい開発機能を追加して互換性をテストしたかったので、開発を機能ブランチにマージしました。これは、機能ブランチに加えられたすべての変更を記述しない、復帰コミットも適用しました。> <
グレッグ、

86

コミットグラフを見てください(gitkまたは同様のプログラムを使用)。プルリクエストからのコミットが表示され、独自のコミットとマージコミットが表示されます(早送りマージでない場合)。マージする前に自分のコミットの最後を見つけ、ブランチをこのコミットにリセットするだけです。

(ブランチのreflogがある場合、マージの前にコミットを見つけるのがさらに簡単になるはずです。)


(コメントの詳細を編集した後:)

さて、グラフを見てみましょう:

スクリーンショット1

最後の(最も右の)コミットは、プルリクエストによる間違ったマージであったと思います。あなたの最後の良いコミットは前の黒い線で、ここでは赤でマークされています:

ここに画像の説明を入力してください

このコミットにリセットすると、大丈夫です。

つまり、ローカルの作業コピーでこれを行います(たとえば、git stashによって、コミットされていないものがないことを確認した後)。

git checkout master
git reset --hard 7a62674ba3df0853c63539175197a16122a739ef
gitk 

ここで、私がそこにマークしたコミットに本当に参加していることを確認してください。そうすれば、その祖先にプルされたものが表示されなくなります。

git push -f origin master

(githubリモートに名前が付けられている場合 origin -それ以外の変更してください)。

これで、すべてがgithubでも正しく表示されるはずです。コミットはまだリポジトリにありますが、どのブランチからも到達できないため、そこに害を及ぼすことはありません。(もちろん、それらはまだRogerPaladinのリポジトリにあります。)

(同じことを行うGithub固有のWeb専用の方法があるかもしれませんが、Githubとそのプルリクエスト管理システムについてはあまり詳しくありません。)

注意コミット誰が既に間違ってご主人を引っ張ってきた可能性がある場合、彼らはあなたが現在持っているのと同じ問題を抱えているし、本当に戻って貢献することができません。新しいマスターバージョンにリセットする前。

これが発生したと思われる場合、または単に問題を回避したい場合は、のgit revert代わりにコマンドを使用しgit resetて、古いコミットに戻す代わりに、新しいコミットで変更を元に戻します。(公開されたブランチをリセットしないでくださいと考える人もいます。)これを行う方法については、この質問に対する他の回答を参照してください。

将来のために:

RogerPaladinのブランチのコミットの一部のみが必要な場合は、のcherry-pick代わりに使用することを検討してくださいmerge。または、RogerPaladinに連絡して、それらを別のブランチに移動し、新しいプルリクエストを送信します。


しかし、マージと彼の最初のコミットの間にたくさんのコミットがあります。したがって、マージコミットのように、自分自身のコミットと、その後の彼による別のコミットがあります。それは彼の本当に古いコミットにマージされたようです。
ウィル

ええ、それはマージされたコミットの祖先であるすべてのものにマージされます(まだコミットの祖先ではありません)。これによってリセットが妨げられることはありません。後でリベースを行わなかった場合、コミット自体が並べ替えられることはありません。
–PaŭloEbermann、2011

1
ええ、今、それは正しく見えます(奇妙なマージ自体は別として -これはネットワークグラフソフトウェアの不具合かもしれません)。:-)私は助けることができてうれしいです。
–PaŭloEbermann、2011

6
誰かが不正なコミットをプルし、後で同じ不正なコミットを含むプルリクエストを送信した場合、こっそりとリポに侵入した場合、これはおそらく問題になると思います。悪いコミットを元に戻す新しいコミットを作成する方が安全ではないでしょうか?そうすれば、悪いコミットが他のブランチ/フォークにプルされた場合、それらは他のブランチ/フォークへの別のプルによって効果的に削除されますか?私はこれを事実として述べているのではなく、これは私が本当だと思うかもしれないことであり、OPと同じ立場にあり、私のオプションを考慮して1時間ほど費やしました。
Myles McDonnell、

4
@この回答を受け入れないことをお勧めします。これはまだプッシュされていないコードの場合は問題ありません(その場合、これはより関連するSOの質問ですが、パブリックに共有されているコードの場合、履歴を書き換えるgitコマンドを実行します(この場合、reset --hard強制プッシュは非常に悪い習慣)以下の@errordeveloperによる回答は、履歴の書き換えや強制プッシュなしでこれを行う方法を示しています
asmeurer

34

引きが最後だったなら

git reset --hard HEAD~1

3
この指示に注意してください。実際には、1つのステップではなく2つのステップに戻ります。
szeitlin

1
@szeitlinどのようにして、1ステップではなく2ステップ戻ったのでしょうか。私はこのコメントが4年以上前に残されたことを知っていますが、それがどのように起こるかについての答えを誰かが知っているかどうか知りたいです。これは私にとって非常に重要です。ありがとう。
Haradzieniec 2016年

今は覚えていませんが、リセットしようとしたときに新しいコミットを行った場合に発生するのではないでしょうか。あなたがそれについて心配しているなら、私はダミーのレポでそれをテストします。
szeitlin

これは私にはうまくいきました。最近マージされたプルリクエストを削除しました。の後git reset --hard HEAD~1、私git push origin -fはリモートリポジトリを更新するために使用しました。ただし、これを行う前に注意してください。
Denis Oluka

24

2014年6月24日以降、PRを簡単にキャンセルすることができます(「プルリクエストを元に戻す」を参照))。

元に戻すボタンの紹介

[元に戻す]をクリックすると、GitHubのプルリクエストを簡単に元に戻すことができます。

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

元に戻された変更を使用して、新しいプルリクエストを作成するように求められます。

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

それはテストする必要がありますが、その復帰が使用する場合 -mか(マージをリバートする場合も同様)

しかし、アディルHラザはコメントに追加しました(2019年12月):

これは予想される動作であり、新しいブランチを作成し、この新しいブランチからへのPRを作成できますmaster
この方法で、将来、必要に応じて元に戻すことができますmaster。これは最も安全なオプションであり、を直接変更することはありません。


警告コライエムはコメントで次のよう指摘しています

元に戻した後、Gitブランチにいくつかの変更を加え、同じソース/宛先ブランチから新しいPRを作成したとします。
PRには新しい変更のみが表示されますが、元に戻す前の状態は何も表示されません

Korayemは、詳細について「Github:変更を元に戻した後無視される変更(git cherry-pickgit rebase」と呼んでいます。


私はこれを試しましたが、マスターでPRを取り消す代わりに新しいブランチを作成しましたか?
Грозный

奇妙な。その動作を説明するために、新しい質問をしてもらえますか?
VonC 2017年

これは予想される動作であり、新しいブランチを作成し、この新しいブランチからマスターへのPRを作成できます。この方法で、将来、必要に応じて元に戻すことができます。これは、マスターを直接変更するのではなく、最も安全なオプションです。
アディルH.ラザ

1
@ AdilH.Razaありがとうございます。見やすくするために、回答にコメントを含めました。
VonC、

1
@VonC指が、これはあまりにも多くの苦しみと時間の無駄から、世界中の開発者が保存されます交差
Korayem

8

削除したくないコミットを含むgithubプルリクエストを元に戻すには、次のコマンドを実行する必要があります。

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

コミットハッシュはプルリクエストをマージする前のコミットです。これにより、履歴内のコミットに影響を与えることなく、プルリクエストからすべてのコミットが削除されます。

これを見つける良い方法は、現在閉じられているプルリクエストに移動して、このフィールドを見つけることです。

プルリクエスト画像 プルリクエスト画像

を実行した後、次を実行しますgit reset

git push origin --force <branch name>

これにより、プルリクエストからのコミットの間にコミット履歴にペッパーされたブランチ内のコミットに影響を与えることなく、プルリクエストの前にブランチが元に戻ります。

編集:

プルリクエストで元に戻すボタンをクリックすると、ブランチに追加のコミットが作成されます。コミット解除またはマージ解除されません。つまり、元に戻すボタンを押した場合、新しいプルリクエストを開いてこのコードをすべて追加し直すことはできません。


クレイジーな復帰やチェリーピッキングを必要とせずに物事をまっすぐにするための素晴らしい方法
Cumulo Nimbus 2017

ありがとう!それが私がやろうとしていた計画でしたが、チェリーピックアウトへの約200回のコミットでした。
FluffySamurai

1

いつもこの場所を利用しています。

プルリクエストを元に戻す方法を探していて、ここにたどり着きました。

私はgit reset --hard「ずっと前に」しようとしていて、プルリクエストを行う前の状態に早送りし直していました。

ここを見るだけでなく、同僚にも何をするかを尋ねたところ、彼は通常は良い答えを出しました。上記の最初の答えの出力例を使用する:

git reset --hard 9271e6e

Gitでのほとんどのことと同様に、簡単ではない方法でそれを行っている場合は、おそらくそれが間違っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.