gitの履歴が次のようになっているとします。
1 2 3 4 5
1–5は個別のリビジョンです。1、2、4、5を維持したまま3を削除する必要があります。これを行うにはどうすればよいですか?
削除するリビジョンの後に何百ものリビジョンがある場合、効率的な方法はありますか?
git rebase --onto 2 3 HEAD
ほぼ3とHEADの間のコミットで2にリベースすることを意味します(HEADはオプション、この場合は5)
gitの履歴が次のようになっているとします。
1 2 3 4 5
1–5は個別のリビジョンです。1、2、4、5を維持したまま3を削除する必要があります。これを行うにはどうすればよいですか?
削除するリビジョンの後に何百ものリビジョンがある場合、効率的な方法はありますか?
git rebase --onto 2 3 HEAD
ほぼ3とHEADの間のコミットで2にリベースすることを意味します(HEADはオプション、この場合は5)
回答:
リビジョン3と4を1つのリビジョンに結合するには、git rebaseを使用できます。リビジョン3の変更を削除する場合は、インタラクティブリベースモードで編集コマンドを使用する必要があります。変更を1つのリビジョンに結合する場合は、スカッシュを使用します。
私はこのスカッシュテクニックをうまく使用しましたが、以前にリビジョンを削除する必要はありませんでした。「Splitting commits」の下にあるgit-rebaseのドキュメントは、それを理解するのに十分なアイデアを提供してくれるはずです。(または他の誰かが知っているかもしれません)。
gitドキュメントから:
そのまま保持したい最も古いコミットから始めます。
git rebase -i <after-this-commit>
エディターは、現在のブランチ(マージコミットは無視)内のすべてのコミットで起動されます。これらのコミットは、指定されたコミットの後に来ます。このリストのコミットを思い通りに並べ替えたり、削除したりできます。リストは多かれ少なかれこのように見えます:
pickdeadbeeこのコミットの1行 pick fa1afe1次のコミットの1行 ...onelineの説明は、純粋にあなたの喜びのためのものです。git-rebaseはそれらを参照せず、コミット名(この例では「deadbee」と「fa1afe1」)を参照するため、名前を削除または編集しないでください。
コマンド「pick」をコマンド「edit」に置き換えることで、そのコミットの適用後に停止するようにgit-rebaseに指示できるため、ファイルやコミットメッセージを編集し、コミットを修正して、リベースを続行できます。
2つ以上のコミットを1つにまとめたい場合は、2回目以降のコミットの「pick」コマンドを「squash」に置き換えます。コミットの作成者が異なる場合、つぶされたコミットは最初のコミットの作成者に帰属します。
パーこのコメント(と私はこれが真実であることを確認)、ラドーの答えは非常に近いですが、葉は切り離さヘッド状態ではgit。代わりに、HEAD
これを削除<commit-id>
して使用して、現在のブランチから削除します。
git rebase --onto <commit-id>^ <commit-id>
^
ように変更し~1
ます。
--strategy-option theirs
て、最後に再実行してください。
以下は、非対話的に特定のを削除する方法です。削除するの<commit-id>
は自分だけ<commit-id>
です。
git rebase --onto <commit-id>^ <commit-id> HEAD
HEAD
頭が外れないように、@ kareemの省略の回答を参照してください。
前述のように、git-rebase(1)はあなたの友達です。コミットがmaster
ブランチにあると想定すると、次のようになります。
git rebase --onto master~3 master~2 master
前:
1---2---3---4---5 master
後:
1---2---4'---5' master
git-rebase(1)から:
一連のコミットはリベースで削除することもできます。次のような状況の場合:
E---F---G---H---I---J topicA
次にコマンド
git rebase --onto topicA~5 topicA~3 topicA
コミットFとGが削除されます。
E---H'---I'---J' topicA
これは、FとGに何らかの欠陥がある場合、またはtopicAの一部ではない場合に役立ちます。--ontoへの引数とパラメーターは、有効な任意のcommit-ishにすることができます。
--onto master~3 master~1
か?
MERGE CONFLICT
エラー。私はstackoverflow.com/questions/2938301/remove-specific-commitに記載されているシナリオを使用しましたが、その例では2番目のコミットを削除できません。
リビジョン3で行った変更を削除するだけの場合は、git revertを使用できます。
Git revertは、元に戻すリビジョンのすべての変更を取り消す変更を含む新しいリビジョンを作成するだけです。
これは、不要なコミットとそれらの変更を削除するコミットの両方に関する情報を保持することを意味します。
元に戻す操作は基本的に標準のコミットに過ぎないので、誰かがあなたのリポジトリからその間引っ張ってきたとしたら、これはおそらくもっと友好的です。
これまでのすべての回答は、末尾の懸念に対処していません。
削除するリビジョンの後に何百ものリビジョンがある場合、効率的な方法はありますか?
手順は次のとおりですが、参考のために、次の履歴を想定します。
[master] -> [hundreds-of-commits-including-merges] -> [C] -> [R] -> [B]
C:削除するコミットの直後にコミット(クリーン)
R:削除するコミット
B:削除するコミットの直前のコミット(ベース)
「何百もの改訂」制約のため、私は次の前提条件を想定しています。
これはかなり制限的な制約のセットですが、このコーナーケースで実際に機能する興味深い答えがあります。
手順は次のとおりです。
git branch base B
git branch remove-me R
git branch save
git rebase --preserve-merges --onto base remove-me
本当に競合がない場合は、これ以上の中断はありません。衝突がある場合は、それらを解決するか、rebase --continue
または恥ずかしさやrebase --abort
。
これでmaster
、コミットRがなくなったはずです。save
あなたが調整したい場合には、前にいた場所への分岐点。
他の全員の新しい履歴への転送をどのように手配するかはあなた次第です。あなたは精通する必要がありますstash
、reset --hard
とcherry-pick
。そして、あなたは削除することができbase
、remove-me
およびsave
枝を