「git replace --hard hash」と「git checkout hash」に違いはありますか?
-
23-09-2019 - |
質問
その間 reset
そして checkout
ほとんどの場合、使用法が異なりますが、これら 2 つにどのような違いがあるのかわかりません。
おそらく誰かがいるか、誰もわざわざ追加しなかったでしょう --hard
基本的なことを行うオプション checkout
できる。
おそらく歴史の見方に違いがあるのでしょうか?
解決
この回答は主に、以前の質問に対する私の回答から引用されています。 わかりやすい英語での git リセット.
両者は大きく異なります。インデックスとワーク ツリーの状態は同じになりますが、結果の履歴と現在のブランチは同じではありません。
現在マスター ブランチがチェックアウトされている履歴が次のようになっているとします。
- 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 を使用して、そのコミットをチェックアウトします。いじったり、好きなことをしたりできますが、ブランチを置き去りにしたことになります。ブランチも移動したい場合は、reset を使用します。
他のヒント
だが提供するドキュメンテーションとGitなおこれらを実現するために、 視覚Gitを参照 マークLodato.
特にまとの比較 git checkout <non-branch>
と git reset --hard <non-branch>
(hotlinked):
(出典: github.com)
るということに注意してくださの場合 git reset --hard master~3
お帰りの背景の一部DAGの改正にも犯して参照されないよ。その保護のための(デフォルト)から30日以 reflog;いい最終的には剪定(削除).
git-reset hash
それを所定のハッシュへの分岐参照を設定し、必要に応じてチェックし、with--hard
。
git-checkout hash
は、与えられたハッシュに作業ツリーを設定します。ハッシュは、ブランチ名でない限り、あなたは切り離さ頭になってしまいます。
最終的には、3つの事とgitの情報:
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
は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]