web-dev-qa-db-ja.com

"git reset"と "git checkout"の違いは何ですか?

私はいつもgit resetgit checkoutを同じものとして考えていました、両方ともプロジェクトを特定のコミットに戻すという意味でです。しかし、それは冗長になるため、まったく同じにはできないと思います。両者の実際の違いは何ですか? svnはコミットを元に戻すためのsvn coしか持っていないので、少し混乱しています。

追加

VonCとCharlesは、git resetgit checkoutの違いを本当によく説明しました。私の現在の理解では、git resetはすべての変更を特定のコミットに戻しますが、git checkoutは多かれ少なかれブランチの準備をします。次の2つの図が、この理解に役立つ上で非常に役立ちます。

http://a.imageshack.us/img651/1559/86421927.pnghttp://a.imageshack.us/img801/1986/resetr.png

追加3

から http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html =、チェックアウトとリセットはリベースをエミュレートできます。

enter image description here

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

enter image description here

393
prosseek
  • git reset は、特にインデックスの更新についてです、HEADを移動します。
  • git checkout は、作業ツリーを更新する(インデックスまたは指定されたツリーへ)です。ブランチをチェックアウトする場合にのみ、HEADを更新します(チェックアウトしない場合、 detached HEAD になります)。
    (実際、Git 2.23 Q3 2019では、これは git restore になり、必ずしもgit checkoutではありません)

比較すると、svnにはインデックスがなく、作業ツリーのみであるため、 svn checkout は、指定されたリビジョンを別のディレクトリにコピーします。
git checkoutに近いものは:

  • svn update (同じブランチにいる場合、同じSVN URLを意味します)
  • svn switch (同じブランチを別のSVNリポジトリURLからチェックアウトする場合)

これら3つの作業ツリーの変更(svn checkoutupdateswitch)はすべて、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自体を移動して別のブランチをポイントします。

http://git-scm.com/images/reset/reset-checkout.png

ただし、これらの点については:

LarsH 追加 コメント内

ただし、この回答の最初の段落は誤解を招く可能性があります。「git checkout ...は、ブランチをチェックアウトした場合にのみHEADを更新します(そうでない場合は、HEADが切り離されます)。
trueではありません:ブランチではないコミットをチェックアウトした場合でも、git checkoutはHEADを更新します(そして、はい、分離されたHEADになりますが、それでも更新されます)。

git checkout a839e8f updates HEAD to point to commit a839e8f.

De Novo 同意 コメント内

@LarsHは正しいです。
2番目の箇条書きには、HEADの内容に関する誤解があり、ブランチをチェックアウトした場合にのみHEADが更新されます。
HEADはどこにいても影のように行きます。
非ブランチ参照(タグなど)をチェックアウトするか、直接コミットすると、HEADが移動します。切り離されたヘッドは、HEADから切り離されたことを意味するのではなく、ヘッドがブランチ参照から切り離されたことを意味します。たとえば、git log --pretty=format:"%d" -1から参照できます。

  • 付加されたヘッド状態は(HEAD ->で始まり、
  • 分離はまだ(HEADを表示しますが、ブランチ参照への矢印はありません。
177
VonC

最も単純な形式では、resetは作業ツリーに触れずにインデックスをリセットし、checkoutはインデックスに触れずに作業ツリーを変更します。

作業ツリーをそのままにして、インデックスをHEADに一致するようにリセットします。

git reset

概念的には、これはインデックスを作業ツリーにチェックアウトします。実際に何かを実行するには、-fを使用してローカルの変更を上書きするように強制する必要があります。これは、「引数なし」形式が破壊的ではないことを確認するための安全機能です。

git checkout

パラメータを追加し始めたら、重複があることは事実です。

checkoutは通常、ブランチ、タグ、またはコミットと共に使用されます。この場合、作業ツリーへのインデックスのチェックアウトを実行するだけでなく、HEADおよびインデックスを指定のコミットにリセットします。

また、reset--hardを指定した場合は、resetに作業ツリーの上書きとインデックスの再設定を依頼することができます。

現在ブランチをチェックアウトしている場合は、別のブランチまたはコミットを指定したときにresetcheckoutの間に重大な違いがあります。 resetは現在のブランチを選択されたコミットを指すように変更しますが、checkoutは現在のブランチをそのままにしますが、代わりに提供されたブランチまたはコミットをチェックアウトします。

他の形式のresetおよびcommitでは、パスを指定する必要があります。

resetにパスを指定した場合、--hardを指定することはできません。また、resetは、指定したパスのインデックスバージョンを、指定したコミットのバージョンにのみ変更します(コミットを指定しない場合はHEAD)。

checkoutのようにresetにパスを指定すると、指定されたコミット(またはHEAD)と一致するように指定されたパスのインデックスバージョンを更新しますが、指定されたパスのインデックスバージョンを作業ツリーにチェックアウトします。

61
CB Bailey

変更を元に戻すときの簡単な使用例
1。変更したファイルのステージングを元に戻す場合は、resetを使用してください。
2。ステージングされていないファイルへの変更を破棄したい場合は、チェックアウトを使用してください。

28
John Doe

Atlassiangit resetgit checkoutなどについて優れた説明をしてくださいgit revert。この記事では、ファイル、ステージングされたスナップショット、およびコミットという、さまざまなレベルでのこれらのコマンドのさまざまな使用法について説明します。

https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting

9
Rochadsouza

一言で言えば、reset現在のブランチ参照を移動するであるのに対し、checkoutname__は移動しない(HEADを移動する)ということです。

Pro Gitの本が Demystifiedをリセット で説明しているように、

resetname__が最初に行うことはHEADが指すものをに移動することです。これはHEAD自体の変更(これはcheckoutname__の動作です)と同じではありません。 resetブランチを移動する that HEADが指している。これは、HEADがmastername__ブランチに設定されている場合(つまり、現在mastername__ブランチにいる場合)、git reset 9e5e6a4の実行はmastername__を9e5e6a4に設定することから始まります。 [強調を追加]

同じ記事の 非常に役立つテキストと図の抜粋 に対するVonCの回答も参照してください。ここでは説明しません。

checkoutname__とresetname__がインデックスと作業ツリーにどのような影響を与えるかについては、使用されるパラメータに応じて、より多くの詳細があります。 2つのコマンドの間には多くの類似点と相違点があります。しかし、私が見ているように、最も重要な違いはそれらが現在のブランチの先端を動かすかどうかです。

8
LarsH

2つのコマンド(リセットとチェックアウト)はまったく異なります。

checkout X IS NOT reset --hard X

Xがブランチ名の場合、checkout Xは現在のブランチを変更しますが、reset --hard Xは変更しません。

1
wiki1000