Зробіть .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.