gitignore: игнорировать все файлы в иерархии папок, кроме одного конкретного типа файла

Я хочу, чтобы игнорировать все файлы и папки кроме определенного типа файла, который может быть где-то в иерархии папок:

пример

/Test
/Test/unknown/folder/structure/below

теперь я хотел бы игнорировать все файлы в и ниже Test папка, кроме определенного файла css с именем layout.css, например:

/Test/layout.css
/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/layout.css
/Test/in/a/unknown/folder/ignore.me

.gitignore должен игнорировать

/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/ignore.me

мой .файл gitignore не работает:

Test/
!layout.css

какие предложения?

3 ответов


я смог заставить ваш пример работать, поставив на Test/ каталог со следующим содержимым.

*
!*/
!.gitignore
!layout.css

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

основная идея заключается в том, что вам нужно исключить каждый родительский каталог любого файла, который вы хотите unignored.

Итак, если вы хотите / Test/in/a/unknown/folder / layout.css будет добавлен в ваше репозиторий git, затем вам нужно будет unignore/ Test/,/Test/ in/,/Test/in/ a/,/Test/in/a/ unknown /и/Test/in/a/unknown/folder/.

затем, когда Вы, наконец, доберетесь до каталога с некоторые игнорируемые и некоторые неуказанные файлы, вам нужно будет указать каждый отдельно следующим образом:

# Fille: .gitignore
!Test/
Test/*
!Test/layout.css
Test/fileto.ignore
!Test/another/
Test/another/*
!Test/another/folder/
Test/another/folder/*
!Test/in/
Test/in/*
!Test/in/a/
Test/in/a/*
!Test/in/a/unknown/
Test/in/a/unknown/*
!Test/in/a/unknown/folder/
Test/in/a/unknown/folder/ignore.me
!Test/in/a/unknown/folder/layout.css

так когда вы бежите $ git add-all вы увидите желаемые результаты:

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   .gitignore
    new file:   Test/in/a/unknown/folder/layout.css
    new file:   Test/layout.css

Примечание: Вы можете найти объяснение, почему git add-all Это лучший способ добавить файлы в репозиторий git на http://lexsheehan.blogspot.com/2014/05/git-add-update.html


довольно старый вопрос, но так как я боролся с этой проблемой даже сейчас, я решил, что поделюсь фактическим решением проблемы.

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

от https://git-scm.com/docs/gitignore

трейлинг "/**" матчей все, что внутри. Например, " abc/**" соответствует всем файлам внутри каталог "abc", относительно местоположения этот.файл gitignore, с бесконечной глубиной.

косая черта, за которой следуют две последовательные звездочки, затем совпадает косая черта ноль или более каталогов. Например, "a/** / b "соответствует" a/b", "a/x/b", "a/x/y / b" и так далее.

** соответствует все внутри-буквально все-файлы и каталоги.

это приводит нас к другому моменту в документах gitignore:

необязательный префикс "!" который отрицает шаблон; любой соответствующий файл исключенный предыдущим шаблоном будет включен снова. это не можно повторно включить файл, если родительский каталог файл исключенный. Git не перечисляет исключенные каталоги для производительности причины, поэтому любые шаблоны на файлах contained не имеют эффекта, независимо от того где они определены. Поместите обратную косую черту ( " \ " ) перед первой "!"для шаблонов, которые начинаются с буквального"!", например, "!важно!.формат txt."

если шаблон заканчивается косой чертой, он удаляется с целью следующее описание, но оно найдет только совпадение с справочник. Другими словами, foo / будет соответствовать каталогу foo и путям под ним, но не будет соответствовать обычным файлом или символической ссылкой foo (это согласуется с тем, как pathspec работает в целом в Мерзавец.)

теперь, скажем, у нас есть следующий dir структура:

/path/to/git/repo
|-- .gitignore
|-- /cache
    |-- somefile
    |-- README    
    |-- /dir
        |-- somefile2
        |-- README

и мы хотим игнорировать все файлы внутри кэша / за исключением файлов README.

если мы указываем gitignore следующим образом:

/cache/**
!README

git будет игнорировать все, кроме /cache/README. Другой README не появится, потому что его каталог /cache/dir была отчислена с /cache/** и !README даже не обращаться к нему. Чтобы решить проблему, нам нужно указать gitignore следующим образом:

# Ignore everything inside cache/ dir
/cache/**
# Except for subdirectories(won't be commited anyway if there is no commited file inside)
!/cache/**/
# And except for README files
!README