Vai al contenuto principale

Git Reflog: capire e usare i reference log in Git

Scopri come git reflog aiuta a tracciare e recuperare commit persi, annullare errori e gestire la cronologia dei branch. Scopri casi d’uso pratici e comandi per padroneggiare git reflog.
· 10 min leggi

Scopri con l'IA

Per uno sviluppatore o un data engineer non c’è nulla di più fastidioso che eliminare per sbaglio branch di git o resettare commit quando non volevi farlo. Ecco perché sono felice di condividere qualcosa che ho imparato sulla mia pelle e che avrei voluto conoscere prima: come usare git reflog. git reflog è una di quelle tecniche che vale davvero la pena imparare; con un po’ di tempo ora, puoi evitarti grossi mal di testa in futuro. 

Mentre ti mostrerò git reflog, che trovo davvero utile per orientarsi e riprendersi dagli errori, ti consiglio anche i nostri corsi Foundations of Git e Introduction to GitHub Concepts per imparare tutto sul version control.

Che cos’è git reflog?

Git reflog, o reference log, è un meccanismo di tracciamento locale che registra gli aggiornamenti delle punte dei branch e del riferimento HEAD in un repository Git. (Nel contesto di Git, HEAD si riferisce al commit corrente su cui si basano la working directory e l’area di staging.)

Diversamente da git log, che mostra la cronologia dei commit in base all’ascendenza, illustrando come i commit sono collegati in un branch, git reflog cattura tutti i movimenti di HEAD, inclusi cambi di branch, rebase, reset e commit. Questo rende reflog utile per recuperare commit persi e fare il debug delle azioni recenti.

Quando vengono creati gli entry del reflog?

Le voci del reflog vengono create ogni volta che esegui azioni che cambiano lo stato di HEAD o dei riferimenti dei branch. Gli scenari comuni includono:

  • Eseguire commit con git commit.

  • Passare a un branch diverso con git checkout branch_name.

  • Creare un nuovo branch con git branch new_branch.

  • Rebase git rebase

  • Reset a un commit precedente git reset --hard.

  • Merge di branch con git merge.

Ecco il comando che usi per tracciare gli aggiornamenti nel repository locale:

git reflog

Usare git reflog per tracciare gli aggiornamenti nel repository locale.

Usare git reflog per tracciare gli aggiornamenti nel repository locale. Immagine dell’autore.

Come si interpreta l’output di git reflog?

Puoi interpretare l’output come segue:

  • HEAD@{0}: L’azione più recente è stato il passaggio al branch puntato da HEAD.

  • HEAD@{1}: Prima di ciò, avevo cambiato il tipo di file da formato .xlxs a .csv.

  • HEAD@{2}: Ho fatto il primo commit quando ho pushato i file nel repository.

Ogni voce mostra:

  • L’hash del commit (fa82776)

  • L’indice del reflog (HEAD@{0}, HEAD@{1}, ecc.)

  • Una descrizione dell’azione eseguita (commit, checkout, rebase)

Come usare git reflog

Git reflog offre un modo per tracciare gli aggiornamenti dei riferimenti e ripristinare gli stati precedenti del repository. Capendo come navigare le voci del reflog, puoi recuperare commit persi, annullare modifiche e confrontare versioni passate del tuo lavoro. 

Comando base di git reflog

Di seguito trovi il comando base di reflog:

git reflog

Il comando sopra mostra un elenco delle azioni recenti che hanno aggiornato HEAD o i riferimenti dei branch, inclusi commit, cambi di branch, reset, rebase e altro. Ogni voce è indicizzata, ad esempio HEAD@{0} e HEAD@{1}, per rappresentare la sua posizione nella cronologia del reflog.

Fare riferimento a stati passati

Git reflog funge da registro degli aggiornamenti dei riferimenti passati, permettendoci di individuare e ripristinare punti precedenti nella cronologia del repository. Senza di esso, questi riferimenti non esisterebbero e ci servirebbero hash di commit esatti per tornare a stati specifici. Ora vediamo come Git ci consente di navigare questi stati passati usando git checkout.

HEAD@{n}: si riferisce a una specifica voce del reflog, dove n è l’indice. Ad esempio, HEAD@{2} indica il terzo stato più recente di HEAD.

git checkout HEAD@{2}

Usare git checkout per tracciare le modifiche passate.

Usare git checkout per tracciare le modifiche passate. Immagine dell’autore.

branch@{time}: si riferisce allo stato di un branch in un momento specifico. Ad esempio, main@{1.week.ago} si riferisce allo stato del branch main una settimana fa, mentre feature@{yesterday} si riferisce allo stato del branch feature ieri.

git checkout main@{1.week.ago}

Usare git checkout per tracciare le modifiche passate.

Usare git checkout per tracciare le modifiche passate. Immagine dell’autore.

Qualificatori basati sul tempo

git reflog non solo ci aiuta a ripristinare stati passati, ma permette anche di confrontarli. Poiché il reflog traccia gli aggiornamenti dei riferimenti, possiamo usarlo per vedere come il repository è cambiato nel tempo. Ora vediamo come git diff sfrutta le voci del reflog per confrontare stati passati e presenti.

Ecco alcuni esempi di qualificatori temporali che rendono facile ripristinare il repository a un momento specifico, invece di affidarsi soltanto ai numeri di indice del reflog.

git checkout HEAD@{1.minute.ago}     # Stato di un minuto fa
git checkout HEAD@{1.hour.ago}       # Stato di un’ora fa
git checkout HEAD@{1.week.ago}       # Stato di una settimana fa
git checkout HEAD@{yesterday}        # Stato di ieri
git checkout HEAD@{2024-01-01.12:00:00} # Stato a un timestamp specifico

Confrontare stati passati con git diff

Puoi confrontare stati passati con comandi come git diff. Il comando seguente confronta lo stato attuale del branch principale main@{0} con il suo stato di un giorno fa, main@{1.day.ago}. L’output mostrerà le differenze tra questi due snapshot.

git diff main@{0} main@{1.day.ago}

Confrontare stati passati con git diff.

Confrontare stati passati con git diff. Immagine dell’autore.

Casi d’uso comuni per Git Reflog

Git reflog è uno strumento prezioso per recuperare modifiche perse, annullare errori e risolvere inconvenienti comuni di Git. Di seguito alcuni scenari pratici in cui git reflog può aiutare.

Annullare un reset errato

Se hai resettato per sbaglio il tuo branch con git reset --hard, puoi usare il reflog per ripristinare lo stato precedente.

git reset --hard HEAD@{3}

Recuperare commit persi

Se elimini per errore un branch o perdi dei commit a causa di un reset o di un rebase, puoi trovare il commit perso usando git reflog.

git reflog

Individua l’hash del commit dall’output del reflog ed effettua il checkout:

git checkout <commit-hash>

Una volta verificato il commit perso, puoi creare un nuovo branch per preservarlo:

git branch recovered-branch <commit-hash>

Sistemare un rebase andato male

Se un rebase va storto, puoi usare git reflog per trovare il commit precedente al rebase e resettare il branch. Identifica il commit prima del rebase e fai il reset.

git reset --hard HEAD@{3}  # Regola il numero in base all’output del reflog

Ripristinare un branch eliminato

Se elimini per sbaglio un branch, puoi recuperarlo usando git reflog. Trova l’ultimo commit noto del branch eliminato e ricrealo:

git branch restored-branch <commit-hash>

Tracciare la cronologia degli stash

Git reflog può essere usato anche per visualizzare la cronologia degli stash. Il comando seguente elenca le operazioni di stash, permettendoti di recuperare stash più vecchi se necessario. 

git reflog stash

Per applicare una voce di stash precedente, usa il seguente comando:

git stash apply stash@{2}

Dai un’occhiata al nostro tutorial Git Pull Force: How to Overwrite a Local Branch With Remote per imparare le best practice per sovrascrivere le modifiche locali.

Sottocomandi e opzioni di Git Reflog

Git fornisce diversi sottocomandi e opzioni per gestire e interagire con i reflog. 

Sottocomandi di git reflog

Di seguito una panoramica strutturata dei principali sottocomandi di git reflog e del loro utilizzo.

git reflog show: mostra per default le voci del reflog per HEAD o per un riferimento specificato, come un branch.

git reflog show

Usare git reflog show per visualizzare le voci per un riferimento specificato.

Usare git reflog show per visualizzare le voci per un riferimento specificato. Immagine dell’autore.

git reflog list: questo comando mostra tutti i riferimenti con un reflog. È utile per individuare branch e riferimenti HEAD con voci di reflog memorizzate.

git reflog list

git reflog delete <ref>@{<specifier>}: pulisce le voci di reflog vecchie che superano il limite di tempo specificato. Ad esempio, il comando seguente rimuove le voci più vecchie di 30 giorni.

git reflog expire --expire=30.days.ago

git reflog delete <ref>@{<specifier>}: elimina una specifica voce del reflog in base al suo riferimento e alla posizione. Il comando sotto rimuove la voce di reflog all’indice 2 per HEAD.

git reflog delete HEAD@{2}

git reflog exists <ref>: verifica se esiste un reflog per un riferimento specifico. Ad esempio, il comando sotto restituisce successo se il branch main ha un reflog.

git reflog exists main

Opzioni per i sottocomandi di git reflog

Di seguito le opzioni disponibili per i sottocomandi git reflog e il loro utilizzo.

--expire-unreachable=<time>: elimina solo le voci di reflog non raggiungibili da alcun ref. Ad esempio, il comando seguente rimuove le voci di reflog non raggiungibili più vecchie di 7 giorni.

git reflog expire --expire-unreachable=7.days.ago

--all: elabora i reflog per tutti i riferimenti, non solo per HEAD. Il comando seguente pulisce tutti i reflog più vecchi di 60 giorni su tutti i branch.

git reflog expire --expire=60.days.ago --all

--dry-run: simula l’esecuzione di un comando, mostrando cosa verrebbe eliminato senza cancellare realmente nulla. Ad esempio, il comando seguente mostra quali voci verrebbero rimosse.

git reflog expire --expire=30.days.ago --dry-run

--verbose: fornisce output dettagliato sulle azioni eseguite dal comando. Il comando seguente mostra dettagli verbosi mentre scade le voci di reflog vecchie.

git reflog expire --expire=90.days.ago --verbose

Git Reflog vs. Git Log: differenze chiave

Sia git log che git reflog offrono informazioni sulla storia di un repository, ma servono a scopi diversi. Vediamo queste differenze per capire come usarli per strategie di version control e recupero.

  • git log mostra la cronologia dei commit seguendo l’ascendenza dei commit in un branch. Fornisce una vista cronologica di come è evoluto il contenuto del repository.

  • git reflog registra gli aggiornamenti ai riferimenti come HEAD, branch e stash, incluse azioni come cambi di branch, reset, rebase e altro. Traccia cambiamenti che potrebbero non far parte dell’ascendenza dei commit.

  • git reflog è strettamente locale alla tua macchina e non viene condiviso con i repository remoti.

  • Mentre git log non può recuperare commit che non fanno più parte dell’ascendenza del branch, git reflog può aiutare a recuperare commit “persi” tracciando gli aggiornamenti dei riferimenti, anche se quei commit non sono più raggiungibili da alcun branch.

La tabella seguente riassume queste differenze chiave.

Featuregit loggit reflog
Tracks commitsYesNo
Track reference updatesNoYes
Shared in remoteYesNo
Can recover lost commitsNoYes

Best Practices for Using Git Reflog

Git reflog è uno strumento potente per recuperare commit persi e sistemare problemi di cronologia, ma usarlo in modo efficace richiede cautela. Ecco alcune best practice da seguire quando lavori con il reflog.

  • Usa il Reflog per recupero e debug: se resetti o fai rebase di un branch in modo errato, controlla git reflog per trovare un riferimento precedente e ripristinarlo.

  • Fai attenzione con git reset --hard: git reset --hard può rimuovere in modo permanente le modifiche non committate. Controlla sempre prima il reflog per assicurarti di poter recuperare qualcosa se va storto.

  • Tieni backup prima di eseguire comandi distruttivi: per proteggerti dalla perdita di dati, implementa backup automatici dei repository Git. Conserva sempre i backup in una posizione sicura e off-site per garantirne il recupero in caso di guasti hardware o altri disastri.

  • Non fare affidamento solo sul Reflog per recuperi a lungo termine: per impostazione predefinita, le voci del reflog vengono mantenute per 90 giorni. Dopo questo periodo, possono essere eliminate dalla garbage collection e diventare irrecuperabili. Fai regolarmente push dei tuoi commit su un repository remoto per assicurarne la conservazione oltre il tuo reflog locale.

  • Usa git reflog expire per gestire le voci vecchie: se il reflog del tuo repository diventa affollato, elimina le voci più vecchie o non raggiungibili usando git reflog expire.

Conclusione

Gestire efficacemente la cronologia di un progetto in Git richiede più dei comandi di base. Esplorare strumenti avanzati che tracciano gli aggiornamenti dei riferimenti può offrire una rete di sicurezza preziosa per recuperare commit persi, ripristinare branch eliminati e correggere errori. Fare esperienza pratica con questi strumenti, insieme a comandi come git reset, git checkout e git revert, può migliorare sensibilmente la tua padronanza del version control.

Seguire i nostri corsi non è solo un ottimo modo per imparare: è anche un segnale per i datori di lavoro che prendi sul serio lo sviluppo software. A tal fine, ti consiglio di studiare il nostro post Top 20 Git Interview Questions and Answers for All Levels e di seguire il nuovo skill track Git Fundamentals per diventare un esperto di tutto ciò che riguarda Git.

Allan Ouko

Autore

Allan Ouko

Technical writer di Data Science con esperienza pratica in data analytics, business intelligence e data science. Scrivo contenuti pratici e orientati al settore su SQL, Python, Power BI, Databricks e data engineering, basati su lavoro di analytics reale. La mia scrittura unisce profondità tecnica e impatto sul business, aiutando i professionisti a trasformare i dati in decisioni sicure.

git reflog - Domande frequenti

Che cos’è Git reflog?

Git reflog è un reference log che traccia gli aggiornamenti delle punte dei branch e di HEAD, aiutandoti a recuperare commit persi e ad annullare errori.

In cosa Git reflog è diverso da Git log?

git log traccia la cronologia dei commit, mentre git reflog registra le modifiche ai riferimenti come HEAD e i branch.

Git reflog viene condiviso con i repository remoti?

No, git reflog è locale e non viene condiviso quando esegui il push su un repository remoto.

Il reflog traccia le modifiche non committate?

No, il reflog traccia solo le modifiche ai riferimenti e non registra il lavoro non committato.

Quali azioni creano voci di reflog?

Commit, checkout di branch, reset, rebase, merge e operazioni di stash generano tutti voci nel reflog.

Quanto durano le voci del reflog?

Per impostazione predefinita, le voci del reflog scadono dopo 90 giorni, ma questo è configurabile.

Argomenti

Correlato