ほとんどの場合、reset
とcheckout
は用途が異なりますが、これら 2 つの間にどのような違いがあるのか わかりません。
--hard
基本機能でできることを行うためのオプションをわざわざ追加しようとは思わなかった人もいるでしょうcheckout
。
歴史の見方に違いがあるのではないでしょうか?
ほとんどの場合、reset
とcheckout
は用途が異なりますが、これら 2 つの間にどのような違いがあるのか わかりません。
--hard
基本機能でできることを行うためのオプションをわざわざ追加しようとは思わなかった人もいるでしょうcheckout
。
歴史の見方に違いがあるのではないでしょうか?
この回答は、主に前の質問に対する私の回答から引用されています: git reset in plain english。
2つは非常に異なります。インデックスと作業ツリーは同じ状態になりますが、結果の履歴と現在のブランチは同じではありません。
master ブランチが現在チェックアウトされている状態で、履歴が次のようになっているとします。
- 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)
つまり、checkout を使用して、そのコミットをチェックアウトします。あなたはそれをいじることができ、好きなことをすることができますが、あなたはあなたのブランチを置き去りにしています. ブランチも移動したい場合は、リセットを使用します。
Git で提供されるドキュメントが役に立たない場合は、Mark Lodato によるA Visual Git Referenceを参照してください。
git checkout <non-branch>
特に(ホットリンク)と比較している場合git reset --hard <non-branch>
:
(ソース: github.com )
git reset --hard master~3
リビジョンの DAG の一部を残す場合、一部のコミットはどのブランチからも参照されないことに注意してください。これらはreflogによって (デフォルトで) 30 日間保護されます。それらは最終的に剪定 (削除) されます。
git-reset hash
指定されたハッシュへのブランチ参照を設定し、オプションでチェックアウトし--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
次に、X を指すようにgit reset X
名前をリセットします。topic2
つまり、ブランチ topic2 で P をコミットすると、次のようになります。
T--S--R--Q [master][dev]
/
A--B--C--D--E--F--G [topic1]
\
Z--Y--X--W [topic3]
\
P [topic2]