コミットを分割したいのですが、どのリセット オプションを使用すればよいかわかりません。
私はそのページを見ていた簡単に言うと、「git reset」は何をしますか?しかし、git インデックスやステージング領域が何であるかを本当に理解していないため、説明が役に立たないことに気付きました。
--mixed
また、その回答では、と の使用例は--soft
同じに見えます (修正して再コミットする場合)。 誰か、これをさらに詳しく説明してもらえませんか? おそらく がオプションであることはわかっていますが、なぜ なのか--mixed
を知りたいです。最後に、 はどうでしょうか?--hard
3 つのオプションを選択する場合のワークフロー例を教えていただけますか?
ベストアンサー1
リポジトリ内のファイルを変更すると、変更は最初はステージングされていません。コミットするには、 を使用してステージング、つまりインデックスに追加する必要がありますgit add
。コミットすると、コミットされる変更はインデックスに追加された変更です。1
git reset
少なくとも、現在のブランチ2--mixed
が指している場所が変更されます。との違いは--soft
、インデックスも変更されるかどうかです。したがって、master
この一連のコミットでブランチにいる場合:
- A - B - C (master)
HEAD
(現在のコミット) はC
3で、インデックスは一致しますC
( で変更をステージングしていないと仮定しますgit add
)。
を実行するとgit reset --soft B
、master
(したがってHEAD
間接的に)は を指すようになりますB
が、インデックスにはまだ からの変更が残っているのでC
、git status
ステージング済みとして表示されます。そのため、git commit
この時点で を実行すると、 と同じ変更を含む新しいコミットが取得されますC
。
(リセット前にステージングされた変更があった場合、それらはインデックス内に残り、git commit
からの変更に加えてそれらの変更がコミットされますC
。)
さて、ここからまた始めましょう:
- A - B - C (master)
それでは、 を実行してみましょうgit reset --mixed B
。 (--mixed
はデフォルトのオプションなので、 と同等ですgit reset B
)。 もう一度、master
とHEAD
は を指しますB
が、今回はインデックスも と一致するように変更されますB
。git commit
この時点で を実行しても、インデックスが と一致するため何も起こりませんHEAD
。 作業ディレクトリに変更が残っていますが、インデックスにないため、ではgit status
ステージングされていないものとして表示されます。 変更をコミットするには、 を実行しgit add
てから、通常どおりコミットします。
(今回は、リセット前に変更をステージングしていた場合、それらの変更はインデックスから削除されますが、ファイル自体には行われた変更が引き続き含まれます。)
最後に、--hard
は と同じです--mixed
(HEAD
と のインデックスを変更します)。ただし、 は--hard
作業ディレクトリも変更します。 でC
を実行するとgit reset --hard B
、 で追加された変更と、 で行ったコミットされていない変更がすべてC
削除され、作業コピー内のファイルはコミット と一致します。この方法では変更が永久に失われる可能性があるため、ハードリセットを行う前に必ず を実行して、作業ディレクトリがクリーンであること、またはコミットされていない変更を失っても問題がないことを確認する必要があります。B
git status
上記の各ケースでは、B
リセットするコミット ( ) を指定しました。コミットを指定しない場合は、HEAD
デフォルトとして が使用されます。git reset --soft
コミットを指定しない場合は何も行われません (現在のブランチが既に指していた場所を指すようになります) が、他の 2 つのモードでは役立ちます。git reset --mixed
(または単にgit reset
) は、現在のコミットと一致するようにインデックスを更新します。これにより、追加されたがコミットされていない変更がステージング解除されます。git reset --hard
は同じことに加え、作業ディレクトリ内のすべての変更が削除されるため、すべてのファイルが現在のブランチの最新のコミットと一致するようになります。(繰り返しますが、これらの変更は永久に失われるため、ハードリセットを行うときは注意が必要です。)
1インデックスは「ステージング領域」とも呼ばれます。リポジトリ内のすべてのファイルの別のコピーと考えることができます。ブランチがチェックアウトされると、インデックスが更新され、そのブランチのすべてのファイルがそのブランチの内容と一致するようになります。ファイルをチェックアウトすると、git add
そのファイルに加えた変更がすべてインデックスにコピーされ、チェックアウトすると、git commit
インデックスの内容がコミットに変換され、現在のブランチに追加されます。
2 HEAD
は、Git が現在チェックアウトされているコミットを参照する方法です。HEAD
(ほとんどの場合) 現在のブランチと呼ばれる特定のブランチを指し、そのブランチは特定のコミットを指します。
3HEAD
は を指しmaster
、master
は を指しているためですC
。現在のブランチでコミットを追加または削除するたびに、 を参照するコミットがHEAD
変更されるのは、コミットHEAD
自体が変更されたからではなく、 を指しているブランチがHEAD
そのコミットを指すように更新されたためです。