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.