Comment pouvez-vous annuler le dernier ajout de git?


193

Est-il possible de supprimer la dernière modification par étapes (non validée) dans git ? Supposons qu'il y ait beaucoup de fichiers dans la branche actuelle, certains mis en scène, d'autres non. À un moment donné, un programmeur stupide a exécuté accidentellement:

git add -- .

...au lieu de:

git checkout -- .

Ce programmeur peut-il maintenant mettre en scène ses derniers changements avec une commande git magique ? Ou aurait-il dû s'engager avant d'expérimenter en premier lieu?


Il h. Nous avons cependant obtenu une question et une réponse utiles.
steveha

2
doublon possible de git add avant
Jim Fell

Je crois que ce n'est pas le doublon. OP dans l'autre question demande un moyen d'annuler cela ou de supprimer ces fichiers du commit. Je veux (ed) précisément et uniquement pour annuler les modifications qui ont été ajoutées avec la dernière git addcommande, en particulier pour les fichiers qui avaient déjà des modifications par étapes et qui avaient des modifications qui devaient être annulées et non pas par étapes. Je ne peux pas dire que l'autre question n'est pas liée cependant.
septembre

1
Peut-être aurait-il dû / être / engagé avant d'expérimenter en premier lieu.
android.weasel

@ android.weasel oui, c'était il y a de nombreuses années ...
Septagram

Réponses:


299

Vous pouvez utiliser git reset. Cela «décortiquera» tous les fichiers que vous avez ajoutés après votre dernier commit.

Si vous souhaitez supprimer uniquement certains fichiers, utilisez git reset -- <file 1> <file 2> <file n>.

Il est également possible de supprimer certaines des modifications des fichiers à l'aide de git reset -p.


3
Quelle tristesse. Je suppose qu'il y a quelque chose de mal dans mes pratiques d'engagement après tout. Accepter cette réponse, car vous avez mentionné le -pchangement. Merci! :)
Septagram

Génère (pour moi) l'erreur: fatale: impossible de résoudre «HEAD» en tant que référence valide. Je n'ai encore rien engagé (nouveau dépôt), je viens de faire git add. et l'a regretté. Je ne veux pas réinitialiser l'intégralité de l'ajout, juste un répertoire. git reset - dir /*.* génère l'erreur ci-dessus.
Francis Davey

... Ah, je vois ce qui m'arrive. Je n'avais encore rien sur lequel pointe HEAD et donc la réinitialisation de git a échoué (car elle fonctionne sur la tête).
Francis Davey

42

Vous ne pouvez pas annuler le dernier ajout de git, mais vous pouvez annuler tous les adds depuis le dernier commit. git resetsans argument de validation réinitialise l'index (annule les modifications par étapes):

git reset

2
"Vous ne pouvez pas annuler le dernier ajout de git": Wow, c'est surprenant et potentiellement douloureux. Y a-t-il une source définitive pour cela? Y a-t-il également une bonne raison pour qu'il en soit ainsi? Merci!
Andrew Moylan

@AndrewMoylan: eh bien, il n'y a pas de moyen automatique de le faire. Vous pouvez toujours resetun seul fichier, ou utiliser reset -ppour déchausser un morceau spécifique.
knittl

15

Donc, la vraie réponse à

Ce programmeur peut-il maintenant mettre en scène ses derniers changements avec une commande git magique?

est en fait: Non, vous ne pouvez pas mettre en scène juste le dernier git add.

C'est si nous interprétons la question comme dans la situation suivante:

Fichier initial:

void foo() {

}

main() {
    foo();
}

Premier changement suivi de git add:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

Deuxième changement suivi de git add:

void foo(int bar, String baz) {
    print("$bar $baz");
}

main() {
    foo(1337, "h4x0r");
}

Dans ce cas, git reset -pn'aidera pas, car sa plus petite granularité est des lignes. gitne sait pas que sur l'état intermédiaire de:

void foo(int bar) {
    print("$bar");
}

main() {
    foo(1337);
}

plus.


J'ai apprécié parce qu'en tant que nouvel utilisateur de git, c'est une distinction très importante qui met en évidence ce que mes amis décrivent comme "avoir une bonne hygiène d'enregistrement" ... mon expérience personnelle - elle a été décrite comme "covoiturage" (mauvaise!).
benc


3

À la date où git vous invite:

  1. use "git rm --cached <file>..." to unstagesi les fichiers n'étaient pas dans le dépôt. Il décompose les fichiers en les y conservant.
  2. use "git reset HEAD <file>..." to unstagesi les fichiers étaient dans le référentiel et que vous les ajoutez tels que modifiés. Il conserve les fichiers tels qu'ils sont et les décompose.

À ma connaissance, vous ne pouvez pas annuler la git add --mais vous pouvez supprimer une liste de fichiers comme mentionné ci-dessus.


2
  • Supprimez le fichier de l'index, mais conservez-le versionné et laissez les modifications non validées dans la copie de travail:

    git reset head <file>
    
  • Réinitialisez le fichier dans le dernier état de HEAD, annulant les modifications et les supprimant de l'index:

    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>

    Cela est nécessaire car git reset --hard HEADne fonctionnera pas avec des fichiers uniques.

  • Supprimer <file>de l'index et du versionnage, en conservant le fichier non versionné avec des modifications dans la copie de travail:

    git rm --cached <file>
    
  • Supprimer <file>complètement de la copie de travail et du versioning:

    git rm <file>
    

2

Si vous souhaitez supprimer tous les fichiers ajoutés de git pour validation

git reset

Si vous souhaitez supprimer un fichier individuel

git rm <file>

1

Vous pouvez utiliser

git reset

pour annuler les fichiers locaux récemment ajoutés

 git reset file_name

pour annuler les modifications d'un fichier spécifique


0

En fonction de la taille et de l'échelle de la difficulté, vous pouvez créer une branche scratch (temporaire) et y valider le travail en cours.

Basculez ensuite vers votre branche d'origine et extrayez-la, puis choisissez les fichiers appropriés dans le commit de scratch.

Au moins, vous auriez un enregistrement permanent des états actuel et précédent à partir duquel travailler (jusqu'à ce que vous supprimiez cette branche scratch).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.