web-dev-qa-db-fra.com

Comment annuler l'annulation de 'git add' avant la validation?

J'ai ajouté par erreur des fichiers à git en utilisant la commande:

git add myfile.txt

Je n'ai pas encore exécuté git commit. Existe-t-il un moyen de l'annuler pour que ces fichiers ne soient pas inclus dans la validation?

8347
paxos1977

Vous pouvez annuler git add avant de valider avec

git reset <file>

qui le supprimera de l'index actuel (la liste "sur le point d'être engagée") sans rien changer d'autre.

Vous pouvez utiliser

git reset

sans nom de fichier pour supprimer toutes les modifications dues. Cela peut être utile lorsqu'il y a trop de fichiers à répertorier un par un dans un délai raisonnable.

Dans les anciennes versions de Git, les commandes ci-dessus sont équivalentes à git reset HEAD <file> et git reset HEAD respectivement, et échoueront si HEAD n'est pas défini (car vous n'avez encore effectué aucune validation dans votre référentiel). ou ambigu (parce que vous avez créé une branche appelée HEAD, ce qui est une chose stupide à ne pas faire). Ceci a été modifié dans Git 1.8.2 , cependant, donc dans les versions modernes de Git, vous pouvez utiliser les commandes ci-dessus même avant de faire votre premier commit:

"git reset" (sans options ni paramètres) utilisé pour l'erreur quand vous n'avez aucun commit dans votre historique, mais il vous donne maintenant un index vide (pour correspondre à un commit inexistant, vous n'êtes même pas sur).

9480
genehack

Tu veux:

git rm --cached <added_file_to_undo>

Raisonnement:

Quand j'étais nouveau dans ce domaine, j'ai d'abord essayé

git reset .

(pour annuler tout mon ajout initial), seulement pour obtenir ce message (pas si) utile:

fatal: Failed to resolve 'HEAD' as a valid ref.

Il se trouve que c'est parce que la HEAD ref (branche?) N'existe qu'après la première validation. Autrement dit, vous rencontrerez le même problème de débutant que moi si votre flux de travail, comme le mien, ressemblait à quelque chose comme:

  1. allez dans mon nouveau répertoire de projets pour essayer Git, le nouveau point chaud
  2. git init
  3. git add .
  4. git status

    ... beaucoup de rouleaux de merde par ...

    => Zut, je ne voulais pas ajouter tout ça.

  5. google "annuler git add"

    => trouver le débordement de pile - yay

  6. git reset .

    => fatal: Impossible de résoudre "HEAD" comme réf. valide.

Il s'avère en outre qu’il ya n bogue enregistré contre l’inefficacité de cela dans la liste de diffusion.

Et que la solution correcte était là dans la sortie du statut Git (que, oui, j’ai passé sous silence comme "merde")

...
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
...

Et la solution consiste en effet à utiliser git rm --cached FILE.

Notez les avertissements ailleurs ici - git rm supprime votre copie de travail locale du fichier, mais pas si vous utilisez - en cache . Voici le résultat de git help rm:

--cached Utilisez cette option pour décomposer et supprimer les chemins uniquement de l'index. Les fichiers d'arbre de travail, modifiés ou non, seront conservés.

Je procède à utiliser

git rm --cached .

tout enlever et recommencer. Cela n'a pas fonctionné, car bien que add . soit récursif, il s'avère que rm a besoin de -r pour générer une récurrence. Soupir.

git rm -r --cached .

Ok, maintenant je suis de retour à où j'ai commencé. La prochaine fois que je vais utiliser -n pour effectuer un essai et voir ce qui sera ajouté:

git add -n .

J'ai tout zippé dans un endroit sûr avant de faire confiance à git help rm à propos du --cached ne rien détruire (et si je l'orthographiais de manière erronée).

2082
Rhubarb

Si vous tapez:

git status

git vous dira ce qui est mis en scène, etc., y compris des instructions sur la façon de décompresser:

use "git reset HEAD <file>..." to unstage

Je trouve que git fait un très bon travail en me poussant du coude à faire la bonne chose dans des situations comme celle-ci.

Remarque: les versions récentes de Git (1.8.4.x) ont modifié ce message:

(use "git rm --cached <file>..." to unstage)
515
Paul Beckingham

Pour clarifier: git add déplace les modifications du répertoire de travail actuel vers zone de stockage intermédiaire (index).

Ce processus s'appelle staging. Ainsi, la commande la plus naturelle pour stage les modifications (fichiers modifiés) est la plus évidente:

git stage

git add est simplement un alias plus facile à taper pour git stage

Dommage qu'il n'y ait pas de commande git unstage ni git unadd. La question pertinente est plus difficile à deviner ou à retenir, mais elle est assez évidente:

git reset HEAD --

Nous pouvons facilement créer un alias pour cela:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

Et enfin, nous avons de nouvelles commandes:

git add file1
git stage file2
git unadd file2
git unstage file1

Personnellement, j'utilise des alias encore plus courts:

git a #for staging
git u #for unstaging
241
takeshin

Un ajout à la réponse acceptée, si votre fichier ajouté par erreur était énorme, vous remarquerez probablement que, même après l'avoir supprimé de l'index avec 'git reset', il semble toujours occuper de l'espace dans le .git répertoire. Cela n’a rien d’inquiétant, le fichier est en effet toujours dans le référentiel, mais uniquement en tant qu’objet "en vrac", il ne sera pas copié dans d’autres référentiels (via clone, Push), et l’espace sera finalement récupéré - bien que peut-être pas très bientôt. Si vous êtes inquiet, vous pouvez exécuter:

git gc --Prune=now

Mise à jour (Ce qui suit est ma tentative de dissiper une certaine confusion qui peut découler des réponses les plus votées.):

Alors, quel est le réel annuler de git add?

git reset HEAD <file>?

ou

git rm --cached <file>?

Strictement parlant, et si je ne me trompe pas: aucun.

git addne peut pas être annulé - en toute sécurité, en général.

Rappelons d’abord ce que git add <file> fait réellement:

  1. Si <file> était pas encore suivi, git addl'ajoute au cache, avec son contenu actuel.

  2. Si <file> était déjà suivi, git addenregistre le contenu actuel (instantané, version) dans le cache. Dans GIT, cette action est toujours appelée add, (pas simplement update it), car deux versions différentes (instantanés) de un fichier sont considérés comme deux éléments différents: par conséquent, nous ajoutons effectivement un nouvel élément au cache, pour être ultérieurement validés.

À la lumière de ceci, la question est légèrement ambiguë:

J'ai ajouté par erreur des fichiers à l'aide de la commande ...

Le scénario du PO semble être le premier (fichier non suivi), nous voulons que "annuler" supprime le fichier (pas seulement le contenu actuel) des éléments suivis. Si c'est le cas, alors vous pouvez exécuter git rm --cached <file>.

Et nous pourrions aussi lancer git reset HEAD <file>. Ceci est généralement préférable, car cela fonctionne dans les deux scénarios: cela annule également lorsque nous avons ajouté à tort une version d'un élément déjà suivi.

Mais il y a deux mises en garde.

Premièrement: il n'y a (comme indiqué dans la réponse) qu'un seul scénario dans lequel git reset HEAD ne fonctionne pas, mais git rm --cached le fait: un nouveau référentiel (pas de validation). Mais, en réalité, ceci est un cas pratiquement hors de propos.

Deuxièmement: Sachez que git reset HEAD ne peut pas récupérer par magie le contenu du fichier précédemment mis en cache, il le resynchronise à partir de HEAD. Si notre git add mal inspiré a écrasé une version non validée précédemment mise en scène, nous ne pouvons pas la récupérer. C'est pourquoi, à proprement parler, nous ne pouvons pas annuler [*].

Exemple:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # first add  of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt   
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # oops we didn't mean this
$ git reset HEAD file.txt  # undo ?
$ git diff --cached file.txt  # no dif, of course. stage == HEAD
$ git diff file.txt   # we have lost irrevocably "version 2"
-version 1
+version 3

Bien sûr, cela n’est pas très critique si nous suivons simplement le workflow paresseux habituel consistant à faire "git add" uniquement pour ajouter de nouveaux fichiers (cas 1), et nous mettons à jour le nouveau contenu via la commande commit, git commit -a.


* (Edit: ce qui précède est pratiquement correct, mais il peut toujours exister des méthodes légèrement hackish/compliquées pour récupérer des modifications mises en scène mais non validées puis écrasées - voir les commentaires de Johannes Matokic et iolsmit)

161
leonbloy
git rm --cached . -r

"annulera" tout ce que vous avez ajouté à partir de votre répertoire actuel récursivement

92
braitsch

Annuler un fichier déjà ajouté est assez facile en utilisant git , pour réinitialiser myfile.txt qui déjà ajouté, utilisez:

git reset HEAD myfile.txt

Expliquez:

Après avoir mis en place un ou plusieurs fichiers indésirables à annuler, vous pouvez effectuer git reset, Head en tête de votre fichier en local et le dernier paramètre est le nom de votre fichier.

Je crée les étapes dans l'image ci-dessous de manière plus détaillée pour vous, y compris toutes les étapes pouvant se produire dans les cas suivants:

git reset HEAD file

90
Alireza

Courir

git gui

et supprimez tous les fichiers manuellement ou en les sélectionnant tous en cliquant sur le bouton annuler la validation de commit.

86
Khaja Minhajuddin

Git a des commandes pour chaque action imaginable, mais a besoin de connaissances approfondies pour bien faire les choses et, pour cette raison, il est au mieux contre-intuitif ...

Ce que vous avez fait auparavant

  • Changé un fichier et utilisé git add . ou git add <file>.

Ce que vous voulez:

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

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

    # Think `svn revert <file>` IIRC.
    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 HEAD ne fonctionnera pas avec des fichiers uniques.

  • Supprimez <file> de l'index et de la gestion des versions, en conservant le fichier sans version avec les modifications apportées à la copie de travail:

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

    git rm <file>
    
80
sjas

La question n'est pas clairement posée. La raison en est que git add a deux significations:

  1. ajouter un nouveau fichier à la zone de transfert, puis annuler avec git rm --cached file.
  2. ajouter un fichier modifié à la zone de transfert, puis annuler avec git reset HEAD file.

en cas de doute, utilisez

git reset HEAD file

Parce qu'il fait la chose attendue dans les deux cas.

Attention: Si vous faites git rm --cached file sur un fichier qui était modifié (un fichier qui existait auparavant dans le référentiel), le fichier sera supprimé sur git commit! Il existera toujours dans votre système de fichiers, mais si quelqu'un d'autre extrait votre commit, le fichier sera supprimé de leur arbre de travail.

git status vous dira s'il s'agit d'un fichier nouveau fichier ou modifié:

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   my_new_file.txt
    modified:   my_modified_file.txt
74
Michael_Scharf

Si vous êtes sur votre commit initial et que vous ne pouvez pas utiliser git reset, déclarez simplement "Git faillite" et supprimez le dossier .git et recommencez.

63
Paul Betts

Comme dans beaucoup d’autres réponses, vous pouvez utiliser git reset

MAIS:

J'ai trouvé ce super petit article qui ajoute la commande Git (un alias) pour git unadd: voir git unadd pour plus de détails ou. .

Simplement,

git config --global alias.unadd "reset HEAD"

Maintenant vous pouvez

git unadd foo.txt bar.txt
55
electblake

git remove ou git rm peut être utilisé à cet effet, avec le drapeau --cached. Essayer:

git help rm
43
gnud

Utilisez git add -i pour supprimer les fichiers que vous venez d'ajouter à votre prochain commit. Exemple:

Ajouter le fichier que vous ne vouliez pas:

$ git add foo
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]#

Entrer dans add interactif pour annuler votre ajout (les commandes saisies ici sont "r" (revert), "1" (la première entrée de la liste affiche revers), "return" pour quitter le mode revert et "q" (quitter):

$ git add -i
           staged     unstaged path
  1:        +1/-0      nothing foo

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +1/-0      nothing [f]oo
Revert>> 1
           staged     unstaged path
* 1:        +1/-0      nothing [f]oo
Revert>> 
note: foo is untracked now.
reverted one path

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> q
Bye.
$

C'est ça! Voici votre preuve, montrant que "foo" est de retour sur la liste non suivie:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]
#       foo
nothing added to commit but untracked files present (use "git add" to track)
$
42
Alex North-Keys

Voici un moyen d'éviter ce problème épineux lorsque vous démarrez un nouveau projet:

  • Créez le répertoire principal pour votre nouveau projet.
  • Exécutez git init.
  • Créez maintenant un fichier .gitignore (même s'il est vide).
  • Commettez votre fichier .gitignore.

Git rend vraiment difficile de faire git reset si vous n'avez pas de commits. Si vous créez un petit commit initial juste pour en avoir un, vous pourrez ensuite git add -A et git reset autant de fois que vous le souhaitez afin de tout corriger.

Un autre avantage de cette méthode est que si vous rencontrez des problèmes de fin de ligne plus tard et que vous devez actualiser tous vos fichiers, rien de plus simple:

  • Découvrez ce commit initial. Cela supprimera tous vos fichiers.
  • Puis vérifiez à nouveau votre plus récent commit. Cela permettra de récupérer de nouvelles copies de vos fichiers, en utilisant vos paramètres de fin de ligne actuels.
37
Ryan Lundy

Peut-être que Git a évolué depuis que vous avez posté votre question.

$> git --version
git version 1.6.2.1

Maintenant, vous pouvez essayer:

git reset HEAD .

Cela devrait être ce que vous recherchez.

33
Kokotte23

Notez que si vous ne spécifiez pas de révision, vous devez inclure un séparateur. Exemple de ma console:

git reset <path_to_file>
fatal: ambiguous argument '<path_to_file>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

git reset -- <path_to_file>
Unstaged changes after reset:
M   <path_to_file>

(version git 1.7.5.4)

33
powlo

Pour supprimer les nouveaux fichiers de la zone de transfert (et uniquement dans le cas d'un nouveau fichier), comme suggéré ci-dessus:

git rm --cached FILE

Utilisez rm --cached uniquement pour les nouveaux fichiers ajoutés par inadvertance.

30
Ran

Pour réinitialiser chaque fichier d'un dossier particulier (et de ses sous-dossiers), vous pouvez utiliser la commande suivante:

git reset *
24
Zorayr

utilisez la commande * pour gérer plusieurs fichiers à la fois

git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*

etc

24
boulder_ruby

Il suffit de taper git reset pour revenir en arrière et c'est comme si vous n'aviez jamais saisi git add . depuis votre dernier commit. Assurez-vous que vous avez commis avant.

22
Donovan

Supposons que je crée un nouveau fichier newFile.txt.

enter image description here

Supposons que j'ajoute le fichier accidentellement, git add newFile.txt

enter image description here

Maintenant, je veux annuler cet ajout avant la validation, git reset newFile.txt

enter image description here

18
Vidura Mudalige

Pour un fichier spécifique:

  • git reset my_file.txt
  • git checkout mon_fichier.txt

Pour tous les fichiers ajoutés:

  • git reset.
  • git checkout.

Remarque: checkout modifie le code dans les fichiers et passe au dernier état mis à jour (validé). réinitialiser ne change pas les codes; il ne fait que réinitialiser l'en-tête.

17
Hasib Kamal

Pour annuler git add use

git reset filename

13
Anirudh Sood

Cette commande va décompresser vos modifications:

git reset HEAD filename.txt

Vous pouvez aussi utiliser

git add -p 

ajouter des parties de fichiers.

13
wallerjake

Je suis surpris que personne ne mentionne le mode interactif:

git add -i

choisissez l'option 3 pour annuler l'ajout de fichiers. Dans mon cas, je souhaite souvent ajouter plusieurs fichiers. En mode interactif, vous pouvez utiliser des chiffres comme celui-ci pour ajouter des fichiers. Cela prendra tout sauf 4: 1,2,3,5

Pour choisir une séquence, tapez simplement 1-5 et prenez tout de 1 à 5.

fichiers intermédiaires Git

13
Jonathan

git add myfile.txt # ceci ajoutera votre fichier dans la liste à valider

Tout à fait opposé à cette commande est,

git reset HEAD myfile.txt  # this will undo it. 

alors, vous serez dans l'état précédent. spécifié sera à nouveau dans la liste non suivie (état précédent).

cela réinitialisera votre tête avec ce fichier spécifié. donc, si votre tête n’a pas les moyens, il la réinitialisera simplement

9
git reset filename.txt

Supprime un fichier nommé filename.txt de l'index actuel, la zone "sur le point d'être validée", sans rien changer d'autre.

9
Rahul Sinha

Dans SourceTree, vous pouvez le faire facilement via l'interface graphique. Vous pouvez vérifier quelle commande sourcetree utilise pour décomposer un fichier.

J'ai créé un nouveau fichier et l'a ajouté à git. Ensuite, je l'ai décomposé en utilisant le gui SourceTree. Voici le résultat:

Décompression des fichiers [08/12/15 10:43]
git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree réinitialiser -q - chemin/vers/fichier/nom_fichier.Java

SourceTree utilise reset pour décomposer les nouveaux fichiers.

8
miva2
git reset filename.txt  

Supprime un fichier nommé filename.txt de l'index actuel, la zone "sur le point d'être validée", sans rien changer d'autre.

7
Joseph Mathew

L’une des solutions les plus intuitives consiste à utiliser SourceTree .

Vous pouvez simplement glisser-déposer des fichiers stockés et non stockés enter image description here

7
Marcin Szymczak

La commande git reset vous aide à modifier la zone de stockage intermédiaire ou l’arborescence de travail. La capacité de Git à créer des commits exactement comme vous le souhaitez signifie que vous devez parfois annuler les modifications apportées aux modifications que vous avez effectuées avec git add.

Vous pouvez le faire en appelant git reset HEAD <file to change>. Vous avez deux options pour vous débarrasser complètement des changements. git checkout HEAD <file(s) or path(s)> est un moyen rapide d'annuler les modifications apportées à votre zone de travail intermédiaire et à votre arbre de travail. Soyez prudent avec cette commande, cependant, car elle supprime toutes les modifications de votre arbre de travail. Git ne sait rien de ces changements car ils n'ont jamais été engagés. Il n'y a aucun moyen de récupérer ces modifications une fois que vous avez exécuté cette commande.

Une autre commande à votre disposition est git reset --hard. Il est également dommageable pour votre arbre de travail: toute modification non validée ou mise en échec est perdue après son exécution. Lancer git reset -hard HEAD fait la même chose que git checkout HEAD. Cela ne nécessite aucun fichier ou chemin pour fonctionner.

Vous pouvez utiliser --soft avec git reset. Il réinitialise le référentiel sur le commit que vous spécifiez et met en œuvre toutes ces modifications. Les modifications que vous avez déjà effectuées ne sont pas affectées, pas plus que les modifications dans votre arborescence de travail.

Enfin, vous pouvez utiliser --mixed pour réinitialiser l’arborescence de travail sans enregistrer les modifications. Cela annule également les changements mis en scène.

1
SAIguru011