.gitignore исключить папку, но включить определенную подпапку
У меня есть папка application/, которую я добавляю в.gitignore. Внутри приложения / папки находится папка application/language/gr. Как я могу включить эту папку? Я пробовал это
application/
!application/language/gr/
без удачи...
21 ответ
Если вы исключите 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/
).
Коммит 59856de от Karsten Blees (kblees) для Git 1.9 / 2.0 (первый квартал 2014 года) проясняет этот случай:
gitignore.txt
: уточнить рекурсивный характер исключенных каталогов
Необязательный префикс "
!
msgstr "который отменяет шаблон; любой соответствующий файл, исключенный предыдущим шаблоном, снова будет включен.Невозможно повторно включить файл, если родительский каталог этого файла исключен. (
*
)
(*
: если в 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/gr/**
Сначала вы должны занести в белый список папки, прежде чем сможете занести в белый список файлы в данной папке.
Обновление февраль / март 2016:
Обратите внимание, что в git 2.9.x/2.10 (середина 2016 года?) Может оказаться возможным повторно включить файл, если родительский каталог этого файла будет исключен, если в пути не будет подстановочного знака.
Nguy Thn Thái Ngọc Duy ( pclouds
) пытается добавить эту функцию:
- commit 506d8f1 для git v2.7.0, возвращен в commit 76b620d git v2.8.0-rc0
- commit 5e57f9c git v2.8.0-rc0,... отменен (!) в коммите 5cee3493 git 2.8.0.
Так что с git 2.9+ это могло бы сработать, но в конечном итоге было отменено:
application/
!application/language/gr/
@Chris Johnsen ответил великолепно, но в более новых версиях 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), используя **
шаблон в сочетании с исключениями для каждого подкаталога, ведущего к вашим файлам работает. Например:
# 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
Я нашел только это на самом деле работает.
**/node_modules/*
!**/node_modules/keep-dir
По этому поводу есть куча похожих вопросов, поэтому я выложу то, что написал ранее:
Единственный способ заставить это работать на моей машине - это сделать так:
# 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 глубоко под темами, мне все еще нужно разобрать это.
Это из комментария @ Ярина здесь: /questions/27976168/ispolzovaniegitignore-dlya-ignorirovaniya-vsego-krome-opredelennyih-katalogov/27976178#27976178
Это были полезные темы:
- Как работают шаблоны с отрицанием в.gitignore?
- Как на самом деле работают правила исключения из gitignore?
Я тоже пробовал
*
*/*
**/**
а также **/wp-content/themes/**
или же /wp-content/themes/**/*
Ничто из этого не сработало для меня. Много следов и ошибок!
Самый простой и, вероятно, лучший способ - попробовать добавить файлы вручную (обычно это имеет приоритет перед .gitignore
правила стиля):
git add /path/to/module
Вы даже можете захотеть -N
намерение добавить флаг, чтобы предложить вам будет добавить их, но не сразу. Я часто делаю это для новых файлов, которые еще не готов поставить.
Это копия ответа, размещенного на том, что легко может быть дубликатом QA. Я публикую его здесь для большей наглядности - мне легче не иметь беспорядка правил gitignore.
Я хотел отслеживать файлы конфигурации Nagios, расположенные в
/etc/nagios/
вместе с плагинами в
/usr/lib64/nagios/plugins/
. Для этого я инициализировал репозиторий git в
/
и использовал следующий список исключений:
/*
!etc
etc/*
!etc/nagios
!usr
usr/*
!usr/lib64
usr/lib64/*
!usr/lib64/nagios
usr/lib64/nagios/*
!usr/lib64/nagios/plugins
Git проходит по списку вот так:
/* exclude everything under / ...
!etc but include /etc back
etc/* exclude everything under /etc/...
!etc/nagios but include /etc/nagios back
!usr but include /usr back
usr/* exclude everything under /usr/...
and so on...
add a file named
.gitignore
to subfolder, then fill with
!/Bin/
this works for me!
Я нашел похожий случай здесь, где в 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/*/*
Моя конфигурация JetBrains IntelliJ IDEA .gitignore, где мне нужно исключить все .idea
папка кроме .idea/runConfigurations
:
.idea
!.idea/
.idea/*
!.idea/runConfigurations/
см. https://github.com/daggerok/gitignore-idea-runConfigurations
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
Добавить дополнительный ответ:
!/.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
вот результат:
Итак, поскольку многие программисты используют ноды. случай использования, который отвечает этому вопросу, должен исключить node_modules
кроме одного модуля module-a
например:
!node_modules/
node_modules/*
!node_modules/module-a/
Это сработало для меня:
**/.idea/**
!**/.idea/copyright/
!.idea/copyright/profiles_settings.xml
!.idea/copyright/Copyright.xml
Особенно для старых версий Git большинство предложений не будут работать так хорошо. Если это так, я бы поместил отдельный каталог.gitignore в каталог, куда я хочу, чтобы контент был включен, независимо от других настроек, и разрешил там все, что нужно.
Например: /.gitignore
# ignore all .dll files
*.dll
/dependency_files/.gitignore
# include everything
!*
Так что все в /dependency_files (даже.dll-файлы) включены просто отлично.
В 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/**
Еще один пример перехода по структуре каталогов, чтобы получить именно то, что вы хотите. Примечание: я не исключил 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
Подобно этому комментарию, ни одно из решений и шаблонов не сработало для меня; заставить git добавить файлы и папки, которые следует исключить, сработало:
git add -f .
Я хотел отследить JS-файлы JQuery производства, и это сработало:
node_modules/*
!node_modules/jquery
node_modules/jquery/*
!node_modules/jquery/dist/*
Я часто использую этот обходной путь в CLI, где вместо настройки моего .gitignore
Я создаю отдельный .include
файл, в котором я определяю (под) каталоги, которые я хочу включить, несмотря на то, что каталоги прямо или рекурсивно игнорируются .gitignore
,
Таким образом, я дополнительно использую
git add `cat .include`
во время постановки, перед совершением.
Для ФП я предлагаю использовать .include
который имеет эти строки:
<parent_folder_path>/application/language/gr/*
ПРИМЕЧАНИЕ. Использование cat
не позволяет использовать псевдонимы (в пределах .include
) для указания $HOME (или любого другого конкретного каталога). Это потому что линия homedir/app1/*
когда прошло git add
использование приведенной выше команды выглядит как git add 'homedir/app1/*'
и включение символов в одинарные кавычки ('') сохраняет буквальное значение каждого символа в кавычках, тем самым предотвращая функционирование псевдонимов (таких как homedir) (см. Bash Single Quotes).
Вот пример .include
файл, который я использую в моем репо здесь.
/home/abhirup/token.txt
/home/abhirup/.include
/home/abhirup/.vim/*
/home/abhirup/.viminfo
/home/abhirup/.bashrc
/home/abhirup/.vimrc
/home/abhirup/.condarc
Эта проблема:
- Вы хотите исключить
application
папка. - Вы хотите включить
application/language/gr/
папка.
Решение:
Пояснение: что происходит?
application/
просто исключит папку приложения и все, что под ней.application/*
(но на этот раз с завершающей звездочкой*
) исключит папку приложения, но на этот раз позволит вам повторно включить дочерний файл и каталоги.
Если вы хотите повторно включить файлы / каталоги, то:
- Использовать
!
идентифицировать файлы / каталоги, которые вы хотите повторно включить.
!application/language/gr/
Ключевые выносы
parent-folder-to-exclude/*
!parent-folder-to-exclude/child-folder-to-include/
(Надеюсь, вышеизложенное будет очень, очень понятно и просто для вас - если есть какие-либо вопросы, просто оставьте комментарий, и я постараюсь уточнить.)