web-dev-qa-db-ja.com

git checkout <commit-hash>とgit checkoutブランチ

私はgitで遊んでいて、ここで混乱しました。

[〜#〜] head [〜#〜] of developブランチは
235a6d8

私がする時:

git checkout 235a6d8

他のブランチまたはdevelopブランチから、これは私を切り離したままにします。
このブランチの最新のコミットにチェックアウトしているときに、なぜこれが起こるのかわかりません。

私がする時:

git checkout develop

ブランチを正しく開発するように切り替えることができます。

git checkout <commit-has>およびgit checkout branchname
どのように違うのですか?

9
Tooba Iqbal

A git checkout <commit-hash><commit>の上で作業する準備をし、HEAD at at at at ""( " DETACHED HEAD" section )を参照)、更新する作業ツリーのインデックスとファイル。

git checkout <branch>は切り替えを行いますが、<branch>での作業の準備をし、作業ツリー内のインデックスとファイルを更新し、HEADをブランチでポイントすることで切り替えます。

これは紛らわしいです。

Mark Longairなぜgitコマンドが「git checkout」という名前のブランチを切り替えるコマンドなのか」に混乱を文書化しましたか? "

彼はまた、2012年5月に次のように書いています: " 最もわかりにくいgit用語 ":

CVSおよびSubversionでは、「チェックアウト」により、そのリポジトリにリンクされているソースコードの新しいローカルコピーが作成されます。
Gitで最も近いコマンドは「git clone」です。
しかし、gitでは、「git checkout」は完全に異なるものに使用されます。
実際、2つの大きく異なる動作モードがあります。

  • HEADをポイントして新しいブランチまたはコミットを切り替えるには、使用方法git checkout <branch><branch>が本当にローカルブランチである場合、これはそのブランチに切り替えます(HEADは参照名を指します)、またはコミットに解決される場合は、デタッチHEADでコミットのオブジェクト名を直接指します。
  • 作業コピーとインデックス内の1つまたは複数のファイルを、特定のコミットまたはインデックスの内容で置き換える。
    これは、使用法git checkout -- (update from the index)およびgit checkout <tree-ish> --で見られます(<tree-ish>は通常、コミットです)。

私の理想的な世界では、これらの2つの操作モードには異なる動詞があり、どちらも「checkout」ではありません

そうですね...それが、Git 2.23(2019年第3四半期)がチェックアウトを次のように分割する理由です。

  • git restore 作業ツリー(および場合によってはインデックス)を更新します
  • git switch すべての新しいコミットをこのブランチの先端に追加するために、ブランチを切り替えるか、要求された場合は1つをデタッチできます。
7
VonC

ここに簡単な説明があります:

HEADは、ブランチとコミットへの参照を保持する単なるポインタのようなものです。

新しいコミットを作成するたびに、その特定のブランチの新しいコミットを指すように自動的に移動されます。

git checkout <branch name>を実行すると、HEADポインターはそのブランチとその最後のコミット、ブランチの先端を指します。

コミットハッシュを直接チェックアウトする場合、HEADは特定のコミットを指しますが、特定のブランチは指しません。つまり、detachedです。

HEADを再びアタッチするには、単にブランチをチェックアウトすると、ブランチにアタッチされ、最後のコミットを指すようになり、通常の動作に戻ります。

切り離されたHEAD状態で実行できることは他にもありますが、その詳細については docs で確認できます。

1
rbento