Gitignore файлы в папке но не папку

Обновлено: 30.06.2024

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

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

Которая добавит все файлы в каталоге проекта.

Но что если нам не нужны абсолютно все файлы, а есть файлы например в каталоге /cache или /images или /runtime проекта, которые генерируются в процессе работы. Они не должны быть добавлены в репозиторий.

Тут нам и нужен .gitignore. Вам нужно его самим создать и разместить в корне проекта либо нужной подпапке.

Где должен находиться этот файл

Файл может находиться в корне проекта или любом подкаталоге.

Либо можно задать глобальный файл gitignore, таким образом:

Таким образом вы сможете записать в глобальный файл

/.gitignore_global настройки, общие для всех ваших проектов. В нем могут храниться например файлы для игнорирования, которые специфичны для вашей IDE, и по этому не логично добавлять их в репозиторий. Однако файлы, которые специфичны для конкретного проекта, обязательно нужно добавлять в .gitignore самого проекта.

Примеры содержимого .gitignore файла

Подробнее о шаблонах игнорирования

ШаблонПримеры соответствияПояснение*
**/logslogs/debug.log logs/monday/foo.bar build/logs/debug.logДобавьте в начало шаблона две звездочки, чтобы сопоставлять каталоги в любом месте репозитория.
**/logs/debug.loglogs/debug.log build/logs/debug.log но не logs/build/debug.logДве звездочки можно также использовать для сопоставления файлов на основе их имени и имени родительского каталога.
*.logdebug.log foo.log .log logs/debug.logОдна звездочка — это подстановочный знак, который может соответствовать как нескольким символам, так и ни одному.
*.log !important.logdebug.log trace.log но не important.log logs/important.logДобавление восклицательного знака в начало шаблона отменяет действие шаблона. Если файл соответствует некоему шаблону, но при этом также соответствует отменяющему шаблону, указанному после, такой файл не будет игнорироваться.
.log !important/.log trace.*debug.log important/trace.log но не important/debug.logШаблоны, указанные после отменяющего шаблона, снова будут помечать файлы как игнорируемые, даже если ранее игнорирование этих файлов было отменено.
/debug.logdebug.log но не logs/debug.logКосая черта перед именем файла соответствует файлу в корневом каталоге репозитория.
debug.logdebug.log logs/debug.logПо умолчанию шаблоны соответствуют файлам, находящимся в любом каталоге
debug?.logdebug0.log debugg.log но не debug10.logЗнак вопроса соответствует строго одному символу.
debug3.logdebug0.log debug1.log но не debug10.logКвадратные скобки можно также использовать для указания соответствия одному символу из заданного диапазона.
debug[01].logdebug0.log debug1.log но не debug2.log debug01.logКвадратные скобки соответствуют одному символу из указанного набора.
debug[!01].logdebug2.log но не debug0.log debug1.log debug01.logВосклицательный знак можно использовать для указания соответствия любому символу, кроме символов из указанного набора.
debug[a-z].logdebuga.log debugb.log но не debug1.logДиапазоны могут быть цифровыми или буквенными.
logslogs logs/debug.log logs/latest/foo.bar build/logs build/logs/debug.logБез косой черты в конце этот шаблон будет соответствовать и файлам, и содержимому каталогов с таким именем. В примере соответствия слева игнорируются и каталоги, и файлы с именем logs
logs/logs/debug.log logs/latest/foo.bar build/logs/foo.bar build/logs/latest/debug.logКосая черта в конце шаблона означает каталог. Все содержимое любого каталога репозитория, соответствующего этому имени (включая все его файлы и подкаталоги), будет игнорироваться
logs/ !logs/important.loglogs/debug.log logs/important.logМинуточку! Разве файл logs/important.log из примера слева не должен быть исключен нз списка игнорируемых? Нет! Из-за странностей Git, связанных с производительностью, вы не можете отменить игнорирование файла, которое задано шаблоном соответствия каталогу
logs/**/debug.loglogs/debug.log logs/monday/debug.log logs/monday/pm/debug.logДве звездочки соответствуют множеству каталогов или ни одному.
logs/*day/debug.loglogs/monday/debug.log logs/tuesday/debug.log but not logs/latest/debug.logПодстановочные символы можно использовать и в именах каталогов.
logs/debug.loglogs/debug.log но не debug.log build/logs/debug.logШаблоны, указывающие на файл в определенном каталоге, задаются относительно корневого каталога репозитория. (При желании можно добавить в начало косую черту, но она ни на что особо не повлияет.)

Что если файлы из gitignore уже добавлены в репозиторий

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

Нам придется вручную их удалить из репозитория.

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

То же самое для Powershell

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

Либо можно удалять файлы вручную, таким образом:

Либо если нам нужно удалить целую директорию из git, то воспользуемся следующей командой:

Либо так мы могли бы удалить все файлы с расширением .log в папке log:

Параметр --cached означает, что файлы будут удалены только из раздела "проиндексированных файлов". На диске (рабочем каталоге) они останутся нетронутыми.

Как понять, почему игнорируется конкретный файл

Запустите команду вместо path/to/file следует указать путь к файлу.

В итоге мы получим ответ, в котором содержится конкретная строка .gitignore, благодаря которой данный файл игнорируется.

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

Файл .gitignore указывает, какие неотслеживаемые файлы должен игнорировать Git .

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

Игнорируемые файлы обычно представляют собой файлы, специфичные для платформы, или автоматически созданные из сборочных систем. Ниже приводятся некоторые общие примеры:

  • Runtime файлы, такие как log , lock , cache или временные файлы ( tmp ).
  • Файлы с конфиденциальной информацией, такие как пароли или ключи API.
  • Каталоги зависимостей, такие как /vendor или /node_modules .
  • Build каталоги, такие как /public или /dist .
  • Системные файлы, такие как .DS_Store или Thumbs.db
  • Конфигурационные файлы IDE или текстового редактора.

Шаблоны .gitignore

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

.gitignore использует glob шаблоны для сопоставления имен файлов с символами подстановки (Это что-то вроде регулярных выражений). Если у вас есть файлы или каталоги, содержащие шаблон подстановки (например * ), вы можете использовать один обратный слеш ( \* ), чтобы экранировать такой символ.

Комментарии

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

Если шаблон не начинается со слэша, он соответствует файлам и каталогам в любом каталоге или подкаталоге.

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

Имена файлов

Самый простой шаблон - это просто имя файла без каких-либо специальных символов.

ШаблонПримеры совпадений
/access.log access.log
access.log access.log
logs/access.log
var/logs/access.log
build/ build

Символы подстановки

* - Символ звездочки соответствует нулю или более символам.

ШАБЛОНПРИМЕРЫ СОВПАДЕНИЙ
*.log error.log
logs/debug.log
build/logs/error.log

** - Два соседних символа звездочки соответствуют любому файлу или нулю или более каталогам. Когда за ним следует косая черта ( / ), она соответствует только каталогам.

ШАБЛОНПРИМЕРЫ СОВПАДЕНИЙ
logs/** Совпадает со всем, что находится в каталоге logs.
**/build var/build
pub/build
build
foo/**/bar foo/bar
foo/a/bar
foo/a/b/c/bar

? - Вопросительный знак соответствует любому отдельному символу.

ШАБЛОНПРИМЕРЫ СОВПАДЕНИЙ
access?.log access0.log
access1.log
accessA.log
foo?? fooab
foo23
foo0s

Квадратные скобки

[…] - Совпадает с любыми символами, заключенными в квадратные скобки. Когда два символа разделены дефисом - обозначает диапазон символов. Диапазон включает в себя все символы, находящиеся между этими двумя символами. Диапазон может быть алфавитным или цифровым.

Если первый символ после [ является восклицательным знаком ( ! ), то образец соответствует любому символу, кроме символов из указанного набора.

ШАБЛОНПРИМЕРЫ СОВПАДЕНИЙ
*.[oa] file.o
file.a
*.[!oa] file.s
file.1
file.0
access.2.log access.0.log
access.1.log
access.2.log
file.[a-c].out file.a.out
file.b.out
file.c.out
file.[a-cx-z].out file.a.out
file.b.out
file.c.out
file.x.out
file.y.out
file.z.out
access.[!0-2].log access.3.log
access.4.log
access.Q.log

Исключающие шаблоны

Шаблон, начинающийся с восклицательного знака ( ! ), отменяет (повторно включает) любой файл, игнорируемый предыдущей шаблоном. Исключением из этого правила является повторное включение файла, если его родительский каталог исключен.

ШАБЛОНПРИМЕРЫ СОВПАДЕНИЙ
*.log
!error.log
error.log or logs/error.log will not be ignored

Пример .gitignore

Локальный .gitignore

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

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

Персональные правила игнорирования

Шаблоны, специфичные для вашего локального репозитория и не подлежащие распространению в других репозиториях, должны быть установлены в файле .git/info/exclude .
Например, этот файл можно использовать для игнорирования сгенерированных файлов из ваших личных инструментов проекта.

Глобальный .gitignore

Git также позволяет вам создать глобальный файл .gitignore , в котором вы можете определить правила игнорирования для каждого Git-репозитория вашей локальной системы.

Файл может называться по вашему усмотрению и храниться в любом месте. Наиболее распространенным местом хранения этого файла является домашний каталог. Вам придется вручную создать файл и настроить Git для его использования.

Например, чтобы установить

/.gitignore_global в качестве глобального файла игнорирования Git, выполните следующие действия:

1. Создайте файл:

2. Добавьте этот файл в Git-конфигурацию:

3. Откройте файл в текстовом редакторе и добавьте в него свои правила.

Глобальные правила особенно полезны при игнорировании определенных файлов, которые вы никогда не захотите фиксировать, таких как файлы с конфиденциальной информацией или скомпилированные исполняемые файлы.

Игнорирование ранее зафиксированных файлов

Файлы в вашей рабочей копии могут отслеживаться или не отслеживаться.

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

Опция --cached говорит не удалять файл из рабочего дерева, а только удалять его из индекса.

Для рекурсивного удаления каталога используйте параметр -r :

Если вы хотите удалить файл как из индексной, так и из локальной файловой системы, опустите опцию --cached .

При рекурсивном удалении файлов используйте опцию -n , которая выполнит пробный запуск и покажет, какие файлы будут удалены:

Отладка файла .gitignore

Иногда бывает сложно определить, почему тот или иной файл игнорируется, особенно если вы используете несколько файлов .gitignore или сложные шаблоны. В этом случае пригодится команда git check-ignore с опцией -v, которая указывает на то, что нужно отображать детали совпадающего шаблона.

Например, чтобы проверить, почему файл www/yarn.lock игнорируется, нужно выполнить следующее:

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

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

Отображение всех игнорируемых файлов

Команда git status с опцией -ignored отображает список всех проигнорированных файлов:

Заключение

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

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

Так что в .gitignore если я пойду:

Это игнорирует все, что не то, что я хочу.

Я нашел этот вопрос: Как добавить пустой каталог в репозитории Git? и кто-то предложил «обходной путь» с 54 ответами:

«Энди Лестер прав, но если ваш каталог просто должен быть пустым, а не пустым, вы можете поместить туда пустой файл .gitignore в качестве обходного пути . »

Итак, теперь я иду:

И взял предложение из принятого ответа и сделал:

Но все равно не получить желаемого результата.

Как я могу зафиксировать выходную папку в хранилище для задачи gulp?

3 ответа

Хорошо, я разобрался:

По сути, любой файл в любой папке ниже одного уровня в / public должен игнорироваться.

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

Теперь проблема здесь в том, что когда Git выполняет свои "трюки как можно быстрее, даже если это смущает всех" :-), он может обнаружить, что .gitignore перечисляет имя каталога и что он - в частности, index в Git - не имеет файлов уже в этом каталоге, и он даже не потрудится заглянуть внутрь каталога для файлов. Вот как git add пропускает прямо над директивой !public/.gitignore : пока он просматривал, он нашел public в качестве каталога, но в нем еще не было файлов для фиксации, а затем нашел > в .gitignore и решил вообще не заглядывать внутрь public .

Если вместо перечисления public в вашем .gitignore вы перечислите public/* , Git должен заглянуть внутрь public , чтобы найти все свои файлы и подкаталоги, чтобы выяснить, могут ли они быть пропущенным Заглянув внутрь, он проверит public/.gitignore содержимое .gitignore . Запись public/* скажет «пропустить это», но более поздняя запись !public/.gitignore скажет «не пропустить». Затем более поздняя запись переопределяет, и public/.gitignore вставляется в индекс Git с помощью git add --all или git commit --all .

Как только public/.gitignore находится в индексе, он переходит к следующему коммиту. Как только это произойдет, на самом деле безопасно перечислить public , а не public/* в файле .gitignore , потому что теперь, когда Git имеет файл в каталоге, Git вынужден сканировать каталог. Запись для public/.gitignore будет только удалена из индекса только после явного запроса на удаление этой записи ( git rm public/.gitignore или git rm --cached public/.gitignore ) или перехода к ( git checkout - ing) существующий коммит, в котором нет public/.gitignore файла. После удаления записи указателя перечислять public , а не public/* , теперь небезопасно, поскольку Git может вернуться к своей уловке, заметив, что public является каталогом и игнорируется , и Git ничего не заставляет Git заглядывать внутрь public , поэтому он не заглядывает внутрь и не находит public/.gitignore и, следовательно, не делает проверьте на исключение.

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

Затем Git будет сканировать каталог public на наличие файлов, поскольку он не игнорируется; в этом каталоге есть файл .gitignore , и этот файл .gitignore говорит: игнорировать все здесь, кроме .gitignore здесь. , поскольку Git уже вошел в каталог на данный момент, и обнаружил список всех файлов и подкаталогов в этом каталоге, он проверит каждый такой файл и подкаталог по отдельности для этого .gitignore и проигнорирует все из них, кроме .gitignore сам.

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

Если это единственный элемент в папке, и вам нужно сохранить эту папку активной, возможно, поместите в нее пустой текстовый файл

Читаю книгу Test-Driven Development with Python, во второй главе описывается создание git-репозитория. Я следую всем инструкциям, но мой файл .gitignore не игнорирует записанное в нём. В чём проблема?

pic


31.9k 22 22 золотых знака 119 119 серебряных знаков 206 206 бронзовых знаков


505 1 1 золотой знак 4 4 серебряных знака 7 7 бронзовых знаков Вероятно вы добавили в .gitignore файлы, которые уже попали в ваш репозиторий попробуйте git rm --cached, как там написано @Darth, оформите, пожалуйста, ваш комментарий в виде ответа. А покажите содержимое файла .gitignore, а то есть подозрение, что там db.sqlite3 может быть записан не на отдельной строке, а где-то после другой сигнатуры. Судя по скриншоту, не похоже, что файлы уже попали в репозиторий, поскольку git status отмечает их как новые. Дмитрий, как там ваш репозиторий? Получилось решить задачу?

Подозреваю, что вы добавили файлы в индекс раньше, чем начали игнорировать. То есть до той git add . , который на скриншоте, была еще одна такая команда. Чтобы узнать точно, не хватает git status перед добавлением.

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

Если файлы только добавлены, но еще не включены в коммит

В данном конкретном случае именно так и есть. При этом достаточно удалить их из индекса. Данная команда возвращает индекс к HEAD, то есть состоянию последнего коммита.

Вы можете заметить, что сам Git предлагает использовать другую команду:

Если игнорируемые файлы уже есть в последнем коммите

Возможна и такая ситуация, на всякий случай я опишу и ее. Здесь reset не сработает, нужен rm . Аргумент --cached заставляет Git удалить файл из индекса, но не трогать рабочую область. То есть он буквально индексирует удаление файла, хотя этого удаления не было. Если сделать это с файлом, который не игнорируется, то после коммита он будет в категории неотслеживаемых (untracked).

Если нужно убрать целую игнорируемую папку, добавляем ключ -r:

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

Читайте также: