On ne peut pas à proprement parler supprimer un commit de Git. Mais on peut l’inverser proprement.
Assurez-vous d’avoir une copie de travail propre (sans files to be commited ou conflits, quitte à stasher). Puis:
git revert HEAD~1
Cette commande va immédiatement prendre le précédent commit, créer une commit exactement inverse, et l’appliquer.
Si vous aviez: C1 — C2 — C3
Et que vous vouliez annuler C3.
Vous allez vous retrouver avec: C1 — C2 — C3 — C4.
Avec C4 comme exacte inverse de C3.
Si vous voulez annuler plus d’un commit: git revert HEAD~nombre-de-commits
Y a plus qu’à pusher !
Ceci est complètement différent de git commit --amend
qui lui remplace le commit précédent par le commit actuel à condition de ne pas avoir pushé le commit précédent.
Avec amend, si vous aviez:
Si vous aviez: C1 — C2 — C3
Et que vous vouliez annuler C3.
Vous allez vous retrouver avec: C1 — C2 — C4
Mais il faut créer C4 de toute pièce.
revert
, c’est comme Cabrel: c’était mieux avant.
amend
, c’est comme Britney: ooups, I did it again.
Super commande, mais le amend ne sert pas reellement dans ces conditions. Il vaut mieux faire un `git rebase -i HEAD~nombre_de_commit’ pour changer l’histoire du depot (remetre dans l’ordre, supprimer ou modifier un commit et son message).
Petit detail : Git est decentralise, donc il ne veut pas imposer certains choix a ces utilisateurs. La notion de ‘avoir pushe’ n’a pas de sens dans le cas car tu veux pouvoir avoir plusieurs depots distants attaches a ton depot local.
Quand tu dis creer le C4 de toute piece, tu veux dire `git diff co_actuel co_precedent > patch && git apply patch’ ?
Merci du tuyaux, je cherchais ça depuis longtemps !
Connais-tu la différence avec
git reset --hard
(comme expliqué dans un de mes articles SVN revert mais avec Git mis à jour pour l’occassion ;-)) ? Si je comprends bien avec “revert” on reste en local, alors qu’avec “reset” on créé un nouveau commit contenant une branche donnée, par exemple “origin/master”.@Vash: je suis d’accord avec toi pour le côté décentralisé mais:
1 – 99 % utilisent un repo central
2 – ces mêmes gens auraient de problèmes avec un amend qu’il auraient pushé sur ce repo central.
Pour des personnes qui comprennent cette subtilité, l’article est de toute façon inutile, donc je saute cette précision.
Et pour le “de toute pièce”, je veux dire qu’il faut faire les modification à la main soi-même. Cette commande diff peut faire l’affaire, mais seulement à condition que ton diff editor n’ai pas été changé, ce qui est le cas pour les débutant qui utilisent un truc graphique comme meld.
Je vise les gens qui se prennent la tête avec Git, il faut donc penser à ce genre de choses. Trop d’explications sur Git balance les commandes pour faire le malin “regarde on peut faire ça et ça et ça”. Les gens en ont rien à foutre, ils veulent juste que ça marchent.
Avec git, il faut trouver un équilibre subtile entre le clé en main et l’explication, car sans comprendre, on finit par se gauffrer, mais si on explique tout, on perd le client.
@Rylhan: les deux créent un commit, mais si on utilise reset et qu’on a pushé avant, on va se payer plus de problèmes de conflits.
@Sam : Pour te dire, je ne savais pas qu’on pouvait changer le diff editor. Je trouve la ligne de commande plus pratique dans ma facon d’utiliser git. Mais la n’est pas la question. Personellemet j’ai très peu configurer git. Les commandes de bases (à par des raccourcies) me suffisent.
Je n’ai pas l’impression d’avoir joué à qui balance la commande la plus longue. Je mettais, un peu brutalement je l’avoue, des pointeurs sur des particularités de git liés au sujet. Perso, j’aime bien avoir des pointeurs sur des sujets liés à l’article de base.