Белый список и подкаталоги в Git

91

Я создал белый список только для текстовых файлов.

*
!*.txt

Теперь у меня есть неотслеживаемый текстовый файл в подкаталоге - sub/dir/file.txt, и он НЕ отображается (игнорируется). Однако отображаются текстовые файлы в корневом каталоге.

Почему это так и как это исправить?

Нейт
источник
1
Связанный: stackoverflow.com/q/987142/78845
Johnsyweb
Файлы, которые вы хотите включить в подкаталог? В таком случае этот подкаталог может быть проигнорирован первой звездочкой в ​​вашем .gitignore.
fajran 06
Да. Эти файлы будут такими же низкими в структуре каталогов, как папка 11.1.102.55 в моем примере. Вложение между папками / продуктами не всегда одинаково.
Nate
1
Я знаю об этой функции. У нас сотни каталогов. Было бы быстрее просто явно игнорировать типы файлов, которые нам не нужны, чем создавать по одному gitignore для каждого каталога. Я действительно ищу способ получить функциональность белого списка из файла .gitignore.
Nate
1
Я не понимаю, как это дубликат. Другой вопрос спрашивает, как внести определенные файлы в белый список, в то время как этот спрашивает, как внести в белый список определенные типы файлов, включая подпапки. На самом деле это больше похоже на дубликат stackoverflow.com/questions/8024924/… .
Big McLargeHuge

Ответы:

146

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

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

.gitignoreФайл , который будет делать это:

# First, ignore everything
*
# Now, whitelist anything that's a directory
!*/
# And all the file types you're interested in.
!*.one
!*.two
!*.etc

Испытано это в структуре трехуровневой белого списка для .txtфайлов в присутствии *.one, *.twoи *.threeфайлы , используя .gitignoreрасположенные в корневом каталоге репозитория - работает для меня. Вам не нужно будет добавлять.gitignore файлы во все каталоги в вашей структуре.

Информация, которую я использовал для выяснения ответа, пришла, помимо прочего, с этого (stackoverflow.com).

Симонт
источник
18
Вам также нужна запись !.gitignoreпри использовании *, не так ли?
sjas 06
2
См. Мой ответ здесь: stackoverflow.com/questions/987142/. Может быть более полезно использовать /*для внесения в черный список только папки верхнего уровня, но не всех папок рекурсивно, что на самом деле означает, что не .gitignoreследует заглядывать в подпапки папки из белого списка.
Райан Тейлор
2

Более простой способ добиться этого:

# Ignore all files...
*.*

# ...except the ones we want
!*.txt

Это работает, потому что gitignoreшаблоны, которые не начинаются, применяются /ко всем уровням ниже .gitignoreфайла:

Если есть разделитель в начале или в середине (или в обоих) шаблона, то шаблон относится к уровню каталога конкретного файла .gitignore. В противном случае шаблон также может совпадать на любом уровне ниже уровня .gitignore.

Если вы хотите сделать это с файлами внутри каталога , все становится сложнее:

# Ignore all files in all directories inside subdir...
/subdir/**/*.*

# ...except the ones we want
!/subdir/**/*.txt

Это работает, потому что gitignoreесть специальные правила для **:

Две последовательные звездочки (" **") в образцах, совпадающих с полным путем, могут иметь особое значение:

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

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

Шарад
источник
0

Долго искал:

  1. Предположим, у меня есть большая структура папок с рекурсивно вложенными каталогами ~ 100 000. В этих папках около 30 000 файлов типа .txt(в моем случае: type *.md). Рядом с этими *.mdфайлами есть, скажем, 500 ГБ (более миллиона) файлов, которые я не хочу отслеживать.

  2. Я хочу, чтобы git отслеживал только .txt(или *.md) файлы во всех папках и подкаталогах.

Правильный ответ должен быть: в Git это невозможно.

Что я сделал вместо этого:

[edit: тоже не сработало - я пытался создать папку с символическими ссылками (или жесткими ссылками) и использовать там git, но git не следует символическим ссылкам и перезаписывает жесткие ссылки. Дох!]

Alex
источник