В чем разница между Git, игнорирующим каталог, и каталог / *?

108

Я не понимаю, как правильно игнорировать содержимое каталога в git.

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

my_project  
     |--www  
         |--1.txt  
         |--2.txt
     |--.gitignore

В чем разница между этим:

www

И это?

www/*

Причина, по которой я задаю этот вопрос: в git, если каталог пуст, git не будет включать такой пустой каталог в репозиторий. Итак, я пробовал решение, которое добавляет дополнительный файл .gitkeep в каталог, чтобы он не был пустым. Когда я пробовал это решение, если в файле .gitignore я писал, как показано ниже:

www
!*.gitkeep

Это не работает (я намерен игнорировать все содержимое в www, но сохранить каталог). Но если я попробую следующее:

www/* 
!*.gitkeep

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

Аарон Шен
источник
Простое различие между binи bin/заключается в том, что первый игнорирует файлы или папки, а второй - только папки. Я не знаю разницу сbin/*
полковник Panic

Ответы:

203

Есть различия между www, www/и www/*.

В основном из документации и моих собственных тестов wwwнайти совпадение с файлом или каталогом, соответствует www/только каталогу, а www/*соответствует каталогам и файлам внутри www.

Я буду обсуждать только различия между www/и www/*здесь, поскольку различия между wwwи www/очевидны.

Ведь www/git игнорирует сам каталог www, а это значит, что git даже не заглянет внутрь. Но для www/*git проверяет все файлы / папки внутри wwwи игнорирует их все с шаблоном *. Похоже, это приводит к тем же результатам, поскольку git не будет отслеживать пустую папку, wwwесли все ее дочерние файлы / папки игнорируются. И действительно, результаты не будут различаться для случая OP www/или www/*автономного. Но это имеет значение, если совмещать с другими правилами.

Например, что, если мы хотим только включить, www/1.txtно игнорировать всех остальных внутри www?

Следующее .gitignoreне сработает.

www/
!www/1.txt

Хотя следующее .gitignoreработает, почему?

www/*
!www/1.txt

В первом случае git просто игнорирует каталог wwwи даже не заглядывает внутрь, чтобы www/1.txtснова включить его. Первое правило исключает родительский каталог, wwwно не исключает www/1.txt, и в результате www/1.txtне может быть " включено снова ".

Но для последнего git сначала игнорирует все файлы / файлы, находящиеся под ним www, а затем снова включает один из них, который есть www/1.txt.

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

Необязательный префикс "!" который сводит на нет узор; любой соответствующий файл, исключенный предыдущим шаблоном, снова будет включен. Невозможно повторно включить файл, если родительский каталог этого файла исключен.

Landys
источник
Не думаете ли вы , что www/1.txtи тогда www/будет делать то же самое, что второй подход ...
Навид Батт
8

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

$ cat .gitignore
    # exclude everything except directory foo/bar
    /*
    !/foo
    /foo/*
    !/foo/bar

Я сделал тест выше, и если заменить !/fooс !/foo/*, вы действительно получите другой результат.

Заметка

foo

Исключит любой файл foo, но

foo/

исключит только каталоги с именем foo.

Джехлин
источник
3

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

Так что если вы хотите , чтобы игнорировать все файлы внутри www, но whant wwwпапки для версируются, вместо того , чтобы использовать пустой .gitkeep, .dummyили любое имя вы выбрали, почему бы не использовать .gitignoreтам, говоря , чтобы игнорировать все файлы?

/
|- .gitignore   (a)
\- www
    |- .gitignore   (b)
    |- 1.jpg
    \- 2.jpg

В корне .gitignore(а) вы ничего не говорите о wwwпапке или ее содержимом.

В www/.gitignore(б) вы указываете следующее:

# ignore all files in this folder except this .gitignore
*
!.gitignore

Таким образом, все выглядит более организованным (по крайней мере, для меня).

Карлос Кампдеррос
источник
1

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

www/[^.]*

Так что не нужно ничего лишнего .gitignore, просто добавьте .keepфайл в свой wwwкаталог.

Koen.
источник