web-dev-qa-db-ja.com

変更を保持しながら、選択したコミットログエントリを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

これは可能ですか?はいの場合、どのように?

これはかなり新しいプロジェクトであるため、現時点ではブランチが存在しないため、マージも行われません。

235
xk0der

git-rebase(1) はまさにそれを行います。

$ git rebase -i HEAD~5

git awsome-ness [git rebase --interactive] の例が含まれています。

  1. パブリック(リモート)コミットではgit-rebaseを使用しないでください。
  2. 作業ディレクトリがクリーンであることを確認してください(commitまたはstash現在の変更)。
  3. 上記のコマンドを実行します。 $EDITORが起動します。
  4. pickCの前のDsquashに置き換えます。 CとDをBにマージします。コミットを削除する場合は、その行を削除します。

紛失した場合は、次を入力します。

$ git rebase --abort  
267
jfs
# 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
72
CB Bailey

削除するコミットIDのみを知っている特定のコミットIDを削除する方法を次に示します。

git rebase --onto commit-id^ commit-id

これにより、コミットによって導入された変更が実際に削除されることに注意してください。

39
rado

J.F.セバスチャンの答えを拡張するには:

Git-rebaseを使用して、コミット履歴にあらゆる種類の変更を簡単に加えることができます。

Git rebase --interactiveを実行すると、$ EDITORに以下が表示されます。

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つのコミットを1つのコミットに結合(スカッシュ)するコマンド(前のコミットは上記のコミット)、コミットの編集(変更内容)、またはコミットメッセージの書き換えコマンドを追加できます。

ピックとは、そのコミットをそのままにしておきたいという意味です。

(例は here から)

19
idbrii

次のようにして、非対話的にremove BとCの例を使用できます。

git rebase --onto HEAD~5 HEAD~3 HEAD

または象徴的に、

git rebase --onto A C HEAD

BとCの変更はnotではDになります。それらはgoneになります。

14
Head

もう一つの方法、

git rebase -i ad0389efc1a79b1f9c4dd6061dca6edc1d5bb78a (C's hash)
and
git Push Origin master  -f

ベースとして使用するハッシュを選択します。上記のコマンドは、すべてのtopメッセージを押しつぶすことができるように対話型にする必要があります(最も古いものを残す必要があります)

3
resultsway

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>
2
Eric Woodruff

すべての人々の答えを収集しただけです:(git plzの新しいmは参照のためにのみ使用します)

コミットを削除するgit rebase

git log

-first check from which commit you want to rebase

git rebase -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)

次に、画面は次のようになります。

pick 0c2236d新しい行を追加しました。

2a1cd65..0c2236dを2a1cd65にリベースします(1コマンド)

コマンド:

p、選択=コミットを使用

r、reword =コミットを使用するが、コミットメッセージを編集する

e、編集=コミットを使用、ただし修正のため停止

s、squash =コミットを使用しますが、前のコミットにマージします

f、fixup = "squash"に似ていますが、このコミットのログメッセージを破棄します

x、exec =シェルを使用してコマンド(行の残り)を実行

d、ドロップ=コミットの削除

これらの行は並べ替えることができます。それらは上から下に実行されます。

ここで行を削除すると、コミットが失われます。

ただし、すべてを削除すると、リベースは中止されます。

空のコミットはコメントアウトされていることに注意してください〜〜









ここで、必要に応じて最初の行を変更します(上記のコマンドを使用して、「コミット」を削除するために「ドロップ」など)。編集が完了したら、「:x」を押してエディターを保存して終了します(これはvimエディター専用です)

その後

git Push

その問題を示している場合は、変更を強制的にリモートにプッシュする必要があります(非常に重要:チームで作業している場合、プッシュを強制しないでください)

git Push -f Origin

0
Shrinath Kopare