Passa temporaneamente la copia di lavoro a un commit Git specifico


248

Come passare al commit Git specifico senza perdere tutti i commit effettuati dopo di esso ?

Voglio che i file locali vengano modificati, ma il database dei commit rimarrà intatto, solo il puntatore della posizione corrente è impostato sul commit attualmente selezionato.

Voglio cambiare lo stato dei file in commit specifico, eseguire il progetto e, al termine, ripristinare i file all'ultimo commit.

Come fare questo senza zippare l'intera cartella del progetto?


Risposte:


344

Se sei in una determinata filiale mybranch, vai avanti e git checkout commit_hash. Quindi puoi tornare alla tua filiale entro git checkout mybranch. Oggi ho avuto lo stesso gioco in una volta bisecare un bug :) Inoltre, dovresti conoscere git bisect .


6
Nota che puoi fare solo git checkout commit_hashse sei in un repository pulito e non hai bisogno di fare ramificazioni. Potrebbe essere più facile per alcuni casi d'uso (come il mio).
Enderland,

@enderland: la tua TESTA punta sempre verso qualche ramo, normalmente :)
Alexander Pavlov,

Ho avuto un problema in cui dovevo usare l'intero hash di commit perché non ne era stato accettato uno parziale.
mightyiam

6
Voto per il git bisectriferimento; che strumento estremamente utile!
Niek,

54

Innanzitutto, utilizza git logper visualizzare il registro, seleziona il commit desiderato, annota l'hash sha1 utilizzato per identificare il commit. Quindi, corrigit checkout hash . Dopo aver finito, git checkout original_branch. Questo ha il vantaggio di non spostare HEAD, ma cambia semplicemente la copia di lavoro in uno specifico commit.


4
Penso che tu intenda git checkout <original_branch>. git checkout HEADè effettivamente un NOOP
Abe Voelker,

3
git reset --hard <hash>cambia il HEAD del ramo corrente, mentre con git checkout <hash>te ottieni un checkout distaccato che non cambia alcun ramo, e puoi facilmente tornare senza conoscere l'ID hash originale del tuo ramo come mostrato in questa risposta.
jofel,

@Femaref Domanda per principianti: dato il contesto di questa domanda (passare temporaneamente a un commit precedente), perché sarebbe un vantaggio o uno svantaggio spostare o non spostare HEAD?
pazzo di schifoso

@nuttyaboutnatty Supponendo che la mia modifica sia approvata, dovrebbe rispondere alla tua domanda. HEAD viene effettivamente spostato in ogni caso; ma in un checkout il riferimento di ramo HEAD punta a non viene spostato.
ecristopherson,

15

Oltre alle altre risposte qui che ti mostrano come git checkout <the-hash-you-want>vale la pena sapere che puoi tornare a dove stavi usando:

git checkout @{-1}

Questo è spesso più conveniente di:

git checkout what-was-that-original-branch-called-again-question-mark

Come puoi prevedere, git checkout @{-2}ti riporterà al ramo che eri due git checkouts fa, e allo stesso modo per altri numeri. Se riesci a ricordare dove eri per numeri più grandi, dovresti ottenere una sorta di medaglia per quello.


Purtroppo per la produttività, git checkout @{1}non ti porta al ramo in cui ti troverai in futuro, il che è un peccato.


1
Nota che git checkout - è un alias di stenografia pergit checkout @{-1}
Nathanael

@Nathanael OMGOD , assolutamente ... questo cambia tutto! Bello grazie! ... Stavo per incorporare questo nella risposta, ma penso che sia anche utile conoscere la @{n}sintassi generale , poiché funziona con molti comandi git. Ho trovato difficile aggiungere la tua stenografia senza rendere la risposta piuttosto confusa. Invece ho votato il tuo commento - spero che la gente lo veda. Grazie ancora.
Benjohn,

1
Nessun problema. Questa discussione è comunque tangenziale alla domanda reale. Più di un bonus! Uso spesso la stessa sintassi per unire le funzionalità in una versione. ad esempio git merge -per unire il ramo che è stato estratto per ultimo nel ramo attualmente estratto. È come cd -in bash.
Nathanael
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.