.gitignore исключить папку, но включить определенную подпапку

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

application/
!application/language/gr/

без везения...

Ответы

Ответ 1

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

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

# 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/).

Ответ 2

Коммит 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/

Ответ 3

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

  # Предполагая, что корневая папка, которую вы хотите игнорировать, является  "приложением",
выражение /**/*

# вложенную папку (ы), которую вы хотите отслеживать:
! Приложение/язык/г/
Код>

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


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

  # Предполагая, что корневая папка, которую вы хотите игнорировать, является  "приложением",
выражение /**

# Явно отслеживать определенное содержимое, вложенное в папку "приложение":
! Приложение/язык/
! Приложение/язык/г/
! application/language/gr/** # Пример добавления всех файлов & в папке "gr" 
! application/language/gr/SomeFile.txt # Пример добавления определенного файла в папку 'gr'
Код>

Ответ 4

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

Единственный способ заставить это работать на моей машине - это сделать так:

# Ignore all directories, and all sub-directories, and it 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 глубоко под темами, мне все еще нужно разобрать это.

Это из комментария @Yarin здесь: fooobar.com/questions/11138/...

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

Я тоже пробовал

*
*/*
**/**

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

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

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

Ответ 5

Я нашел, что это действительно работает.

**/node_modules/*
!**/node_modules/keep-dir

Ответ 6

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

!node_modules/

node_modules/*
!node_modules/module-a/

Ответ 7

Еще один пример перехода по структуре каталогов, чтобы получить именно то, что вы хотите. Примечание. Я не исключил 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

Ответ 8

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

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

# ignore all .dll files
*.dll

/dependency_files/.gitignore

# include everything
!*

Так что все файлы /dependency _files (даже DLL файлы) включены в комплект.

Ответ 9

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

*
!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/*/*

Ответ 10

В WordPress это помогло мне:

wp-admin/
wp-includes/
/wp-content/*
!wp-content/plugins/
/wp-content/plugins/*
!/wp-content/plugins/plugin-name/
!/wp-content/plugins/plugin-name/*.*
!/wp-content/plugins/plugin-name/**

Ответ 11

Я часто использую этот обходной путь в CLI, где вместо настройки моего .gitignore я создаю отдельный файл .include где я определяю (под) каталоги, которые я хочу включить, несмотря на то, что каталоги напрямую или рекурсивно игнорируются .gitignore.

Таким образом, я дополнительно использую

git add 'cat .include'

во время постановки, перед совершением.

Для OP я предлагаю использовать .include который имеет следующие строки:

<parent_folder_path>/application/language/gr/*

ПРИМЕЧАНИЕ. Использование cat не позволяет использовать псевдонимы (в .include) для указания $ HOME (или любого другого конкретного каталога). Это связано с тем, что строка homedir/app1/* при передаче в git add с использованием указанной команды появляется как git add 'homedir/app1/*', а вложенные символы в одинарных кавычках ('') сохраняют буквальное значение каждого символа в пределах цитаты, тем самым предотвращая функционирование псевдонимов (таких как homedir) (см. " Отдельные кавычки" Bash).

Вот пример .include файла я использую в моем репо здесь.

/home/abhirup/token.txt
/home/abhirup/.include
/home/abhirup/.vim/*
/home/abhirup/.viminfo
/home/abhirup/.bashrc
/home/abhirup/.vimrc
/home/abhirup/.condarc

Ответ 12

Добавьте дополнительный ответ:

!/.vs/              <== include this folder to source control, folder only, nothing else
/.vs/*              <== but ignore all files and sub-folder inside this folder
!/.vs/ProjectSettings.json <== but include this file to source control
!/.vs/config/       <== then include this folder to source control, folder only, nothing else
!/.vs/config/*      <== then include all files inside the folder

вот результат:

enter image description here

Ответ 13

gitignore - Определяет намеренно не отслеживаемые файлы для игнорирования.

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

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

Еще один пример для WordPress:

!/wp-content
wp-content/*
!/wp-content/plugins
wp-content/plugins/*
!wp-content/plugins/my-awesome-plugin

Больше информации здесь: https://git-scm.com/docs/gitignore

Ответ 14

Я хотел отслеживать js файлы jquery production, и это сработало:

node_modules/*
!node_modules/jquery
node_modules/jquery/*
!node_modules/jquery/dist/*

Ответ 15

Эта проблема:

  • Вы хотите исключить папку application.
  • Вы хотите включить папку application/language/gr/.

Решение:

The solution

Объяснение: Что происходит?

  • application/ просто исключит папку приложения и все, что под ней.
  • application/* (но на этот раз с конечной звездочкой *) исключает папку приложения, но на этот раз позволит вам повторно включить дочерний файл и каталоги с отдельным правилом (см. ниже):

Если вы хотите повторно включить файлы/каталоги, выполните следующие действия:

  • Используйте ! для идентификации файлов/каталогов, которые вы хотите повторно включить.

!application/language/gr/

Ключевые выходы + пример

parent-folder-to-exclude/*

!parent-folder-to-exclude/child-folder-to-include/

(Надеюсь, что это будет очень, очень ясно и просто для вас - если есть какие-либо вопросы, просто отправьте комментарий, и я попытаюсь уточнить.)

Ответ 16

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

git add /path/to/module

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


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