Réécrire l'Histoire
Amend, rebase, reset et reflog
Introduction
Tu pénètres dans une aile secrète des Archives, dissimulée derrière une tapisserie ancienne. La pièce est faiblement éclairée par des bougies flottantes. Des parchemins raturés, grattés et réécrits s'empilent sur les étagères. Le Maître Archiviste referme la porte derrière toi d'un geste grave.
« Apprenti, tu maîtrises désormais les branches et la fusion des chroniques. Mais il existe un art plus ancien, plus puissant - et plus dangereux. Certains Archivistes d'élite savaient réécrire l'Histoire elle-même - modifier une entrée passée, réorganiser la chronologie, effacer un événement comme s'il n'avait jamais eu lieu. Cet art est utile, mais il obéit à une règle d'or absolue : on ne réécrit jamais une chronique qui a déjà été partagée avec d'autres guildes. »
Modifier le dernier commit - git commit --amend
Tu viens de consigner une entrée dans les archives, mais tu remarques une faute. Pas besoin de créer une nouvelle entrée - tu peux modifier la dernière :
Corriger le message du dernier commit
git commit --amend -m "Nouveau message corrigé" Ajouter un fichier oublié au dernier commit
git add fichier-oublie.txt
git commit --amend --no-edit L'option --no-edit conserve le message original. Le commit est remplacé par un nouveau (avec un hash différent).
Quand utiliser --amend ?
- Tu as fait une faute de frappe dans le message
- Tu as oublié d'ajouter un fichier
- Tu veux ajuster le contenu du dernier commit
--amend ne modifie pas le commit existant - il le remplace. L'ancien commit disparaît de l'historique visible (mais reste récupérable via git reflog).
Le Rebase - Réécrire la chronologie
Le git rebase est l'un des outils les plus puissants de Git. Il permet de rejouer tes commits sur une autre base, comme si tu avais commencé ton travail à partir d'un point plus récent.
Principe
Imagine que tu travailles sur une branche feature créée depuis main. Entre-temps, d'autres commits ont été ajoutés sur main. Le rebase prend tes commits et les rejoue un par un au sommet de main :
Avant le rebase :
C---D (feature)
/
A---B---E---F (main) Après git rebase main (depuis feature) :
C'---D' (feature)
/
A---B---E---F (main) Les commits C et D deviennent C' et D' - ce sont de nouveaux commits (nouveaux hashs) avec le même contenu, mais repositionnés.
Comment faire un rebase
# Se placer sur la branche à rebaser
git switch feature
# Rebaser sur main
git rebase main Tes commits de feature sont maintenant au-dessus des derniers commits de main. L'historique est linéaire et propre.
Rebase vs Merge - Le grand débat
Les deux permettent d'intégrer les changements d'une branche dans une autre, mais de manière très différente.
Merge (fusion)
git switch main
git merge feature C---D (feature)
/ \
A---B---E---F---G (main, commit de merge) - Crée un commit de fusion (merge commit)
- Préserve l'historique tel qu'il s'est réellement passé
- L'historique peut devenir complexe avec beaucoup de branches
Rebase
git switch feature
git rebase main C'---D' (feature)
/
A---B---E---F (main) - Pas de commit de fusion - historique linéaire
- Réécrit l'historique (nouveaux hashs)
- Plus facile à lire
Quand utiliser quoi ?
| Situation | Recommandation |
|---|---|
Mettre à jour ta branche avec les derniers changements de main | Rebase |
Intégrer une branche terminée dans main | Merge |
| Branche déjà partagée (push) | Merge (jamais rebase !) |
| Nettoyer l'historique avant de partager | Rebase |
La Règle d'Or
Rebase interactif - Un aperçu
Le rebase interactif (git rebase -i) permet de manipuler plusieurs commits à la fois : réordonner, fusionner, modifier, supprimer. C'est un outil extrêmement puissant que nous ne pratiquerons pas en exercice ici, mais que tu dois connaître :
git rebase -i HEAD~3 Cette commande ouvre un éditeur avec les 3 derniers commits et des options comme :
pick- garder le commit tel quelreword- modifier le messagesquash- fusionner avec le commit précédentdrop- supprimer le commit
C'est l'outil ultime pour nettoyer un historique avant de le partager.
Git Reset - Revenir en arrière
git reset permet de déplacer HEAD (et potentiellement la branche) vers un commit antérieur. Il existe trois modes, de plus en plus destructifs :
git reset --soft HEAD~1
git reset --soft HEAD~1 - Annule le dernier commit
- Les fichiers restent dans la zone de staging (prêts à être re-committés)
- Utile pour : reformuler un commit ou en changer le contenu
git reset --mixed HEAD~1 (par défaut)
git reset HEAD~1 - Annule le dernier commit
- Les fichiers retournent dans le répertoire de travail (non stagés)
- C'est le comportement par défaut (pas besoin de
--mixed) - Utile pour : retravailler les modifications avant de les re-committer
git reset --hard HEAD~1
git reset --hard HEAD~1 ATTENTION - DANGER ! Cette commande est destructive et irréversible (sauf via reflog). Elle supprime le commit ET toutes les modifications associées. Les fichiers modifiés sont perdus définitivement. Utilise-la uniquement si tu es absolument sûr de vouloir tout effacer.
Résumé visuel
| Mode | Commit | Staging | Fichiers |
|---|---|---|---|
--soft | Annulé | Conservés | Conservés |
--mixed (défaut) | Annulé | Vidé | Conservés |
--hard | Annulé | Vidé | Supprimés |
Git Reflog - Le filet de sécurité
Tu as fait une erreur ? Un reset --hard de trop ? Pas de panique. Git garde une trace secrète de tous les mouvements de HEAD dans le reflog :
git reflog Le reflog affiche chaque action qui a modifié HEAD : commits, rebase, reset, checkout... Même les commits "supprimés" y apparaissent pendant au moins 30 jours.
Récupérer un commit perdu
# 1. Trouver le hash du commit perdu dans le reflog
git reflog
# 2. Revenir à ce commit
git reset --hard <hash-du-commit-perdu> Le reflog est ton filet de sécurité ultime. Tant qu'un commit a existé, tu peux le retrouver.
Avant toute opération risquée (rebase, reset --hard), note le hash du commit actuel avec git log --oneline -1. En cas de problème, tu pourras toujours y revenir.
Exercice pratique - Nettoyer les chroniques
Le Maître Archiviste te confie un registre mal tenu. Des entrées contiennent des erreurs, la chronologie est confuse. Ta mission : remettre de l'ordre en utilisant --amend et rebase.
« Ces chroniques sont un désastre. Des fautes dans les entrées, des événements dans le désordre... Nettoie tout cela. Montre-moi que tu maîtrises l'art de réécrire l'Histoire. »
Étape 1 - Créer le registre
Crée un nouveau dossier et initialise un dépôt Git :
mkdir chroniques-nettoyees
cd chroniques-nettoyees
git init -b main Étape 2 - Consigner trois entrées (avec une erreur)
Crée un fichier registre.txt et fais 3 commits :
echo "Jour 1 : Fondation du royaume" > registre.txt
git add registre.txt
git commit -m "Ajouter l'entrée du Jour 1"
echo "Jour 2 : Alliance avec les elfes" >> registre.txt
git add registre.txt
git commit -m "Ajouter l'entrée du Jour 2"
echo "Jour 3 : Découverte de la mine d'or" >> registre.txt
git add registre.txt
git commit -m "Ajoouter l'entrée du Jour 3" Oups ! Le message du dernier commit contient une faute : "Ajoouter" au lieu de "Ajouter".
Étape 3 - Corriger avec --amend
Corrige le message du dernier commit :
git commit --amend -m "Ajouter l'entrée du Jour 3" Vérifie avec git log --oneline que le message est corrigé.
Étape 4 - Créer une branche parallèle
Crée une branche refonte-archives et ajoute-y des entrées :
git switch -c refonte-archives
echo "Jour 4 : Construction de la forteresse" >> registre.txt
git add registre.txt
git commit -m "Ajouter l'entrée du Jour 4"
echo "Jour 5 : Traité de paix avec les nains" >> registre.txt
git add registre.txt
git commit -m "Ajouter l'entrée du Jour 5" Étape 5 - Ajouter un commit sur main
Retourne sur main et ajoute un commit :
git switch main
echo "Annexe : Liste des rois" >> annexes.txt
git add annexes.txt
git commit -m "Ajouter la liste des rois en annexe" Étape 6 - Rebaser la branche
Rebase refonte-archives sur main pour obtenir un historique linéaire :
git switch refonte-archives
git rebase main Étape 7 - Vérifier le résultat
Admire l'historique propre et linéaire :
git log --oneline --graph --all Tu devrais voir tous les commits alignés sur une seule ligne, sans fourche ni commit de fusion.
Étape 8 - Lancer la vérification
Lance le script de vérification pour valider ta quête :
Bash (Linux / macOS / Git Bash sur Windows) :
bash verifier.sh PowerShell (Windows) :
.\verifier.ps1 Le script vérifie :
- Tu es dans un dépôt Git
- Tu as utilisé --amend (visible dans le reflog)
- Tu as effectué un rebase (visible dans le reflog)
- Au moins 3 commits existent dans l'historique
Le Maître Archiviste examine les chroniques réécrites, passant son doigt le long des lignes soigneusement réorganisées.