24024 votes

Comment annuler les plus récents commits locaux dans Git ?

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

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

La seule solution semble être de copier les modifications dans une sorte d'éditeur de texte graphique, puis d'effacer tout le clone local, puis de cloner à nouveau le référentiel, puis de réappliquer les modifications. Cependant,

  • Cela peut entraîner une perte de données.
  • C'est très difficile de faire ça quand seulement un accident git commit a été exécuté.

Y a-t-il un meilleur moyen ?

0 votes

Voir ce guide pour annuler les commits Git sur les branches locales, publiques et Git. Comment défaire les commits Git comme un pro ?

365 votes

Vous savez ce dont git a besoin ? git undo c'est tout. Ensuite, la réputation de git pour gérer les erreurs faites par nous, simples mortels, disparaît. Implémenter en poussant l'état actuel sur une pile git avant d'exécuter tout git commande. Cela affecterait les performances, il serait donc préférable d'ajouter un indicateur de configuration permettant de l'activer ou non.

36 votes

@YiminRong Cela peut être fait avec l'outil Git alias fonction : git-scm.com/book/fr/v2/Git-Basics-Git-Aliases

26079voto

Esko Luontola Points 53877

Annuler un commit & redo

$ git commit -m "Something terribly misguided" # (0: Your Accident)
$ git reset HEAD~                              # (1)
[ edit files as necessary ]                    # (2)
$ git add .                                    # (3)
$ git commit -c ORIG_HEAD                      # (4)
  1. Cette commande est responsable de la annuler . Cela annulera votre dernière livraison pendant que laissant votre arbre de travail (l'état de vos fichiers sur le disque) intact. Vous devrez les ajouter à nouveau avant de pouvoir les valider à nouveau).

  2. Apporter des corrections aux fichiers de l'arbre de travail.

  3. git add tout ce que vous voulez inclure dans votre nouvelle livraison.

  4. Valider les changements, en réutilisant l'ancien message de validation. reset copié l'ancienne tête sur .git/ORIG_HEAD ; commit con -c ORIG_HEAD ouvrira un éditeur, qui contient initialement le message de log de l'ancien commit et vous permet de le modifier. Si vous n'avez pas besoin de modifier le message, vous pouvez utiliser la commande -C option.

Alternativement, pour éditer la livraison précédente (ou juste son message de livraison) , commit --amend ajoutera les changements dans l'index courant à la livraison précédente.

Pour supprimer (sans revenir en arrière) un commit qui a été poussé vers le serveur réécrire l'histoire avec git push origin master --force est nécessaire.


Autres lectures

Comment puis-je déplacer HEAD vers un emplacement précédent ? (Tête détachée) & Annuler les commits

La réponse ci-dessus vous montrera git reflog que vous pouvez utiliser 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 chose que HEAD~1 . L'article Qu'est-ce que le HEAD dans git ? est utile si vous voulez annuler plusieurs commits.

551 votes

Et si le commit était dans la mauvaise branche, vous pouvez git checkout theRightBranch avec toutes les étapes de changement. Comme je devais le faire.

553 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, il ne fonctionnera donc pas correctement. Aussi, --soft est la valeur par défaut, vous pouvez donc l'omettre si vous le souhaitez et dire simplement git reset HEAD~1 .

150 votes

Que les utilisateurs de zsh pourraient obtenir : zsh: no matches found: HEAD^ - vous devez échapper ^, c'est-à-dire git reset --soft HEAD\^

11782voto

Kyralessa Points 76456

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

option 1 : git reset --hard

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

   (F)
A-B-C

  master

Vous voulez nuke commit C et ne jamais le revoir et perdre tous les changements dans les fichiers modifiés localement. . Vous faites ça :

git reset --hard HEAD~1

Le résultat est :

 (F)
A-B

master

Maintenant B est la TÊTE. Parce que vous avez utilisé --hard vos fichiers sont remis dans l'état où ils étaient lors de la validation B.

option 2 : git reset

Ah, mais supposons que la commission C n'était pas un désastre, mais juste un peu à côté. Vous voulez annuler la livraison mais conserver vos modifications pour un peu d'édition avant de faire un meilleur engagement. Recommencez à partir d'ici, avec C comme HEAD :

   (F)
A-B-C

  master

Vous pouvez le faire 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 demandez à Git de reculer le pointeur HEAD 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 enregistré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 livraison mais laisser vos fichiers et vos indice :

git reset --soft HEAD~1

Cela ne laisse pas seulement vos fichiers seuls, cela laisse même votre indice seul. Quand vous le faites git status vous verrez que les mêmes fichiers sont dans l'index que précédemment. En fait, juste après cette commande, vous pourriez faire git commit et vous devrez refaire le même commit que vous venez de faire.

option 4 : vous l'avez fait git reset --hard et j'ai besoin de récupérer ce code

Une dernière chose : Supposons que vous détruisiez un commit comme dans le premier exemple, mais ensuite découvrir que vous en aviez besoin après tout ? Pas de chance, hein ?

Non, il y a toujours un moyen de le récupérer. Type git reflog et vous verrez une liste de commit (partiel) shas (c'est-à-dire des hachages) dans lesquels vous vous êtes 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 avant environ 90 jours, donc vous pouvez généralement revenir en arrière et sauver un commit dont vous n'aviez pas l'intention de vous débarrasser.

2 votes

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

1 votes

Ne fonctionne pas avec OS x. - J'obtiens "ambiguous argument 'HEAD^' ... Révision inconnue ou chemin ne se trouvant pas dans l'arbre de travail". L'utilisation de 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 pousser, j'ai découvert que c'était 400 Mo de données ( !) (un dossier Ressources profondément imbriqué contenant des fichiers vidéo et musicaux). Donc, j'ai besoin d'annuler le commit, mais de garder les fichiers sources, et je les commiterai plus tard, quand j'aurai une meilleure connexion internet - ou dans un autre dépôt.

2464voto

Andrew Points 30079

Il y a deux façons d'"annuler" votre dernier commit, selon que vous avez ou non déjà rendu votre commit public (poussé vers votre dépôt distant) :

Comment annuler un commit local

Disons que j'ai fait un commit local, mais que je veux maintenant supprimer ce commit.

git log
    commit 101: bad commit    # Latest commit. This would be called 'HEAD'.
    commit 100: good commit   # Second to last commit. This is the one we want.

Pour restaurer tout ce qui était avant le dernier commit, nous devons reset à l'engagement avant HEAD :

git reset --soft HEAD^     # Use --soft if you want to keep your changes
git reset --hard HEAD^     # Use --hard if you don't care about keeping the changes you made

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 "rétablira" les changements effectués dans votre précédent commit (HEAD actuel).

git revert HEAD

Vos modifications seront maintenant annulées et prêtes à être validées :

git commit -m 'restoring the file I removed by accident'
git log
    commit 102: restoring the file I removed by accident
    commit 101: removing a file we don't need
    commit 100: adding a file that we need

Pour plus d'informations, consultez le site Les bases de Git - Annuler des choses .

126 votes

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

7 votes

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

0 votes

revert a supprimé certains fichiers que j'ai ajoutés à mon repo. Utilisez-le avec précaution !

1860voto

bdonlan Points 90068

Ajoutez/supprimez des fichiers pour obtenir les choses comme vous le souhaitez :

git rm classdir
git add sourcedir

Puis modifiez le commit :

git commit --amend

Le commit précédent, erroné, sera édité 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.

Notez que vous ne devez faire cela que si vous n'avez pas encore poussé. Si vous avez poussé, il vous suffit de commiter un correctif normalement.

13 votes

FYI : Cela supprime tous mes fichiers et j'ai perdu des modifications.

0 votes

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

5 votes

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

1167voto

Lennart Koopmann Points 4533
git rm yourfiles/*.class
git commit -a -m "deleted all class files in folder 'yourfiles'"

o

git reset --hard HEAD~1

Avertissement : La commande ci-dessus supprimera de façon permanente les modifications apportées au fichier .java (et tout autre fichier) que vous vouliez livrer.

El hard reset à HEAD-1 mettra votre copie de travail à l'état de la livraison avant votre mauvaise livraison.

26 votes

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

0 votes

Une autre utilisation "raccourcie" de la cachette ; si vous voulez tout déstager (annuler git add), il suffit de git stash alors git stash pop

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