Git не игнорирует подкаталоги - PullRequest
1 голос
/ 08 ноября 2019

У меня было static/ в .gitignore, которое успешно игнорировало весь каталог. Теперь я хочу включить в него все, кроме static/vendor.

Я думал, что наличие static/vendor/ внутри .gitignore сделает это. Однако это не так. Когда я отправляю static для постановки, все файлы изнутри static/vendor все равно заканчивают тем, что ставятся рядом с другими, которые мне действительно нужны.

Есть ли хитрость в этом? Чего мне не хватает?

1 Ответ

2 голосов
/ 08 ноября 2019

Правила .gitignore немного странные. (В этом отношении имя .gitignore немного странное, но простительное: лучше было бы назвать .git-do-not-complain-about-some-files-that-are-untracked-and-do-not-automatically-add-them-in-that-case-but-this-file-has-no-effect-on-files-that-are-tracked или что-то такое же непристойное.)

Каждая строка в .gitignore имеет одну из немногихобщие формы:

  • комментарии и пустые строки игнорируются;
  • строки с ! являются правилами "не игнорировать";и
  • остальные строки являются правилами игнорирования.

Это позволяет нам полностью отказаться от первого типа и подумать о втором и третьем типе линии, используя один набор правил,с «не игнорировать» применяется в конце. Итак, теперь мы придерживаемся следующих подправил:

  • строки могут содержать имя с no косой чертой вообще: foo или
  • строки могут содержать имя файла с начальным слешем, но без встроенной косой черты: /leading или
  • строки могут содержать имя файла с косой чертой, но без встроенного слеша: trailing/ или * 1030Строки *
  • могут содержать имя файла с начальной косой чертой и , но без встроенной косой черты: /leadandtrail/, или
  • строки могут содержать имя файла, которое делает имеют встроенную косую черту в сочетании с любым или всем перечисленным выше: has/slash, /has/slash, has/slash/ и т. Д.

(строки могут также содержать различные символы глобуса,о чем пока не будем беспокоиться!)

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

Имя с привязкой - это любое имя, которое либо начинается с косой черты, либо содержит встроенную косую черту (или обе). Так что /leading и has/slash и /has/slash все привязаны, но foo и trailing/ являются незафиксированными .

A с косой чертой name - это любое имя, которое оканчивается косой чертой. Эта последняя косая черта удаляется, как только имя классифицируется как суффикс с косой чертой. Таким образом, trailing/ суффикс с косой чертой, но затем обрабатывается так, как если бы оно было написано trailing, а has/slash/ также суффикс с косой чертой и обрабатывается, как если бы оно было только что написано has/slash.

Следовательно,запись:

vendor/

с косой чертой, но без привязки, в то время как:

static/vendor/

с косой чертой и с привязкой.

(Имя, такое как a/b//, с косой чертой и привязкой и обработкой, как a/b/, а имя, как b//, с косой чертой, привязкой и обработкой, как b/. Дополнительная косая черта, оставшаяся после, просто плохаяИдея: не делайте этого. Я не уверен, что на самом деле происходит!)

Теперь, когда мы классифицировали имена как привязанные или незафиксированные и с косой чертой или без косой черты, мыможет описать, как для них работают правила gitignore:

  • Любое имя с суффиксом в виде косой черты соответствует частичному имени пути, если и только если это частичное имя пути представляет каталог / папку. Таким образом, vendor/ соответствует каталогу (или папке) vendor, но не файлу , чей компонент имени vendor. Без косой черты имя соответствует и файла и каталога.

  • Любого привязанного совпадения именитолько компоненты имени файла, которые начинаются с того же каталога, в котором был найден файл .gitignore . То есть, учитывая привязанный vendor, мы исключим vendor в этом каталоге, но не a/vendor, b/vendor и так далее. Для данного незанятого поставщика мы исключим vendor в этом каталоге и a/vendor и b/vendor и т. Д.

Вот почему добавление static/ перед вашим vendor/ изменило его поведение: оно перешло с не привязанного к привязанному, так что оно начало действовать как /static/vendor/ (что, конечно, сделало бы то же самое: привязанодвумя способами, но единственное, что имеет значение, это то, что он закреплен).

Добавление **/ впереди позволяет (все еще привязанному!) Строке static/vendor/ соответствовать a/static/vendor, b/static/vendor и так далее. Вам не нужно было **/ впереди, когда vendor/ был не закреплен.

Альтернатива

Обратите внимание, кстати, что вы можете удалить vendor/ полностью введите этот файл .gitignore (где бы он ни находился) и создайте запись static/ в vendor/.gitignore, создавая этот файл при необходимости. Это было бы не на якоре, а с косой чертой. Он будет соответствовать каталогу static в этом каталоге или любом подкаталоге из этого каталога. Редактировать: К сожалению, это было бы в обратном направлении: вы бы хотели vendor/ в каталоге static/,Но здесь применяется общий принцип.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...