Зробіть .gitignore ігнорувати все, крім кількох файлів


1698

Я розумію, що файл .gitignore маскує вказані файли з управління версіями Git. У мене є проект (LaTeX), який генерує безліч зайвих файлів (.auth, .dvi, .pdf, журнали тощо) під час його запуску, але я не хочу, щоб вони відслідковувалися.

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

Однак чи є можливий спосіб зберегти вихідні файли в корені дерева проектів і використовувати .gitignore для ігнорування всього, крім файлів, які я відстежую з Git? Щось на зразок

# Ignore everything
*

# But not these files...
script.pl
template.latex
# etc...

12
Дублікат stackoverflow.com/q/9162919/321973 (я знаю, що це новіше, але відповідь там правильніша). Насправді ця відповідь , мабуть, найкраща
Тобіас Кіенцлер

Відповіді:


2437

Необов’язковий префікс, !який заперечує візерунок; будь-який відповідний файл, виключений за попереднім шаблоном, знову буде включений. Якщо заперечений візерунок збігається, це скасує джерела шаблонів нижчих пріоритетів.

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# ...even if they are in subdirectories
!*/

# if the files to be tracked are in subdirectories
!*/a/b/file1.txt
!*/a/b/c/*

14
Схоже, це також "ігнорує" підпапки, так що будь-які файли з ім'ям "script.pl" у будь-якому іншому, крім кореневого режиму, не знайдеться. Я використовую це зараз (з * .pl) і всі * .pl файли ігноруються, навіть якщо в підкаталогах під файлом
.gitignore

38
@PandaWood Це питання було порушено тут (stackoverflow.com). Це викликано першим виразом, що відповідає всім, включаючи каталоги, які ви ніколи не заперечуєте. Щоб виправити, додайте (! * /), Що відповідає будь-яким підкаталогам (рекурсивно) у поточному каталозі. Це не допоможе батьківській відповіді, яка містить білі списки певних файлів (якщо вони знаходяться в підкаталогах, ви, мабуть, захочете вручну вказати повний шлях або використовувати специфічні для каталогу файли .gitignore).
simont

40
Я не міг змусити це працювати. Я wp/ігнорую папку (наприклад ), але хочу НЕ ігнорувати деякі файли в цій папці (наприклад wp/path/to/some/location/*). Єдиний спосіб, як я міг змусити його працювати, це робивgit add -f wp/path/to/some/location/*
trusktr

13
@trusktr Використовуйте !*/виняток simont
Tobias Kienzler

7
Останнє правило, Гізес: !*/має все значення в моїх марних спробах налаштувати .gitignoreфайл на роботу. Дуже дякую.
racl101

627

Якщо ви хочете ігнорувати весь вміст каталогу, крім одного файлу всередині нього, ви можете написати пару правил для кожного каталогу в шляху до файлу. Наприклад, .gitignore ігнорувати папку pippo, крім pippo / pluto / paperino.xml

.gitignore

pippo/*
!pippo/pluto
pippo/pluto/*
!pippo/pluto/paperino.xml

58
Відмінний відповідь, але варто відзначити , це для тих , хто наступаючих через це пізніше , що fooі foo/*це НЕ те ж саме. Для цього вам потрібно використовувати foo/*базову папку
thislooksfun

20
@Mayank Pippo - гуфі італійською мовою, тоді як Paperino - Дональд Дак, а Плутон - такий самий, як англійською мовою. Вони раніше були дуже поширеною трійкою імен змінних для програмування зразків ще в ті часи. Приємно було їх знову прочитати .. :)
Ghidello

Що говорить @thislooksfun важливо, якщо ви хочете "виключити папку, крім файлу x".
Чехологія

8
не працює для мене: node_modules / *! node_modules / bootstrap
SuperUberDuper

1
@simple_human Це було б правдою, якби він ігнорував все в корені сховища, або якщо у нього були .gitignore файли, про які слід дбати, всередині згаданих каталогів.
xZero

244

Ви хочете використовувати /*замість цього *або */в більшості випадків

Використання *дійсне, але воно працює рекурсивно. З цього моменту він не загляне в каталоги. Люди рекомендують знову використовувати !*/в білих списках каталоги, але насправді краще передати чорний список папки найвищого рівня/*

# Blacklist files/folders in same directory as the .gitignore file
/*

# Whitelist some files
!.gitignore
!README.md

# Ignore all files named .DS_Store or ending with .log
**/.DS_Store
**.log

# Whitelist folder/a/b1/ and folder/a/b2/
# trailing "/" is optional for folders, may match file though.
# "/" is NOT optional when followed by a *
!folder/
folder/*
!folder/a/
folder/a/*
!folder/a/b1/
!folder/a/b2/
!folder/a/file.txt

# Adding to the above, this also works...
!/folder/a/deeply
/folder/a/deeply/*
!/folder/a/deeply/nested
/folder/a/deeply/nested/*
!/folder/a/deeply/nested/subfolder

Наведений вище код буде ігнорувати всі файли , за винятком .gitignore, README.md, folder/a/file.txt, folder/a/b1/і folder/a/b2/та все , що містяться в цих останніх двох папках. (І.DS_Store і *.logфайли будуть ігноруватися в цих папках.)

Очевидно, я міг би зробити, наприклад, !/folderабо!/.gitignore теж.

Більше інформації: http://git-scm.com/docs/gitignore


3
Дуже розумно, дякую. IMO, це найкращий спосіб зробити це для сайтів WordPress з мінімальною кількістю правил включення. Крім того, будь-які нові плагіни, теми чи оновлення WP не видаляються та не додаються без вашого прямого дозволу. Під час використання GitHub Desktop я знаходжу, що .DS_Storeфайли не ігноруються, але через командний рядок це не проблема. Щоб обійти це, мені довелося перенести наведені **/.DS_Storeнижче всі інші правила.
Джибран

7
Мій внутрішній синтаксис підсвічує дивну реакцію на назву вашої публікації.
itadok

3
Грацій! ви також можете додати білий список у папку ..! /some/folder/file.txt
PodTech.io

Чудово, використовуючи / * замість *, виправили всі мої проблеми, коли відповіді вище не було. Моє єдине питання зараз - в чому різниця між! / Folder і! / Folder / *? Якщо я використовую! / Папку без *, вона все одно збирає зміни до всіх файлів у теці, наскільки я можу сказати.
Даллін

1
@dallin різниці немає. Один додає до списку папку, а інший додає до списку дітей із цієї папки, що робить те саме. Єдина проблема , це папка або батьківські файли має в білому списку , перш ніж він може бути білим списку, так що ви не можете зробити /*те !/nested/folder/*(або еквівалент !/nested/folder) , не роблячи !/nested/або !/nestedпершим! (і, напевно, /nested/*між ними). Хитрість, яку потрібно пам’ятати, це якщо ви перебуваєте в
Ryan Taylor

75

Трохи конкретніше:

Приклад: ігноруйте все в webroot/cache- але продовжуйтеwebroot/cache/.htaccess .

Зверніть увагу на косу рису (/) після cacheпапки:

ПОМИЛКИ

webroot/cache*
!webroot/cache/.htaccess

РОБОТИ

webroot/cache/*
!webroot/cache/.htaccess

Якщо ви використовуєте код VS, будьте обережні, щоб не перечитати забарвлення файлу після застосування цього до папки з .gitkeep, оскільки ім'я папки стане зеленим, але файл .gitkeep стане сірим, як і всі інші проігноровані файли; .gitkeep виглядатиме як ігнорований, але ви повинні побачити, що на правій стороні є "U", що вказує на те, що його виявлено
OzzyTheGiant


28

Щоб ігнорувати деякі файли в каталозі, потрібно зробити це в правильному порядку :

Наприклад, ігноруйте все в папці "додаток", крім index.php та папки "config", зверніть увагу на замовлення .

Ви повинні заперечувати, що хочете спочатку.

ПОМИЛКИ

application/*

!application/config/*

!application/index.php

РОБОТИ

!application/config/*

!application/index.php

application/*


38
Неправильно. Ви заперечуєте після "ігноруйте все".
Карлос

2
Не обманюйте себе, git statusщоб перевірити, чи зміни, .gitignoreяк очікували,
Філіп Рате

10
Якщо ви git statusне збираєтесь розповідати, на що він дивиться, а що ігнорується, то як ви можете знати, чи працює це?
kris

1
@kris Очистіть кеш git спочатку. Спершу зробіть "git rm --cached *", тоді ви можете зробити "git add --all", тоді "git status" покаже вам всі нові зміни gitignore.
Марк

20

Ви можете використовувати, git config status.showUntrackedFiles noі всі відслідковувані файли будуть приховані від вас. Детальніше man git-configдивіться.


Це чудово, якщо ви хочете зробити лише декілька файлів з багатьох!
Джош М.

16

Щоб виключити папку з .gitignore, можна зробити наступне.

!app/

app/*
!app/bower_components/

app/bower_components/*
!app/bower_components/highcharts/

Це ігнорує всі файли / підпапки всередині, bower_componentsкрім /highcharts.


14

З цим існує маса подібних питань, тому я опублікую те, що писав раніше:

Єдиний спосіб, коли я змусив це працювати на своїй машині, це зробити це так:

# Ignore all directories, and all sub-directories, and it's contents:
*/*

#Now ignore all files in the current directory 
#(This fails to ignore files without a ".", for example 
#'file.txt' works, but 
#'file' doesn't):
*.*

#Only Include these specific directories and subdirectories and files if you wish:
!wordpress/somefile.jpg
!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/
!wordpress/*/wp-content/themes/*
!wordpress/*/wp-content/themes/*/*
!wordpress/*/wp-content/themes/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*/*

Зауважте, як вам явно потрібно дозволити вміст для кожного рівня, який ви хочете включити. Тож якщо у мене є підкаталоги 5 глибоких тем, мені все одно потрібно це прописати.

Це з коментаря @ Yarin тут: https://stackoverflow.com/a/5250314/1696153

Це були корисні теми:

Я також спробував

*
*/*
**/**

і **/wp-content/themes/**

або /wp-content/themes/**/*

Нічого з того не працювало і для мене. Багато слідів і помилок!


2
Це єдиний метод, який працює виключно для включення певних розширень файлів. Ще краще - це чудове мистецтво ASCII: gist.github.com/Wolfgange3311999/91c671f5e4d3c56cf5a1
Меттью Д. Скоулфілд

10

У мене була проблема з папкою.

Не працює:

/custom/*
!/custom/config/foo.yml.dist

Працює:

/custom/config/*
!/custom/config/foo.yml.dist

9

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

Це був спосіб пошуку рішення. Я почав із додавання винятків для всіх папок у своєму дереві папок, щоб він працював, що є пекельною роботою. Згодом я зміг ущільнити детальну конфігурацію до конфігурації нижче, що трохи суперечить документації.

Робота .gitignore:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' subfolder
/Pro/3rdparty/*
!Pro/3rdparty/domain/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

Як результат, я бачу в своєму клієнті git, що лише два файли всередині Pro / 3rdparty / домен / ім'я модуля / папки ставляться до наступної фіксації, і саме це я шукав.

І якщо вам потрібно додати до списку декількох підпапок однієї папки, то згрупуйте рядки знаків оклику нижче виключення оператора, як це:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' & 'hosting' subfolders
/Pro/3rdparty/*
!Pro/3rdparty/domain/
!Pro/3rdparty/hosting/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

# Ignore the 'hosting' folder, except for the 'modulename' subfolder
Pro/3rdparty/hosting/*
!Pro/3rdparty/hosting/modulename/

Інакше це не буде працювати, як очікувалося.


Нарешті відповідь, яка спрацювала. Цікаво, коли я зрозумію, як насправді працює .gitignore
Девід

8

Ось що для мене спрацювало, я хотів зафіксувати лише один плагін Cordova на репо:

...
plugins/*
!plugins/cordova-plugin-app-customization

8

Я знаю, що я спізнююсь на вечірку, але ось моя відповідь.

Як сказав @Joakim, для ігнорування файлу ви можете використовувати щось на зразок нижче.

# Ignore everything
*

# But not these files...
!.gitignore
!someFile.txt

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

Наприклад, якщо ми хочемо пропустити всі файли в gitпроекті, але не той, a.txtякий знаходиться в aDir/anotherDir/someOtherDir/aDir/bDir/cDir. Тоді наше .gitignoreбуде щось подібне

# Skip all files
*

# But not `aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt`
!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Вищенаведений .gitignoreфайл пропустить усі файли та файли, крім!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Як ви могли зауважити, ці правила важко визначити.

Щоб вирішити цю перешкоду, я створив просту консольну програму під назвою git-do-not-ignore, яка створить правила для вас. Я приймав проект у github із детальною інструкцією.

Приклад використання

java -jar git-do-not-ignore.jar "aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt"

Вихідні дані

!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Там також простий веб - версія доступна тут

Дякую.


7

У мене є Jquery і Angular від bower. Бауер встановив їх у

/public_html/bower_components/jquery/dist/bunch-of-jquery-files
/public_html/bower_components/jquery/src/bunch-of-jquery-source-files
/public_html/bower_components/angular/angular-files

Мінімізований jquery знаходиться всередині distкаталогу, а angular - всередині angularкаталогу. Мені потрібні були лише мінімізовані файли, щоб передавати в github. Деякі фальсифікації .gitignore, і ось що мені вдалося покликати ...

/public_html/bower_components/jquery/*
!public_html/bower_components/jquery/dist
/public_html/bower_components/jquery/dist/*
!public_html/bower_components/jquery/dist/jquery.min.js
/public_html/bower_components/angular/*
!public_html/bower_components/angular/angular.min.js

Сподіваюсь, хтось може вважати це корисним.


7

Ось як я це зробив:

# Ignore everything
*

# Whitelist anything that's a directory
!*/

# Whitelist some files
!.gitignore

# Whitelist this folder and everything inside of it
!wordpress/wp-content/themes/my-theme/**

# Ignore this folder inside that folder
wordpress/wp-content/themes/my-theme/node_modules

# Ignore this file recursively
**/.DS_Store

Використовуйте gig status -uдля перегляду окремих файлів у необроблених каталогах рекурсивно - git statusви бачите лише папки, які можуть змусити вас думати, що все, що знаходиться всередині них, відстежується


5

Просте рішення, якщо вам потрібно ігнорувати все, крім кількох файлів і декількох кореневих папок:

/*
!.gitignore
!showMe.txt
!my_visible_dir

Магія в /*(як описано вище), вона ігнорує все в папці (root), АЛЕ НЕ рекурсивно.


4

У мене також були деякі проблеми з запереченням окремих файлів. Я зміг їх зробити, але мій IDE (IntelliJ) завжди скаржився на ігноровані файли, які відслідковуються.

git ls-files -i --exclude-from .gitignore

Виведено два файли, які я виключив таким чином:

public/
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

Зрештою, це спрацювало для мене:

public/*
!public/typo3conf/
public/typo3conf/*
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

Ключовим було спочатку заперечення папки typo3conf/ .

Крім того, здається, що порядок висловлювань не має значення . Натомість вам потрібно явно заперечувати всі папки, перш ніж ви зможете зняти з нього окремі файли.

Папка !public/typo3conf/та вміст папки - public/typo3conf/*це дві різні речі для .gitignore.

Чудова нитка! Це питання мене хвилювало деякий час;)


3

Досі нічого не працювало для мене, тому що я намагався додати одну банку з lib.

Це не спрацювало:

build/*
!build/libs/*
!build/libs/
!build/libs/myjarfile.jar 

Це спрацювало:

build/*
!build/libs

3

У мене це працює

# Vendor
/vendor/braintree/braintree_php/*
!/vendor/braintree/braintree_php/lib

2

Мав аналогічне питання, як ОП, але жоден із 10 найвищих відповідей насправді не працював .
Нарешті я з’ясував таке

Неправильний синтаксис:

*
!bin/script.sh

Правильний синтаксис:

*
!bin
!bin/script.sh

Пояснення зі сторінки чоловіка gitignore :

Необов’язковий префікс "!" що заперечує візерунок; будь-який відповідний файл, виключений за попереднім шаблоном, знову буде включений. Неможливо повторно включити файл, якщо батьківський каталог цього файлу виключений . Git не перераховує виключені каталоги з міркувань продуктивності, тому будь-які шаблони вміщених файлів не мають впливу, незалежно від того, де вони визначені.

Розширений приклад:

$ дерево.

.
├── .gitignore
└── bin
    ├── ignore.txt
    └── sub
        └── folder
            └── path
                ├── other.sh
                └── script.sh

$ cat .gitignore

*
!.gitignore
!bin
!bin/sub
!bin/sub/folder
!bin/sub/folder/path
!bin/sub/folder/path/script.sh

$ git status - незатребувані файли - позначено синьо

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore
        bin/sub/folder/path/script.sh

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        bin/ignore.txt
        bin/sub/folder/path/other.sh

nothing added to commit but untracked files present (use "git add" to track)

1

Суть

# Ignore everything
*

# But not these files...
!script.pl
!template.latex

І, ймовірно, включають:

!.gitignore

Довідково

З https://git-scm.com/docs/gitignore :

Необов’язковий префікс " !", який заперечує шаблон; будь-який відповідний файл, виключений за попереднім шаблоном, знову буде включений. Неможливо повторно включити файл, якщо батьківський каталог цього файлу виключений. Git не перераховує виключені каталоги з міркувань продуктивності, тому будь-які шаблони вміщених файлів не мають впливу, незалежно від того, де вони визначені. Покладіть зворотну косу рису (" \") перед першою " !" для шаблонів, які починаються з прямолінійного " !", наприклад, " \!important!.txt".

...

Приклад для виключення всього, крім конкретного каталогу foo/bar(зауважте /*- без косої риски підстановка також виключатиме все, що знаходиться в межах foo/bar):

$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar

0

Я, здається, знайшов щось, що працювало для мене, про що ніхто більше не згадував.

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# And if you want to include a sub-directory and all sub-directory and files under it, but not all sub-directories
!subdir/
!subdir/**/*

В основному, схоже, це заперечує ігнорування підкаталогу, у вас повинні бути дві записи, одна для самого підреєстру, !subdir/а потім інша, яка розширюється на всі файли та папки під нею.!subdir/**/*

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