J'ai accidentellement ajouté beaucoup de fichiers temporaires en utilisant git add -A
J'ai réussi à décomposer les fichiers à l'aide des commandes suivantes et à supprimer l'index modifié.
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
Les commandes ci-dessus sont répertoriées dans le git help rm
. Mais malheureusement, mes fichiers ont également été supprimés lors de l’exécution, même si j’avais donné l’option cache. Comment puis-je effacer l'index sans perdre le contenu?
De plus, il serait utile que quelqu'un puisse expliquer le fonctionnement de cette opération.
git reset
Si tout ce que vous voulez, c'est annuler une course trop zélée "git add":
git reset
Vos modifications seront décomposées et prêtes à être rajoutées à votre guise.
NE PAS EXECUTER git reset --hard
.
Cela annulera non seulement les fichiers ajoutés, mais annulera également les modifications apportées à votre répertoire de travail. Si vous avez créé de nouveaux fichiers dans le répertoire de travail, il les supprime ne le fera pas.
Si vous avez un dépôt vierge (ou HEAD n'est pas défini) [1] vous pourriez simplement
rm .git/index
Bien sûr, cela vous obligera à rajouter les fichiers que vous avez voulez ajouter.
[1] Remarque (comme expliqué dans les commentaires), cela ne se produit généralement que lorsque le repo est tout neuf ("vierge") ou si aucune validation n'a été effectuée. Plus techniquement, lorsqu'il n'y a pas de caisse ou d'arbre de travail.
Juste pour être plus clair :)
Utilisez git reset HEAD
pour réinitialiser l'index sans supprimer de fichiers. (Si vous souhaitez uniquement réinitialiser un fichier particulier dans l'index, vous pouvez utiliser git reset HEAD -- /path/to/file
pour le faire.)
L'opérateur de canal, dans un shell, prend la stdout
du processus à gauche et le transmet sous la forme stdin
au processus à droite. C'est essentiellement l'équivalent de:
$ proc1 > proc1.out
$ proc2 < proc1.out
$ rm proc1.out
mais à la place, c'est $ proc1 | proc2
, le deuxième processus peut commencer à obtenir des données avant que le premier soit terminé, et aucun fichier n'est impliqué.
Si HEAD n'est pas défini, vous pouvez également faire
git rm -rf --cached .
tout défaire. C'est en fait la même chose que la solution de sehe, mais cela évite de gâcher avec les internes de Git.
git stash && git stash pop
Attention: n'utilisez pas la commande suivante à moins que vous ne vouliez perdre du travail non souscrit!
L'utilisation de git reset
a été expliquée, mais vous avez également demandé une explication des commandes redirigées.
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
La commande git ls-files
répertorie tous les fichiers connus de git. L'option -z
leur impose un format spécifique, le format attendu par xargs -0
, qui y invoque ensuite rm -f
, ce qui signifie de les supprimer sans vérification de votre approbation.
En d’autres termes, "liste tous les fichiers que git connaît et supprime votre copie locale".
Ensuite, nous arrivons à git diff
, qui montre les changements entre les différentes versions des éléments que git connaît. Celles-ci peuvent être des changements entre différentes arborescences, des différences entre les copies locales et des copies distantes, etc.
Tel qu’utilisé ici, il montre les changements non mis en scène; les fichiers que vous avez modifiés mais que vous n'avez pas encore engagés. L'option --name-only
signifie que vous voulez uniquement les noms de fichiers (complets) et --diff-filter=D
signifie que vous êtes intéressé uniquement par les fichiers supprimés. (Hé, n'avons-nous pas simplement supprimé un tas de choses?) Ceci est ensuite transféré dans le xargs -0
que nous avons vu auparavant, qui invoque git rm --cached
sur eux, ce qui signifie qu'ils sont supprimés du cache, tandis que l'arborescence de travail doit être laissée seule - sauf que vous venez de supprimer tous les fichiers de votre arborescence de travail. Maintenant, ils sont également supprimés de votre index.
En d'autres termes, tous les changements, programmés ou non, ont disparu et votre arbre de travail est vide. Faites un cri, récupérez vos fichiers d'origine ou distants et refaites votre travail. Maudit le sadique qui a écrit ces lignes infernales; Je ne sais absolument pas pourquoi quelqu'un voudrait faire cela.
TL; DR: vous venez de tout arroser; recommencez et utilisez git reset
à partir de maintenant.
Je crains que la première de ces lignes de commande ne supprime inconditionnellement de la copie de travail tous les fichiers qui se trouvent dans la zone de transfert de git. Le second a libéré tous les fichiers suivis mais maintenant supprimés. Malheureusement, cela signifie que vous aurez perdu toutes les modifications non validées apportées à ces fichiers.
Si vous souhaitez obtenir votre copie de travail et l'indexation sur leur état d'origine lors de la dernière validation , vous pouvez (avec soin) utilisez la commande suivante:
git reset --hard
Je dis "soigneusement" depuis git reset --hard
effacera les modifications non validées de votre copie de travail et index. Cependant, dans cette situation, il semble que vous souhaitiez simplement revenir à l'état lors de votre dernier commit, et les modifications non validées ont été perdues de toute façon.
Mise à jour: vos commentaires sur la réponse d'Amber semblent indiquer que vous n'avez pas encore créé de commits (car HEAD ne peut pas être résolu), cela ne vous aidera donc pas. 'ai peur.
En ce qui concerne le fonctionnement de ces canaux: git ls-files -z
et git diff --name-only --diff-filter=D -z
produisent tous deux une liste de noms de fichiers séparés par l'octet 0
. (Ceci est utile car, contrairement aux nouvelles lignes, 0
octets sont garantis ne pas apparaître dans les noms de fichiers sur les systèmes de type Unix.) Le programme xargs
construit essentiellement des lignes de commande à partir de son entrée standard, par défaut en prenant lignes de l'entrée standard et en les ajoutant à la fin de la ligne de commande. L'option -0
indique qu'il faut s'attendre à une entrée standard séparée par 0
octets. xargs
peut appeler la commande plusieurs fois pour utiliser tous les paramètres de l'entrée standard, en s'assurant que la ligne de commande ne devient jamais trop longue.
Par exemple, si vous avez un fichier appelé test.txt
avec le contenu suivant:
hello
goodbye
hello again
... alors la commande xargs echo whatever < test.txt
appellera la commande:
echo whatever hello goodbye hello again
Si vous souhaitez annuler toutes les modifications, utilisez la commande ci-dessous,
git reset --soft HEAD
Dans le cas où vous souhaitez annuler la mise en scène des modifications et les revenir du répertoire de travail,
git reset --hard HEAD