Как работают отрицательные шаблоны в .gitignore?

94

Я пытаюсь использовать файл .gitignore с отрицательными шаблонами (строки, начинающиеся с!), Но он работает не так, как я ожидал.

В качестве минимального примера у меня есть следующая структура каталогов:

C:/gittest
 -- .gitignore
 -- aaa/
   -- bbb/
     -- file.txt
   -- ccc/
     -- otherfile.txt

и в моем файле gitignore у меня есть это:

aaa/
!aaa/ccc/

Я понимаю (на основе этой страницы документа ), что файл aaa / ccc / otherfile.txt не следует игнорировать, но на самом деле git игнорирует все, что находится под aaa.

Не понимаю ли я это предложение: «Необязательный префикс!, Который отрицает шаблон; любой соответствующий файл, исключенный предыдущим шаблоном, будет снова включен»?

Кстати, это в Windows с msysgit 1.7.0.2.

Крис Перкинс
источник

Ответы:

163

Я думаю, что на самом деле вы хотите:

aaa/*
!aaa/ccc

Вы говорите ему «не заглядывать внутрь aaa», поэтому он даже не исследует путь aaa/ccc. Если вы используете подстановочный знак, он по-прежнему считывает содержимое aaa, затем каждая запись соответствует подстановочному знаку и игнорируется, кроме той, aaa/cccкоторая возвращается.

Каскабель
источник
2
@iconoclast: Значит, вы, наверное, делаете что-то другое. Если вам нужна помощь, задайте другой вопрос (с полной информацией).
Cascabel
У меня это тоже не сработало: / apps / *! / Apps / myApps / FluidTest / bin /
Джаррод Смит,
5
@Jarrod Это действительно работает; ты просто делаешь что-то другое. Вам придется использовать этот метод рекурсивно по причинам, указанным в ответе. ! apps / myApps, apps / myApps / * и так далее.
Cascabel
Ах, извините, теперь я понимаю. Но ТАК не позволит мне снова проголосовать.
Джаррод Смит
Интересно, почему это не работает для aaa / ** / *! Aaa / ccc / eee (игнорировать все, кроме файлов по определенному пути)
Phng Nguyễn
23

Если вы хотите исключить все внутри aaa, но включить aaa/cccи все, что ниже, вы должны использовать:

aaa/*
!aaa/ccc
!aaa/ccc/*

Первая строка говорит git игнорировать все, что находится ниже aaa, вторая говорит ему не игнорировать папку, aaa/cccкоторая фактически «включает» третью строку, которая затем говорит ему не игнорировать все, что ниже aaa/ccc.

xmak
источник
1
Третья строка для меня не имела значения.
Джеймс Хопкин
3
Чтобы иметь возможность включать все в любой подкаталог aaa/cccлюбого уровня, у меня сработало !aaa/ccc/**вместо!aaa/ccc/*
boclodoa
3

Если кто-то все еще не видит недавно не проигнорированных элементов при git statusзапуске, это git update-indexможет помочь git увидеть изменения (по крайней мере, в версии 1.9.x gitbash).

Alexkb
источник