git reset --mixed、--soft、--hard の違いは何ですか? 質問する

git reset --mixed、--soft、--hard の違いは何ですか? 質問する

コミットを分割したいのですが、どのリセット オプションを使用すればよいかわかりません。

私はそのページを見ていた簡単に言うと、「git reset」は何をしますか?しかし、git インデックスやステージング領域が何であるかを本当に理解していないため、説明が役に立たないことに気付きました。

--mixedまた、その回答では、と の使用例は--soft同じに見えます (修正して再コミットする場合)。 誰か、これをさらに詳しく説明してもらえませんか? おそらく がオプションであることはわかっていますが、なぜ なのか--mixedを知りたいです。最後に、 はどうでしょうか?--hard

3 つのオプションを選択する場合のワークフロー例を教えていただけますか?

ベストアンサー1

リポジトリ内のファイルを変更すると、変更は最初はステージングされていません。コミットするには、 を使用してステージング、つまりインデックスに追加する必要がありますgit add。コミットすると、コミットされる変更はインデックスに追加された変更です。1

git reset少なくとも、現在のブランチ2--mixedが指している場所が変更されます。との違いは--soft、インデックスも変更されるかどうかです。したがって、masterこの一連のコミットでブランチにいる場合:

- A - B - C (master)

HEAD(現在のコミット) はC3で、インデックスは一致しますC( で変更をステージングしていないと仮定しますgit add)。

を実行するとgit reset --soft Bmaster(したがってHEAD間接的に)は を指すようになりますBが、インデックスにはまだ からの変更が残っているのでCgit statusステージング済みとして表示されます。そのため、git commitこの時点で を実行すると、 と同じ変更を含む新しいコミットが取得されますC

(リセット前にステージングされた変更があった場合、それらはインデックス内に残り、git commitからの変更に加えてそれらの変更がコミットされますC。)


さて、ここからまた始めましょう:

- A - B - C (master)

それでは、 を実行してみましょうgit reset --mixed B。 (--mixedはデフォルトのオプションなので、 と同等ですgit reset B)。 もう一度、masterHEADは を指しますBが、今回はインデックスも と一致するように変更されますBgit commitこの時点で を実行しても、インデックスが と一致するため何も起こりませんHEAD。 作業ディレクトリに変更が残っていますが、インデックスにないため、ではgit statusステージングされていないものとして表示されます。 変更をコミットするには、 を実行しgit addてから、通常どおりコミットします。

(今回は、リセット前に変更をステージングしていた場合、それらの変更はインデックスから削除されますが、ファイル自体には行われた変更が引き続き含まれます。)


最後に、--hardは と同じです--mixed(HEADと のインデックスを変更します)。ただし、 は--hard作業ディレクトリも変更します。 でCを実行するとgit reset --hard B、 で追加された変更と、 で行ったコミットされていない変更がすべてC削除され、作業コピー内のファイルはコミット と一致します。この方法では変更が永久に失われる可能性があるため、ハードリセットを行う前に必ず を実行して、作業ディレクトリがクリーンであること、またはコミットされていない変更を失っても問題がないことを確認する必要があります。Bgit 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は を指しmastermasterは を指しているためですC。現在のブランチでコミットを追加または削除するたびに、 を参照するコミットがHEAD変更されるのは、コミットHEAD自体が変更されたからではなく、 を指しているブランチがHEADそのコミットを指すように更新されたためです。

おすすめ記事