Как игнорировать файлы в каталоге в Git?

544

Каков правильный синтаксис для .gitignoreфайла, чтобы игнорировать файлы в каталоге?

Будет ли это

config/databases.yml
cache/*
log/*
data/sql/*
lib/filter/base/*
lib/form/base/*
lib/model/map/*
lib/model/om/*

или

/config/databases.yml
/cache/*
/log/*
/data/sql/*
/lib/filter/base/*
/lib/form/base/*
/lib/model/map/*
/lib/model/om/*

?

Крис Макнайт
источник
5
делает .gitignoreразличие между файлами и каталогами , что он игнорирует? например, означает ли dataпротив data/разные вещи?
Чарли Паркер
6
@CharlieParker yes-ish: dataбудет игнорировать файлы и каталоги, которые соответствуют, data/будет игнорировать только каталоги, которые соответствуют.
Jox
Всегда помните, что если вы поставили или передали файл, который пытаетесь игнорировать, то нет способа проигнорировать его :( Просто мои 2 цента после того, как я подумала, что мой шаблон ошибочен, и потратила четверть часа.
Адам
@ Adam правильно, вам нужно обновить .gitignore, затем unstage / git rm - кэшировать файл.
Крис Макнайт

Ответы:

374

ФОРМАТ ШАБЛОНА

  • Пустая строка не соответствует ни одному файлу, поэтому она может служить разделителем для удобства чтения.

  • Строка, начинающаяся с #комментария.

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

  • Если шаблон заканчивается косой чертой, он удаляется с целью следующего описания, но он будет только находить совпадение с каталогом. Другими словами, foo/будет соответствовать каталог fooи пути под ним, но не будет совпадать с обычным файлом или символической ссылкой foo(это согласуется с тем, как pathspec работает в git в целом).

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

  • В противном случае git рассматривает шаблон как глобус оболочки, подходящий для использования fnmatch(3)с помощью FNM_PATHNAMEфлага: подстановочные знаки в шаблоне не будут совпадать с /именем в пути. Например, Documentation/*.htmlсоответствует, Documentation/git.htmlно не Documentation/ppc/ppc.htmlили tools/perf/Documentation/perf.html.

  • Начальная косая черта соответствует началу пути. Например, /*.cсоответствует, cat-file.cно нет mozilla-sha1/sha1.c.

Вы можете найти больше здесь

git help gitignore
или
man gitignore

Оп Де Циркель
источник
2
Как я могу поместить файл .gitignore на верхний уровень и заставить его работать для любой папки под ним? Благодарю вас.
Рой
104
-1 TL; DR и едва отвечает на вопрос. Речь идет о каталогах, а не файлах, поэтому выделенный раздел только уместен с некоторой умственной гимнастикой. @Jefromi был более прямым.
Боб Стейн
Я прочитал этого человека, и ответ @ Jefromi лучше - если вы также прочитали предупреждение @ jox - и @ Luke Hutton может быть более полезным для игнорирования, например, файлов проекта IDE.
WillC
1
Это на самом деле копия-вставка из документации git
mcont
1
Не уверен (по сути), копирование manстраницы или официального документа - лучший формат для SO ...
jdk1.0
183

Это было бы первым. Перейти по расширениям, а не структура папок.

Т.е. мой пример игнорирования разработки на C #:

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

Обновить

Я думал, что предоставлю обновление из комментариев ниже. Хотя он не отвечает непосредственно на вопрос OP, см. Следующие примеры для получения дополнительных примеров .gitignoreсинтаксиса.

Сообщество вики (постоянно обновляется):

.gitignore для проектов и решений Visual Studio

Больше примеров с использованием определенного языка можно найти здесь (благодаря комментарию Криса Макнайта):

https://github.com/github/gitignore

Люк Хаттон
источник
5
@ Stallman, это range. Так что это совпадает, *.Objа также *.obj.
Норберт
131

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

Итак, поскольку во всех приведенных вами примерах пути содержат косую черту, две версии идентичны. Единственный раз, когда вам нужно поставить ведущую косую черту, это когда ее уже нет на пути. Например, чтобы игнорировать foo только на верхнем уровне хранилища, используйте /foo. Простое написание fooигнорирует все, что называется foo, в любом месте хранилища.

Ваши подстановочные знаки также избыточны. Если вы хотите игнорировать весь каталог, просто назовите его:

lib/model/om

Единственная причина использовать подстановочные знаки, как у вас есть, если вы собираетесь впоследствии игнорировать что-то в каталоге:

lib/model/om/*      # ignore everything in the directory
!lib/model/om/foo   # except foo
Cascabel
источник
5
Лучшее объяснение, чем принятый ответ на этот вопрос
eerrzz
78

Начальная косая черта указывает, что запись игнорирования должна быть действительной только в отношении каталога, в котором находится файл .gitignore. При указании *.oигнорируются все файлы .o в этом каталоге и все его подкаталоги, в то время как /*.oони просто игнорируются в этом каталоге , а опять-таки /foo/*.oигнорируются только в /foo/*.o.

Йоргенсен
источник
34

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

Например, чтобы игнорировать все *.mapфайлы в /src/main/папке и подпапках, используйте:

/src/main/**/*.map
petrsyn
источник
Мне нужно было сделать это. Не уверен, зачем тебе два ** . Одного мне было достаточно.
Новокаин
8
** соответствует также файлам в подкаталогах
petrsyn
Спасибо за информацию @petrsyn
Новокаин
30

Оба примера в этом вопросе на самом деле очень плохие, что может привести к потере данных!

Мой совет: никогда не /*добавляйте каталоги в файлах .gitignore, если у вас нет веских причин!

Хорошей причиной будет, например, то, что написал Джефроми: «если вы собираетесь впоследствии что-то игнорировать в каталоге» .

Причина, по которой этого не следует делать, заключается в том, что добавление /*к каталогам, с одной стороны, работает таким образом, что оно правильно игнорирует все содержимое каталога, но, с другой стороны, имеет опасный побочный эффект:

Если вы выполняете git stash -u(для временного хранения отслеживаемых и неотслеживаемых файлов) или git clean -df(для удаления неотслеживаемых, но сохраняющих игнорируемые файлы) в своем хранилище, все каталоги, которые игнорируются с добавлением, /*будут безвозвратно удалены !

Некоторый фон

Я должен был выучить это трудным путем. Кто-то в моей команде /*добавлял некоторые каталоги в нашем .gitignore. Со временем у меня были случаи, когда определенные каталоги внезапно исчезали. Каталоги с гигабайтами локальных данных, необходимых нашему приложению. Никто не мог объяснить это, и я всегда хочу повторно загрузить все данные. Через некоторое время я понял, что это может быть связано с git stash. Однажды я захотел почистить локальный репозиторий (сохраняя при этом игнорируемые файлы), и я использовал, git clean -dfи мои данные снова исчезли. На этот раз мне хватило и исследовало проблему. Я наконец понял, что причина в приложении /*.

Я предполагаю, что это может быть как-то объяснено тем фактом, что directory/*игнорируется все содержимое каталога, но не сам каталог. Таким образом, это не считается отслеживаемым или игнорируемым, когда вещи удаляются. Хотя git statusи git status --ignoredприведу немного другую картину на нем.

Как воспроизвести

Вот как воспроизвести поведение. В настоящее время я использую Git 2.8.4.

Каталог, вызываемый localdata/с помощью фиктивного файла в нем ( important.dat), будет создан в локальном репозитории git, и его содержимое будет игнорироваться при добавлении /localdata/*в .gitignoreфайл. Когда одна из двух упомянутых команд git выполняется сейчас, каталог будет (неожиданно) потерян.

mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file

Если вы сделаете git status --ignoredздесь, вы получите:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  untracked-file

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

  localdata/

Сейчас либо делаю

git stash -u
git stash pop

или

git clean -df

В обоих случаях якобы игнорируемый каталог localdataисчезнет!

Не уверен, что это можно считать ошибкой, но я думаю, что это по крайней мере функция, которая никому не нужна.

Я сообщу об этом в список разработки git и посмотрю, что они об этом думают.

JOX
источник
15

Это было бы:

config/databases.yml
cache
log
data/sql
lib/filter/base
lib/form/base
lib/model/map
lib/model/om

или, возможно, даже:

config/databases.yml
cache
log
data/sql
lib/*/base
lib/model/map
lib/model/om

в случае, если это filterи formесть единственные каталоги в lib, которые имеют baseподкаталог, который нужно игнорировать (см. пример того, что вы можете сделать со звездочками).

aefxx
источник
14

Первый. Эти пути к файлам являются относительными от того, где находится ваш файл .gitignore.

Unixmonkey
источник
2
Это верно только для шаблонов, которые содержат косую черту. Одно имя каталога, такое как «mydir», также будет игнорировать каталоги (и файлы), которые находятся в подпапках на любой глубине. Только косая черта впереди сделает его относительно того, где находится ваш файл .gitignore.
Jox 29.09.16
4

Я поддерживаю сервис на основе GUI и CLI, который позволяет .gitignoreочень легко создавать шаблоны на https://www.gitignore.io .

Вы можете либо ввести нужные шаблоны в поле поиска, либо установить псевдоним командной строки и запустить

$ gi swift,osx

Джо
источник
0

Пример файла .gitignore может выглядеть так, как показано ниже для проекта Android Studio

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties


#Eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
YourProjetcName/.gradle/
YourProjetcName/app/build/
*/YourProjetcName/.gradle/
*/YourProjetcName/app/build/

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath

# Proguard folder generated by Eclipse
proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/
/build
build/
*/build/
*/*/build/
*/*/*/build/
*.bin
*.lock
YourProjetcName/app/build/
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
.gradle/
app/build/
*app/build/

# Local configuration file (sdk path, etc)
local.properties
/YourProjetcName/build/intermediates/lint-cache/api-versions-6-23.1.bin
appcompat_v7_23_1_1.xml
projectFilesBackup
build.gradle
YourProjetcName.iml
YourProjetcName.iml
gradlew
gradlew.bat
local.properties
settings.gradle
.gradle
.idea
android
build
gradle
Шириш Хервейд
источник