reset
とcheckout
の使用法はほとんどの場合異なりますが、これら2つの間にどのような違いがあるのかわかりません。
基本的なcheckout
が実行できることを実行するために--hard
オプションを追加することを気にしない人がおそらく1人または誰もいないでしょう。
たぶん、あなたが歴史を見る方法に違いがありますか?
この回答は、主に前の質問に対する私の回答から引用されています: 平易な英語でのgitリセット 。
2つは非常に異なります。インデックスと作業ツリーの状態は同じになりますが、結果の履歴と現在のブランチは同じではありません。
マスターブランチが現在チェックアウトされている状態で、履歴が次のようになっているとします。
- A - B - C (HEAD, master)
git reset --hard B
を実行します。あなたはこれを得るでしょう:
- A - B (HEAD, master) # - C is still here, but there's no
# branch pointing to it anymore
--mixed
または--soft
も使用すると、実際にその効果が得られます。唯一の違いは、作業ツリーとインデックスに何が起こるかです。 --hard
の場合、作業ツリーとインデックスはB
と一致します。
ここで、代わりにgit checkout B
を実行するとします。あなたはこれを得るでしょう:
- A - B (HEAD) - C (master)
切り離されたHEAD状態になりました。HEAD
、作業ツリー、インデックスはすべてB
に一致します。ハードリセットの場合と同じですが、マスターブランチはC
に残されました。この時点で新しいコミットD
を行うと、これが得られますが、これはおそらくあなたが望むものではありません。
- A - B - C (master)
\
D (HEAD)
したがって、チェックアウトを使用して、そのコミットをチェックアウトします。あなたはそれをいじって、あなたが好きなことをすることができます、しかしあなたはあなたの枝を置き去りにしました。ブランチも移動する場合は、リセットを使用します。
Gitで提供されているドキュメントが役に立たない場合は、Mark Lodatoによる A Visual Git Reference をご覧ください。
特に、git checkout <non-branch>
とgit reset --hard <non-branch>
(ホットリンク)を比較している場合:
(ソース: github.com )
git reset --hard master~3
の場合、リビジョンのDAGの一部を残すことに注意してください。一部のコミットは、どのブランチからも参照されません。それらは(デフォルトで)30日間reflog;によって保護されます。それらは最終的に剪定(削除)されます。
git-reset hash
は、指定されたハッシュへのブランチ参照を設定し、オプションでそれをチェックアウトします。with--hard
。
git-checkout hash
作業ツリーを指定されたハッシュに設定します。ハッシュがブランチ名でない限り、ヘッドが切り離されてしまいます。
最終的に、gitは3つのことを扱います:
working tree (your code)
-------------------------------------------------------------------------
index/staging-area
-------------------------------------------------------------------------
repository (bunch of commits, trees, branch names, etc)
git-checkout
デフォルトでは、インデックスと作業ツリーを更新するだけで、オプションでリポジトリ内の何かを更新できます(-b
オプション)
git-reset
デフォルトでは、リポジトリとインデックス、およびオプションで作業ツリーを更新するだけです(--hard
オプション)
リポジトリは次のように考えることができます。
HEAD -> master
refs:
master -> sha_of_commit_X
dev -> sha_of_commit_Y
objects: (addressed by sha1)
sha_of_commit_X, sha_of_commit_Y, sha_of_commit_Z, sha_of_commit_A ....
git-reset
ブランチ参照が指すものを操作します。
履歴が次のようになっているとします。
T--S--R--Q [master][dev]
/
A--B--C--D--E--F--G [topic1]
\
Z--Y--X--W [topic2][topic3]
ブランチは、コミットすると自動的に進む名前にすぎないことに注意してください。
したがって、次のブランチがあります。
master -> Q
dev -> Q
topic1 -> G
topic2 -> W
topic3 -> W
そしてあなたの現在のブランチはtopic2
、つまり、HEADはtopic2を指します。
HEAD -> topic2
次に、git reset X
は名前をリセットしますtopic2
Xを指す;つまり、ブランチtopic2でコミットPを実行すると、次のようになります。
T--S--R--Q [master][dev]
/
A--B--C--D--E--F--G [topic1]
\
Z--Y--X--W [topic3]
\
P [topic2]