変更を保持したまま、選択したコミット ログ エントリを Git リポジトリから削除するにはどうすればよいですか?
質問
選択したコミット ログ エントリを線形コミット ツリーから削除して、エントリがコミット ログに表示されないようにしたいと考えています。
私のコミットツリーは次のようになります。
R--A--B--C--D--E--HEAD
B と C のエントリを削除してコミット ログに表示されないようにしたいのですが、A から D までの変更は保持する必要があります。おそらく単一のコミットを導入すると、B と C が BC になり、ツリーは次のようになります。
R--A--BC--D--E--HEAD
または、理想的には、A の後に直接 D が来ます。D' は、A から B、B から C、C から D への変化を表します。
R--A--D'--E--HEAD
これは可能でしょうか?「はい」の場合、どのようにして?
これはかなり新しいプロジェクトなので、現時点ではブランチがなく、マージもありません。
解決
git-rebase(1) まさにそれを行います。
$ git rebase -i HEAD~5
git awsome-ness [git rebase --interactive] には例が含まれています。
- 使用しないでください
git-rebase
パブリック (リモート) コミットについて。 - 作業ディレクトリがクリーンであることを確認してください (
commit
またはstash
現在の変更)。 - 上記のコマンドを実行します。それはあなたの
$EDITOR
. - 交換する
pick
前にC
そしてD
によるsquash
. 。CとDをBに融合させます。コミットを削除したい場合は、その行を削除するだけです。
迷った場合は、次のように入力してください。
$ git rebase --abort
他のヒント
# detach head and move to D commit
git checkout <SHA1-for-D>
# move HEAD to A, but leave the index and working tree as for D
git reset --soft <SHA1-for-A>
# Redo the D commit re-using the commit message, but now on top of A
git commit -C <SHA1-for-D>
# Re-apply everything from the old D onwards onto this new place
git rebase --onto HEAD <SHA1-for-D> master
ここで削除したいだけコミットIDを知っているIDをコミット特定を削除する方法です。
git rebase --onto commit-id^ commit-id
これは実際にコミットによって導入された変更を削除することに注意してください。
J.F.セバスチャンの答えに展開します:
あなたは簡単にあなたのコミットの歴史への変更のすべての種類を作るためにはgit-リベースを使用することができます。
あなたの$ EDITORで、次の取得--interactiveリベースgitのを実行した後:
pick 366eca1 This has a huge file
pick d975b30 delete foo
pick 121802a delete bar
# Rebase 57d0b28..121802a onto 57d0b28
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
あなたはコミットの順番を変更し、そのコミット削除する行を削除する行を移動することができます。それとも、コミットメッセージ(変更されたもの)、編集がコミット(上記コミットコミット前の)単一のコミットに(スカッシュ)結合するために2つのコミットをしてコマンドを追加、または言い替えることができます。
私はちょうどあなたが一人でコミットそのままにしておきたいということを意味選んだと思います。
(例はこちら からである)
あなたは非対話のあなたの例ではのBとCを削除することができてます:
git rebase --onto HEAD~5 HEAD~3 HEAD
や象徴、
git rebase --onto A C HEAD
BとCの変化がしない Dであろうことに留意されたいです。彼らはの。
消えてしまいますもう一つの方法は、
git rebase -i ad0389efc1a79b1f9c4dd6061dca6edc1d5bb78a (C's hash)
and
git push origin master -f
あなたはベースとしてそれを使用するハッシュを選択し、上記のコマンドは、それはインタラクティブなので、あなたはすべてのトップをつぶすことができます行う必要があります。のメッセージが(あなたがままにする必要がある最も古い)
私はこの新しいブランチがどのように見えるかと満足していることを確認することができますので、必要な変更をAのSHA1から別のブランチを作成し、チェリー選ぶことによって理解することは、このプロセスがはるかに安全かつ簡単に見つけます。その後、古い枝を削除して新しい名前を変更するのは簡単です。
git checkout <SHA1 of A>
git log #verify looks good
git checkout -b rework
git cherry-pick <SHA1 of D>
....
git log #verify looks good
git branch -D <oldbranch>
git branch -m rework <oldbranch>
ただ、すべての人の答えを収集:(PLZ gitの参考のためにそれを使用して新しいメートルのみ)
gitがコミットを削除するには、リベース
gitのログ
-first check from which commit you want to rebase
gitのリベース-i HEAD〜1
-Here i want to rebase on the second last commit- commit count starts from '1')
-this will open the command line editor (called vim editor i guess)
すると画面はこのようになります。
を追加しました新しい行を0c2236d選んます。
2a1cd65に2a1cd65..0c2236dを再配置(1つのコマンド)
#
コマンド:
P、コミット=使用を選ぶ
rは、=コミット使用言い替えるが、コミットメッセージを編集
E、編集=使用はコミットが、改正のための停止
S、スカッシュ=使用コミットが、前回のコミット
にメルドF、 "スカッシュ" のようなフィックスアップ=が、これはメッセージ
のログのコミット破棄X、EXEC =実行コマンド(行の残りの部分)を使用してシェル
D
をコミット削除=ドロップ#
これらの行は、再注文することができます。彼らは、上から下に実行されます。
#
あなたはCOMMITここで行を削除すると失われます。
#
あなたはすべてのものを削除する場合は、しかし、リベースが中止されます。
#
空のコミットが~~
コメントアウトされていることに注意してください〜
〜
〜
〜
〜
〜
〜
〜
〜
ここであなたの必要性に従って(コミットなどを取り除くために、すなわち「ドロップ」の上に記載されているコマンドを使用して)最初の行を変更 「:X」エディタを保存して終了する(これが唯一のvimエディタのためである)
一度編集プレスを行ってそして
Gitのプッシュ
その上映の問題は、あなたが強制的にリモートに変更をプッシュする必要がある場合(その非常にCRITICAL:あなたはチームで作業している場合は力のプッシュいけない)
起源-f Gitのプッシュ
あなたは、このためのgitチェリーピックを使用することができます。 「チェリーピックは、」今のブランチあなたの上にコミット適用されます。
、その後行う
git rebase --hard <SHA1 of A>
そしてDを適用すると、Eがコミットします。
git cherry-pick <SHA1 of D>
git cherry-pick <SHA1 of E>
これは、Bをスキップして、Cコミットします。 YMMVので、DがBなしブランチにコミット適用することは不可能かもしれないと言ってます。