私は自分のマスターブランチの「中間」コミットをポップアップしてゴミ箱に捨てる必要があります。どうすればできますか?


94

たとえば、次のマスターブランチでは、コミットaf5c7bf16e6f04321f966b4231371b21475bc4daだけを破棄する必要があります。これは、前のリベースによる2番目です。

commit 60b413512e616997c8b929012cf9ca56bf5c9113
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Tue Apr 12 23:50:15 2011 +0200

    add generic config/initializers/omniauth.example.rb

commit af5c7bf16e6f04321f966b4231371b21475bc4da
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Fri Apr 22 00:15:50 2011 +0200

    show github user info if logged

commit e6523efada4d75084e81971c4dc2aec621d45530
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Fri Apr 22 17:20:48 2011 +0200

    add multiple .container at blueprint layout

commit 414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Thu Apr 21 19:55:57 2011 +0200

    add %h1 Fantastic Logo + .right for 'Sign in with Github'

私はマンテインする必要があります

  • 最初のコミット60b413512e616997c8b929012cf9ca56bf5c9113、
  • 3番目のコミットe6523efada4d75084e81971c4dc2aec621d45530および
  • 最後のコミット414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22

「捨てる」だけ2番目のコミットaf5c7bf16e6f04321f966b4231371b21475bc4da

どうやってやるの?事前にありがとうルカ

回答:


98

リベースまたは元に戻すには、オプションです。リベースは実際には履歴からコミットを削除するため、2番目のコミットは存在しなかったように見えます。これは、masterブランチを他のリポジトリにプッシュした場合に問題になります。この場合、リベースの後にプッシュしようとすると、gitは非早送りマージ拒否エラーを表示します。

ブランチが他のリポジトリと共有されている場合、Revertは正しいソリューションです。git revert af5c7bf16af5c7bf16が導入した変更を単に逆にする新しいコミットを作成します。このようにして、履歴は書き直されず、間違いの明確な記録が維持され、他のリポジトリはプッシュを受け入れます。

消去する良い方法git rebase -i <commit>^ は次のとおりです。削除するコミットの直前のコミットに移動します。対話型エディターは、その時点までのすべてのコミットのリストを表示します。ピック、スカッシュなどを実行できます。この場合、消去するコミットの行を削除して、ファイルを保存します。リベースはその作業を終了します。


2
私がリベースを選択する場合、リベースするための正しいコミットは何ですか?私は2番目だけを落とす必要があります...
ルカG.ソアーヴェ

@ BBJ3ミパディの答えを見てください。
Prajwal Dhatwalia

32

リベースがオプションの場合は、リベースしてドロップするだけです。

$ git rebase -i 414ceffc^

リベースがオプションでない場合は、元に戻すことができます。

$ git revert af5c7bf16

以前の4番目のコミットである「git rebase 414ceffc」を取得した場合、3番目のe6523と最初の60b41も失うことはありませんか?
Luca G. Soave

3
@Luca G. Soave:(対話モードでgit rebase実行rebaseしてそのエントリを削除することにより)コミットを削除するように明確に指示した場合にのみ、コミットを「失う」。
mipadi

mipadiに感謝します。たとえあなたが2人だったとしても、広範な説明のためにJCottonに基本的に投票しました。同じことを言いました...もう一度ありがとう。
Luca G. Soave

29

元の回答がここで受けたすべての信用にもかかわらず、私はそれらが質問に満足に答えることができませんでした。コミット、または履歴の途中からコミットのコレクションを削除する必要がある状況に気づいた場合、これは私が提案するものです:

  • すべてのコミットを含むブランチの先頭から新しいブランチを作成し、それに切り替えます。
  • 新しいブランチを、新しいベースを開始するポイントに戻します。
  • 次に、(ここが重要な点です)元のブランチから新しいコミットに実際に適用したい後続のコミットを選択し、不要になったコミット(つまり、削除するコミット)をスキップします。
  • 必要に応じて、元のブランチの名前を古いコードであることを示す名前に変更してから、元のブランチの名前を新しいブランチの名前に変更します。
  • 最後に、変更をリモートリポジトリにプッシュします(使用している場合)。おそらく「強制プッシュ」を使用する必要があります。共同編集者がリビジョンの取得に問題を抱えている場合、リモートソースから再度リポジトリを複製するのが最も簡単です。いずれにせよ、とにかくあなたが歴史の真ん中からコミットを引き抜いているなら、あなたは彼らと話したいと思うでしょう!

チェリーピッキングに関する情報:gitでコミットをチェリーピッキングする とはどういう意味ですか?

Tortoise Gitを使ってこれを実行する方法をいくつか紹介します(私が行ったように)。これらの種類の操作には、GUIユーティリティを使用する方が間違いなく簡単です。 TortoiseGitを使用したチェリーピック


6
これが一番の答えだったはずです!
MadOgre 2017

チェリーピックを使用する良い方法です。このソリューションは、複数のコミットを「スキップ」する場合にさらに優れています。
ジョニーウィラー

元の質問には実際には対応していません。提案されたソリューションは機能しますが、かなり時間がかかり/厄介であり、IMOは何のメリットももたらしません。ブランチが既にプッシュされている(そして実際に使用されている)場合、リバート戦略がおそらく答えです。そうでない場合は、インタラクティブにリベースし、問題のコミットを削除するのが私が使用する方法です。プッシュされたが誰も使用していないことがわかっいる場合は、リベースの後に強制プッシュを実行することで問題を回避できます。
raduw
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.