私はいつもgit reset
とgit checkout
を同じものとして考えていました、両方ともプロジェクトを特定のコミットに戻すという意味でです。しかし、それは冗長になるため、まったく同じにはできないと思います。両者の実際の違いは何ですか? svnはコミットを元に戻すためのsvn co
しか持っていないので、少し混乱しています。
VonCとCharlesは、git reset
とgit checkout
の違いを本当によく説明しました。私の現在の理解では、git reset
はすべての変更を特定のコミットに戻しますが、git checkout
は多かれ少なかれブランチの準備をします。次の2つの図が、この理解に役立つ上で非常に役立ちます。
から http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html =、チェックアウトとリセットはリベースをエミュレートできます。
git checkout bar
git reset --hard newbar
git branch -d newbar
git reset
は、特にインデックスの更新についてです、HEADを移動します。git checkout
は、作業ツリーを更新する(インデックスまたは指定されたツリーへ)です。ブランチをチェックアウトする場合にのみ、HEADを更新します(チェックアウトしない場合、 detached HEAD になります)。git restore
になり、必ずしもgit checkout
ではありません)比較すると、svnにはインデックスがなく、作業ツリーのみであるため、 svn checkout
は、指定されたリビジョンを別のディレクトリにコピーします。git checkout
に近いものは:
svn update
(同じブランチにいる場合、同じSVN URLを意味します)svn switch
(同じブランチを別のSVNリポジトリURLからチェックアウトする場合)これら3つの作業ツリーの変更(svn checkout
、update
、switch
)はすべて、gitにコマンドが1つだけあります:git checkout
。
しかし、gitにはインデックス(リポジトリと作業ツリーの間の「ステージングエリア」)の概念もあるため、git reset
もあります。
Thinkeye 言及 コメント内 記事「 Reset Demystified 」。
たとえば、異なるコミットを指す「
master
」と「develop
」の2つのブランチがあり、現在は「develop
」にいる場合(つまりHEADはそれを指します)そして、git reset master
を実行します。'develop
'自体は、'master
'と同じコミットを指すようになります。一方、代わりに
git checkout master
を実行すると、「develop
」は移動せず、HEAD
自体が移動します。HEAD
は 'master
'を指すようになりました。したがって、どちらの場合も、
HEAD
を移動してコミットA
を指すようにしますが、その方法は非常に異なります。reset
はブランチを移動しますHEAD
はポイントし、チェックアウトはHEAD
自体を移動して別のブランチをポイントします。
ただし、これらの点については:
ただし、この回答の最初の段落は誤解を招く可能性があります。「
git checkout
...は、ブランチをチェックアウトした場合にのみHEADを更新します(そうでない場合は、HEADが切り離されます)。
trueではありません:ブランチではないコミットをチェックアウトした場合でも、git checkout
はHEADを更新します(そして、はい、分離されたHEADになりますが、それでも更新されます)。git checkout a839e8f updates HEAD to point to commit a839e8f.
@LarsHは正しいです。
2番目の箇条書きには、HEADの内容に関する誤解があり、ブランチをチェックアウトした場合にのみHEADが更新されます。
HEADはどこにいても影のように行きます。
非ブランチ参照(タグなど)をチェックアウトするか、直接コミットすると、HEADが移動します。切り離されたヘッドは、HEADから切り離されたことを意味するのではなく、ヘッドがブランチ参照から切り離されたことを意味します。たとえば、git log --pretty=format:"%d" -1
から参照できます。
- 付加されたヘッド状態は
(HEAD ->
で始まり、- 分離はまだ
(HEAD
を表示しますが、ブランチ参照への矢印はありません。
最も単純な形式では、reset
は作業ツリーに触れずにインデックスをリセットし、checkout
はインデックスに触れずに作業ツリーを変更します。
作業ツリーをそのままにして、インデックスをHEAD
に一致するようにリセットします。
git reset
概念的には、これはインデックスを作業ツリーにチェックアウトします。実際に何かを実行するには、-f
を使用してローカルの変更を上書きするように強制する必要があります。これは、「引数なし」形式が破壊的ではないことを確認するための安全機能です。
git checkout
パラメータを追加し始めたら、重複があることは事実です。
checkout
は通常、ブランチ、タグ、またはコミットと共に使用されます。この場合、作業ツリーへのインデックスのチェックアウトを実行するだけでなく、HEAD
およびインデックスを指定のコミットにリセットします。
また、reset
に--hard
を指定した場合は、reset
に作業ツリーの上書きとインデックスの再設定を依頼することができます。
現在ブランチをチェックアウトしている場合は、別のブランチまたはコミットを指定したときにreset
とcheckout
の間に重大な違いがあります。 reset
は現在のブランチを選択されたコミットを指すように変更しますが、checkout
は現在のブランチをそのままにしますが、代わりに提供されたブランチまたはコミットをチェックアウトします。
他の形式のreset
およびcommit
では、パスを指定する必要があります。
reset
にパスを指定した場合、--hard
を指定することはできません。また、reset
は、指定したパスのインデックスバージョンを、指定したコミットのバージョンにのみ変更します(コミットを指定しない場合はHEAD
)。
checkout
のようにreset
にパスを指定すると、指定されたコミット(またはHEAD
)と一致するように指定されたパスのインデックスバージョンを更新しますが、指定されたパスのインデックスバージョンを作業ツリーにチェックアウトします。
変更を元に戻すときの簡単な使用例
1。変更したファイルのステージングを元に戻す場合は、resetを使用してください。
2。ステージングされていないファイルへの変更を破棄したい場合は、チェックアウトを使用してください。
Atlassiangit reset、git checkoutなどについて優れた説明をしてくださいgit revert。この記事では、ファイル、ステージングされたスナップショット、およびコミットという、さまざまなレベルでのこれらのコマンドのさまざまな使用法について説明します。
https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting
一言で言えば、reset
現在のブランチ参照を移動するであるのに対し、checkout
name__は移動しない(HEADを移動する)ということです。
Pro Gitの本が Demystifiedをリセット で説明しているように、
reset
name__が最初に行うことはHEADが指すものをに移動することです。これはHEAD自体の変更(これはcheckout
name__の動作です)と同じではありません。reset
ブランチを移動する that HEADが指している。これは、HEADがmaster
name__ブランチに設定されている場合(つまり、現在master
name__ブランチにいる場合)、git reset 9e5e6a4
の実行はmaster
name__を9e5e6a4
に設定することから始まります。 [強調を追加]
同じ記事の 非常に役立つテキストと図の抜粋 に対するVonCの回答も参照してください。ここでは説明しません。
checkout
name__とreset
name__がインデックスと作業ツリーにどのような影響を与えるかについては、使用されるパラメータに応じて、より多くの詳細があります。 2つのコマンドの間には多くの類似点と相違点があります。しかし、私が見ているように、最も重要な違いはそれらが現在のブランチの先端を動かすかどうかです。
2つのコマンド(リセットとチェックアウト)はまったく異なります。
checkout X
IS NOT reset --hard X
Xがブランチ名の場合、checkout X
は現在のブランチを変更しますが、reset --hard X
は変更しません。