git履歴からマージコミットを削除


97

私のGit履歴は次のようになります。

Gitの履歴

紫色のコミットを1つにまとめたいのですが。コミットログで二度とそれらを見たくありません。

私はを試みましたが、青いブランチ(画像を参照)にあるにgit rebase -i 1もかかわらず1、紫色のブランチですべてのコミットが表示されます。

紫色のブランチを(コミットログから)完全に削除するにはどうすればよいですか?


あなたのリポジトリは、他の人がそこから引っ張ったどこかに押し込まれていますか?
シュライス2013

両方のブランチは純粋にローカルです。
Benjamin Toueg 2013

回答:


100

くださいgit rebase -i <sha before the branches diverged>これはあなたがコミットマージを削除することができます、あなたが望んでいたとしてログには、1つの行になります。また、不要になったコミットを削除することもできます。リベースが機能しなかった理由は、十分に戻ってこなかったためです。

警告:これを実行している履歴を書き換えています。リモートリポジトリにプッシュされた変更でこれを行うと、問題が発生します。これはローカルのコミットでのみ行うことをお勧めします。


4
ブランチが分岐する前にshaを選択した場合でも、紫色のブランチのすべてのコミットが表示されます-_-
Benjamin Toueg 2013

1
ええ、あなたは付属のエディタでそれらを削除するとgit rebase、それらは削除されます。
シュライス2013

4
コミットを削除すると、マージのすべての変更が失われました。しかし、ソフトリセットを実行したところ、希望どおりのものができました(順序が最初の期待と一致しません)。
Benjamin Toueg 2013

2
この答えは詳細に不完全です、どのブランチからリベースを開始しますか?
grgry

3
コミットを「削除」したくないのはかなり確実です。「削除」はリベースのオプションではありませんが、削除はオプションです。コミットを削除すると、それが導入した変更が失われます。コミットを押しつぶしたい。
thecoshman 2017年

69

元の状態のリポジトリから始める

元のレポ履歴

マージコミットを削除し、メインラインでブランチを単一のコミットにつぶすには

押しつぶされたコミット、マージコミットなし

次のコマンドを使用します(5と1を対応するコミットのSHAで置き換えます)。

git checkout 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git rebase HEAD master

マージコミットを保持しながらブランチコミットを1つに潰すには:

押しつぶされたコミット、保持されたマージコミット

次のコマンドを使用します(5、1、Cを対応するコミットのSHAで置き換えます)。

git checkout -b tempbranch 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git checkout C
git merge --no-ff tempbranch
git rebase HEAD master

マージコミットを削除し、ブランチからの個別のコミットで置き換えるには

ブランチがメインラインに移動、マージコミットなし

ただ行う(5を対応するコミットのSHAで置き換える):

git rebase 5 master

そして最後に、ブランチを完全に削除するには

完全に削除されたブランチ

次のコマンドを使用します(CおよびDを対応するコミットのSHAで置き換えます)。

git rebase --onto C D~ master

git rebase 5 master場合、なぜそれが"ABC 1 2 3 4 5 D ..."ためではないでしょうか?
ロイ・

1
このコマンドは、master共通していないコミットを取り、5それらをの上に配置し5ます。でのコミットCはの系統の一部ではなく5、の上に移動される最初のものです5
アレンルーチェ

2
:あなたは「ABC 1 2 3 4 5 D ...」あなたが行うことができますで終わるしたい場合git rebase C 5; git rebase 5 master
アレンルーチェ

16

これに取り組む方法は2つあります。

解決策1:パープルコミットを削除し、履歴を保持する(ロールバックする場合)

git revert -m 1 <SHA of merge>

-m 1 選択する親行を指定します

パープルコミットは引き続き履歴に残りますが、元に戻したため、それらのコミットのコードは表示されません。


解決策2:紫色のコミットを完全に削除します(リポジトリが共有されている場合、破壊的な変更)

git rebase -i <SHA before branching out>

紫色のコミットに対応する削除(行の削除)。

マージ後にコミットが行われなかった場合、これはそれほど難しくありません。追加のコミットにより、中の競合の可能性が高まりrevert/rebaseます。


これは正しく聞こえません。元の投稿者が紫のコミットで最初に何をしたかったのかを判断するのが難しいという事実は別として、マージを元に戻すと、問題ありません。そのコミットからの変更のリバースパッチを実行し、次のように追加します。別のコミット、紫色のコミットをキャンセルします。みたい1 - 1 = 0です。しかし、紫色のコミットをリベースすると、それもリベースしない限り、元に戻されたパッチが残ります。そうでない場合は、-1ではなく履歴に適用するようなものな0ので、不要な変更を残しておきます。

@Cupcakeは、2つの別々の回答を提供しました。混乱を少なくするために答えを修正しました:P
prem

これはOPが求めているものではありません。彼は変更を維持したいが、ログからノイズを取り除きます。そのため、彼はコミットを押しつぶす必要があり、削除すると変更が削除されます。
thecoshman 2017年

確かに、元の質問は言い換えられているようです。この答えはOPの問題ではありません。
プレム

16

マージコミットを削除するには

あなたがしたいのがマージコミット(2)を削除してそれが決して起こらなかったようなものである場合、コマンドは次のようになります

git rebase --onto <sha of 1> <sha of 2> <blue branch>

そして今、紫色のブランチは青のコミットログにはまったく含まれておらず、再び2つの別々のブランチがあります。その後、パープルを個別に押しつぶし、マージコミットを行わずに、必要な他の操作を行うことができます。


すべての答えの中で、これは最も簡単で、最も簡単に実行できることです。ありがとうございました。
ロシャンボ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.