Che cos'è HEAD in git?


232

Sembra che ci sia una differenza tra l'ultimo commit, HEAD e lo stato del file che posso vedere nella mia directory.

Che cos'è HEAD, cosa posso farci e quale errore dovrei evitare?



1
A partire da Git v1.8.4, tutte le risposte sottostanti che utilizzano HEADo headpossono ora utilizzare @al posto di HEAD. Vedi questa risposta (ultima sezione) per sapere perché puoi farlo.

3
Da git-scm : HEAD in Git è il puntatore al riferimento di ramo corrente, che a sua volta è un puntatore all'ultimo commit che hai fatto o all'ultimo commit che è stato estratto nella tua directory di lavoro. Ciò significa anche che sarà il genitore del prossimo commit che fai. In genere è più semplice pensarci perché HEAD è l'istantanea del tuo ultimo commit.
Quazi Irfan,

3
Possibile duplicato di What is HEAD in Git?
Ma il

Risposte:


185

HEAD è un riferimento all'ultimo commit nel ramo attualmente estratto.


C'è una piccola eccezione a questo, che è la testa staccata. Un HEAD distaccato è la situazione in cui ti trovi ogni volta che controlli un commit (o tag) anziché un ramo. In questo caso, devi immaginarlo come un ramo temporaneo senza un nome; quindi invece di avere un riferimento al ramo denominato, abbiamo solo HEAD. Ti consentirà comunque di eseguire commit (che aggiornerà HEAD), quindi la definizione breve sopra è ancora vera se pensi a un HEAD distaccato come un ramo temporaneo senza un nome.


1
Allora perché puoi avere due teste?
e-soddisfa il

1
@ e-satis: a volte vedrai i rami indicati come head - sono memorizzati refs/heads. HEADTuttavia, la testa minuscola è diversa . La mia risposta chiarisce un po 'questo.
Cascabel,

7
@ e-satis: non è regex. Il ^è la notazione solo di git per "il commit prima di" - che è il commit prima di quella corrente. (Se la corrente è una fusione, utilizza il primo genitore.)
Cascabel

1
@ e-satis: per maggiori informazioni su tutti i modi per specificare i commit, vedere la sezione specifica delle revisioni della pagina man per git-rev-list - questo è solo un piccolo pezzo. kernel.org/pub/software/scm/git/docs/…
Cascabel

1
No, quando rev e HEAD indicano lo stesso commit, non c'è differenza. E potresti anche scrivere l'id di commit (il valore SHA-1) invece di rev o HEAD. E non preoccuparti, non ci molesti con le domande :) (almeno io: P)
colpisci il

87

HEAD è un riferimento (riferimento) al commit attualmente estratto.

In stati normali, in realtà è un riferimento simbolico al ramo che hai estratto - se guardi il contenuto di .git / HEAD vedrai qualcosa come "ref: refs / heads / master". Il ramo stesso è un riferimento al commit sulla punta del ramo. Pertanto, nello stato normale, si HEADriferisce effettivamente al commit sulla punta del ramo corrente.

È anche possibile avere una "TESTA staccata". Ciò accade quando si verifica qualcosa oltre a un ramo (locale), come un ramo remoto, un commit specifico o un tag. Il luogo più comune per vederlo è durante un rebase interattivo, quando si sceglie di modificare un commit. In uno stato HEAD distaccato, HEAD è un riferimento diretto a un commit: il contenuto di .git / HEAD sarà un hash SHA1.

In generale, HEAD è solo un nome conveniente per significare "ciò che hai verificato" e non devi preoccuparti molto. Basta essere consapevoli di ciò che è stato verificato e ricordare che probabilmente non si desidera impegnarsi se non si è su un ramo (stato HEAD distaccato) a meno che non si sappia cosa si sta facendo (ad es. In un rebase interattivo) .


6
Questo è qualcosa che non capisco. Se esegui il checkout di un ramo remoto, perché finisci con un "HEAD distaccato". Perché non saltare automaticamente nella filiale del repository locale corrispondente al telecomando?
e-soddisfa il

3
@ e-satis: se vuoi la filiale locale, controlla la filiale locale. Ricorda che i due non sono necessariamente gli stessi: devi dire a quello locale di unire quello remoto (o tirare). Il tracciamento è solo per sapere quale estrarre automaticamente quando lo chiedi. Il motivo per cui è staccato è che il ramo remoto deve essere un puntatore all'ultima posizione del ramo nel repository remoto. Se si tenta di impegnarsi, il repository remoto non cambia, quindi nemmeno il ramo remoto.
Cascabel,

1
OK, questo è quello che non ho avuto: avere un ramo locale nominato in un modo non implica che sia lo stesso di quello remoto. Davvero difficile da ottenere all'inizio perché vengo da uno sfondo SVN :-) Grazie amico. A proposito, come si sposta una TESTA senza testa in una filiale locale per impegnarla qui?
e-soddisfa il

3
@ e-satis: la risposta generale è git rebase <branch> HEAD. Questo troverà l'ultimo antenato comune di <branch>e HEAD, quindi prenderà tutti i commit da lì HEADe li applicherà (rifondali) su <branch>. Lo fa essenzialmente applicandoli come patch, quindi se i due rami sono davvero diversi, potrebbero esserci dei conflitti. Ma se <branch>è un antenato HEAD(vale a dire che eri nel posto giusto, hai dimenticato di esserti distaccato HEAD) il rebase è solo una fusione in avanti veloce.
Cascabel,

3
Questa è una delle descrizioni più chiare e accurate di git HEAD che ho visto, dopo aver cercato per un po '.
LarsH

21

Ho sempre pensato che HEAD~5significa GO to 5 commit prima. Ma non contiene la parte GO del comando. Porta solo il riferimento / "dove" parte del comando.

In parole povere è usato per rispondere alla domanda di: DOVE dovrei andare? A quale impegno?

  • HEAD significa (il riferimento al) commit corrente
  • HEAD~1 significa (il riferimento a) 1 commit prima
  • HEAD~ Significa ANCHE (il riferimento a) 1 commit prima
  • HEAD~87 significa (il riferimento a) 87 commette prima

Uso:

  • git checkout HEAD~1 andrà effettivamente / checkout su 1 commit / riferimento prima
  • git reset HEAD~3 interromperà i tuoi ultimi 3 commit - senza rimuovere le modifiche, ovvero puoi vedere tutte le modifiche apportate negli ultimi 3 commit insieme, rimuovere tutto ciò che non ti piace o aggiungere su di esso e quindi impegnarli nuovamente.
  • git reset --hard HEAD~3annullerà il commit dell'ultimo commit e rimuoverà le modifiche . Rimuoverà completamente tali modifiche. Per di più vedi qui .
  • git diff HEAD~3 per il controllo delle modifiche negli ultimi 3 commit

3
tornando alla mia risposta :)
Honey

15

Puntatore HEAD in Git

Git mantiene una variabile di riferimento chiamata HEAD. E chiamiamo questa variabile un puntatore, perché il suo scopo è di fare riferimento o indicare un commit specifico nel repository. Man mano che effettuiamo nuovi commit, il puntatore cambierà o passerà a puntare a un nuovo commit. HEAD punta sempre alla punta del ramo corrente nel nostro repository. Ora, questo ha a che fare con il nostro repository, non con il nostro indice di gestione temporanea o la nostra directory di lavoro.

Un altro modo di pensarlo è l'ultimo stato del nostro repository o quello che è stato verificato per ultimo, e poiché è dove il repository ha interrotto o l'ultimo stato, puoi anche dire che HEAD punta al genitore del prossimo commit o è dove avrà luogo la scrittura di commit.

Penso che una buona metafora a cui pensare sia la riproduzione e la testa di registrazione su un registratore a cassette. Quando iniziamo a registrare l'audio, il nastro si sposta oltre la testa e registra su di esso. quando premiamo Stop, il punto in cui si ferma quella testina è il punto in cui riprenderà a registrare quando premiamo Record una seconda volta. Ora possiamo spostarci, possiamo spostare la testa in luoghi diversi, ma ovunque sia posizionata la testa quando premiamo di nuovo Record è lì che inizierà la registrazione.

Il puntatore HEAD in Git è molto simile, indica il punto in cui inizieremo la registrazione successiva. È il luogo in cui abbiamo lasciato nel nostro repository le cose che abbiamo commesso.


0

In termini semplici, HEAD è un riferimento all'ultimo commit nel ramo di check-out attualmente.

Pensa a HEAD come al "ramo attuale". Quando si cambiano i rami con git checkout, la revisione HEAD cambia in modo che punti alla punta del nuovo ramo.

Puoi vedere a cosa punta HEAD facendo:

cat .git/HEAD

È possibile che HEAD faccia riferimento a una revisione specifica che non è associata al nome di un ramo. Questa situazione si chiama HEAD distaccato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.