Skip to content

La machine à remonter le temps de Git : le reflog

Vous avez rebasé un peu trop fort, supprimé « la mauvaise branche » avec un flegme admirable, ou fusionné sur main un vendredi à 18h ? Respirez. Git a un airbag.

Il s’appelle le reflog. Pensez‑le comme la boîte noire de votre dépôt : chaque mouvement de HEAD y est consigné - commit, merge, rebase, checkout… Et oui, ça veut dire « retour en arrière quand vous avez cartonné ».

Vous pouvez l’afficher avec :

shell
git reflog

Vous verrez un journal privé, antéchronologique, de tout ce qui s’est passé sur votre dépôt local.

shell
93fbb13 (HEAD -> feature/GG-2_deploymentTooling) HEAD@{0}: commit: task(deployment): some stuff
d7e56ba HEAD@{1}: commit: task(deployment): fixing issues
33246f4 HEAD@{2}: pull origin feature/doc: Merge made by the 'ort' strategy.
783d150 HEAD@{3}: commit: task(deployment): cleanup
2bcb935 HEAD@{4}: commit: task(deployment): Added pipeline
ce2bee3 HEAD@{5}: commit: task(deployment): init script
0dfcf77 HEAD@{6}: checkout: moving from main to feature/GG-2_deploymentTooling

Et si je vous disais que vous pouvez l’utiliser pour revenir à n’importe lequel de ces états et récupérer votre dépôt, vos commits et vos fichiers tels qu’ils étaient ?

Nom de Zeus !

Regardons le reflog. Vous voyez ces références HEAD@{x} ? Ce sont des pointeurs flottants vers n’importe quel état précédent de votre dépôt. À chaque commande exécutée, l’état courant est poussé plus bas dans la liste (style FILO). Pour revenir à un point précis, utilisez le hash de commit affiché à côté.

La lecture peut sembler un peu dense, mais l’idée est simple : repérez le moment où vous avez fait l’erreur, puis ancrez‑vous à l’état « juste avant ».

Supposons que je me sois trompé : je voulais rebaser, pas fusionner, et je veux revenir juste avant d’avoir fait le pull. Je vois que l’entrée correspondant au pull est 33246f4 HEAD@{2}. Je préfère revenir juste avant, donc sur 783d150 HEAD@{3}. Je n’ai plus qu’à faire un reset dessus :

shell
git reset --hard 783d150

Et voilà : ma branche redevient exactement comme au commit task(deployment): cleanup.

shell
$> git log
commit 783d1503f9054440912c3df1d73f8242fe682966 (HEAD -> feature/GG-2_deploymentTooling)
Author: Mickaël Forgh <mickael.forgh@git-gud.com>
Date:   Mon Oct 27 22:34:11 2025 +0100

    task(deployment): cleanup

commit 2bcb935549942b197bb331c48b348a6b7362f2c0
Author: Mickaël Forgh <mickael.forgh@git-gud.com>
Date:   Mon Oct 27 22:34:00 2025 +0100

    task(deployment): Added pipeline

commit ce2bee3f1d853ca9d9e5d546f6560fde6b2b4704
Author: Mickaël Forgh <mickael.forgh@git-gud.com>
Date:   Mon Oct 27 22:33:46 2025 +0100

    task(deployment): init script

commit 0dfcf7771114be2daff46ddc9218f3605cd04398
Author: Mickaël Forgh <mickael.forgh@git-gud.com>
Date:   Wed Oct 1 02:57:13 2025 +0200

    feat(doc): workflow big picture and feature branch

Au passage, le reset que vous venez d’effectuer a aussi été ajouté au reflog. Si vous regrettez votre voyage temporel et voulez « revenir vers le futur », servez‑vous du reflog pour retrouver l’état précédent.

Branche courante

Attention : reset --hard remet les commits de votre branche dans l’état choisi, mais ne change pas la branche sur laquelle vous êtes. Si vous êtes sur main et faites un hard reset vers un commit d’une branche de fonctionnalité, vous récupérerez ces commits… mais vous resterez sur main.

Commitez vos changements régulièrement

Cette technique ne permet de revenir qu’à un état déjà enregistré par un commit. Elle ne retrouvera pas un fichier que vous n’avez jamais pris la peine de committer. Donc, commitez fréquemment !