HEAD e ORIG_HEAD in Git


252

A cosa si riferiscono questi simboli e cosa significano?

(Non riesco a trovare alcuna spiegazione nella documentazione ufficiale)


4
Nota: HEADè ora (imminente git1.8.4) ' @'! Vedi la mia risposta modificata di seguito
VonC,

Nota-bis: ' @' (per HEAD) è ancora in arrivo, ma non per la risposta 1.8.4 modificata e modificata .
VonC,

1
Nota ter: ' @' for HEADè tornato per git 1.8.5 / 1.9. risposta modificata di nuovo .
VonC,

21
HEADe ORIG_HEADin Git sono come $PWDe $OLDPWDin Bash. :)
musiphil,

Risposte:


325

HEADè il riferimento (diretto o indiretto, cioè simbolico) al commit corrente. È un commit che hai controllato nella directory di lavoro (a meno che tu non abbia apportato alcune modifiche, o equivalente), ed è un commit in cima al quale "git commit" ne farebbe una nuova. Di solito HEADè un riferimento simbolico ad un altro ramo chiamato; questo ramo è attualmente estratto ramo, o ramo corrente. HEADpuò anche indicare direttamente un commit; questo stato è chiamato "HEAD distaccato" e può essere compreso come ramo anonimo senza nome.

E da @solo è una scorciatoia per HEAD, da Git 1.8.5

ORIG_HEADè lo stato precedente di HEAD, impostato da comandi che potrebbero avere un comportamento pericoloso, per poterli ripristinare facilmente. È meno utile ora che Git ha reflog: HEAD@{1}è approssimativamente equivalente a ORIG_HEAD( HEAD@{1}è sempre l'ultimo valore di HEAD, ORIG_HEADè l'ultimo valore di HEADprima di un'operazione pericolosa).

Per maggiori informazioni leggi la manpage di git (1) , il Manuale dell'utente di Git , il Git Community Book e il Glossario Git


2
Ciao Jakub. +1 per la spiegazione. Potresti dettagliare la parte "approssimativamente equivalente" di HEAD @ {1}? Mi riferisco nella mia risposta al thread thread.gmane.org/gmane.comp.version-control.git/38379 (eri in esso, nel febbraio 2007), e non ho capito esattamente la discussione che avete avuto in giro la sintassi @ {...}.
VonC

19
ORIG_HEAD è impostato (credo) solo da comandi "pericolosi", che spostano HEAD di più di un commit. Quindi ORIG_HEAD non è sempre impostato, mentre HEAD @ {1} è sempre impostato. @ {1} è $ (git symbolic-ref HEAD) @ {1}, ovvero utilizza reflog per il ramo corrente, non reflog HEAD.
Jakub Narębski,

Riiight ... Ora capisco :) Grazie per quel chiarimento. Per quello che vale, ho votato anche il tuo commento!
VonC

1
"e HEAD è un commit in cima al quale" git commit "ne farebbe uno nuovo." - Buono a ricordare, grazie! Sempre da @VonC, "È il commit" git commit "basato su, e" git diff --cached "e" git status "si confrontano."
Minqi Pan

1
Le revisioni di aiuto di git richiamano git-scm.com/docs/gitrevisions , che descrive tutti i modi per fare riferimento ai commit (incluso HEADe ORIG_HEAD).
Dahlbyk,

104

Da git reset

"pull" o "merge" lascia sempre la punta originale del ramo corrente ORIG_HEAD.

git reset --hard ORIG_HEAD

La reimpostazione forzata su di esso riporta il file di indice e l'albero di lavoro su quello stato e reimposta la punta del ramo su quel commit.

git reset --merge ORIG_HEAD

Dopo aver esaminato il risultato dell'unione, è possibile che la modifica nell'altro ramo non sia soddisfacente. L'esecuzione di " git reset --hard ORIG_HEAD" ti consentirà di tornare al punto in cui ti trovavi, ma eliminerà le modifiche locali che non desideri. " git reset --merge" mantiene le modifiche locali.


Prima di applicare eventuali patch, ORIG_HEAD è impostato sulla punta del ramo corrente.
Ciò è utile se si hanno problemi con più commit, come eseguire ' git am' sul ramo sbagliato o un errore nei commit che è più facilmente risolto cambiando la cassetta postale (es. + Errori nelle righe "Da:").

Inoltre, l'unione imposta sempre ' .git/ORIG_HEAD' sullo stato originale di HEAD, in modo che un'unione problematica possa essere rimossa usando ' git reset ORIG_HEAD'.


Nota: da qui

HEAD è un puntatore mobile. A volte significa l'attuale ramo, a volte no.

Quindi HEAD NON è già sinonimo di "ramo attuale" ovunque.

HEAD significa "corrente" ovunque in git, ma non significa necessariamente "ramo corrente" (cioè HEAD distaccato).

Ma quasi sempre significa "commit corrente".
È il commit " git commit" si basa su, e " git diff --cached" e " git status" confrontano.
Significa il ramo corrente solo in contesti molto limitati (esattamente quando vogliamo che un nome di ramo operi su --- reimpostazione e crescita della punta del ramo tramite commit / rebase / ecc.).

Reflog è un veicolo per tornare indietro nel tempo e le macchine del tempo hanno un'interazione interessante con la nozione di "corrente".

HEAD@{5.minutes.ago}potrebbe significare "dereference HEAD symref per scoprire quale ramo siamo su RIGHT NOW, e quindi scoprire dove era la punta di quel ramo 5 minuti fa".
In alternativa, potrebbe significare "qual è il commit che avrei chiamato HEAD 5 minuti fa, ad esempio se avessi fatto" git show HEAD "allora".


git1.8.4 (luglio 2013) introduce ha introdotto una nuova notazione!
(in realtà, sarà per 1.8.5 o 1.9, Q4 2013: reintrodotto con commit 9ba89f4 )

Invece di digitare quattro lettere maiuscole " HEAD", puoi pronunciare " @" ora,
ad es. " git log @".

Vedi commit cdfd948

Digitare ' HEAD' è noioso, soprattutto quando possiamo usare ' @' invece.

Il motivo della scelta di " @" è che deriva naturalmente dalla ref@opsintassi (ad esempio HEAD@{u}), tranne per il fatto che non abbiamo alcun riferimento e nessuna operazione, e quando non li abbiamo, ha senso assumerlo HEAD".

Quindi ora possiamo usare ' git show @~1', e tutta quella bontà.

Fino ad ora ' @' era un nome valido, ma è in conflitto con questa idea, quindi rendiamolo non valido. Probabilmente pochissime persone hanno usato questo nome.


Un post sul blog durante il periodo 1.8.4-rc3 (14 agosto 2013) ha annunciato che questa funzione è stata ripristinata e ritardata (grazie Cupcake per l'heads-up ).
Ancora una volta, viene nuovamente introdotto con commit 9ba89f4 (settembre 2013).

Vedi commit 2c2b664 :

Ripristina "Aggiungi nuova @scorciatoia per HEAD"

Questo ripristina il commit di cdfd948 , in quanto non si applica solo a " @" (e ai moduli con modificatori come @{u}applicati ad esso), ma influisce anche su " refs/heads/@/foo", cosa che non dovrebbe.

L'idea di base di dare una scorciatoia potrebbe essere buona, e l'argomento può essere riprovato più tardi, ma torniamo indietro per evitare di influenzare i casi d'uso esistenti per ora per la prossima versione.


Dopo aver eseguito git, ripristinare ORIG_HEAD e confermare. ORIG_HEAD è ancora presente sotto Riferimenti accanto a HEAD. Perché non è stato rimosso dalla vista?
powder366,

@ powder366 ma a git resetgenererà a ORIG_HEAD. Quindi è necessario rmmanualmente. Vedere stackoverflow.com/a/12418078/6309 per esempio.
VonC,

1
@VonC è stato ripristinato (temporaneamente?) L'@ alias per la versione Git 1.8.4 ! È stato appena annunciato oggi! HEAD

Mi è piaciuto il commento "heads-up"!
Robino,

2

La mia comprensione è che HEAD punta il ramo corrente, mentre ORIG_HEAD viene utilizzato per memorizzare il HEAD precedente prima di eseguire operazioni "pericolose".

Ad esempio git-rebase e git-am registrano la punta del ramo originale prima di applicare qualsiasi modifica.


4
HEAD non punta sempre sul ramo corrente (può essere rimosso)
VonC

1
Allora, qual è il "ramo corrente" quando HEAD è "staccato"?
cjs,

@ CurtJ.Sampson Questo è "nessun ramo". ecco perché quando sei in testa distaccata, lo fai git branch foo -bper "creare" un ramo per cui gli orfani si impegnano.
Royi Namir,

1

A partire dal man 7 gitrevisions :

HEAD nomina il commit su cui hai basato le modifiche nell'albero di lavoro. FETCH_HEAD registra il ramo che hai recuperato da un repository remoto con l'ultima tua chiamata a git fetch. ORIG_HEAD è creato da comandi che spostano la tua HEAD in modo drastico, per registrare la posizione della HEAD prima della loro operazione, in modo da poter facilmente riportare la punta del ramo allo stato prima di eseguirli. MERGE_HEAD registra i commit che stai unendo nel tuo ramo quando esegui git merge. CHERRY_PICK_HEAD registra il commit che stai selezionando cherry quando esegui git cherry-pick.

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.