5

68cce45最近、git リポジトリで作業しているときに、古いコミット ( ) でコードを表示したかったので、

git checkout 68cce45

変更を確認した後、現在のバージョンのリポジトリに戻って作業を続けたいと思いました。2bcfd11最新のコミットだったので、私はやった

git checkout 2bcfd11

その後、いくつかの変更を加えて実行しました

git add *

その後

git status

これにより、次の警告が表示されましたHEAD detached at 2bcfd11

よくわかりません。チェックアウトした最後のコミットが数バージョン前だった場合、「切り離された HEAD 状態」になる理由は理解できます。しかし、最後にチェックアウトしたコミットがリポジトリの最新バージョンだったのに、どうして切り離された HEAD 状態になるのでしょうか? HEAD はリポジトリの「トップ」を指していませんか?

4

4 に答える 4

2

phd の回答を少し拡張すると、Git ではHEAD、このようにすべて大文字で綴られている1は非常に特別な名前です。 (ブランチ名に)アタッチすることも、デタッチHEADすることもできます。どちらの場合でも、Git は使用しているコミットを通知できます。

git rev-parse HEAD

ハッシュIDを出力します。ただしHEAD、 がブランチ名に関連付けられている場合にのみ、Gitは使用しているブランチ名を通知できます。

git rev-parse --symbolic-full-name HEAD
git symbolic-ref HEAD

ブランチ上にいる場合、どちらも現在のブランチの名前(プレフィックスがrefs/heads/) を提供します。デタッチされた HEAD モードの場合、前者は単に出力さHEADれ、後者はエラーを生成します:

$ git checkout --detach master
HEAD is now at 7c20df84bd Git 2.23-rc1
Your branch is up to date with 'origin/master'.
$ git rev-parse --symbolic-full-name HEAD
HEAD
$ git symbolic-ref HEAD
fatal: ref HEAD is not a symbolic ref

の多くの形式git checkoutデタッチ HEADします。いくつかのフォームが添付されます。を使用するとアタッチされますが、上に示すように、追加して、デタッチされるか、デタッチされたままになるようにすることができます。git checkout branch-name--detach

7c20df84bdこの特定のコミットを識別する 1 つ以上のブランチ名がある場合でも、常になどの生のハッシュ ID を使用すると、切り離された HEAD になります。

すべてが同じコミットを識別するように、好きなだけブランチ名を付けることができることに注意してください。

$ for i in m1 m2 m3; do git branch $i master; done
$ git checkout m1
Switched to branch 'm1'
$ git rev-parse HEAD
7c20df84bd21ec0215358381844274fa10515017
$ git checkout m2
Switched to branch 'm2'
$ git rev-parse HEAD
7c20df84bd21ec0215358381844274fa10515017

を明示的にチェックアウトする場合7c20df84bd21ec0215358381844274fa10515017、4 つの名前 (<code>m1 m2、、、、m3または) のmasterどれを Git に使用させますか? しかし、それはそれらのどれも使用しません: 名前を使用したい場合は、自分で名前を指定する必要があります:

$ git checkout master
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

その後、余分な名前を削除して、コミット7c20df84bd21ec0215358381844274fa10515017が同時に 4 つのブランチの先端にあるのではなく、 の先端にあるようにしますmaster

$ for i in m1 m2 m3; do git branch -d $i; done
Deleted branch m1 (was 7c20df84bd).
Deleted branch m2 (was 7c20df84bd).
Deleted branch m3 (was 7c20df84bd).

2 つの機能HEADがあることを忘れないでください。現在のブランチ(名前) を見つけるか、切り離されている場合は失敗します。現在のcommit を見つけます。2 Git から得られる答えは、尋ねた質問によって異なります。ブランチ名を知りたいですか、それとも現在のコミット ハッシュ IDを知りたいですか?HEAD


1一部のシステムでは、小文字の で綴ることがheadでき、同じ効果が得られます。ただし、これは、追加された作業ツリーで不思議なことに失敗し始めます。すべて大文字を使用するのが最善です。HEAD入力するのが煩わしい場合は、1 文字@が同じ特別な意味を持ちます。

2これも失敗する可能性がありますが、特別な状態でのみです。あなたは新しい完全に空のリポジトリでこの状態にあり、現在のブランチは ですmasterが、ブランチmaster自体はまだ存在していません。これは、ブランチ名に既存の有効なコミット オブジェクトのハッシュ ID が含まれている必要があるためです。新しい完全に空のリポジトリでは、コミットはまったくありません。したがって、ブランチ名は存在できません。とはいえ、HEAD名前には がついていますmaster

あなたがこの状態にあるとき — Git の一部はこれを のように孤立したブランチgit checkout --orphan呼び、他の部分はそれをunborn ブランチと呼びgit statusます —次のようにコミットすると、ブランチ名が存在します。名前はすでにどこかに (具体的には保存されています) ありますが、名前が保持できるハッシュ ID を持つ有効なコミットを最初に作成した後HEAD、コミットはその名前を有効なブランチ名として作成します。

于 2019-08-18T05:16:22.747 に答える