25854 votes

Comment annuler les derniers commits locaux dans Git ?

J'ai accidentellement commis les mauvais fichiers dans Git, mais je n'ai pas encore poussé le commit sur le serveur.

Comment puis-je annuler ces commits depuis le dépôt local ?

2 votes

Voir ce guide pour annuler les engagements Git sur Local, Public et Git Branch Comment annuler les engagements Git comme un pro

663 votes

Tu sais de quoi git a besoin? git undo, c'est tout. Ensuite, la réputation de git pour la gestion des erreurs commises par nous, simples mortels, disparaît. Implémentez en poussant l'état actuel sur une pile git avant d'exécuter n'importe quelle commande git. Cela affecterait les performances, il serait donc préférable d'ajouter un indicateur de configuration pour décider de l'activer.

57 votes

@YiminRong Cela peut être fait avec la fonction alias de Git : git-scm.com/book/en/v2/Git-Basics-Git-Aliases

28258voto

Esko Luontola Points 53877

Annuler un commit et recommencer

$ git commit -m "Quelque chose de terriblement malavisé" # (0: Votre accident)
$ git reset HEAD~                              # (1)
[ modifier les fichiers si nécessaire ]                    # (2)
$ git add .                                    # (3)
$ git commit -c ORIG_HEAD                      # (4)
  1. git reset est la commande responsable de l'annulation. Elle annulera votre dernier commit tout en laissant votre arborescence de travail (l'état de vos fichiers sur le disque) intacte. Vous devrez les ajouter à nouveau avant de pouvoir les committer à nouveau.
  2. Apportez des corrections aux fichiers de l'arborescence de travail.
  3. git add tout ce que vous souhaitez inclure dans votre nouveau commit.
  4. Validez les modifications en réutilisant l'ancien message de commit. reset a copié l'ancienne tête dans .git/ORIG_HEAD; commit avec -c ORIG_HEAD ouvrira un éditeur, qui contient initialement le message de log de l'ancien commit et vous permet de l'éditer. Si vous n'avez pas besoin de modifier le message, vous pourriez utiliser l'option -C.

Alternativement, pour modifier le commit précédent (ou juste son message de commit), commit --amend ajoutera les modifications dans l'index actuel au commit précédent.

Pour supprimer (et non revenir en arrière) un commit qui a été poussé sur le serveur, il est nécessaire de recréer l'historique avec git push origin main --force[-with-lease]. C'est presque toujours une mauvaise idée d'utiliser --force; préférez plutôt --force-with-lease et comme indiqué dans le manuel de git:

Vous devez comprendre les implications de la modification de l'historique si vous modifiez un commit qui a déjà été publié.


Lecture complémentaire

Vous pouvez utiliser git reflog pour déterminer le SHA-1 du commit vers lequel vous souhaitez revenir. Une fois que vous avez cette valeur, utilisez la séquence de commandes comme expliqué ci-dessus.


HEAD~ est la même que HEAD~1. L'article Qu'est-ce que le HEAD en git? est utile si vous voulez annuler plusieurs commits.

588 votes

Et si le commit a été effectué sur la mauvaise branche, vous pouvez git checkout theRightBranch avec toutes les modifications en attente. Comme je viens de le faire.

577 votes

Si vous travaillez sous DOS, au lieu de git reset --soft HEAD^, vous devrez utiliser git reset --soft HEAD~1. Le ^ est un caractère de continuation dans DOS, donc cela ne fonctionnera pas correctement. De plus, --soft est la valeur par défaut, vous pouvez donc l'omettre si vous le souhaitez et simplement dire git reset HEAD~1.

160 votes

Les utilisateurs de zsh pourraient obtenir: zsh: aucune correspondance trouvée: HEAD^ - vous devez échapper ^ c'est-à-dire git reset --soft HEAD\^

12521voto

Kyralessa Points 76456

Annuler un commit est un peu effrayant si vous ne savez pas comment cela fonctionne. Mais c'est en fait étonnamment facile si vous comprenez. Je vais vous montrer les 4 différentes façons d'annuler un commit.

Disons que vous avez ceci, où C est votre HEAD et (F) est l'état de vos fichiers.

   (F)
A-B-C
    ↑
  master

Option 1: git reset --hard

Vous voulez détruire le commit C et également jeter tout changement non validé. Vous faites ceci :

git reset --hard HEAD~1

Le résultat est :

 (F)
A-B
  ↑
master

Maintenant B est le HEAD. Parce que vous avez utilisé --hard, vos fichiers sont réinitialisés à leur état au commit B.

Option 2: git reset

Peut-être que le commit C n'était pas un désastre, mais juste un peu hors sujet. Vous voulez annuler le commit mais conserver vos changements pour un peu d'édition avant de faire un meilleur commit. En repartant d'ici, avec C comme votre HEAD:

   (F)
A-B-C
    ↑
  master

Faites ceci, en laissant de côté le --hard:

git reset HEAD~1

Dans ce cas, le résultat est :

   (F)
A-B-C
  ↑
master

Dans les deux cas, HEAD est juste un pointeur vers le dernier commit. Lorsque vous faites un git reset HEAD~1, vous dites à Git de déplacer le pointeur HEAD en arrière d'un commit. Mais (à moins que vous n'utilisiez --hard) vous laissez vos fichiers tels qu'ils étaient. Donc maintenant, git status montre les changements que vous aviez validés dans C. Vous n'avez rien perdu !

Option 3: git reset --soft

Pour la touche la plus légère, vous pouvez même annuler votre commit mais laisser vos fichiers et votre index:

git reset --soft HEAD~1

Cela ne modifie pas vos fichiers et laisse même votre index tel quel. Lorsque vous faites git status, vous verrez que les mêmes fichiers sont dans l'index qu'auparavant. En fait, juste après cette commande, vous pourriez faire git commit et vous reprendriez le même commit que vous aviez auparavant.

Option 4: vous avez fait git reset --hard et avez besoin de récupérer ce code

Une chose de plus : Supposons que vous détruisez un commit comme dans le premier exemple, mais découvrez ensuite que vous en aviez besoin après tout ? Pas de chance, n'est-ce pas ?

Non, il y a encore un moyen de le récupérer. Tapez ceci

git reflog

et vous verrez une liste de (partiels) SHAs de commit que vous avez déplacés. Trouvez le commit que vous avez détruit, et faites ceci :

git checkout -b someNewBranchName shaYouDestroyed

Vous avez maintenant ressuscité ce commit. Les commits ne sont pas réellement détruits dans Git pendant environ 90 jours, donc vous pouvez généralement retourner en arrière et sauver un que vous n'avez pas voulu supprimer.

2 votes

@Kyralessa: Si je fais git reset --hard HEAD^ deux fois, l'état va-t-il passer à (A)?

1 votes

Ne fonctionne pas avec OS X. - Je reçois "argument ambigu 'HEAD^' ... Révision inconnue ou chemin ne se trouve pas dans l'arborescence de travail". Utiliser la version tilde ne fait aucune différence. Mais git log et git status semblent tous deux montrer qu'il y a un commit valide en place

1 votes

@Kyralessa - oui, je pense que c'est peut-être le problème. Dans ce cas, j'ai commis quelque chose que je pensais être petit - et quand j'ai essayé de Push, j'ai découvert que c'était 400 Mo de données (!) (un dossier Resources profondément imbriqué contenant des fichiers vidéo et musique). Donc, je dois annuler la validation, mais conserver les fichiers sources, et je les validerai plus tard, lorsque j'aurai une meilleure connexion Internet - ou dans un dépôt différent.

2665voto

Andrew Points 30079

Il existe deux façons d' "annuler" votre dernier commit, en fonction que vous l'ayez déjà rendu public (poussé vers votre dépôt distant) ou non :

Comment annuler un commit local

Disons que j'ai commité localement, mais maintenant je veux supprimer ce commit.

git log
    commit 101: mauvais commit    # Dernier commit. Celui-ci serait appelé 'HEAD'.
    commit 100: bon commit   # Avant-dernier commit. C'est celui que nous voulons.

Pour restaurer tout à l'état avant le dernier commit, nous devons faire un reset au commit précédent HEAD :

git reset --soft HEAD^     # Utilisez --soft si vous voulez conserver vos modifications
git reset --hard HEAD^     # Utilisez --hard si vous ne vous souciez pas de conserver les modifications que vous avez apportées

Maintenant git log montrera que notre dernier commit a été supprimé.

Comment annuler un commit public

Si vous avez déjà rendu vos commits publics, vous voudrez créer un nouveau commit qui "annulera" les modifications apportées dans votre commit précédent (HEAD actuel).

git revert HEAD

Vos modifications seront maintenant annulées et prêtes pour vous à commit :

git commit -m 'restaurer le fichier que j'ai supprimé par erreur'
git log
    commit 102: restaurer le fichier que j'ai supprimé par erreur
    commit 101: supprimer un fichier que nous n'avons pas besoin
    commit 100: ajouter un fichier dont nous avons besoin

Pour plus d'informations, consultez Git Basics - Annuler des choses.

136 votes

J'ai trouvé cette réponse la plus claire. git revert HEAD^ n'est pas le précédent, c'est le précédent du précédent. J'ai fait : git revert HEAD puis poussé à nouveau et ça a fonctionné :)

9 votes

Si Git vous demande "More?" lorsque vous essayez ces commandes, utilisez la syntaxe alternative de cette réponse : stackoverflow.com/a/14204318/823470

0 votes

revert a supprimé certains fichiers que j'avais ajoutés à mon dépôt. Utilisez-le avec prudence !

1922voto

bdonlan Points 90068

Ajoutez/supprimez des fichiers pour obtenir ce que vous voulez :

git rm classdir
git add sourcedir

Ensuite, amender le commit :

git commit --amend

Le commit précédent, erroné, sera modifié pour refléter le nouvel état de l'index - en d'autres termes, ce sera comme si vous n'aviez jamais fait l'erreur en premier lieu.

Remarquez que vous ne devriez faire cela que si vous n'avez pas encore poussé. Si vous avez déjà poussé, alors vous devrez simplement commettre une correction normalement.

22 votes

FYI: Cela supprime tous mes fichiers et j'ai perdu les changements.

0 votes

UPD: Cependant, je l'ai restauré en utilisant reflog. Mais le reçu n'a pas fonctionné pour le commit initial.

10 votes

Utilisez git rm --cached pour conserver les fichiers dans le système de fichiers et les supprimer uniquement de l'index git !

1265voto

Lennart Koopmann Points 4533

Cela ajoutera un nouveau commit qui supprime les fichiers ajoutés.

git rm yourfiles/*.class
git commit -a -m "supprimé tous les fichiers .class dans le dossier 'yourfiles'"

Ou vous pouvez réécrire l'historique pour annuler le dernier commit.

Attention : cette commande va supprimer définitivement les modifications apportées aux fichiers .java (et à tout autre fichier) que vous avez commités -- et supprimer toutes vos modifications de votre répertoire de travail :

git reset --hard HEAD~1

La réinitialisation dure à HEAD-1 ramènera votre copie de travail à l'état du commit précédant votre mauvais commit.

28 votes

git commit -a -m "" ou git commit -am "" naturellement! :]

0 votes

Une autre utilisation "astuce" de la stash ; si vous voulez annuler tout (défaire git add), tapez simplement git stash, puis git stash pop

12 votes

Gosh... cette réponse devrait être supprimée. git reset --hard HEAD-1 est incroyablement dangereux - ce n'est pas juste "d'annuler le commit", cela supprime également toutes vos modifications, ce qui n'est pas ce que l'utilisateur initial a demandé. Malheureusement, j'ai appliqué cette réponse (que StackOverflow montre pour une raison quelconque en premier plutôt que la réponse acceptée avec 26k votes positifs) et je vais maintenant avoir du mal à récupérer toutes mes modifications.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X