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 ?
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 ?
$ 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)
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.git add
tout ce que vous souhaitez inclure dans votre nouveau 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é.
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.
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.
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
.
Les utilisateurs de zsh pourraient obtenir: zsh: aucune correspondance trouvée: HEAD^
- vous devez échapper ^ c'est-à-dire git reset --soft HEAD\^
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
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.
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 !
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.
git reset --hard
et avez besoin de récupérer ce codeUne 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.
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
@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.
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 :
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é.
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.
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é :)
Si Git vous demande "More?" lorsque vous essayez ces commandes, utilisez la syntaxe alternative de cette réponse : stackoverflow.com/a/14204318/823470
revert
a supprimé certains fichiers que j'avais ajoutés à mon dépôt. Utilisez-le avec prudence !
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.
UPD: Cependant, je l'ai restauré en utilisant reflog. Mais le reçu n'a pas fonctionné pour le commit initial.
Utilisez git rm --cached
pour conserver les fichiers dans le système de fichiers et les supprimer uniquement de l'index git !
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.
Une autre utilisation "astuce" de la stash ; si vous voulez annuler tout (défaire git add), tapez simplement git stash
, puis git stash pop
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 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.
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 commandegit
. 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-Aliases124 votes
Pour les utilisateurs de VsCode, il suffit de taper ctrl +shift +G puis de cliquer sur les trois points, c'est-à-dire, plus d'options, puis de cliquer sur Annuler la dernière validation.
26 votes
@YiminRong Annuler quoi exactement? Il existe des dizaines de cas fonctionnels très différents où "annuler" signifie quelque chose de complètement différent. Je parie que l'ajout d'une nouvelle baguette magique ne ferait qu'embrouiller encore plus les choses.
49 votes
@YiminRong Je n'achète pas cela. Les gens continueraient à se tromper et à annuler des choses qui ne doivent pas être annulées. Mais plus important encore,
git reflog
est déjà proche de ce que vous décrivez, mais donne à l'utilisateur plus de contrôle sur ce qu'il doit faire (ou ne pas faire). Mais s'il vous plaît, non, "annuler" ne fonctionne pas de la même manière partout, et les gens s'attendraient à de nombreuses choses différentes pour que la fonctionnalité soit accomplie. Annuler le dernier commit? Annuler la dernière action? Si la dernière action était un push, annuler comment exactement, (réinitialiser et push) ou (revenir en arrière et push)?10 votes
Pour faire quelque chose de simple dans git, soit effectuer la tâche extrêmement difficile A, soit la tâche extrêmement difficile B. Ensuite, faites une petite erreur et essayez de revenir en arrière en effectuant la tâche extrêmement difficile C ou la tâche extrêmement difficile D.
4 votes
Git est un framework pour gérer la version de nombreux fichiers et permettre le travail collaboratif. Il nécessite un contrôle absolu sur ce que vous faites pour atteindre ces objectifs. C'est génial précisément parce qu'il essaie de laisser de côté toute la "magie" inutile. Quelque chose comme
git undo
est généralement une mauvaise idée, mais c'est ridiculement facile à implémenter si vous le souhaitez vraiment. Mais ensuite, soyez conscient, vous en êtes responsable. Je trouve vraiment incroyable comment les gens abandonneraient si promptement le contrôle pour éviter d'avoir à apprendre des choses. Git est facile, vous devez juste apprendre les concepts.2 votes
"défaire des choses qui ne peuvent être défaites" - Ces choses seraient toutes les choses. Comment puis-je vraiment faire confiance à mon code source à quelque chose qui me permet (ou à d'autres) de changer l'histoire.
8 votes
S'opposer à une commande
undo
est une rigidité artificielle. Oui, vous pouvez le faire avec une combinaison dereflog
, dereset
et decheckout
. Le problème est que c'est une expression totalement artificielle de l'intention pour quiconque ne le fait pas régulièrement. Mercurial arollback
et cela n'a rien cassé. Git devrait avoir quelque chose aussi.4 votes
Vous pouvez installer git-extras qui sont un ensemble de fonctions utilitaires git - inclut la commande
git undo
pour annuler le commit le plus récent. Je l'utilise tout le temps lorsque je viens de commettre quelque chose (et n'ai pas encore poussé) et j'ai besoin d'ajouter un fichier non suivi ou de modifier le commentaire du commit.0 votes
@ashad - Votre suggestion était parfaite pour moi! Merci!!
2 votes
Pour votre cas, vous pouvez simplement faire le git reset (si vous n'avez pas poussé vers la branche). Si vous avez déjà poussé vers la branche, alors faites git reset --hard HEAD^1
1 votes
Essayez avec git diff + git apply
1 votes
Peut-être pourrions-nous simplement améliorer / modifier le comportement de la commande
git revert
pour réellement annuler les effets d'une validation, plutôt que de créer une validation d'annulation.1 votes
"undo" est la question la plus vague dans la gestion de code avec git. Vous devez spécifier où vous voulez que votre code se trouve. La documentation de git reset est un bon point de départ et référence.
git reset --mixed
est l'action par défaut pourgit reset
, vous devriez réfléchir à la raison de cela, ainsi vous aurez une attente claire sur la gestion de code avant de vous plonger dans l'utilisation de git.