infra / git-github
Reflog : récupérer des commits perdus
Explication
Ce que vous allez apprendre
- Comprendre que le reflog garde une trace de presque tout ce que tu fais avec HEAD
- Récupérer un commit apparemment perdu après un
reset --hardmalencontreux - Retrouver et restaurer une branche supprimée par erreur
- Comprendre les deux limites du reflog : local à la machine, et avec une durée de vie limitée
- Adopter le réflexe "consulter le reflog" avant de paniquer après une manipulation destructive
Dans quel contexte ?
Un développeur tape git reset --hard HEAD~3 en pensant annuler un seul commit expérimental, mais réalise immédiatement qu'il vient d'effacer trois commits utiles, dont deux jours de travail sur boutique-api. Plutôt que de recommencer ce travail depuis zéro, git reflog révèle que ces commits existent encore, simplement invisibles dans les vues habituelles.
La peur classique du débutant
D'abord, une des plus grandes peurs quand on débute avec Git est de "casser" son historique avec une commande destructrice comme reset --hard, en croyant avoir perdu du travail pour de bon.
La bonne nouvelle
Bonne nouvelle : Git garde en réalité une trace de presque tout ce que tu fais, même ce qui semble avoir disparu.
Le filet de sécurité méconnu
Le reflog est ce filet de sécurité : un journal local qui enregistre chaque déplacement du pointeur HEAD, chaque commit, chaque reset, chaque changement de branche.
Ce qu'il garde même quand ça semble perdu
Il inclut même les commits qui ne sont techniquement plus rattachés à aucune branche visible.
Le point conceptuel clé : supprimé n'est pas effacé
Quand un commit "disparaît" après un reset --hard ou une suppression de branche, il n'est en réalité pas immédiatement effacé du disque.
Ce qui se passe réellement
Il devient simplement invisible dans les vues habituelles, git log ou git branch, car plus aucune référence ne pointe directement vers lui. Le reflog, lui, garde la mémoire de son existence.
La procédure de sauvetage
Face à une perte apparente, le réflexe est toujours le même : consulter git reflog pour identifier l'identifiant du commit juste avant l'accident.
Deux façons de le récupérer ensuite
Ensuite, soit y revenir directement, soit créer une nouvelle branche à partir de ce point pour sécuriser le travail retrouvé sans perturber l'état actuel.
Bonne pratique
Après avoir retrouvé un commit via le reflog, crée immédiatement une nouvelle branche dessus (git switch -c recovery/nom) plutôt que de rester en mode "detached HEAD". Cela sécurise définitivement le travail retrouvé, qui redeviendrait sinon vulnérable au prochain nettoyage automatique de Git.
Deux limites à garder en tête
Le reflog est strictement local à ta machine : il ne se partage jamais via push/pull, donc il ne protège pas contre la perte de ton disque.
Une seconde limite : il expire
Il expire aussi au bout de plusieurs semaines. Ce n'est donc pas un substitut à une vraie sauvegarde distante, seulement une seconde chance à court terme.
| Limite du reflog | Conséquence |
|---|---|
| Local à la machine | Ne se partage jamais via push/pull |
| Expire (90 jours par défaut) | Pas un substitut à un vrai backup distant |
| Ne couvre que HEAD | Ne remplace pas git push pour sécuriser un travail important |
La leçon suivante s'attaque à un besoin différent : marquer un moment important dans l'historique de façon permanente, avec les tags et les releases.
Commandes & code
Reflog
Le reflog trace TOUS les mouvements de HEAD localement (commits, resets, rebases, checkouts) même ceux qui semblent "perdus".
# Historique complet des déplacements de HEAD sur cette machine
git reflog
# a1b2c3d HEAD@{0}: commit: Add payment retry logic
# e4f5g6h HEAD@{1}: reset: moving to HEAD~1 <- un reset --hard récent
# h7i8j9k HEAD@{2}: commit: Fix flaky test# Scénario catastrophe : un "reset --hard" a fait disparaître un commit important
git reset --hard HEAD~3 # oups, 3 commits utiles viennent de "disparaître"
git reflog
# a1b2c3d HEAD@{1}: commit: Add payment retry logic <- toujours là dans le reflog !
# Récupérer ce commit précis
git checkout a1b2c3d # inspecter d'abord en mode detached HEAD
git switch -c recovery/payment-logic # créer une branche pour le sauver définitivement
# Ou directement, si on sait déjà où on veut revenir
git reset --hard HEAD@{1}# Récupérer une branche supprimée par erreur
git branch -D feature/important
git reflog | grep "feature/important"
# retrouver le SHA du dernier commit de cette branche, puis :
git branch feature/important a1b2c3d# Le reflog n'est PAS partagé (local uniquement) et a une durée de vie limitée
git config --get gc.reflogExpire # par défaut : 90 jours pour les commits atteignables
git config --get gc.reflogExpireUnreachable # 30 jours pour les commits inatteignables
# Forcer la conservation avant un grand nettoyage
git reflog expire --expire=never --allRésumé
- Le reflog enregistre localement chaque déplacement de HEAD, même après un
reset --hard. git reflog+git reset --hard HEAD@{n}ougit branch <nom> <sha>sauvent une branche "perdue".- Le reflog est LOCAL à la machine et expire (90 jours par défaut) : ce n'est pas un backup distant.
- Toujours vérifier
git reflogavant de paniquer après une manipulation destructive.
Exercices pratiques
Mission : sauver deux jours de travail après un reset raté
Objectif : Utiliser le reflog pour retrouver et sécuriser des commits apparemment perdus après une manipulation destructive.
Contexte
Un développeur tape git reset --hard HEAD~3 en pensant annuler un seul commit expérimental, mais efface en réalité trois commits utiles représentant deux jours de travail sur boutique-api.