8.1 Настройка Git – Конфигурация Git
До этого момента мы описывали основы того, как Git работает, и как его использовать, а также мы познакомились с некоторыми инструментами Git, которые делают его использование простым и эффективным. В этой главе мы рассмотрим некоторые настройки Git и систему хуков, что позволяет настроить поведение Git. Таким образом, вы сможете заставить Git работать именно так, как нужно вам или вашей компании.
В главе «Введение» кратко упоминалось, что вы можете настроить Git, используя команду git config
. Первое, что вы сделали, это установили свои имя и e-mail адрес:
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com
Сейчас вы познакомитесь с несколькими наиболее интересными опциями, которые можно установить для настройки поведения Git.
Кратко: Для изменения стандартного поведения, если это необходимо, Git использует набор конфигурационных файлов. Вначале Git ищет настройки в файле /etc/gitconfig, который содержит настройки для всех пользователей в системе и всех репозиториев. Если передать опцию --system
команде git config
, то операции чтения и записи будут производиться именно с этим файлом.
Следующее место, куда смотрит Git – это файл ~/.gitconfig (или ~/.config/git/config), который хранит настройки конкретного пользователя. Вы можете указать Git читать и писать в него, используя опцию --global
.
Наконец, Git ищет параметры конфигурации в файле настроек в каталоге Git (.git/config) текущего репозитория. Эти значения относятся только к текущему репозиторию и доступны при передаче параметра --local
команде git config
(если уровень настроек не указан явно, то подразумевается локальный).
Каждый из этих уровней (системный, глобальный, локальный) переопределяет значения предыдущего уровня, например, значения из .git/config важнее значений из /etc/gitconfig.
Примечание
Конфигурация Git – это обычные текстовые файлы, поэтому необходимые значения можно установить вручную, используя соответствующий синтаксис. Как правило, это проще, чем вызывать команду git config
для каждого параметра.
Базовая конфигурация клиента
Конфигурационные параметры Git разделяются на две категории: настройки клиента и настройки сервера. Большая часть – клиентские настройки для ваших личных предпочтений в работе. Существует много, очень много настроек, но подавляющее большинство из них применимо только в конкретных случаях; мы рассмотрим только самые основные и самые полезные из них. Для просмотра полного списка настроек, поддерживаемых вашей версией Git, выполните команду:
$ man git-config
Эта команда выведет список доступных настроек с довольно подробным описанием. Также соответствующую документацию можно найти здесь https://git-scm.com/docs/git-config.html.
core.editor
По умолчанию Git использует ваш редактор по умолчанию ($VISUAL
или $EDITOR
); если значение не задано, то при создании и редактировании сообщений коммитов или тегов переходит к использованию редактора vi
. Чтобы изменить редактор по умолчанию, воспользуйтесь настройкой core.editor
:
$ git config --global core.editor emacs
Теперь вне зависимости от того, какой редактор является основным для вашего окружения, Git будет вызывать Emacs для редактирования сообщений.
commit.template
Если указать путь к существующему файлу, то при создании коммита он будет использован как сообщение по умолчанию. Смысл создания шаблона сообщения коммита в том, чтобы лишний раз напомнить себе (или другим) о требованиях к формату или стилю оформления сообщения коммита.
Например, предположим, что вы создали файл ~/.gitmessage.txt, который выглядит так:
Строка темы (попытайтесь уложиться в 50 символов)
Многострочное описание коммита,
не стесняйтесь подробностей.
[Тикет: X]
Обратите внимание, что шаблон напоминает коммитеру о том, чтобы строка заголовка сообщения была короткой (для поддержки однострочного вывода команды git log --oneline
), что дополнительную информацию в сообщении следует располагать ниже, а так же о том, что было бы неплохо при наличии добавить ссылку на номер задачи или сообщения в системе отслеживания ошибок.
Чтобы заставить Git отображать содержимое этого файла в редакторе каждый раз при выполнении команды git commit
, следует установить значение параметра commit.template
:
$ git config --global commit.template ~/.gitmessage.txt
$ git commit
Теперь, при создании коммита, в вашем редакторе будет отображаться сообщение изменённого вида:
Строка темы (попытайтесь уложиться в 50 символов)
Многострочное описание коммита,
не стесняйтесь подробностей.
[Тикет: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: lib/test.rb
#
~
~
".git/COMMIT_EDITMSG" 14L, 297C
Если ваша команда придерживается требований к сообщениям коммитов, то создание шаблона такого сообщения и настройка Git на его использование увеличит вероятность соответствия заданным требованиям.
core.pager
Данная настройка определяет, какая логика будет использована для разбиения текста на страницы при выводе такой информации как log
и diff
. Вы можете указать more
или любую другую (по умолчанию используется less
), а также выключить совсем, установив пустое значение:
$ git config --global core.pager ''
В таком случае, Git будет выводить весь текст полностью, вне зависимости от его длины.
user.signingkey
Если вы создаёте подписанные аннотированные теги (как описано в разделе «Подпись» главы 7), то установка GPG-ключа в настройках облегчит вам задачу. Установить ключ можно следующим образом:
$ git config --global user.signingkey <gpg-key-id>
Теперь, вам не нужно указывать ключ для подписи каждый раз при вызове команды git tag
:
$ git tag -s <tag-name>
core.excludesfile
В разделе «Игнорирование файлов» главы 2 сказано, что вы можете указывать шаблоны исключений в файле .gitignore вашего проекта, чтобы Git не отслеживал их и не добавлял в индекс при выполнении команды git add
.
Однако иногда вам нужно игнорировать определенные файлы во всех ваших репозиториях. Если на вашем компьютере работает Mac OS X, вероятно вы знакомы с файлами .DS_Store. Если вы используете Emacs или Vim, то вы знаете про файлы, имена которых заканчиваются на ~ или .swp.
Данная настройка позволяет вам определить что-то вроде глобального файла .gitignore. Если вы создадите файл ~/.gitignore_global с содержанием:
*~
.*.swp
.DS_Store
… и выполните команду git config --global core.excludesfile ~/.gitignore_global
, то Git больше не потревожит вас из-за этих файлов.
help.autocorrect
Если вы ошибётесь в написании команды, Git покажет вам что-то вроде этого:
$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.
The most similar command is
checkout
Git старается угадать, что вы имели ввиду, но при этом команду не выполняет. Если вы установите help.autocorrect
в значение 1, то Git будет выполнять эту команду:
$ git chekcout master
WARNING: You called a Git command named 'chekcout', which does not exist.
Continuing under the assumption that you meant 'checkout'
in 0.1 seconds automatically...
Обратите внимание, что команда выполнилась через «0.1» секунды. help.autocorrect
– это число, указываемое в десятых долях секунды. Поэтому, если вы установите значение 50, то Git даст вам 5 секунд изменить своё решение перед тем, как выполнить скорректированную команду.
Цвета в Git
Git полностью поддерживает цветовой вывод в терминале, что позволяет быстро и легко визуально анализировать вывод команд. Существует несколько опций для настройки цветов.
color.ui
Git автоматически подсвечивает большую часть своего вывода, но это можно отключить, если вам не нравится такое поведение. Для отключения цветового вывода в терминал, выполните следующую команду:
$ git config --global color.ui false
Значение по умолчанию – auto
, при котором цвета используются при непосредственном выводе в терминал, но исключаются при перенаправлении вывода в именованный канал или файл.
Вы также можете установить значение always
, что делает вывод одинаковым как в терминал, так и в именованный канал. Скорее всего, вам это не понадобится; в большинстве случаев, при желании использовать цвета в перенаправленном выводе, указывается флаг --color
команде Git для принудительного использования цветовых кодов. Практически всегда стандартное значение подходит лучше всего.
color.*
Если вы хотите явно указать, вывод каких команд должен быть подсвечен, и как, Git предоставляет соответствующие настройки. Каждая из них может быть установлена в значения true
, false
или always
:
color.branch
color.diff
color.interactive
color.status
Каждая из них имеет вложенную конфигурацию, которую можно использовать для настройки отдельных частей вывода при желании переопределить их цвет. Например, чтобы установить для метаинформации вывода команды diff
синий цвет, чёрный фон и полужирный шрифт, выполните команду:
$ git config --global color.diff.meta "blue black bold"
Для установки цвета доступны следующие значения: normal
, black
, red
, green
, yellow
, blue
, magenta
, cyan
и white
. Для указания атрибутов текста (как bold
в предыдущем примере) доступны значения: bold
, dim
, ul
(подчёркнутый), blink
и reverse
(поменять местами цвет фона и цвет текста).
Внешние программы слияния и сравнения
Хоть в Git и есть встроенная программа сравнения, которая описывается в этой книге, вы можете установить вместо неё другую. Вы также можете настроить графический инструмент разрешения конфликтов слияния вместо того, чтобы разрешать конфликты вручную. Мы покажем, как настроить Perforce Visual Merge Tool (P4Merge) для разрешения конфликтов слияния, так как это отличный и бесплатный инструмент.
Если у вас есть желание попробовать P4Merge, то она работает на всех основных платформах, так что у вас должно получиться. В примерах мы будем использовать пути к файлам, которые работают в системах Linux и Mac; для Windows вам следует изменить /usr/local/bin на путь к исполняемому файлу у вас в системе.
Для начала скачайте P4Merge. Затем создайте скрипты обёртки для вызова внешних программ. Мы будем использовать путь к исполняемому файлу в системе Mac; в других системах – это путь к файлу p4merge
. Создайте скрипт с названием extMerge
для вызова программы слияния и передачи ей заданных параметров:
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*
Скрипт вызова программы сравнения проверяет наличие 7 аргументов и передаёт 2 из них в скрипт вызова программы слияния. По умолчанию Git передаёт следующие аргументы программе сравнения:
path old-file old-hex old-mode new-file new-hex new-mode
Так как вам нужны только old-file
и new-file
, следует использовать скрипт, который передаст только необходимые параметры.
$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"
Также следует убедиться, что созданные скрипты могут выполняться:
$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff
Теперь можно изменить файл конфигурации для использования ваших инструментов слияния и сравнения. Для этого необходимо изменить ряд настроек:
merge.tool
– чтобы сказать Git, какую стратегию использовать;mergetool.<tool>.cmd
– чтобы сказать Git, как запускать команду;mergetool.<tool>.trustExitCode
– чтобы сказать Git, как интерпретировать код выхода из программы;diff.external
– чтобы сказать Git, какую команду использовать для сравнения.
Таким образом, команду конфигурации нужно запустить четыре раза:
$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
'extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.extMerge.trustExitCode false
$ git config --global diff.external extDiff
или вручную отредактировать файл ~/.gitconfig, добавив соответствующие строки:
[merge]
tool = extMerge
[mergetool "extMerge"]
cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
trustExitCode = false
[diff]
external = extDiff
После этого, вы можете запускать команды diff
следующим образом:
$ git diff 32d1776b1^ 32d1776b1
Вместо отображения вывода diff
в терминале Git запустит P4Merge, выглядеть это будет примерно так:
Если при слиянии двух веток у вас возникнут конфликты, выполните команду git mergetool
; она запустит P4Merge, чтобы вы могли разрешить конфликты, используя графический интерфейс.
Используя скрипт обёртку для вызова внешних программ, вы можете легко изменить вызываемую программу. Например, чтобы начать использовать KDiff3 вместо P4Merge, достаточно изменить файл extMerge
:
$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*
Теперь, Git будет использовать программу KDiff3 для сравнения файлов и разрешения конфликтов слияния.
Git изначально настроен на использование ряда других инструментов для разрешения конфликтов слияния, поэтому вам не нужно дополнительно что-то настраивать. Для просмотра списка поддерживаемых инструментов, выполните команду:
$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
emerge
gvimdiff
gvimdiff2
opendiff
p4merge
vimdiff
vimdiff2
The following tools are valid, but not currently available:
araxis
bc3
codecompare
deltawalker
diffmerge
diffuse
ecmerge
kdiff3
meld
tkdiff
tortoisemerge
xxdiff
Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.
Если вы хотите использовать KDiff3 только для разрешения конфликтов слияния, но не для сравнения, выполните команду:
$ git config --global merge.tool kdiff3
Если выполнить эту команду вместо настройки использования файлов extMerge
и extDiff
, то Git будет использовать KDiff3 для разрешения конфликтов слияния, а для сравнения – стандартную программу diff
.
Форматирование и пробелы
Проблемы форматирования и пробелов являются одними из самых неприятных и незаметных проблем, с которыми сталкивают разработчики при совместной работе, особенно используя разные платформы. Это легко может произойти с патчами или с любой другой совместной работой, так как редакторы молча исправляют несоответствия, и если ваши файлы когда либо касаются систем Windows, то переносы строк могут быть заменены. В Git есть несколько настроек, чтобы справиться с этими проблемами.
core.autocrlf
Если вы программируете в Windows и работаете с людьми, которые не используют её (или наоборот), рано или поздно, вы столкнётесь с проблемами переноса строк. Это происходит потому, что Windows при создании файлов использует для обозначения переноса строки два символа «возврат каретки» и «перевод строки», в то время как Mac и Linux используют только один – «перевод строки». Это незначительный, но невероятно раздражающий факт кроссплатформенной работы; большинство редакторов в Windows молча заменяют переносы строк вида LF на CRLF или вставляют оба символа, когда пользователь нажимает клавишу Enter.
Git может автоматически конвертировать переносы строк CRLF в LF при добавлении файла в индекс и наоборот – при извлечении кода. Такое поведение можно включить используя настройку core.autocrlf
. Если у вас Windows, то установите значение true
– при извлечении кода окончания строк LF будут преобразовываться в CRLF:
$ git config --global core.autocrlf true
Если у вас система Linux или Mac, то вам не нужно автоматически конвертировать переносы строк при извлечении файлов; однако, если файл с окончаниями строк CRLF случайно попал в репозиторий, то Git может его исправить. Можно указать Git конвертировать CRLF в LF во время коммита, но не наоборот, установив настройке core.autocrlf
значение input
:
$ git config --global core.autocrlf input
Такая конфигурация позволит вам использовать переносы строк CRLF в Windows, при этом в репозитории и системах Mac и linux будет использован LF.
Если вы используете Windows и программируете только для Windows, то вы можете отключить описанный функционал, задав значение false
, сохраняя при этом символы CR в репозитории:
$ git config --global core.autocrlf false
core.whitespace
Git поставляется настроенным на обнаружение и исправление некоторых проблем с пробелами. Он в состоянии найти шесть основных проблем, обнаружение трёх из них включено по умолчанию, а трёх других – выключено.
По умолчанию включены:
blank-at-eol
ищет пробелы в конце строки;blank-at-eof
ищет пробелы в конце файла;space-before-tab
ищет пробелы перед символом табуляции в начале строки.
По умолчанию выключены:
indent-with-non-tab
ищет строки с пробелами вначале вместо символа табуляции (и контролируется настройкойtabwidth
);tab-in-indent
ищет символы табуляции в отступах в начале строки;cr-at-eol
указывает Git на валидность наличия CR в конце строки.
Указав через запятую значения для настройки core.whitespace
, можно сказать Git, какие из этих опций должны быть включены. Чтобы отключить ненужные проверки, достаточно удалить их из строки значений или поставить знак -
перед каждой из них. Например, чтобы включить все проверки, кроме space-before-tab
, выполните команду (при этом trailing-space
является сокращением и охватывает как blank-at-eol
, так и blank-at-eof
):
$ git config --global core.whitespace \
trailing-space,-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
Или можно указать только часть проверок:
$ git config --global core.whitespace \
-space-before-tab,indent-with-non-tab,tab-in-indent,cr-at-eol
Git будет искать указанные проблемы при выполнении команды git diff
и пытаться подсветить их, чтобы вы могли исправить их перед коммитом. Также эти значения будут использоваться во время применения патчей командой git apply
. При применении патчей, можно явно указать Git информировать вас в случае нахождения проблем с пробелами:
$ git apply --whitespace=warn <patch>
Так же можно указать Git автоматически исправлять эти проблемы перед применением патча:
$ git apply --whitespace=fix <patch>
Эти настройки также применяются при выполнении команды git rebase
. Если проблемные пробелы попали в коммит, но ещё не отправлены в удалённую ветку, можно выполнить git rebase --whitespace=fix
для автоматического исправления этих проблем.
Конфигурация сервера
Для серверной части Git не так много настроек, но есть несколько интересных, на которые стоит обратить внимание.
receive.fsckObjects
Git способен убедиться, что каждый объект, отправленный командой push
, валиден и соответствует своему хешу SHA-1. По умолчанию эта функция отключена; это очень дорогая операция и может привести к существенному замедлению, особенно для больших объёмов отправляемых данных или для больших репозиториев. Вы можете включить проверку целостности объектов для каждой операции отправки, установив значение receive.fsckObjects
в true
:
$ git config --system receive.fsckObjects true
Теперь, Git будет проверять целостность репозитория до принятия новых данных для уверенности, что неисправные или злонамеренные клиенты не смогут отправить повреждённые данные.
receive.denyNonFastForwards
Если вы перебазируете коммиты, которые уже отправлены, и попытаетесь отправить их снова или попытаетесь отправить коммит в удалённую ветку, в которой не содержится коммит, на который она указывает, то данные приняты не будут. В принципе, это правильная политика; но в случае перебазирования вы знаете, что делаете и можете принудительно обновить удалённую ветку, используя флаг -f
для команды push
.
Для запрета перезаписи истории установите receive.denyNonFastForwards
в значение true
:
$ git config --system receive.denyNonFastForwards true
Сделать то же самое можно другим способом – используя хук на стороне сервера, мы рассмотрим его немного позже. Этот подход позволяет более гибко настроить ограничения: например, запретить перезапись истории определённой группе пользователей.
receive.denyDeletes
Политику denyNonFastForwards
можно обойти, удалив ветку и создав новую с таким же именем. Для предотвращения этого, установите receive.denyDeletes
в значение true
:
$ git config --system receive.denyDeletes true
Эта команда запретит удаление веток и тегов всем пользователям. Чтобы удалить ветку, придётся удалить все соответствующие ей файлы на сервере вручную. Куда более интересный способ – это настроить права пользователей, с ним вы познакомитесь в разделе «Пример принудительной политики Git».