Как на самом деле работают правила исключения из gitignore?
Я пытаюсь решить проблему с gitignore в большой структуре каталогов, но для упрощения своего вопроса я сократил ее до следующего.
У меня есть следующая структура каталогов из двух файлов (foo, bar) в новом git-репозитории (пока нет коммитов):
a/b/c/foo
a/b/c/bar
Очевидно, что 'git status -u' показывает:
# Untracked files:
...
# a/b/c/bar
# a/b/c/foo
Я хочу создать файл.gitignore, который игнорирует все, что находится внутри /b/c, но не игнорирует файл 'foo'.
Если я создаю.gitignore таким образом:
c/
Затем 'git status -u' показывает foo и bar как игнорируемые:
# Untracked files:
...
# .gitignore
Что, как я и ожидал.
Теперь, если я добавлю правило исключения для foo, таким образом:
c/
!foo
Согласно руководству gitignore, я ожидаю, что это сработает. Но это не так - все равно игнорирует foo:
# Untracked files:
...
# .gitignore
Это тоже не работает:
c/
!a/b/c/foo
Ни один не делает это:
c/*
!foo
дает:
# Untracked files:
...
# .gitignore
# a/b/c/bar
# a/b/c/foo
В этом случае, хотя foo больше не игнорируется, bar также не игнорируется.
Порядок правил в.gitignore тоже не имеет значения.
Это также не делает то, что я ожидал:
a/b/c/
!a/b/c/foo
Тот игнорирует как foo, так и bar.
Одна ситуация, которая работает, если я создаю файл a /b/c /.gitignore и помещаю туда:
*
!foo
Но проблема в том, что со временем в /b/c появятся другие подкаталоги, и я не хочу вставлять отдельный.gitignore в каждый из них - я надеялся создать "основанный на проекте".gitignore файлы, которые могут находиться в верхнем каталоге каждого проекта и покрывать всю "стандартную" структуру подкаталогов.
Это также кажется эквивалентным:
a/b/c/*
!a/b/c/foo
Это может быть самой близкой вещью к "работе", которую я могу достичь, но необходимо указать полные относительные пути и явные исключения, что будет проблемой, если у меня много файлов с именем "foo" на разных уровнях дерева подкаталогов.
В любом случае, либо я не совсем понимаю, как работают правила исключения, либо они вообще не работают, когда каталоги (а не подстановочные знаки) игнорируются - правилом, оканчивающимся на /
Кто-нибудь может пролить свет на это?
Есть ли способ заставить gitignore использовать что-то разумное, например, регулярные выражения, вместо этого неуклюжего синтаксиса на основе оболочки?
Я использую и наблюдаю это с помощью git-1.6.6.1 на Cygwin/bash3 и git-1.7.1 на Ubuntu/bash3.
5 ответов
/ A / B / C /*! Foo
Кажется, работает для меня (git 1.7.0.4 на Linux). *
важно, так как в противном случае вы игнорируете сам каталог (так что git не будет заглядывать внутрь) вместо файлов внутри каталога (что позволяет исключить).
Думайте об исключениях как о "но не об этом", а не "но включайте это" - "игнорируйте этот каталог (/a/b/c/
) но не этот (foo
) "не имеет особого смысла" игнорировать все файлы в этом каталоге (/a/b/c/*
) но не этот (foo
) ". Цитирую справочную страницу:
Необязательный префикс! который отрицает образец; любой соответствующий файл, исключенный предыдущим шаблоном, снова будет включен.
файл должен быть исключен, чтобы быть включенным снова. Надеюсь, что проливает свет.
У меня похожая ситуация, мое решение было использовать:
/a/**/*
!/a/**/foo
Это должно работать для произвольного числа промежуточных каталогов, если я читаю **
правильно.
Вот еще один вариант:
*
!/a*
!/a/*
!/a/*/*
!/a/*/*/*
Это будет игнорировать все файлы и каталоги, кроме файлов / каталогов на трех уровнях в пределах.
Это определенно не ясно из справочной страницы.gitignore. Это работает:
*
!/a
!/a/b
!/a/b/c
!/a/b/c/foo
# don't forget this one
!.gitignore
Как упомянул Крис, каталог даже не открывается, если он исключен. Поэтому, если вы хотите иметь возможность игнорировать *, но некоторые файлы, вы должны построить путь к этим файлам, как указано выше. Для меня это удобно, потому что я хочу сделать обзор кода для 1 файла библиотеки, и если я хочу сделать еще один позже, я просто добавлю его, а все остальное игнорируется.
На более общей ноте git1.8.2 будет включать патч (также в его v4, вызванный каким-то вопросом переполнения стека) от Adam Spiers о том, какой gitignore
Правило фактически игнорирует ваш файл.
См. Примечания к выпуску git1.8.2 и SO вопрос " какое правило gitignore игнорирует мой файл ":
это будет команда git check-ignore
,