Introduzione
Il reflog registra ogni cambiamento di HEAD e di ogni punta di branch sulla tua macchina locale. È locale, per-clone, e non viene pushato. Quasi ogni commit "perso" può essere recuperato attraverso di esso.
Visualizzare
git reflog # reflog di HEAD
git reflog show main # reflog di main
git reflog --date=iso
git log -g --oneline # walk del log attraverso il reflog
Ogni entry ha una sequenza (HEAD@{0}, HEAD@{1}, ...), un'azione (commit, reset, merge, rebase, ...) e uno SHA target.
Recuperare un commit perso
git reflog
# 9f8a1c2 HEAD@{0}: reset: moving to HEAD~3
# a1b2c3d HEAD@{1}: commit: Important work
git switch -c rescued a1b2c3d
O direttamente:
git reset --hard HEAD@{1}
Sintassi temporale
git show HEAD@{2.hours.ago}
git diff main@{yesterday} main
Git interpreta @{...} come un conteggio o una data.
Scadenza del reflog
Per impostazione predefinita le entry reflog raggiungibili scadono dopo 90 giorni, e quelle irraggiungibili dopo 30:
git config gc.reflogExpire 90.days
git config gc.reflogExpireUnreachable 30.days
Fino alla scadenza, anche i commit di hard-reset rimangono recuperabili.
Reflog per ref
Ogni branch ha il proprio reflog in .git/logs/refs/heads/<name>. Anche stash ne ha uno (refs/stash):
git reflog show stash
Pulire il reflog
git reflog expire --expire=now --all
git gc --prune=now
Usa solo se hai bisogno di cancellare permanentemente dei dati; questo rimuove la rete di sicurezza.
Reflog vs git log
git log percorre il grafo dei commit tramite i puntatori parent; il reflog percorre i movimenti registrati di un ref. Dopo un force-reset, git log non mostra più i commit abbandonati, ma il reflog sì.
Ispezione del reflog per ref
Ogni ref tiene il proprio reflog. Ispeziona il reflog di un branch specifico per vedere come si è mossa la sua punta:
git reflog show feature/login
git log -g feature/login --oneline
cat .git/logs/refs/heads/feature/login
Utile quando si indaga "chi ha mosso questo branch?" su un clone locale. Il formato del file reflog è una riga per cambiamento con vecchio SHA, nuovo SHA, committer, timestamp e un messaggio testuale. Combinato con git blame sul file, dà una traccia di audit locale completa; ricorda che i reflog non vengono pushati, quindi la traccia copre solo la tua macchina.
Errori comuni
Dimenticare che il reflog esiste in preda al panico e rifare ore di lavoro che era facilmente recuperabile. Controlla sempre git reflog per primo. Pushare durante il recupero e assumere che il reflog sia sul server; non lo è, solo il tuo clone locale ce l'ha. Eseguire git gc --prune=now per istinto di "pulizia" e distruggere la rete di sicurezza per qualsiasi commit non referenziato. E infine, trattare le entry reflog come permanenti; i ref cancellati da tempo invecchiano. Tagga o ramifica qualsiasi cosa tu voglia mantenere prima che passino 30 giorni.