git reflog
Questa pagina fornisce una discussione dettagliata del comando git reflog
. Git tiene traccia degli aggiornamenti alla punta dei branch utilizzando un meccanismo chiamato log di riferimento o "reflog. " Molti comandi Git accettano un parametro per specificare un riferimento o un "ref", che è un puntatore a un commit. Gli esempi più comuni includono:
Reflog tiene traccia di quando i riferimenti di Git sono stati aggiornati nel repository locale. Oltre ai reflog delle punte dei branch, viene mantenuto un reflog speciale per lo stash Git. I reflog sono archiviati nelle directory della directory .git
del repository locale. Le directory git reflog
possono essere trovate all'indirizzo .git/logs/refs/heads/.
, .git/logs/HEAD
, e anche .git/logs/refs/stash
se git stash
è stato utilizzato nel repository.
Abbiamo parlato di git reflog
in generale nella pagina della riscrittura della cronologia. Questo documento tratterà: opzioni di configurazione estese di git reflog
, casi d'uso comuni e insidie di git reflog
, come annullare le modifiche con git reflog
e altro ancora.
Utilizzo di base
Il caso d'uso più semplice di Reflog è il richiamo:
git reflog
Questa è essenzialmente una scorciatoia che equivale a:
git reflog show HEAD
Verrà emesso il reflog HEAD
. Dovresti vedere un output simile a:
eff544f HEAD@{0}: commit: migrate existing content
bf871fd HEAD@{1}: commit: Add Git Reflog outline
9a4491f HEAD@{2}: checkout: moving from main to git_reflog
9a4491f HEAD@{3}: checkout: moving from Git_Config to main
39b159a HEAD@{4}: commit: expand on git context
9b3aa71 HEAD@{5}: commit: more color clarification
f34388b HEAD@{6}: commit: expand on color support
9962aed HEAD@{7}: commit: a git editor -> the Git editor
Visita la pagina della riscrittura della cronologia per un altro esempio di accesso reflog comune.
Riferimenti Reflog
Per impostazione predefinita, git reflog
emetterà il reflog del riferimento HEAD
. HEAD
è un riferimento simbolico al branch attualmente attivo. I reflog sono disponibili anche per altri riferimenti. La sintassi per accedere a un git ref è nome@{qualifier}
. Oltre ai riferimenti HEAD
, è possibile fare riferimento anche ad altri branch, tag, remoti e allo stash Git.
Puoi ottenere un reflog completo di tutti i riferimenti eseguendo:
git reflog show —all
Per vedere il reflog per un branch specifico, passa il nome del branch a git reflog show
git reflog mostra un altro branch 9a4491f otherbranch@ {0}: commit: separare gli articoli in PR dai branch 35aee4a otherbranch {1}: commit (iniziale): commit iniziale aggiunta documenti git-init e impostazione di un repository
L'esecuzione di questo esempio mostrerà un reflog per il branch otherbranch
. L'esempio seguente presuppone che tu abbia precedentemente nascosto alcune modifiche utilizzando il comando git stash
.
git reflog stash 0d44de3 stash@ {0}: WIP su git_reflog: c492574 concretizza l'introduzione
Verrà generato un reflog per lo stash Git. I puntatori di riferimento restituiti possono essere passati ad altri comandi Git:
git diff stash@{0} otherbranch@{0}
Una volta eseguito, questo codice di esempio mostrerà l'output Git diff confrontando le modifiche di stash@ {0}
con il riferimento otherbranch@ {0}
.
Reflog temporizzati
A ogni voce di reflog è associato un timestamp. Questi timestamp possono essere utilizzati come token qualificatore
della sintassi del puntatore di riferimento Git. Ciò consente di filtrare i reflog Git in base al tempo. Di seguito sono riportati alcuni esempi di qualificatori temporali disponibili:
1.minute.ago
1.hour.ago
1.day.ago
Ieri
1.week.ago
1.month.ago
1.year.ago
17/05/2011. 09:00:00
I qualificatori temporali possono essere combinati (ad es. 1.day.2.hours.ago
), Inoltre sono accettate forme plurali (ad es. 5.minutes.ago
).
I riferimenti ai qualificatori temporali possono essere passati ad altri comandi git.
git diff main@{0} main@{1.day.ago}
Questo esempio differenzia l'attuale branch principale da quello principale di 1 giorno fa. Questo esempio è molto utile se vuoi conoscere i cambiamenti che sono avvenuti in un periodo di tempo.
Sottocomandi e opzioni di configurazione
git reflog
accetta alcuni argomenti aggiuntivi che sono considerati sottocomandi.
Mostra: git reflog show
show
è passato implicitamente per impostazione predefinita. Ad esempio, il comando:
git reflog main@{0}
è equivalente al comando:
git reflog show main@{0}
Inoltre, git reflog show
è un alias per git log -g —abbrev-commit —pretty=oneline
. Esecuzione di git reflog show
mostrerà il registro del
Scadenza - git reflog expire
Il sottocomando expire pulisce le voci di reflog vecchie o irraggiungibili. Il sottocomando expire
potrebbe causare la perdita di dati. Questo sottocomando non è in genere utilizzato dagli utenti finali, ma viene utilizzato internamente da git. Passare un'opzione -n
o —dry-run
a git reflog expire
eseguirà un "dry run" che mostrerà quali voci di reflog sono contrassegnate per essere eliminate, ma non le eliminerà effettivamente.
Per impostazione predefinita, la data di scadenza del reflog è impostata su 90 giorni. È possibile specificare una data di scadenza passando l'argomento della riga di comando —expire=time
a git reflog expire
o impostando il nome di configurazione git gc.reflogExpire
.
Elimina: git reflog delete
Il sottocomando delete
si spiega da sé e eliminerà una voce di reflog passata. Come per expire
, delete
potrebbe causare la perdita di dati e non viene comunemente richiamato dagli utenti finali.
Recupero dei commit persi
Git non perde mai davvero nulla, anche quando esegue operazioni di riscrittura della cronologia come rebase o modifica dei commit. Per il prossimo esempio supponiamo di aver apportato alcune nuove modifiche al nostro repository. Il nostro git log —pretty=oneline
ha il seguente aspetto:
338fbcb41de10f7f2e54095f5649426cb4bf2458 contenuto esteso 1e63ceab309da94256db8fb1f35b1678fb74abd4 molti contenuti c49257493a95185997c87e0bc3a9481715270086 approfondire l'introduzione eff544f986d270d7f97c77618314a06f024c7916 migrare i contenuti esistenti bf871fd762d8ef2e146d7f0226e81a92f91975ad aggiungere profilo Git Reflog 35aee4a4404c42128bee8468a9517418ed0eb3dc commit iniziale aggiungere documenti git-init e configurazione repository
Quindi apportiamo le modifiche ed eseguiamo quanto segue:
#make passa a HEAD git commit - sono state apportate "alcune modifiche WIP"
Con l'aggiunta del nuovo commit. Il registro ora ha il seguente aspetto:
37656e19d4e4f1a9b419f57850c8f1974f871b07 alcune modifiche WIP 338fbcb41de10f7f2e54095f5649426cb4bf2458 contenuto esteso 1e63ceab309da94256db8fb1f35b1678fb74abd4 molti contenuti c49257493a95185997c87e0bc3a9481715270086 approfondire l'introduzione eff544f986d270d7f97c77618314a06f024c7916 migrare i contenuti esistenti bf871fd762d8ef2e146d7f0226e81a92f91975ad Aggiungi profilo Git Reflog 35aee4a4404c42128bee8468a9517418ed0eb3dc commit iniziale aggiungere documenti git-init e configurazione repository
A questo punto eseguiamo un rebase interattivo sul branch principale eseguendo...
git rebase -i origine/principale
Durante il rebase contrassegniamo i commit per squash con il sottocomando s
di rebase. Durante il rebase, aggiungiamo alcuni commit ai commit più recenti di "alcune modifiche WIP".
Poiché abbiamo eliminato i commit, l'output del log di git
ora ha il seguente aspetto:
40dhsoi37656e19d4e4f1a9b419f57850ch87dah987698hs alcune modifiche al WIP 35aee4a4404c42128bee8468a9517418ed0eb3dc commit iniziale aggiungere documenti git-init e configurazione repository
Se esaminiamo git log
a questo punto sembra che non abbiamo più i commit contrassegnati per lo squashing. E se volessimo operare su uno dei commit sottoposti a squash? Magari per rimuovere le modifiche dalla cronologia? Questa è un'opportunità per sfruttare reflog.
reflog git 37656e1 HEAD@ {0}: rebase -i (fine): ritorno a refs/heads/git_reflog 37656e1 HEAD@ {1}: rebase -i (inizio): origine/principale del check-out 37656e1 HEAD@ {2}: commit: alcune modifiche WIP
Possiamo vedere che ci sono voci di reflog per l'inizio e la fine del rebase
e prima di queste c'è il nostro commit per le "modifiche WIP". Possiamo passare il ref reflog a git reset
e resettare a un commit precedente al rebase.
git reset HEAD@{2}
L'esecuzione di questo comando di ripristino sposterà HEAD
nel commit in cui sono state aggiunte "alcune modifiche WIP", essenzialmente ripristinando gli altri commit sottoposti a squash.
Riepilogo
In questo tutorial abbiamo discusso del comando git reflog
. Alcuni punti chiave trattati sono stati:
- Come visualizzare i reflog per branch specifici
- Come annullare un rebase git usando reflog
- Come specificare e visualizzare i reflog in base al tempo
Abbiamo accennato brevemente al fatto che git reflog
può essere usato con altri comandi git come git checkout, git reset e git merge. Per saperne di più visita le rispettive pagine. Per ulteriori discussioni su riferimenti e reflog, scopri di più qui.