.gitignore исключить папку, но включить определенную подпапку - PullRequest
802 голосов
/ 04 апреля 2011

У меня есть папка application /, которую я добавляю в .gitignore. Внутри приложения / папки находится папка application / language / gr. Как я могу включить эту папку? Я пробовал это

application/
!application/language/gr/

без удачи ...

Ответы [ 15 ]

1353 голосов
/ 04 апреля 2011

Если вы исключите application/, то все, что находится под ним, всегда будет исключено (даже если какой-то более поздний шаблон отрицательного исключения («unignore») может соответствовать чему-то в application/).

Чтобы делать то, что вы хотите, вы должны «игнорировать» каждый родительский каталог всего, что вы хотите «игнорировать». Обычно вы в конечном итоге пишете правила для этой ситуации попарно: игнорируйте все в каталоге, но не какой-то определенный подкаталог.

# you can skip this first one if it is not already excluded by prior patterns
!application/

application/*
!application/language/

application/language/*
!application/language/gr/

Примечание
Трейлинг /* значим:

  • Шаблон dir/ исключает каталог с именем dir и (неявно) все, что находится под ним.
    С dir/ Git никогда не будет смотреть на что-либо под dir, и, следовательно, никогда не будет применять какие-либо из шаблонов «исключения» к чему-либо под dir.
  • Шаблон dir/* ничего не говорит о самом dir; это просто исключает все под dir. С dir/* Git будет обрабатывать прямое содержимое dir, давая другим шаблонам возможность «исключить» некоторую часть содержимого (!dir/sub/).
119 голосов
/ 18 декабря 2013

Commit 59856de из Karsten Blees (kblees) для Git 1.9 / 2.0 (первый квартал 2014 года) разъясняет этот случай:

gitignore.txt: уточнить рекурсивный характер исключенных каталогов

Необязательный префикс "!", который отменяет шаблон; любой соответствующий файл, исключенный предыдущим шаблоном, снова будет включен.

Невозможно повторно включить файл, если исключен родительский каталог этого файла. (*)
(*: если в git 2.8+ не соблюдены определенные условия, см. Ниже)
Git не выводит список исключенных каталогов по соображениям производительности, поэтому любые шаблоны содержащихся файлов не имеют никакого эффекта, независимо от того, где они определены.

Поставьте обратную косую черту ("\") перед первым "!" для шаблонов, которые начинаются с литерала "!", например, "\!important!.txt".

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

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

В вашем случае:

application/*
!application/**/
application/language/*
!application/language/**/
!application/language/gr/**

Сначала вы должны занести в белый список папок , прежде чем сможете занести в белый список файлы в данной папке.


Обновление за февраль / март 2016 года:

Обратите внимание, что в git 2.9.x / 2.10 (середина 2016 года?) Может быть возможно повторно включить файл, если исключен родительский каталог этого файла , если в пути нет подстановочного знака включено .

Nguyễn Thái Ngọc Duy (pclouds) пытается добавить эту функцию:

Так что с git 2.9+ это могло бы сработать, но в конечном итоге было отменено:

application/
!application/language/gr/
46 голосов
/ 09 сентября 2013

@ Ответ Криса Джонсена великолепен, но в более новых версиях Git (1.8.2 или новее) существует шаблон с двумя звездочками, который можно использовать для более краткого решения:

# assuming the root folder you want to ignore is 'application'
application/**/*

# the subfolder(s) you want to track:
!application/language/gr/

Таким образом, вам не нужно «игнорировать» родительский каталог подпапки, которую вы хотите отслеживать.


В Git 2.17.0 (Не знаю, как раньше, до этой версии. Возможно, до версии 1.8.2), используется шаблон ** в сочетании с exclude для каждого подкаталога, ведущего к вашим файлам. Например:

# assuming the root folder you want to ignore is 'application'
application/**

# Explicitly track certain content nested in the 'application' folder:
!application/language/
!application/language/gr/
!application/language/gr/** # Example adding all files & folder in the 'gr' folder
!application/language/gr/SomeFile.txt # Example adding specific file in the 'gr' folder
15 голосов
/ 30 апреля 2015

Есть множество подобных вопросов по этому поводу, поэтому я опубликую то, что я написал ранее:

Единственный способ, которым я получил это для работы на моей машине, это сделать это так:

# 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:
!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 по темам, мне все равно нужно это изложить.

Это из комментария @ Ярина здесь: https://stackoverflow.com/a/5250314/1696153

Это были полезные темы:

Iтакже пытался

*
*/*
**/**

и **/wp-content/themes/**

или /wp-content/themes/**/*

Ничего из этого не сработало для меня, либо.Много проб и ошибок!

10 голосов
/ 17 февраля 2017

Я нашел только это на самом деле работает.

**/node_modules/*
!**/node_modules/keep-dir
4 голосов
/ 02 сентября 2016

Итак, так как многие программисты используют ноды. вариант использования, который отвечает этому вопросу, должен исключить node_modules, за исключением одного модуля module-a, например:

!node_modules/

node_modules/*
!node_modules/module-a/
3 голосов
/ 21 октября 2017

Я нашел подобный случай здесь, где в laravel по умолчанию .gitignore игнорирует все, используя звездочку, а затем переопределяет публичный каталог.

*
!public
!.gitignore

Этого недостаточно, если вы запускаете сценарий OP.

Если вы хотите зафиксировать определенные подпапки public, например, например, в каталоге public/products выхотите включить файлы глубиной в одну подпапку, например, чтобы включить public/products/a/b.jpg, они не будут правильно обнаружены, даже если вы добавите их именно так !/public/products, !public/products/* и т. д.

убедитесь, что вы добавили запись для каждого уровня пути, как это, чтобы переопределить их все.

*
!.gitignore
!public/
!public/*/
!public/products/
!public/products/*
!public/products/*/
!public/products/*/
!public/products/*/*
3 голосов
/ 06 апреля 2017

Специально для более старых версий Git большинство предложений не будут работать так же хорошо.В этом случае я бы поместил отдельный каталог .gitignore в каталог, в который я хочу, чтобы содержимое было включено независимо от других настроек, и разрешил там все, что нужно.

Например: /.gitignore

# ignore all .dll files
*.dll

/ dependency_files / .gitignore

# include everything
!*

Так что все в / dependency_files (даже в DLL-файлах) включено просто отлично.

3 голосов
/ 14 сентября 2016

Еще один пример перехода по структуре каталогов, чтобы получить именно то, что вы хотите.Примечание: я не исключил Library/, но Library/**/*

# .gitignore file
Library/**/*
!Library/Application Support/
!Library/Application Support/Sublime Text 3/
!Library/Application Support/Sublime Text 3/Packages/
!Library/Application Support/Sublime Text 3/Packages/User/
!Library/Application Support/Sublime Text 3/Packages/User/*macro
!Library/Application Support/Sublime Text 3/Packages/User/*snippet
!Library/Application Support/Sublime Text 3/Packages/User/*settings
!Library/Application Support/Sublime Text 3/Packages/User/*keymap
!Library/Application Support/Sublime Text 3/Packages/User/*theme
!Library/Application Support/Sublime Text 3/Packages/User/**/
!Library/Application Support/Sublime Text 3/Packages/User/**/*macro
!Library/Application Support/Sublime Text 3/Packages/User/**/*snippet
!Library/Application Support/Sublime Text 3/Packages/User/**/*settings
!Library/Application Support/Sublime Text 3/Packages/User/**/*keymap
!Library/Application Support/Sublime Text 3/Packages/User/**/*theme

> git add Library

> git status

On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   Library/Application Support/Sublime Text 3/Packages/User/Default (OSX).sublime-keymap
    new file:   Library/Application Support/Sublime Text 3/Packages/User/ElixirSublime.sublime-settings
    new file:   Library/Application Support/Sublime Text 3/Packages/User/Package Control.sublime-settings
    new file:   Library/Application Support/Sublime Text 3/Packages/User/Preferences.sublime-settings
    new file:   Library/Application Support/Sublime Text 3/Packages/User/RESTer.sublime-settings
    new file:   Library/Application Support/Sublime Text 3/Packages/User/SublimeLinter/Monokai (SL).tmTheme
    new file:   Library/Application Support/Sublime Text 3/Packages/User/TextPastryHistory.sublime-settings
    new file:   Library/Application Support/Sublime Text 3/Packages/User/ZenTabs.sublime-settings
    new file:   Library/Application Support/Sublime Text 3/Packages/User/adrian-comment.sublime-macro
    new file:   Library/Application Support/Sublime Text 3/Packages/User/json-pretty-generate.sublime-snippet
    new file:   Library/Application Support/Sublime Text 3/Packages/User/raise-exception.sublime-snippet
    new file:   Library/Application Support/Sublime Text 3/Packages/User/trailing_spaces.sublime-settings
2 голосов
/ 07 июня 2019

Самый простой и, вероятно, лучший способ - попытаться добавить файлы вручную (обычно это имеет приоритет над правилами .gitignore):

git add /path/to/module

Возможно, вы даже захотите -N намерен добавить флаг , чтобы предложить вам добавит их, но не сразу.Я часто делаю это для новых файлов, которые я еще не готов подготовить.


Это копия ответа , размещенная на том, что может легко быть дубликатом QA.Я размещаю его здесь для большей наглядности - мне проще не иметь беспорядка в правилах gitignore.

...