
[GIT] Réécrire l’histoire
Dans le passé, j’ai fait un commit avec le mauvais utilisateur (Bruce Wayne). Je souhaite réécrire l’histoire et changer l’utilisateur (Batman).
Tout d’abord, il faut trouver quels sont les commit que l’on souhaite modifier. Comme git log
n’est pas très lisible, on va se faire un petit alias qui affiche les logs sur 1 ligne.
Pour cela, on va éditer le fichier .gitconfig
et ajouter :
[alias]
lol = log --pretty=format:"%h\\ %ad%d\\ %s\\ [%cn\\ %ce]" --decorate --date=short
lolc = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn\\ %ce]" --decorate --date=short
tree = log --graph --decorate --pretty=oneline --abbrev-commit
Ainsi git lol
donnera les infos sur 1 seule ligne. Git lolc
affichera la même chose mais avec des couleurs.
Avec git lol
, je repère les commits qui ont été faits par l’utilisateur « Bruce Wayne ».
Supposons que l’historique soit A-B-C-D-E-F
, F
étant HEAD
.
Je dois modifier les commits C
et D
.
- Je fais un rebase interactif sur le commit précédent celui que je veux modifier :
git rebase -i B
Si j’avais besoin de modifier le tout premier, j’aurais utilisé git rebase -i --root
- Un éditeur va s’ouvrir avec la liste de tous les commits. Il faut modifier
pick
enedit
sur tous les commits qu’on souhaite changer. - On sauvegarde et on quitte (
Echap :wq
si on est sous vim). - Le rebase va commencer et s’arrêter à
C
. - On fait amende honorable de ce commit avec :
git commit --amend --author="Batman <batman@gotham.city>"
- Je continue le rebase avec :
git rebase --continue
- Je procède de la même manière pour changer tous mes commits.
- Dans le cas où il y a un problème de merge (avec un fichier binaire par exemple), on peut choisir le fichier à garder :
git checkout --theirs -- [nom du fichier]
git add [nom du fichier]
- Une fois tout l’historique remonté, je termine avec :
git push --force-with-lease
Si ça ne marche pas, on peut forcer comme un bourrin avec git push -f
- Si après ça il reste des mentions de commits non souhaités, on peut forcer le garbage collector à passer avec :
git gc --prune=now --aggressive
Pour aller plus loin
Comment supprimer des merges : https://stackoverflow.com/questions/17577409/git-remove-merge-commit-from-history/17577876