Comment supprimer plusieurs fichiers supprimés dans le référentiel Git


237

J'ai supprimé certains fichiers et l'état de git s'affiche comme ci-dessous.

J'ai commis et poussé.

GitHub affiche toujours les fichiers supprimés dans le référentiel. Comment puis-je supprimer des fichiers dans le référentiel GitHub?

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   deleted:    modules/welcome/language/english/kaimonokago_lang.php
#   deleted:    modules/welcome/language/french/kaimonokago_lang.php
#   deleted:    modules/welcome/language/german/kaimonokago_lang.php
#   deleted:    modules/welcome/language/norwegian/kaimonokago_lang.php

Si j'utilise git rm, cela donne ce qui suit.

usage: git rm [options] [--] <file>...

-n, --dry-run         dry run
-q, --quiet           do not list removed files
--cached              only remove from the index
-f, --force           override the up-to-date check
-r                    allow recursive removal
--ignore-unmatch      exit with a zero status even if nothing matched


Réponses:


638
git add -u 

met à jour toutes vos modifications


31
Fonctionne un charme. Lorsque vous voyez quelque chose comme "git status | sed -n '/ ^ # * supprimé: / s /// p' | xargs git rm" comme solution proposée pour une exigence aussi simple mais fréquente, alors vous savez qu'une meilleure solution est, ou sera bientôt, au coin de la rue.
arcseldon

simple, c'est mieux, c'est vraiment pratique alors la méthode "bash"
castiel

1
L'auteur demande comment supprimer des fichiers, pourquoi l'ajout de fichiers est la bonne réponse?
kelin

3
@kelin: à partir de git docs ( git-scm.com/docs/git-add ): "-u --update Met à jour l'index là où il a déjà une entrée correspondant à <pathspec>. Cela supprime ainsi que modifie les entrées d'index en correspond à l'arborescence de travail, mais n'ajoute aucun nouveau fichier. Si aucun <pathspec> n'est indiqué lorsque l'option -u est utilisée, tous les fichiers suivis dans l'arborescence de travail entière sont mis à jour (les anciennes versions de Git utilisées pour limiter la mise à jour au répertoire actuel et ses sous-répertoires). "
HEDMON

92

Soyez très prudent git rm .; cela pourrait en supprimer plus que vous ne le souhaitez. Bien sûr, vous pouvez récupérer, mais il est plus simple de ne pas avoir à le faire.

Le plus simple serait:

git rm modules/welcome/language/english/kaimonokago_lang.php \
       modules/welcome/language/french/kaimonokago_lang.php \
       modules/welcome/language/german/kaimonokago_lang.php \
       modules/welcome/language/norwegian/kaimonokago_lang.php

Vous ne pouvez pas utiliser de caractères génériques shell car les fichiers n'existent pas, mais vous pouvez utiliser (au moins dans Bash):

git rm modules/welcome/language/{english,french,german,norwegian}/kaimonokago_lang.php

Ou considérez:

git status | sed -n '/^# *deleted:/s///p' | xargs git rm

Cela prend la sortie de git status, n'imprime rien par défaut ( sed -n), mais sur les lignes qui commencent # deleted:, il supprime le #et le deleted:et imprime ce qui reste; xargsrassemble les arguments et les fournit à une git rmcommande. Cela fonctionne pour n'importe quel nombre de fichiers, quelle que soit la similitude (ou la dissemblance) des noms.


6
Vous pouvez utiliser des caractères génériques (bien que vous ayez besoin de les échapper), et git fera correspondre les chemins de l'index, pas seulement ceux de l'arborescence de travail, donc peu importe qu'ils n'existent pas sur le système de fichiers.
Ben James

109
git diff --diff-filter=D --name-only -z | xargs -0 git rmest une approche plus fiable que d'essayer d'analyser git statusqui est orienté utilisateur et non garanti stable sur les futures versions.
CB Bailey

@Charles: c'est certainement mieux, mais cela nécessite pas mal de connaissances sur les options disponibles git diff(que je n'avais pas, n'ayant pas eu le besoin auparavant). Merci!
Jonathan Leffler

8
Notez qu'il y a aussi "git ls-files --deleted"
Petr Gladkikh

1
donc, a git ls-files --deleted | xargs git rmfait l'affaire pour moi.
fiacobelli

50

Une autre version de la réponse ByScripts est

git rm $(git ls-files --deleted)

Cela supprimera UNIQUEMENT les fichiers supprimés du git.

Il pourrait également être utilisé pour ajouter UNIQUEMENT des fichiers modifiés.

git add $(git ls-files --modified)

Ces commandes fonctionnent également sur gitbash pour Windows.


2
Inestimable, le git ls-filesstatut supprimé ou modifié est si utile.
Mario Peshev

1
Le comportement de 'git add --update (or -u)'sans argument de chemin d'un sous-répertoire de l'arbre changera dans Git 2.0 et ne devrait plus être utilisé. Pour ajouter du contenu pour l'arborescence entière, exécutez: git add --update :/ (ou git add -u: /) Pour restreindre la commande au répertoire en cours, exécutez: git add --update . (ou git add -u.) Avec la version actuelle de Git, la commande est limitée à la répertoire actuel
Ans

1
Une idée de comment gérer les chemins avec des espaces en eux? Exemple: src/my spaced directory/myfile. Cela peut être géré individuellement, mais comment peut-il être géré à l'aide des commandes de cette réponse?
Muhammad Gelbana

35

Mettez à jour toutes les modifications que vous avez apportées:

git add -u

Les fichiers supprimés doivent passer de non organisé (généralement de couleur rouge) à intermédiaire (vert). Ensuite, engagez-vous à supprimer les fichiers supprimés:

git commit -m "note"

1
Mérite l'insigne populiste.
John

1
C'est de loin la meilleure solution. Pas de piratage de scripts, pas de processus long, juste un indicateur pour dire à git de mettre à jour son index à fond.
Ron Dahlgren

Brillant! Cela m'a évité d'avoir à taper plus de 20 chemins de fichiers. Merci!
allardbrain

12

La meilleure solution si vous ne vous souciez pas de la mise en scène des fichiers modifiés est d'utiliser git add -ucomme indiqué par mshameers et / ou pb2q .

Si vous souhaitez simplement supprimer les fichiers supprimés, mais ne pas mettre en scène les fichiers modifiés, je pense que vous devriez utiliser l' ls-filesargument avec l' --deletedoption (pas besoin d'utiliser l'expression régulière ou d'autres arguments / options complexes):

git ls-files --deleted | xargs git rm

1
git add -Arésout ce problème ... juste au cas où quelqu'un voudrait savoir à l'avenir. vérifier la réponse ci-dessous
Ja8zyjits

8

Oui, git rm <filename>mettra en scène l'état supprimé d'un fichier, où <filename>pourrait être un modèle global:

$ git rm modules/welcome/language/*/kaimonokago_lang.php
rm modules/welcome/language/english/kaimonokago_lang.php
rm modules/welcome/language/french/kaimonokago_lang.php
rm modules/welcome/language/german/kaimonokago_lang.php
rm modules/welcome/language/norwegian/kaimonokago_lang.php

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    modules/welcome/language/english/kaimonokago_lang.php
#       ...

Ensuite, vous pouvez vous engager.

git commit -a le fera en une seule fois, si vous le souhaitez.

Vous pouvez également utiliser git add -upour mettre en scène toutes les modifications, y compris tous les fichiers supprimés, puis valider.


donc rm. (point final) les supprimer immédiatement?
shin

alors juste git rm supprimera tout à la fois?
shin

1
Vous pouvez utiliser un modèle de style global pour supprimer plusieurs fichiers; J'ai mis à jour ma réponse pour montrer un exemple.
Ben James

5
Il semble que git add -uc'est exactement ce que nous recherchons - si vous effectuez de nombreuses suppressions, puis que vous souhaitez valider toutes les suppressions, cela semble être le moyen le plus simple et le plus `` standard '' (c'est-à-dire, sans globes spécifiques à la casse ou analyse complexe du shell dans xargs). Y a-t-il une raison pour laquelle nous ne voudrions pas l'utiliser, à part le fait qu'il ajoute tous les changements en même temps?
trisweb

7

Lorsque j'ai beaucoup de fichiers que j'ai supprimés qui ne sont pas mis en scène pour la validation, vous pouvez git rmles tous en un seul spectacle avec:

for i in `git status | grep deleted | awk '{print $3}'`; do git rm $i; done

Comme l'a mentionné le répondeur, soyez prudent git rm.


5

Essaye ça:

 git rm `git ls-files -d`

Cela a résolu mon problème de mise en scène uniquement des scripts supprimés (en utilisant bash)
Mariano Argañaraz

3

Vous pouvez utiliser

git commit -m "remove files" -a
git push

Après avoir supprimé les fichiers manuellement.


1
Ou à l'identique mais plus succinctement: git commit -am "remove files"
BradChesney79

3

Vous pouvez créer un script shell qui supprimera tous vos fichiers lors de l'exécution:

git status | grep deleted | awk '{print "git rm " $3;}' > ../remove.sh

Le script créé est remove.shet contient la liste complète des git rmcommandes.


2
git status | sed 's/^#\s*deleted:\s*//' | sed 's/^#.*//' | xargs git rm -rf


2

Si vous souhaitez tous les supprimer en utilisant "git rm". C'est ce que je fais:

git ls-files --deleted -z | xargs -0 git rm

Cette requête répertorie tous les fichiers qui ont été supprimés et les supprime de votre référentiel git. J'espère que ça aide.



1

J'ai eu ce problème de fichiers fantômes apparaissant dans mon référentiel après les avoir supprimés et rencontré cette commande soignée!

git add -A

C'est essentiellement le même que git add -aet git add -ucombiné, mais il est sensible à la casse. Je l'ai obtenu à partir de ce lien génial (ce lien pointe vers la version sur archive.org maintenant, car l'original s'est converti en une page de spam / phishing en juin 2016)


0

Voici comment détecter les fichiers supprimés et organiser leur suppression dans le cadre du prochain commit. Toutes les solutions de ce fil ont des mérites différents. Cette solution ci-dessous traite spécifiquement du problème des noms de fichiers avec des espaces.

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm '{}'

assurez-vous de tester cela avec l'option --dry-run de git avant de l'exécuter avec ce qui suit:

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm --dry-run '{}'

explication:

git status --porcelain

Cela affiche quelque chose comme D "/ chemin vers un dossier / chemin vers un fichier" qui ne se produit que lorsqu'il y a des espaces dans les noms de chemin

awk '/^.D .*$/ {print $0}'

ne correspond qu'aux lignes commençant par "D"

sed 's/ D \(.*\)/\1/'

supprimer "D" de l'avant de chaque chaîne

tr -d '"'

supprimer les citations, le cas échéant

xargs -I {} git rm '{}'

définissez les variables de nom de fichier comme {} exécutez le nom de fichier sous git rm entre guillemets simples afin de vous assurer qu'il prend en charge les noms de fichier avec des espaces.

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.