Risposta breve: nell'uso tipico, il puntatore HEAD punta alla punta del ramo che hai attualmente estratto.
Risposta più lunga:
Prima alcuni concetti e terminologia qui.
Puntatore HEAD - > un modo in cui git si riferisce al commit su cui stai lavorando. Se apporti modifiche e le impegni, ciò che è attualmente referenziato da HEAD diventa il genitore del tuo nuovo commit. Quindi HEAD viene aggiornato per indicare il nuovo commit. Pensa a dove si attaccherà il prossimo commit.
Suggerimento - > un termine tipico per l'ultimo commit in un ramo. Quindi, quando fai qualcosa come git checkout master
(nessun hash del commit), otterrai il tuo HEAD pointer per (in modo efficace) guardare l'ultimo commit sul master (chiamato il tip).
Ora che abbiamo tolto di mezzo ...
Nella maggior parte dei casi di uso quotidiano di git, esegui il checkout di rami, apporta modifiche, esegui commit, ripeti. Pertanto, nell'uso tipico, HEAD punta sempre verso la punta del tuo ramo. Nella mia esperienza, molto raramente (rispetto ad altre operazioni che sto facendo) hai mai bisogno di controllare un ramo su un tag o commit specifico. Ma può succedere. E quando lo fai, ottieni una "testa distaccata".
Parafrasando e prendendo alcuni esempi dalla documentazione di git sui capi staccati :
Supponi di iniziare con questo:
HEAD (refers to branch 'master')
|
v
a---b---c branch 'master' (refers to commit 'c')
^
|
tag 'v2.0' (refers to commit 'b')
Quindi, se aggiungi un commit, diventa il figlio dell'attuale HEAD. (Quindi il riferimento "master" del ramo viene aggiornato per puntare al nuovo commit e quindi HEAD viene aggiornato indirettamente.)
HEAD (refers to branch 'master')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
Ma dì che devi tornare indietro e guardare qualcosa nella versione 2.0. Quindi potresti fare git checkout v2.0
. Quindi il tuo stato è simile a questo:
HEAD (refers to commit 'b')
|
v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
Il che significa che il tuo HEAD non punta più verso la punta del ramo. Se dovessi dimenticare dove ti trovavi e hai aggiunto un commit qui (e hai dimenticato di diramarti, vergognati), ora finisci qui:
HEAD (refers to commit 'e')
|
v
e
/
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
Ora commit e
è su qualcosa di simile a un ramo e viene indicato da HEAD, rendendolo il genitore del prossimo commit. Questo può diventare problematico se muovi il tuo HEAD facendo un altro checkout (per esempio, master). Quindi si arriva a qualcosa di simile:
HEAD (refers to branch 'master')
e---f |
/ v
a---b---c---d branch 'master' (refers to commit 'd')
^
|
tag 'v2.0' (refers to commit 'b')
Senza HEAD che punta a f
, si trova in la-la-land tutto da solo, senza un vero modo per arrivare o fare riferimento a esso (puoi ottenerlo con il reflog se ne hai davvero bisogno). E qualsiasi cosa come e
e f
che non hanno un ref potrebbe (e sarà) essere potato la prossima volta che git fa la garbage collection, il che significa che un po 'di lavoro potrebbe essere inutilizzabile se non stai attento. Per fortuna questo può essere risolto se lo aggiusti prima che il garbage collector lo mangi (non andando a dettagliare qui).
Il punto della risposta lunga qui è duplice. Il primo è che, nella maggior parte dei casi HEAD = punta del tuo ramo. Il secondo è che, nonostante alcune altre risposte, HEAD non deve necessariamente essere la punta del tuo ramo (e può causare problemi se non stai attento).