.gitattributes
.gitattributes — это специальный текстовый файл в репозитории Git, в котором задаются правила (атрибуты) для разных групп файлов по маскам (шаблонам). Он позволяет гибко настраивать обработку файлов для нужд проекта, чтобы избежать проблем при совместной работе, архивации, слияниях, работе на разных ОС и т.д.
С помощью этого файла можно управлять тем, как Git обрабатывает файлы:
- нормализует переводы строк (EOL).
- определяет, что считать бинарным файлом.
- настраивает обработку diff и merge.
- применяет фильтры и спец. правила для архивации.
- управляет кодировкой и автоподстановкой значений.
Каждая строка в файле — это правило вида:
шаблон атрибут1 атрибут2 ...
Например:
# для всех PNG-файлов задать поведение как для бинарных *.png binary
Расположение файла
Файл может располагаться в корне репозитория, в подпапках или в служебных местах.
Порядок приоритетности — позднее найденное правило перебивает более раннее по каждому атрибуту:
.git/info/attributes(локальный) — текущий репозиторий, перебивает всё (наивысший приоритет)..gitattributes(локальный) — ближайший к файлу, перебивает глобальный и системный.core.attributesFile(глобальный) — для всех ваших репозиториев.$(prefix)/etc/gitattributes(системный) — для всех пользователей в системе (самый низкий приоритет).
Пример:
- Атрибут из .git/info/attributes перебьёт все остальные.
- Атрибут из .gitattributes (ближайший к файлу) перебьёт глобальный и системный.
- Если нет локальных правил, Git смотрит глобальный конфиг, потом системный.
Синтаксис строки
шаблон атрибут1 атрибут2 ...
-
Например:
*.jpg binary -
Комментарии: строка с
# -
Пробелы игнорируются
-
Шаблоны — как в
.gitignore, но:- Отрицательные (!) — нельзя.
folder/не рекурсивен — нужно использоватьfolder/**.- Поздние строки перебивают ранние (по каждому атрибуту отдельно).
Состояния атрибута
Это способ указать для Git, как применять конкретный атрибут к файлу или группе файлов.
Каждое состояние определяет, включён или отключён атрибут, или задано для него конкретное значение:
-
attr— Атрибут включён (Git считает его установленным, значение "true").
Пример:*.txt text -
-attr— Атрибут отключён (Git считает его сброшенным, значение "false").
Пример:*.bin -text -
attr=value— Атрибуту присваивается конкретное строковое значение.
Пример:*.sh eol=lf !attr— Атрибут сбрасывается в неопределённое состояние (Unspecified), как будто правило для него не задано вообще.
Пример:*.log !text
Атрибуты
- binary
- Встроенный макро-атрибут: эквивалентен
-diff -merge -text.
Нужно указывать для бинарных файлов. Например:*.png binary. - text
Указывает Git считать файл текстовым и применять нормализацию переводов строк (LF в репозитории, EOL в рабочей копии).
text— всегда считать текстом (LF в индексе, автоконвертация при checkout по OS)-text— не трогать переводы строк, считать бинарникомtext=auto— Git сам определяет (рекомендуется для кроссплатформы)
- eol
Явно задаёт тип перевода строк в рабочей копии (в файлах проекта на вашем компьютере):
eol=lf— только LFeol=crlf— только CRLF
Работает только если включён
textилиtext=auto:*.sh text eol=lf
- diff
Управляет тем, как Git строит различия (diff) для файла:
diff— форсировать обычный текстовый diff.-diff— не показывать diff (Binary files differ).diff=driver— использовать указанный diff-драйвер. Например,diff=php.
В Git есть несколько встроенных diff-драйверов по языкам/форматам: ada, bash, bibtex, cpp, csharp, css, dts, elixir, fortran, fountain, golang, html, java, kotlin, markdown, matlab, objc, pascal, perl, php, python, ruby, rust, scheme, tex.
- merge
Управляет тем, как Git сливает (merge) изменения файла.
merge— использовать стандартный текстовый merge (3-way merge с конфликтами)-merge— всегда считать конфликтным, оставить только вашу версиюmerge=driver— использовать указанный merge-драйвер. Например,merge=binaryили кастомный драйвер.
- filter
Указывает Git применять внешний фильтр к файлу при добавлении (clean) или извлечении (smudge) из репозитория.
Фильтры используются, например, для автоматического преобразования файлов при сохранении или восстановлении (например, сжатие, шифрование, форматирование и др.).
filter=name— имя фильтра, который настроен в конфиге.git/config.Например:
[filter "myfilter"] clean = команда-для-clean smudge = команда-для-smudge
*.ext filter=myfilter
- export-ignore
Говорит Git не включать указанные файлы/папки в архивы, создаваемые командой
git archive(например, zip или tar).Например:
tests/ export-ignore.Архивация используется для релизов и при создании архивово в GitHub / GitLab.
Если пакет собирается через Packagist, он тоже использует
git archive, а значит учитывает export-ignore. Все файлы с этим атрибутом не попадут в дистрибутив Composer-пакета.Файлы с
export-ignoreсохраняются при клонировании.- export-subst
Включает автоматическую подстановку плейсхолдеров (например, информации о коммите) в файле при создании архива через
git archive.Для автозамены шаблонов, как
$Format:%H$(хеш коммита), в контенте файла.Пример:
VERSION export-subst
Теперь указываем шаблон в файле
VERSION:Commit: $Format:%H$ Date: $Format:%cI$
При создании архива через git archive эти плейсхолдеры заменятся на актуальные значения.
При клонировании шаблон останется как есть.
Списко плейсхолдеров:
$Format:%H$ — полный хеш коммита $Format:%h$ — короткий хеш $Format:%an$ — автор (имя) $Format:%ae$ — автор (email) $Format:%ad$ — дата коммита (локальная) $Format:%cd$ — дата коммита (локальная, коммиттер) $Format:%cI$ — дата в формате ISO $Format:%s$ — сообщение коммита $Format:%d$ — рефы (теги, ветки) $Format:%D$ — рефы (полные) $Format:%(describe)$ — git describe (тег/коммит)
Полный список: https://git-scm.com/docs/git-log
- working-tree-encoding
Указывает Git, в какой кодировке файл должен быть в рабочей копии.
В репозитории файл хранится в UTF-8, а при checkout/commit автоматически конвертируется из/в нужную кодировку.
Пример:*.ps1 text working-tree-encoding=UTF-16LE eol=crlf
Полезно для файлов, которые по требованиям должны быть не в UTF-8 (например, скрипты для Windows).
- Работает только при установленном
textилиtext=auto. - Не все версии Git и сторонние клиенты поддерживают этот атрибут.
- Для проверки доступных кодировок используй:
iconv --list
- Работает только при установленном
- ident
Позволяет автоматически подставлять в файл хеш коммита вместо строки
$Id$при извлечении из репозитория (checkout).Используется для идентификации версии файла. Чтобы прямо в файле видеть, из какого коммита он был получен.
Например в файле пишем:
Версия: $Id$
Если для файла включён
ident, после checkout получится:Версия: $Id: <хеш файла> $
- whitespace
Управляет проверкой ошибок пробелов и табов при работе с
diffиpatch.Используется для более строгого контроля стиля кода на уровне репозитория.
whitespace— включить все стандартные проверки (лишние пробелы, табы, пробелы в конце строк и др.)-whitespace— отключить все проверкиwhitespace=option1,option2— включить только указанные проверки (например, whitespace=trailing-space,tab-in-indent)
Пример:
*.py whitespace=tab-in-indent,trailing-space
- conflict-marker-size
Задаёт длину конфликтных маркеров (
<<<<<,=====,>>>>>) при возникновении конфликтов слияния (merge).По умолчанию маркеры длиной 7 символов. Можно увеличить, чтобы маркеры было лучше видно.
Пример:
*.md conflict-marker-size=32
Теперь маркеры в конфликте для
.mdфайлов будут длиной 32 символа.
Макро-атрибуты
Это сокращение, которое задаёт сразу несколько атрибутов для файлов.
Например, стандартный макро-атрибут binary эквивалентен -text -diff -merge.
Можно создать свой макро-атрибут, чтобы не повторять одни и те же атрибуты для разных файлов.
Кастомные макро-атрибуты можно задавать только в корневом файле .gitattributes или в .git/info/attributes.
Пример создания макро-атрибута mybin:
[attr]mybin -text -diff -merge # объявление макро-атрибута mybin *.foo mybin # применить (-text -diff -merge) ко всем *.foo файлов *.bar mybin # применить (-text -diff -merge) ко всем *.bar файлов
По умолчанию в Git есть только один встроенный макро-атрибут:
- binary — устанавливает сразу три атрибута:
-diff -merge -text
Примеры
Исключения файлов из архива
Этот конфиг исключит указанные файлы из Composer-пакета (Packagist). Все файлы с этим атрибутом не попадут в дистрибутив.
/tests/ export-ignore *.md export-ignore secret.txt export-ignore
Демо
Эти правила охватывают обработку переводов строк, бинарных файлов, работу с архивами и распространённые исключения:
# Для всех текстовых файлов — автоопределение * text=auto # Принудительный LF для скриптов *.sh text eol=lf # CRLF для файлов Visual Studio *.vcproj text eol=crlf # Для картинок — бинарные, diff/merge отключён *.jpg binary *.png binary *.gif binary # Не включать тесты в архивы /tests/ export-ignore # Подстановка информации о коммите в файл VERSION при архивировании VERSION export-subst # Принудительно отключить нормализацию строк для PDF *.pdf -text
Массовая нормализация EOL
echo "* text=auto" > .gitattributes git add --renormalize . git status # покажет файлы, где изменилась нормализация git commit -m "Normalize line endings"
Исключения можно задать явным -text для файлов/паттернов.