Команда Git, щоб показати, які конкретні файли ігноруються .gitignore


645

Я мокну ноги від Git і маю таке питання:

Моє дерево джерела проекту:

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

У моїй філії постачальника є код (на даний момент MEF), який я збиратиму там, а потім переміщуму посилання /src/refs, куди проект бере їх.

Моє питання полягає в тому, що я .gitignoreналаштований ігнорувати *.dllі *.pdb. Я можу зробити, git add -f bar.dllщоб змусити додавати проігнорований файл, що нормально, проблема в тому, що я не можу зрозуміти, які списки існують, які файли існують.

Я хочу перелічити проігноровані файли, щоб переконатися, що я не забуду їх додати.

Я прочитав сторінку man на git ls-filesі не можу змусити її працювати. Мені здається, що git ls-files --exclude-standard -iслід робити те, що я хочу. Що я пропускаю?


12
У ці дні ви б не використовували git-ls-файли, а «git ls-файли»
wojo

7
Я благаю вас перевірити відповідь ріяда як правильну, оскільки це єдиний, хто визнає, що немає жодного гарантованого способу зробити це, використовуючи лише команди git (включаючи git cleanтрюк), як показано тут . Крім того, я рекомендую проти прикладу "виключити-з" у своєму резюме, оскільки це фактично не звертає уваги на будь-які файли .gitignore. Я запитую це особливо, тому що ця сторінка - це найкраща відповідь Google.
Олександр Птах

Швидкий пункт "Підсумок того, що працює": "Сторінка" Git ls-files "пояснює, що засоби" -i "включають виключені файли для виводу ls. У мене було таке ж непорозуміння, поки я не прочитав "це повільно". ;-)
буде

2
Відповіді повинні містити відповідь, а не редагувати запитання.
Flimm

У мене є git config --global alias.ls ls-files --exclude-standard, і це дає відповідь на це питання git ls -i.
jthill

Відповіді:


662

Примітки:


Також цікаво (згадується в qwertymk «s відповідь ), ви можете також використовувати git check-ignore -vкоманду, принаймні на Unix ( не працює в CMD Windows , сесії)

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

Другий відображає фактичне правило, .gitignoreяке змушує ігнорувати файл у вашому git repo.
У Unix, використовуючи " Що розширюється до всіх файлів у поточному каталозі рекурсивно? " Та bash4 +:

git check-ignore **/*

(або find -execкоманда)

Примітка: https://stackoverflow.com/users/351947/Rafi Б. пропонує в коментарях , щоб уникнути (ризикований) globstar :

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

Не забудьте виключити файли з .git/підпапки.


Оригінальна відповідь 42009)

git ls-files -i

повинен працювати, за винятком того, що його вихідний код вказує:

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

exc_given ?

Виявляється, потрібен ще один параметр після того, -iяк насправді щось перелічити:

Спробуйте:

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

(але це тільки список вашого кешованого (не ігнорованого) об'єкта, з фільтром, так що це не зовсім те, що ви хочете)


Приклад:

$ 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

Насправді в моєму файлі "gitignore" (званий "виключити") я знаходжу командний рядок, який може вам допомогти:

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]
# *~

Тому....

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

повинен зробити трюк.

Як згадується на сторінці ls-files man , --othersце важлива частина для того, щоб показати вам файли, не кешовані, не скоєні, звичайно ігноровані.

--exclude_standardце не просто ярлик, а спосіб включити всі стандартні налаштування "ігнорованих шаблонів".

exclude-standard
Додати стандартні GIT виключення: .git/info/exclude, .gitignoreв кожному каталозі, і user's global exclusion file.


@VocC, наскільки я розумію ці тести , відповідь, яку ви рекомендуєте вгорі, просто може мати великі вади. Ось чому я зазвичай рекомендую відповідь Ріяда замість цього.
Олександр Птах

2
Оскільки Git v2.13.2 випуску: git status --ignoredздається, він також показує непотрібні
Pau

1
Уау, git check-ignore -v *чудово працює, оскільки показує, де застосовано конфігурацію. Дякую.
Hoang Tran

@MikeD Щоб зробити * / роботу (або насправді, ви просто можете зробити **), вам потрібно встановити globstar, shopt -s globstarпісля чого він повинен працювати.
Веда

Без включення (ризикованого) глобального зірка:git check-ignore -v $(find . -type f -print)
rafi

482

Існує набагато простіший спосіб зробити це (git 1.7.6+):

git status --ignored

Див. Чи є спосіб сказати git-status ігнорувати ефекти файлів .gitignore?


3
Яку версію git ви використовуєте? Міна (1.7.0.4) говорить error: unknown option 'ignored'. Навіть додавання, -sяк було запропоновано у зв’язаній публікації, не працювало.
Олександр Птах

3
Моя версія 1.7.6. Інша версія 1.7.5.1 - це та, яка вимагає -s. Ви можете спробувати git status -hпереконатися, чи --ignoredпідтримується
Penghe Geng

1
Я думаю, що просто ще не підтримується в 1.7.0.4. На моєму іншому комп’ютері є 1.7.9, а там
Олександр Птах

4
Я намагався кожне рішення на цій сторінці. Це найкращий. Він показує як файли, так і каталоги. Ця функція, ймовірно, недоступна, коли це питання було задано спочатку. (До речі, всі рішення не працюватимуть належним чином із абсолютно новим "git init", поки ви принаймні не поетапно зміните.)
wisbucky

12
Це, звичайно, набагато краще, ніж прийнята відповідь. Це також набагато безпечніше git clean -ndXрішення, тому що рідкісна ситуація, коли помилково забули прапори, матиме безповоротний вплив на сховище, оскільки незараховані файли видаляються. Так це небезпечно. Навпаки, git status --ignoredце завжди безпечно, навіть коли помилково набрано і природно запам'ятати.
Іоанніс Філіппідіс

400

Ще один варіант, який є досить чистим (каламбур не призначений.):

git clean -ndX

Пояснення:

$ 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.

Примітка. Це рішення не відображатиме ігноровані файли, які вже були видалені.


Nifty ... однак причина, яку я задала оригінальному питанню, полягала в тому, щоб я міг переконатися, що файли постачальників (* .dll), які повинні були бути там ..., тож видалення їх не буде бажаним результатом. ТАКОЖ: це добре знати, оскільки я змінив свою стратегію від ігнорування * .dll до ігнорування моєї папки вихідного випуску (але не моїх папок постачальника). Це було б хорошою альтернативою make cleanта дуже корисною програмою для побудови сервера.
Ендрю Бернс

2
Я використовую git версії 1.7.0.4, і дві команди ('git ls-files -o -i --exclude-standard', 'git clean -dXn') не є рівнозначними. Перший показує мені 4 файли, а другий лише два. (.gitignore ~, index.php ~, sql / create_users.sql ~, www / index.php ~) (Видалить .gitignore ~, видалив би index.php ~). Я щось тут сумую?
Сезар

@VonC, милий! Дякую! @ Сезар, я не впевнений. Я не такий знайомий git ls-files -o -i --exclude-standard. git clean -dXnзавжди було те, що я хотів, але не показує ігноровані файли, які вже видалено. git ls-files -o -i --exclude-standardможе це зробити. Отже, саме це може бути причиною різниці.
ma11hew28

3
Одна крихітна річ - може бути гарною ідеєю набрати nперший, менший шанс випадкового видалення таким чином; git clean -ndX
Тобіас Коен

1
@TobiasCohen приємно! Я оновив відповідь з вашою пропозицією. Це безпечніше. Хоча, якщо ви не залишите n, Git за замовчуванням fatal: clean.requireForce defaults to true and neither -n nor -f given; refusing to clean. Все ще досить безпечно, але введення nпершого ще безпечніше! :)
ma11hew28

39

Хоча правильне рішення не працює в будь-яких обставинах. Припустимо такий репо-реп:

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

doc:
index.html

tmp:
dir0  file1  file2

tmp/dir0:
file0

і .gitignore так:

# cat .gitignore
doc
tmp/*

При цьому ігнорується docкаталог та всі файли нижче tmp. Git працює як очікувалося, але дана команда для переліку ігнорованих файлів не робить. Давайте подивимось, що має сказати git:

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

Зауважте, що docу списку відсутнє. Ви можете отримати його за допомогою:

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

Зауважте додаткове --directory варіант.

З моїх знань не одна команда , щоб перерахувати всі ігноровані файли відразу. Але я не знаю, чому tmp/dir0взагалі не з’являється.


2
Це отримало мені те, що я хотів, тоді як інші не зробили (для мого конкретного випадку) ... спасибі! Перешкоджати виконанню двох команд, але з ігнорованим каталогом параметр --directory щонайменше знаходить мені це, і я можу передати цю команду для пошуку файлів. Дякую!
Лінд

Це робить все і відразу, і розширює каталоги:(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 вбудована ця функціональність

git check-ignore *

Звичайно, ви можете змінити глобус на щось подібне **/*.dllу вашому випадку

Довідка на Git


7
git check-ignore **/*включити файли у підкаталоги
mzimmer

це лише перелік довідників верхнього рівня.
Radon8472

13

Її має бути достатньо для використання

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

як це охоплює все, що охоплюється

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

тому остання є зайвою.


Ви можете зробити це простіше, додавши псевдонім у ~/.gitconfigфайл:

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

Тепер ви можете просто набрати git ignored щоб побачити список. Набагато простіше запам’ятати та швидше набрати.

Якщо ви віддаєте перевагу більш лаконічному відображенню рішення Джейсона Генга, ви можете додати псевдонім для такого, як це:

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

Однак більш детальний висновок корисніший для усунення проблем з вашими файлами .gitignore, оскільки в ньому перераховано кожен ігнорований бавовняний файл, який ігнорується. Ви, як правило, отримуєте результати, grepщоб побачити, чи є там файл, який ви очікуєте від ігнорування, чи файл, який ви не хочете, щоб його ігнорували.

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

Потім, коли ви просто хочете побачити короткий дисплей, досить легко запам'ятати та набрати

git status --ignored

( -sНормально може бути відключена.)


Це ніколи не працювало для мене, тому що ви повинні вручну перелічити ці файли. git status --ignoredпрацює над Debian sid, але може бути дуже новим ... але, мабуть, він додався завдяки популярному попиту ;-)
mirabilos

1
Під "працює на Debian sid" я припускаю, що ви маєте на увазі "працює з версією Git, встановленою за замовчуванням на Debian sid"? Вам справді слід уникати того, щоб ви залишалися заручниками версій утиліт, що входять до вашого дистрибутива. Ви можете оновити їх незалежно від самого дистрибутива.
іконоборство

12

Ось як надрукувати повний список файлів у робочому дереві, які відповідають шаблонам, розташованим у будь-якому місці в декількох джерелах Gitgnore Git (якщо ви використовуєте GNU find):

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

Він перевірить усі файли в поточній гілці сховища (якщо ви не видалили їх локально).

І він також визначає конкретні джерельні лінії gitignore.

Git продовжує відстежувати зміни в деяких файлах, які відповідають моделям gitignore, просто тому, що ці файли вже додані. Корисно, що наведена вище команда відображає і ці файли.

Негативні моделі gitignore також відповідають. Однак у переліку їх легко відрізнити, оскільки вони починаються з !.

Якщо ви використовуєте Windows, Git Bash включає GNU find(як було виявлено find --version).

Якщо список довгий (і у вас є rev), ви можете відображати їх також у розширенні (дещо):

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

Для більш докладної інформації, див man find, man git-check-ignore, man rev, і man sort.

Сенс усього цього підходу полягає в тому, що Git (програмне забезпечення) швидко змінюється і є дуже складним. На відміну від проекту GNU findє надзвичайно стабільною (по крайней мере, в його функції використовується тут). Отже, кожен, хто бажає бути конкурентоспроможним, демонструючи свої поглиблені знання про Git, відповість на питання по-іншому.

Яка найкраща відповідь? Це відповідь свідомо мінімізує її залежність від знань Git, до досягнення мети стабільності та простоти за допомогою модульності (інформаційної ізоляції), і покликана тривати довго .


Дуже дякую! Я намагався зрозуміти, чому деякі мої нові вихідні файли періодично відсутні у моїх комісіях. Виявляється, у мене був шаблон: bin *, який я вважав, що він відповідає лише іменам файлів / каталогів, починаючи з біна, але замість цього він відповідає будь-якому, що включає бін у повному шляху файлу / каталогу! Я здогадуюсь, моя проблема пов'язана з нерозумінням точної семантики відповідності шаблону в .gitignore. Ваш 2-рядковий сценарій допоміг мені знайти цю помилку!
Ніколя Рукетет

1

(розширення інших відповідей)

Зауважте, git check-ignoreвикористовує скоєне, .gitignoreа не те, що у вашому робочому дереві! Щоб грати з ним, не забруднюючи вашу історію git, ви можете спробувати її відредагувати, а потім скористатисяgit commit --amend .

Ця проблема виникає головним чином, якщо вам потрібно вирішити проблему, що git не відповідає каталогам. Введіть .gitignore:

dirtokeep/**
!dirtokeep/.keep

.keepмає бути файлом нульової довжини в dirtokeep.

Результатом буде те, що все в програмі dirtokeepбуде проігноровано, за винятком того dirtokeep/.keep , що призведе до того, що також dirtokeepкаталог буде побудований на клоні / реєстрації.


0

Якщо припустити, що існує кілька каталогів ігнорування, чому б не використати "git status node / logs /", який підкаже, які файли потрібно додати? У каталозі у мене є текстовий файл, який не є частиною виводу статусу, наприклад:

Про головного відділення
Ваша філія є в курсі "походження / майстра".
Невикреслені файли:
(використовуйте "git add ...", щоб включити до того, що буде вчинено)

    node/logs/.gitignore 

.gitignore:

*

! .gitignore

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.