+++ date = '2025-10-20T00:01:00+02:00' draft = false title = "Réécrire l'historique Git : Changer les auteurs des commits" +++ Depuis peu j'ai effectué un changement de cap, de vision, de volonté. J'ai viré certains services, certaines habitudes. J'en ai ancré d'autres. Ça m'est déjà arrivé - et ça m'arrivera surement encore - et à chaque fois, la même chose, un changement de pseudo, voire une nouvelle url, et hop ! Pour cette fois ci, je voulais changer les auteurs de commits des dépots git, pour ne pas avoir plusieurs identité sur le même dépôt, ayant peur que certaines personne s'inquiète d'une éventuelle schizophrénie. ## Cas 1 : Remplacer tous les auteurs Si vous souhaitez remplacer **tous** les auteurs par une seule identité : ```bash git filter-repo --commit-callback ' commit.author_name = b"Votre Nom" commit.author_email = b"email@exemple.com" commit.committer_name = b"Votre Nom" commit.committer_email = b"email@exemple.com" ' --force ``` Cette commande parcourt tous les commits et remplace systématiquement l'auteur et le committer. **Points importants :** - Les valeurs doivent être en bytes Python (`b"..."`) - Le flag `--force` est nécessaire pour les remplacements (sans confirmation) - Cette opération recrée les commits, ce qui change leurs SHA ## Cas 2 : Remplacer un auteur spécifique Si vous aviez plusieurs auteurs mais voulez corriger un seul d'entre eux, utilisez une condition : ```bash git filter-repo --commit-callback ' if commit.author_name == b"Ancien Nom": commit.author_name = b"Nouveau Nom" commit.author_email = b"nouvel@email.com" commit.committer_name = b"Nouveau Nom" commit.committer_email = b"nouvel@email.com" ' --force ``` ## Cas 3 : Remplacer uniquement le nom ou uniquement l'email Vous pouvez aussi appliquer des transformations plus granulaires. Par exemple, remplacer uniquement les noms : ```bash git filter-repo --name-callback 'return b"Nouveau Nom"' --force ``` Ou uniquement les emails : ```bash git filter-repo --email-callback 'return b"nouvel@email.com"' --force ``` ## Workflow complet : exemple pratique Imaginons que vous avez des commits avec le nom "Tartanpion" et l'email "ancien@email.com", et vous souhaitez les corriger : ### 1. Vérifiez les auteurs actuels Avant de commencer, voyez qui a contribué : ```bash git log --format='%an <%ae>' | sort | uniq ``` Cela affiche une liste unique de tous les auteurs. ### 2. Lancez le filtre ```bash git filter-repo --commit-callback ' if commit.author_name == b"Tartanpion": commit.author_name = b"DuN0Z" commit.author_email = b"dunoz@porzh.me" commit.committer_name = b"DuN0Z" commit.committer_email = b"dunoz@porzh.me" ' --force ``` ### 3. Vérifiez le résultat ```bash git log --format='%an <%ae>' | sort | uniq ``` Les auteurs devraient maintenant être corrects. ### 4. Vérifiez l'intégrité ```bash git fsck ``` Cette commande vérifie que le référentiel Git est cohérent. ### 5. Forcez le push Puisque vous avez modifié l'historique, vous devez forcer le push sur le serveur distant : ```bash git push origin master --force ``` **Attention :** Le `--force` réécrit l'historique sur le serveur. Assurez-vous que c'est acceptable dans votre équipe ou repo personnel. ## Pièges courants **Refus de git filter-repo sans --force :** Par défaut, Git refuse de réécrire l'historique. Le flag `--force` l'autorise. Utilisez-le consciemment. **Les anciennes références restent locales :** Après le filtrage, Git conserve les anciennes références dans `.git/refs/original/`. Vous pouvez les supprimer : ```bash rm -rf .git/refs/original/ git reflog expire --expire=now --all git gc --prune=now ``` **Collaborateurs affectés :** Si d'autres personnes utilisent ce dépôt, elles devront re-cloner ou rebaser leurs branches locales. Coordonnez-vous ! Moi je m'en fou, ce sont des dépots perso, sur mon instance perso que personne connait. Comme ce blog d'ailleurs, j'adore jeter des bouteilles à la mer ! :-) ## Après le push forcé Une fois le push forcé effectué, le serveur distant reflète les nouveaux commits. Les anciens commits restent temporairement accessibles (garbage collection), mais ils sont progressivement nettoyés. Pour les collaborateurs qui auraient cloner l'ancien historique : ```bash git fetch origin git reset --hard origin/master ``` ## Conclusion Réécrire l'historique Git avec `git filter-repo` est une opération puissante mais à manier avec prudence. Elle est particulièrement utile pour corriger des erreurs de configuration ou pour nettoyer des commits avant de les partager largement. Toujours double-vérifier, et n'hésitez pas à tester sur une copie avant d'affecter votre vrai dépôt. Si vous cherchez à éviter ce problème à l'avenir, configurez correctement votre identité Git : ```bash git config --global user.name "Votre Nom" git config --global user.email "email@exemple.com" ``` Surtout valable si vous avez plusieurs machines, ça peut vite devenir le bordel. Ou alors, vous les mettez toutes sous NixOs, et en faisant votre configuration, vous importez le meme fichier `git.nix` partout. Vous savez quoi ? une machine n'avais pas la même identité, le Mac .... un bon retour de baton dans la gueule ça ! Et vérifiez occasionnellement avec `git log` que vos commits sont signés correctement.