Commande Git pour montrer quels fichiers spécifiques sont ignorés par .gitignore

646

Je mouille les pieds avec Git et j'ai le problème suivant:

Mon arbre source de projet:

/
|
+--src/
+----refs/
+----...
|
+--vendor/
+----...

J'ai du code (actuellement MEF) dans ma branche fournisseur que je vais compiler là-bas et ensuite déplacer les références dans /src/refslesquelles le projet les récupère.

Mon problème est que j'ai mon .gitignorejeu à ignorer *.dllet *.pdb. Je peux faire un git add -f bar.dllpour forcer l'ajout du fichier ignoré, ce qui est correct, le problème est que je n'arrive pas à répertorier les fichiers qui sont ignorés.

Je veux lister les fichiers ignorés pour m'assurer de ne pas oublier de les ajouter.

J'ai lu la page de manuel git ls-fileset je ne peux pas la faire fonctionner. Il me semble que ça git ls-files --exclude-standard -idevrait faire ce que je veux. Qu'est-ce que je rate?

Andrew Burns
la source
12
Ces jours-ci, vous n'utiliseriez pas les fichiers git-ls mais plutôt les «fichiers git ls»
wojo
7
Je vous supplie de vérifier que la réponse de riyad est correcte car c'est la seule qui admet qu'il n'y a aucun moyen garanti de le faire en utilisant uniquement les commandes git (y compris l' git cleanastuce) comme démontré ici . Aussi, je déconseille l'exemple "exclure de" dans votre résumé car cela ne fait en fait pas attention aux fichiers .gitignore. Je pose cette question surtout parce que cette page est la meilleure réponse de Google.
Alexander Bird
Petit point sur "Résumé de ce qui fonctionne": la page de manuel "Git ls-files" explique que le "-i" signifie inclure les fichiers exclus pour la sortie ls. J'ai eu le même malentendu, jusqu'à ce que je le lise «lentement». ;-)
sera
2
Les réponses doivent aller dans un message de réponse et non dans une modification de la question.
Flimm
J'ai git config --global alias.ls ls-files --exclude-standard, et cela fait la réponse à cette question git ls -i.
2018

Réponses:

662

Remarques:


Également intéressant (mentionné dans la réponse de qwertymk ), vous pouvez également utiliser la commande, au moins sur Unix ( ne fonctionne pas dans une session Windows CMD )git check-ignore -v

git check-ignore *
git check-ignore -v *

Le second affiche la règle réelle du .gitignorequi fait qu'un fichier doit être ignoré dans votre dépôt git.
Sous Unix, en utilisant " Qu'est-ce qui s'étend à tous les fichiers du répertoire courant de manière récursive? " Et un bash4 +:

git check-ignore **/*

(ou une find -execcommande)

Remarque: https://stackoverflow.com/users/351947/Rafi B. suggère dans les commentaires d' éviter la globstar (risquée) :

git check-ignore -v $(find . -type f -print)

Assurez-vous cependant d'exclure les fichiers du .git/sous - dossier.


Réponse originale 42009)

git ls-files -i

devrait fonctionner, sauf que son code source indique:

if (show_ignored && !exc_given) {
                fprintf(stderr, "%s: --ignored needs some exclude pattern\n",
                        argv[0]);

exc_given ?

Il s'avère qu'il a besoin d'un paramètre supplémentaire après le -ipour répertorier quoi que ce soit:

Essayer:

git ls-files -i --exclude-from=[Path_To_Your_Global].gitignore

(mais cela ne listerait que votre objet mis en cache (non ignoré), avec un filtre, donc ce n'est pas tout à fait ce que vous voulez)


Exemple:

$ cat .git/ignore
# ignore objects and archives, anywhere in the tree.
*.[oa]
$ cat Documentation/.gitignore
# ignore generated html files,
*.html
# except foo.html which is maintained by hand
!foo.html
$ git ls-files --ignored \
    --exclude='Documentation/*.[0-9]' \
    --exclude-from=.git/ignore \
    --exclude-per-directory=.gitignore

En fait, dans mon fichier 'gitignore' (appelé 'exclude'), je trouve une ligne de commande qui pourrait vous aider:

F:\prog\git\test\.git\info>type exclude
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~

Donc....

git ls-files --others --ignored --exclude-from=.git/info/exclude
git ls-files -o -i --exclude-from=.git/info/exclude

git ls-files --others --ignored --exclude-standard
git ls-files -o -i --exclude-standard

devrait faire l'affaire.

Comme mentionné dans la page de manuel ls-files , --othersest la partie importante, afin de vous montrer les fichiers non mis en cache, non validés, normalement ignorés.

--exclude_standardn'est pas seulement un raccourci, mais un moyen d'inclure tous les paramètres standard de "motifs ignorés".

exclude-standard
Ajoutez les exclusions git standard: .git/info/exclude, .gitignoredans chaque répertoire, et user's global exclusion file.

VonC
la source
@VocC, d'après ma compréhension de ces tests , la réponse que vous recommandez en haut peut simplement avoir de gros défauts. C'est pourquoi je recommanderais normalement la réponse de riyad à la place.
Alexander Bird
2
Depuis la sortie de Git v2.13.2: git status --ignoredil semble également afficher les fichiers non suivis
Pau
1
wow, git check-ignore -v *fonctionne très bien, car il montre où la config s'est appliquée. Je vous remercie.
Hoang Tran
@MikeD Pour faire fonctionner * / (ou en fait, vous pouvez simplement faire **), vous devez définir globstar shopt -s globstaraprès cela.
Veda
Sans activer (risqué) globstar:git check-ignore -v $(find . -type f -print)
rafi
484

Il existe une manière beaucoup plus simple de le faire (git 1.7.6+):

git status --ignored

Voir Existe - t-il un moyen de dire à git-status d'ignorer les effets des fichiers .gitignore?

Penghe Geng
la source
3
Quelle version de git utilisez-vous? Le mien (1.7.0.4) dit error: unknown option 'ignored'. Même l'ajout -scomme suggéré dans le post lié n'a pas fonctionné.
Alexander Bird
3
Ma version est 1.7.6. Une autre version 1.7.5.1 est celle qui nécessite -s. Vous pouvez essayer git status -hde voir si --ignoredest pris en charge
Penghe Geng
1
Je suppose que ce n'est tout simplement pas encore pris en charge dans 1.7.0.4. Mon autre ordinateur a 1.7.9 et le drapeau
Alexander Bird
4
J'ai essayé toutes les solutions sur cette page. C'est le meilleur. Il montre les fichiers et les répertoires. Cette fonctionnalité n'était probablement pas disponible à l'époque où cette question a été posée à l'origine. (Soit dit en passant, toutes les solutions ne fonctionneront pas correctement avec un tout nouveau "git init" jusqu'à ce que vous ayez au moins mis en place des changements.)
wisbucky
12
C'est certainement beaucoup mieux que la réponse acceptée. C'est aussi beaucoup plus sûr que la git clean -ndXsolution, car la rare situation où l'on oublie par erreur les drapeaux aura un effet irrévocable sur le référentiel, car les fichiers non suivis sont supprimés. C'est donc dangereux. Au contraire, il git status --ignoredest toujours sûr, même lorsqu'il est mal tapé et il est naturel de s'en souvenir.
Ioannis Filippidis
400

Une autre option qui est assez propre (sans jeu de mots.):

git clean -ndX

Explication:

$ git help clean

git-clean - Remove untracked files from the working tree
-n, --dry-run - Don't actually remove anything, just show what would be done.
-d - Remove untracked directories in addition to untracked files.
-X - Remove only files ignored by Git.

Remarque: Cette solution n'affichera pas les fichiers ignorés qui ont déjà été supprimés.

ma11hew28
la source
Nifty ... mais la raison pour laquelle j'ai posé la question d'origine était pour que je puisse m'assurer que les fichiers du fournisseur (* .dll) qui étaient censés être là étaient ... afin de les supprimer ne serait pas le résultat souhaité. CEPENDANT: c'est bon à savoir car j'ai changé ma stratégie en ignorant * .dll en ignorant mon dossier de sortie de construction (mais pas mes dossiers de fournisseur). Ce serait une bonne alternative make cleanet très utile sur un serveur de build.
Andrew Burns
2
J'utilise la version 1.7.0.4 de git, et les deux commandes ('git ls-files -o -i --exclude-standard', 'git clean -dXn') ne sont pas équivalentes. Le premier me montre 4 fichiers et le second seulement deux. (.gitignore ~, index.php ~, sql / create_users.sql ~, www / index.php ~) (supprimerait .gitignore ~, supprimerait index.php ~). Suis-je quelque chose de missins ici?
Cesar
@VonC, doux! Merci! @ César, je ne suis pas sûr. Je ne connais pas si bien git ls-files -o -i --exclude-standard. git clean -dXna toujours été ce que je voulais mais n'affiche pas les fichiers ignorés qui ont déjà été supprimés. git ls-files -o -i --exclude-standardpourrait faire ça. Donc, c'est peut-être ce qui cause la différence.
ma11hew28
3
Une toute petite chose - ce pourrait être une bonne idée de taper la npremière, moins de chance de supprimer accidentellement de cette façon; git clean -ndX
Tobias Cohen
1
@TobiasCohen nice! J'ai mis à jour la réponse avec votre suggestion. C'est plus sûr. Bien que, si vous omettez le n, Git soit par défaut fatal: clean.requireForce defaults to true and neither -n nor -f given; refusing to clean. Toujours assez sûr, mais taper le npremier est encore plus sûr! :)
ma11hew28
39

Bien que généralement correcte, votre solution ne fonctionne pas en toutes circonstances. Supposons un répertoire de repo comme celui-ci:

# ls **/*                                                                                                       
doc/index.html  README.txt  tmp/dir0/file0  tmp/file1  tmp/file2

doc:
index.html

tmp:
dir0  file1  file2

tmp/dir0:
file0

et un .gitignore comme celui-ci:

# cat .gitignore
doc
tmp/*

Cela ignore le docrépertoire et tous les fichiers ci-dessous tmp. Git fonctionne comme prévu, mais la commande donnée pour lister les fichiers ignorés ne fonctionne pas. Voyons ce que git a à dire:

# git ls-files --others --ignored --exclude-standard                                                            
tmp/file1
tmp/file2

Notez qu'il docmanque dans la liste. Vous pouvez l'obtenir avec:

# git ls-files --others --ignored --exclude-standard --directory                                                
doc/

Remarquez l' --directoryoption supplémentaire .

D'après mes connaissances, il n'y a pas de commande unique pour répertorier tous les fichiers ignorés à la fois. Mais je ne sais pas pourquoi tmp/dir0n'apparaît pas du tout.

riyad
la source
2
Cela m'a donné ce que je voulais, contrairement aux autres (pour mon cas particulier) ... merci! C'est frustrant d'avoir à exécuter deux commandes, mais avec un répertoire ignoré, l'option --directory me trouve au moins cela, et je peux le canaliser dans une commande find pour trouver les fichiers. Merci!
lindes
Cela fait tout à la fois et étend les répertoires:(git ls-files -oi --exclude-standard; git ls-files -oi --exclude-standard --directory) | perl -nle '$seen{$_}++||next;if(-d){system"find",$_,"-type","f"}else{print}'
Dee Newcum
17

Git a maintenant cette fonctionnalité intégrée

git check-ignore *

Bien sûr, vous pouvez changer le glob en quelque chose comme **/*.dll dans votre cas

Référence Git

qwertymk
la source
7
git check-ignore **/*inclure des fichiers dans des sous
mzimmer
cela répertorie uniquement les répertoires de niveau supérieur.
Radon8472
13

Il devrait être suffisant d'utiliser

git ls-files --others -i --exclude-standard

car cela couvre tout ce qui est couvert par

git ls-files --others -i --exclude-from=.git/info/exclude

ce dernier est donc redondant.


Vous pouvez rendre cela plus facile en ajoutant un alias à votre ~/.gitconfigfichier:

git config --global alias.ignored "ls-files --others -i --exclude-standard"

Maintenant, vous pouvez simplement taper git ignoredpour voir la liste. Beaucoup plus facile à mémoriser et plus rapide à taper.

Si vous préférez l'affichage plus succinct de la solution de Jason Geng, vous pouvez ajouter un alias pour cela comme ceci:

git config --global alias.ignored "status --ignored -s"

Cependant, la sortie plus détaillée est plus utile pour résoudre les problèmes avec vos fichiers .gitignore, car elle répertorie tous les fichiers de sélection de coton qui sont ignorés. Vous devriez normalement diriger les résultats greppour voir si un fichier que vous prévoyez d'ignorer se trouve dedans, ou si un fichier que vous ne voulez pas ignorer est là.

git ignored | grep some-file-that-isnt-being-ignored-properly

Ensuite, lorsque vous voulez juste voir un court affichage, il est assez facile de se souvenir et de taper

git status --ignored

(Le -s peut normalement être laissé de côté.)

iconoclaste
la source
Cela n'a jamais fonctionné pour moi, car vous devez répertorier manuellement ces fichiers. git status --ignoredfonctionne sur Debian Sid mais peut être très nouveau… mais apparemment, il a été ajouté en raison de la demande populaire ;-)
mirabilos
1
Par «fonctionne sur Debian Sid», je suppose que vous voulez dire «fonctionne avec la version de Git installée par défaut sur Debian Sid»? Vous devriez vraiment éviter de vous laisser prendre en otage par les versions des utilitaires inclus dans votre distribution. Vous pouvez les mettre à jour indépendamment de la distribution elle-même.
iconoclaste
12

Voici comment imprimer la liste complète des fichiers dans l'arborescence de travail qui correspondent aux modèles situés n'importe où dans les multiples sources gitignore de Git (si vous utilisez GNU find):

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose

Il vérifiera tous les fichiers de la branche actuelle du référentiel (sauf si vous les avez supprimés localement).

Et il identifie également les lignes source gitignore particulières.

Git continue de suivre les changements dans certains fichiers qui correspondent aux modèles de gitignore, simplement parce que ces fichiers ont déjà été ajoutés. Utilement, la commande ci-dessus affiche également ces fichiers.

Les motifs négatifs de gitignore sont également appariés. Cependant, ceux-ci se distinguent facilement dans la liste, car ils commencent par !.

Si vous utilisez Windows, Git Bash inclut GNU find(comme révélé par find --version).

Si la liste est longue (et vous avez rev ), vous pouvez également les afficher par extension (un peu):

$ cd {your project directory}
$ find . -path ./.git -prune -o -print \
| git check-ignore --no-index --stdin --verbose \
| rev | sort | rev

Pour plus de détails, voir man find,man git-check-ignore , man revet man sort.

L'intérêt de toute cette approche est que Git (le logiciel) évolue rapidement et est très complexe. En revanche, les GNUfind est extrêmement stable (au moins, dans ses fonctionnalités utilisées ici). Ainsi, quiconque souhaite être compétitif en affichant sa connaissance approfondie de Git répondra à la question d'une manière différente.

Quelle est la meilleure réponse? Cette réponse minimise délibérément sa dépendance à l'égard des connaissances Git, pour atteindre l'objectif de stabilité et de simplicité grâce à la modularité (isolation des informations), et est conçue pour durer longtemps .

MarkDBlackwell
la source
Merci beaucoup! J'avais du mal à comprendre pourquoi certains de mes nouveaux fichiers source manquaient parfois à mes commits. Il s'avère que j'avais un modèle: bin *, que je pensais ne correspondre qu'à des noms de fichiers / répertoires commençant par bin mais à la place il correspond à tout ce qui inclut bin dans le chemin complet d'un fichier / répertoire! Je suppose que mon problème vient d'une mauvaise compréhension de la sémantique précise de la correspondance de motifs dans .gitignore. Votre script sur 2 lignes m'a aidé à trouver cette erreur!
Nicolas Rouquette
1

(prolongeant les autres réponses)

Remarque, git check-ignoreutilise le commit .gitignoreet non celui de votre arbre de travail! Pour jouer avec sans polluer votre historique git, vous pouvez librement essayer de le modifier, puis vous engager avec ungit commit --amend .

Ce problème se produit principalement si vous avez besoin d'une solution de contournement du problème, que git ne suit pas les répertoires. Entrez dans .gitignore:

dirtokeep/**
!dirtokeep/.keep

.keepdevrait être un fichier de longueur nulle dirtokeep.

Le résultat sera que tout en dirtokeepsera ignorée, excepter dirtokeep/.keep , ce qui se traduira aussi que le dirtokeeprépertoire sera construit sur le clone / caisse.

peterh - Réintégrer Monica
la source
0

En supposant qu'il existe quelques répertoires ignorés, pourquoi ne pas utiliser "git status node / logs /" qui vous dira quels fichiers doivent être ajoutés? Dans le répertoire, j'ai un fichier texte qui ne fait pas partie de la sortie d'état, par exemple:

Sur le maître de succursale
Votre succursale est à jour avec «origine / maître».
Fichiers non suivis:
(utilisez "git add ..." pour inclure dans ce qui sera validé)

    node/logs/.gitignore 

.gitignore c'est:

*

! .gitignore

pikknz
la source