Retour au cours

infra / git-github

Reflog : récupérer des commits perdus

Leçon 111 exercice

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 --hard malencontreux
  • 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 reflogConséquence
Local à la machineNe se partage jamais via push/pull
Expire (90 jours par défaut)Pas un substitut à un vrai backup distant
Ne couvre que HEADNe 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".

bash
# 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
bash
# 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}
bash
# 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
bash
# 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 --all

Résumé

  • Le reflog enregistre localement chaque déplacement de HEAD, même après un reset --hard.
  • git reflog + git reset --hard HEAD@{n} ou git 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 reflog avant de paniquer après une manipulation destructive.

Exercices pratiques

1 disponible
1

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.

Résoudre l’exercice →