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

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

application/
!application/language/gr/

не повезло...

11 ответов


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

чтобы сделать то, что вы хотите, вы должны "unignore" каждый родительский каталог всего, что вы хотите "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, и, таким образом, никогда не будет применять любой из шаблонов "un-exclude" к чему-либо под dir.
  • шаблон dir/* ничего не говорит о dir себя; он просто исключает все под dir. С dir/*, Git будет обрабатывать прямое содержимое dir, давая другим шаблонам возможность "исключить" некоторый бит содержимого (!dir/sub/).

совершить 59856de С Karsten Blees (kblees) для Git 1.9 / 2.0 (Q1 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
 --------------------------------------------------------------

Обновление Февраль / Март 2016:

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

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

Итак, с 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/

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


С 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

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

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

# 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 глубоко под темами, мне все равно нужно это объяснить.

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

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

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

*
*/*
**/**

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

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

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


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

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

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

!node_modules/

node_modules/*
!node_modules/module-a/

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

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

# ignore all .dll files
*.dll

/ dependency_files/.gitignore

# include everything
!*

Итак, все в /dependency_files (even .dll файлы) включены просто отлично.


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

*
!public
!.gitignore

этого недостаточно, если вы столкнетесь со сценарием OP.

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

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

*
!.gitignore
!public/
!public/*/
!public/products/
!public/products/*
!public/products/*/
!public/products/*/
!public/products/*/*

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

Я хотел отслеживать файлы JS производства jquery, и это сработало:

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