Question Comment annuler 'git add' avant de valider?


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

git add myfile.txt

Je n'ai pas encore couru git commit. Existe-t-il un moyen d'annuler cela, donc ces fichiers ne seront pas inclus dans le commit?


Il y a 48 réponses jusqu'à présent (certaines ont été supprimées). S'il vous plaît ne pas en ajouter un nouveau, sauf si vous avez de nouvelles informations.


7450
2017-12-07 21:57


origine


Réponses:


Vous pouvez annuler git add avant de commettre avec

git reset <file>

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

Vous pouvez utiliser

git reset

sans nom de fichier pour désactiver toutes les modifications dues. Cela peut s'avérer 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 échouera si HEAD est indéfini (car vous n'avez pas encore effectué de commit dans votre repo) ou ambigu (car vous avez créé une branche appelée HEAD, ce qui est une chose stupide que vous ne devriez pas faire). Ce a été modifié dans Git 1.8.2Cependant, dans les versions modernes de Git, vous pouvez utiliser les commandes ci-dessus avant même de faire votre premier commit:

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


8357
2017-12-07 22:30



Tu veux:

git rm --cached <added_file_to_undo>

Raisonnement:

Quand j'étais nouveau, 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 le ref (branche?) HEAD n'existe pas après le premier commit. Autrement dit, vous rencontrerez le même problème que moi si votre flux de travail, comme le mien, était quelque chose comme:

  1. cd à mon grand nouveau répertoire de projet pour essayer Git, la nouvelle hotness
  2. git init
  3. git add .
  4. git status

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

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

  5. google "Annuler git ajouter"

    => trouver Stack Overflow - yay

  6. git reset .

    => fatal: Impossible de résoudre 'HEAD' comme une référence valide.

Il s'avère en outre qu'il y a un bug enregistré contre l'inutilité de ceci dans la liste de diffusion.

Et que la solution correcte était là dans la sortie de l'état Git (que, oui, j'ai glissé comme 'merde)

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

Et la solution est en effet d'utiliser git rm --cached FILE.

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

--cache       Utilisez cette option pour désactiver et supprimer les chemins uniquement de l'index.       Les fichiers d'arborescence de travail, qu'ils soient modifiés ou non, seront conservés.

Je continue à utiliser

git rm --cached .

pour tout enlever et recommencer. Cela n'a pas fonctionné, car pendant que add . est récursif, s'avère rm Besoins -r recurse. Soupir.

git rm -r --cached .

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

git add -n .

J'ai zippé tout à un endroit sûr avant de faire confiance git help rm à propos de --cached ne rien détruire (et si je l'ai mal orthographié).


1950
2018-03-25 16:20



Si vous tapez:

git status

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

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

Je trouve que git fait du bon boulot en me poussant à faire ce qu'il faut dans des situations comme celle-ci.

Note: Les versions récentes de git (1.8.4.x) ont changé ce message:

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

484
2017-12-07 23:22



Clarifier: git add déplace les modifications du répertoire de travail en cours vers le zone de transit (indice).

Ce processus est appelé mise en scène. Donc, la commande la plus naturelle à étape les changements (fichiers modifiés) sont les plus évidents:

git stage

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

Dommage qu'il n'y ait pas git unstage ni git unadd commandes. Le pertinent est plus difficile à deviner ou à retenir, mais est assez évident:

git reset HEAD --

Nous pouvons facilement créer un alias pour ceci:

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

220
2017-09-10 20:28



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

git gc --prune=now

Mettre à jour (Ce qui suit est ma tentative d'effacer une certaine confusion qui peut surgir des réponses les plus votées):

Alors, quel est le vrai annuler de git add?

git reset HEAD <file> ?

ou

git rm --cached <file>?

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

git add  ne peut pas être défait - 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 add  l'ajoute au cache, avec son contenu actuel.

  2. Si <file> était déjà suivi, git add  enregistre le contenu actuel (instantané, version) au cache. En GIT, cette action est toujours appelée ajouter(pas simple mettre à jour it), car deux versions différentes (snapshots) d'un fichier sont considérées comme deux éléments différents: nous ajoutons en effet un nouvel élément au cache, qui sera éventuellement validé ultérieurement.

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

J'ai ajouté par erreur des fichiers en utilisant la commande ...

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

Et nous pourrions aussi courir git reset HEAD <file>. C'est en général préférable, car cela fonctionne dans les deux scénarios: il fait aussi l'annulation lorsque nous avons ajouté par erreur 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 fait: un nouveau dépôt (pas de commits). Mais, vraiment, c'est un cas pratiquement non pertinent.

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 suffit de le resynchroniser à partir du HEAD. Si notre égaré git add écrasé une ancienne version non validée par étapes, nous ne pouvons pas le récupérer. C'est pourquoi, strictement parlant, nous ne pouvons pas défaire.

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, ce n'est pas très critique si nous suivons le workflow paresseux habituel de faire 'git add' seulement pour ajouter de nouveaux fichiers (cas 1), et nous mettons à jour de nouveaux contenus via la validation, git commit -a commander.


136
2018-05-18 18:05



git rm --cached . -r

va "dés-ajouter" tout ce que vous avez ajouté de votre répertoire actuel récursivement


85
2017-12-09 21:19



Courir

git gui

et supprimer tous les fichiers manuellement ou en les sélectionnant tous et en cliquant sur le unstage from commit bouton.


77
2017-10-12 01:12



Git a des commandes pour chaque action imaginable, mais a besoin de connaissances approfondies pour bien faire les choses et à cause de cela, c'est au mieux contre-intuitif ...

Ce que vous avez fait avant:

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

Ce que tu veux:

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

    git reset head <file>
    
  • Réinitialisez le fichier au dernier état de HEAD, annulez les modifications et supprimez-les 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>
    

    Ceci est nécessaire depuis git reset --hard HEAD ne fonctionnera pas avec des fichiers uniques.

  • Retirer <file> à partir de l'index et du contrôle de version, en conservant le fichier non-versionné avec des modifications dans la copie de travail:

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

    git rm <file>
    

73
2018-03-29 11:14



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 transit, puis annuler avec git rm --cached file.
  2. ajouter un modifié fichier à la zone de transit, 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 tu fais git rm --cached file sur un fichier qui était modifié (un fichier qui existait auparavant dans le référentiel), le fichier sera supprimé le git commit! Il existera toujours dans votre système de fichiers, mais si quelqu'un d'autre tire votre commit, le fichier sera supprimé de son arbre de travail.

git status vous dira si le fichier était un 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

62
2018-01-16 19:54