Разница в пути.файл gitignore?


Я использую git, но все еще испытываю путаницу в .gitignore пути к файлам.

Так, в чем разница между следующими двумя путями в .gitignore?

tmp/*
public/documents/**/*

Я могу это понять tmp/* будет игнорировать все файлы и папки внутри него. Я прав? Но что означает эта вторая линия пути?

6 55

6 ответов:

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

/a/*/z
 matches        /a/b/z
 matches        /a/c/z
 doesn't match  /a/b/c/z

** соответствует любой строке из папки:

/a/**/z
 matches        /a/b/z
 matches        /a/b/c/z
 matches        /a/b/c/d/e/f/g/h/i/z
 doesn't match  /a/b/c/z/d.pr0n

комбината ** С * чтобы сопоставить файлы во всем дереве папок:

/a/**/z/*.pr0n
 matches        /a/b/c/z/d.pr0n
 matches        /a/b/z/foo.pr0n
 doesn't match  /a/b/z/bar.txt

если вы используете оболочку, такую как Bash 4, то ** по существу является рекурсивной версией*, которая будет соответствовать любому количеству подкаталогов.

это имеет больше смысла, если вы добавляете расширение файла в свои примеры. Чтобы сопоставить файлы журнала непосредственно внутри tmp, введите:

/tmp/*.log

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

/tmp/**/*.log

но тестирование с Git версии 1.6.0.4 и bash версии 3.2.17 (1)-релиз, это похоже, что git вообще не поддерживает ** глобусы. Элемент самая последняя страница man для gitignore не говоря уже о **, так что это либо (1) Новая (2) не поддерживается, или (3) как-то зависит от системы реализации подстановка.

кроме того, есть что-то тонкое происходит в ваших примерах. Это выражение:

tmp/*

...на самом деле означает "игнорировать любой файл внутри каталог tmp, в любом месте исходного дерева, но не игнорируйте сами каталоги tmp". При нормальных обстоятельствах вы, вероятно, просто напишете:

/tmp

...который будет игнорировать один каталог tmp верхнего уровня. Если вам нужно сохранить каталоги tmp, игнорируя их содержимое, вы должны поместить пустой .gitignore файл в каждом каталоге tmp, чтобы убедиться, что git на самом деле создает каталог.

Обновление (08-Mar-2016)

сегодня, я не могу найти машину, где ** не работает как заявлено. Это включает в себя OSX-10.11.3 (El Capitan) и Ubuntu-14.04.1 (Trusty). Возможно, git-игнорировать, как было обновлено, или, возможно, недавно fnmatch ручки ** как люди ожидают. Таким образом, принятый ответ теперь кажется правильным на практике.


оригинальное сообщение

The ** не имеет особого значения в git. Это особенность bash >= 4.0, через

shopt -s globstar

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

для OP я пробовал каждую комбинацию, которую я могу придумать для и ничего не работает лучше, чем это:

public/documents/

следующий не делает то, что все, кажется, думают:

public/documents/**/*.obj

Я не могу заставить это работать независимо от того, что я пытаюсь, но по крайней мере это согласуется с git docs. Я подозреваю, что когда люди добавляют это к .gitignore, он работает случайно, только потому, что их .obj файлы-это именно один вложенный каталог глубокое. Вероятно, они скопировали двойную звездочку из сценария bash. Но, возможно, есть системы, где fnmatch(3) может обрабатывать двойную звездочку, как bash может.

обратите внимание, что '**',в сочетании с подкаталогом (**/bar), должно быть, изменилось его поведение по умолчанию, так как примечание к выпуску для git1.8. 2 теперь упоминает:

шаблоны .gitignore и .gitattributes файлы могут иметь **/, как шаблон, который соответствует 0 или более уровней подкаталога.

например"foo/**/bar" совпадает с "bar" в "foo " сам или в подкаталоге "foo".


посмотреть commit 4c251e5cb5c245ee3bb98c7cedbe944df93e45f4:

"foo/**/bar" совпадает с "foo/x/bar","foo/x/y/bar"... но не "foo/bar".
Мы делаем особый случай, когда foo/**/ обнаружен (и "foo/ "часть уже сопоставлена), попробуйте сопоставить"bar" с остальной частью строки.

"сопоставьте один или несколько каталогов" семантика может быть легко достигнута с помощью "foo/*/**/bar".

и "**/foo" спичка "foo" в дополнение к "x/foo","x/y/foo"..

подписано-от: Нгуен Нгок Зуй страны <pclouds@gmail.com>


Симон Бакан и прокомментировал:

текущие документы (.gitignore на странице) довольно ясно, что никакой подкаталог не требуется,x/** соответствует всем файлам под (возможно пустым)x

в .gitignore страница делает человек, говоря:

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

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

когда * * не поддерживается, " / " по существу является завершающим символом для подстановочного знака, поэтому, когда у вас есть что-то вроде:

public/documents/**/*

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

public/documents/*/*

Это не работает для меня, но вы можете создать новый .gitignore в этой поддиректории:

tmp/**/*.log

можно заменить на .gitignore на tmp:

*.log