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?
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).
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:
git init
git add .
git status
... beaucoup de rouleaux de merde par ...
=> Zut, je ne voulais pas ajouter tout ça.
google "annuler git add"
=> trouver le débordement de pile - yay
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).
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)
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
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 add
ne peut pas être annulé - en toute sécurité, en général.
Rappelons d’abord ce que git add <file>
fait réellement:
Si <file>
était pas encore suivi, git add
l'ajoute au cache, avec son contenu actuel.
Si <file>
était déjà suivi, git add
enregistre 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)
git rm --cached . -r
"annulera" tout ce que vous avez ajouté à partir de votre répertoire actuel récursivement
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:
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.
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
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>
La question n'est pas clairement posée. La raison en est que git add
a deux significations:
git rm --cached file
.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
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.
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
git remove
ou git rm
peut être utilisé à cet effet, avec le drapeau --cached
. Essayer:
git help rm
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)
$
Voici un moyen d'éviter ce problème épineux lorsque vous démarrez un nouveau projet:
git init
.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:
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.
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)
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.
Pour réinitialiser chaque fichier d'un dossier particulier (et de ses sous-dossiers), vous pouvez utiliser la commande suivante:
git reset *
utilisez la commande *
pour gérer plusieurs fichiers à la fois
git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*
etc
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.
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.
Pour annuler git add use
git reset filename
Cette commande va décompresser vos modifications:
git reset HEAD filename.txt
Vous pouvez aussi utiliser
git add -p
ajouter des parties de fichiers.
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.
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
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.
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.
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.
L’une des solutions les plus intuitives consiste à utiliser SourceTree .
Vous pouvez simplement glisser-déposer des fichiers stockés et non stockés
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.