git 履歴から特定のリビジョンを削除するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/37219

  •  09-06-2019
  •  | 
  •  

質問

git 履歴が次のようになっているとします。

1 2 3 4 5

1 ~ 5 は別のリビジョンです。1、2、4、5 を維持したまま 3 を削除する必要があります。これはどうすればできるのでしょうか?

削除するリビジョンの後に何百ものリビジョンがある場合、効率的な方法はありますか?

役に立ちましたか?

解決

リビジョン 3 と 4 を 1 つのリビジョンに結合するには、git rebase を使用します。リビジョン 3 の変更を削除する場合は、対話型リベース モードで edit コマンドを使用する必要があります。変更を 1 つのリビジョンに結合する場合は、スカッシュを使用します。

私はこのスカッシュ手法をうまく使用してきましたが、これまでにリビジョンを削除する必要があったことはありません。「コミットの分割」にある git-rebase ドキュメントを参照すると、それを理解するための十分なアイデアが得られるはずです。(あるいは他の誰かが知っているかもしれません)。

から git ドキュメント:

そのまま保持したい最も古いコミットから開始します。

git rebase -i <after-this-commit>

エディターが起動され、現在のブランチ内の、指定されたコミットの後にあるすべてのコミット (マージ コミットは無視します) が表示されます。このリスト内のコミットは好きなように並べ替えたり、削除したりできます。リストはほぼ次のようになります。

pick deadbee The oneline of this commit
pick fa1afe1 The oneline of the next commit
...

この 1 行の説明は、純粋に楽しみを目的としたものです。git-rebase はそれらを参照せず、コミット名 (この例では「deadbee」と「fa1afe1」) を参照するため、名前を削除または編集しないでください。

コマンド「pick」をコマンド「edit」に置き換えることで、そのコミットの適用後に停止するように git-rebase に指示できるため、ファイルやコミット メッセージを編集し、コミットを修正してリベースを続行できるようになります。

2 つ以上のコミットを 1 つにまとめる場合は、2 つ目以降のコミットのコマンド「pick」を「squash」に置き換えます。コミットの作成者が異なる場合、潰されたコミットは最初のコミットの作成者に帰属します。

他のヒント

特定のファイルを非対話的に削除する方法は次のとおりです。 <commit-id>, だけを知っている、 <commit-id> 削除したいもの:

git rebase --onto <commit-id>^ <commit-id> HEAD

あたり このコメント (そして、これが真実であることを確認しました)、radoの答えは非常に近いですが、gitは分離されたヘッド状態のままになります。代わりに、削除してください HEAD これを使用して削除します <commit-id> あなたがいるブランチから:

git rebase --onto <commit-id>^ <commit-id>

前に述べたように 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) から:

範囲のコミットは、Rebaseで削除することもできます。次の状況がある場合:

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の一部であってはならない場合に役立ちます。to-ontoとパラメーターへの引数は、有効なコミット違反である可能性があることに注意してください。

リビジョン 3 で行われた変更を削除したいだけの場合は、git revert を使用するとよいでしょう。

Git revert は単に、元に戻すリビジョン内のすべての変更を元に戻す変更を含む新しいリビジョンを作成します。

これは、不要なコミットと、それらの変更を削除するコミットの両方に関する情報を保持することを意味します。

リバートは基本的に単なる標準的なコミットであるため、その間に誰かがリポジトリからプルした可能性がある場合、これはおそらくはるかにフレンドリーです。

これまでの回答はすべて、後続の懸念に対処していません。

削除される後に何百もの改訂がある場合、効率的な方法はありますか?

手順は次のとおりですが、参考までに、次のような履歴があると仮定します。

[master] -> [hundreds-of-commits-including-merges] -> [C] -> [R] -> [B]

C:削除するコミットの直後のコミット (クリーン)

R:削除するコミット

B:削除するコミットの直前のコミット (ベース)

「何百ものリビジョン」という制約があるため、次の前提条件を仮定します。

  1. 存在しないことを望む恥ずかしいコミットがあります
  2. その恥ずかしいコミットに実際に依存する後続のコミットはゼロです (元に戻すときの競合はゼロ)
  3. 介在する何百ものコミットの「コミッター」として自分がリストされることは気にしません (「作成者」は保持されます)。
  4. リポジトリを共有したことがない
    • あるいは、あなたは実際に、そのコミットを含む履歴のクローンを作成したすべての人々に対して、あなたの新しい履歴を使用するよう説得するのに十分な影響力を持っています。
    • あなたも 気にしないでください について 歴史を書き換える

これはかなり制限的な制約セットですが、この特殊なケースで実際に機能する興味深い答えがあります。

手順は次のとおりです。

  1. git branch base B
  2. git branch remove-me R
  3. git branch save
  4. git rebase --preserve-merges --onto base remove-me

本当に競合がない場合は、これ以上中断することなく続行する必要があります。競合がある場合は、それを解決して、 rebase --continue あるいは、恥ずかしさを抱えて生きていくことを決意するか、 rebase --abort.

今、あなたはオンになっているはずです master コミットがなくなったもの R 初期化。の save 和解したい場合に備えて、分岐は以前の場所を指します。

他の人の転送をあなたの新しい履歴にどのように配置するかはあなた次第です。知っておく必要があります stash, reset --hard, 、 そして cherry-pick. 。そして、あなたは削除することができます base, remove-me, 、 そして save

ここでは、私が直面したシナリオと、それをどのように解決したかを示します。

[branch-a]

[Hundreds of commits] -> [R] -> [I]

ここ R 削除する必要があったコミットです。 I 後に続く単一のコミットです R

コミットを元に戻してそれらをまとめました

git revert [commit id of R]
git rebase -i HEAD~3

インタラクティブなリベース中に、最後の 2 つのコミットがスカッシュされます。

私も同様の状況に陥りました。以下のコマンドを使用して対話型リベースを使用し、選択中に 3 番目のコミットをドロップします。

git rebase -i remote/branch

rado と kareem の答えは私にとっては何も起こりません (「現在のブランチは最新です。」というメッセージのみが表示されます)。おそらくこれは、「^」記号が Windows コンソールで機能しないために発生します。ただし、によると、 これ コメントで「^」を「~1」に置き換えると問題は解決します。

git rebase --onto <commit-id>^ <commit-id>

git リポジトリから古いコミット履歴を削除するには:

最初に cmd の下で実行します

rm -rf .git

-- 現在のリポジトリから再作成します

git init                                                                           
git add .                                                  
git commit -m "first commit"

-- Github リモート リポジトリにプッシュします

git remote add origin git@github.com<your git mail>   
git push -u --force origin master
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top