Git
Chapters ▾ 2nd Edition

10.8 Git изнутри - Переменные среды

Переменные среды

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

Глобальное поведение

Поведение Git как компьютерной программы зависит от параметров среды.

GIT_EXEC_PATH определяет где Git будет искать свои подпрограммы Текущие настройки можно узнать командой git --exec-path.

HOME обычно не рассматривается в качестве изменяемого параметра (чересчур много вещей от него зависят), но именно тут Git ищет глобальный файл конфигурации. Если вам нужна по-настоящему portable-версия Git с собственной глобальной конфигурацией, можете переопределить HOME в shell профиле.

PREFIX аналогичная константа, но для общесистемной конфигурации. Git ищет этот файл в $PREFIX/etc/gitconfig.

GIT_CONFIG_NOSYSTEM, если задана, отключает использование файла общесистемной конфигурации. Это пригодится, если ваша системная конфигурация мешает вашим командам, а прав на её редактирование или удаление у вас нет.

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

GIT_EDITOR это редактор, который Git запустит, когда пользователю понадобится отредактировать какой-нибудь текст (например, сообщение коммита). Если не задана, откроется EDITOR.

Расположение репозитория

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

GIT_DIR — это месторасположение директории .git. Если эта переменная не задана, Git будет переходить вверх по дереву директорий, пока не достигнет ~ (домашней директории пользователя) или / (корневой директории), проверяя на каждом шагу наличие директории .git.

GIT_CEILING_DIRECTORIES управляет процессом поиска директории .git. Если вы работаете с медленной файловой системой (типа ленточного накопителя или сетевой папки), вы можете запретить Git доступ к .git без надобности, например, для построения строки приветствия.

GIT_WORK_TREE — это путь к рабочей директории для не-серверного репозитория (с непустой рабочей директорией). Если эта переменная не задана, будет использована родительская директория $GIT_DIR.

GIT_INDEX_FILE — это путь к файлу индекса (только для репозиториев с непустой рабочей директорией).

GIT_OBJECT_DIRECTORY может быть использована для указания директории с объектами вместо .git/objects.

GIT_ALTERNATE_OBJECT_DIRECTORIES — это список разделённых двоеточием директорий (типа /dir/one:/dir/two:…), в которых Git будет пытаться найти объекты, которых нет в GIT_OBJECT_DIRECTORY. Это может быть полезным, если вы работаете над несколькими проектами с одинаковым содержимым, чтобы не дублировать файлы.

Пути к файлам

Эти переменные влияют на то, как Git будет понимать пути к файлам и шаблоны путей. Эти настройки применяются к записям в файлах .gitignore и к путям, переданным в командной строке (git add *.c).

GIT_GLOB_PATHSPECS и GIT_NOGLOB_PATHSPECS управляют поведением шаблонов путей к файлам. Если переменная GIT_GLOB_PATHSPECS установлена в 1, то специальные символы интерпретируются стандартным для шаблонов способом; если же GIT_NOGLOB_PATHSPECS установлена в 1, то специальные символы обрабатываются буквально, это означает, что, например, запись *.c будет обозначать лишь единственный файл с именем "*.c", а не все файлы с расширением ".c". Это поведение можно переопределить в каждом конкретном случае, приписывая к путям строки :(glob) или :(literal), например :(glob)*.c.

GIT_LITERAL_PATHSPECS отключает шаблоны в путях: ни специальные символы, ни специальные префиксы не будут работать.

GIT_ICASE_PATHSPECS делает все пути регистронезависимыми.

Фиксация изменений

Окончательное создание объекта-коммита обычно производится командой git-commit-tree, которая использует приведённые ниже переменные окружения в качестве источника информации. И лишь в случае, если эти переменные не заданы, она будет использовать данные из файлов конфигурации.

GIT_AUTHOR_NAME используется для указания автора коммита.

GIT_AUTHOR_EMAIL задаёт адрес электронной почты автора коммита.

GIT_AUTHOR_DATE время создания коммита.

GIT_COMMITTER_NAME используется для указания человека, применившего коммит.

GIT_COMMITTER_EMAIL задаёт адрес электронной почты человека, применившего коммит.

GIT_COMMITTER_DATE время применения коммита.

EMAIL используется, как запасное значение, если конфигурационный параметр user.email не задан. Если же и эта переменная не задана, Git будет использовать идентификатор пользователя в системе и имя хоста.

Работа с сетью

Git использует библиотеку curl для работы с сетью через HTTP. Задание переменной GIT_CURL_VERBOSE указывает Git’у выводить все сообщения, генерируемые этой библиотекой. Это похоже на использование curl с флагом -v в командной строке.

GIT_SSL_NO_VERIFY отключает проверку SSL сертификатов. Это может пригодиться если вы используете самоподписанные сертификаты для работы репозиториев через HTTPS, или если вы настраиваете Git сервер и ещё не установили необходимые сертификаты.

Если на протяжении более чем GIT_HTTP_LOW_SPEED_TIME секунд скорость передачи данных не поднималась выше GIT_HTTP_LOW_SPEED_LIMIT байт в секунду, Git прервёт операцию. Эти переменные замещают значения конфигурационных параметров http.lowSpeedLimit и http.lowSpeedTime.

GIT_HTTP_USER_AGENT задаёт заголовок User-Agent при работе через HTTP. По умолчанию используется что-то вроде git/2.0.0.

Сравнение файлов и слияния

GIT_DIFF_OPTS — слегка громкое название для этой переменной. Единственными допустимыми значениями являются -u<n> и --unified=<n>, задающие количество контекстных строк, показываемых командой git diff.

GIT_EXTERNAL_DIFF замещает конфигурационный параметр diff.external. Если значение задано, Git вызовет указанную программу вместо git diff.

GIT_DIFF_PATH_COUNTER и GIT_DIFF_PATH_TOTAL используются внутри программы, заданной через GIT_EXTERNAL_DIFF или diff.external. Первая содержит порядковый номер сравниваемого на данный момент файла (начиная с 1), вторая — полное количество файлов, подлежащих сравнению.

GIT_MERGE_VERBOSITY задаёт уровень детализированности вывода при рекурсивном слиянии. Возможные значения перечислены ниже:

  • 0 не выводить ничего, кроме единственного сообщения об ошибке..

  • 1 выводить только конфликты.

  • 2 также выводить изменения файлов.

  • 3 показывать пропущенные неизменённые файлы.

  • 4 выводить все пути при обработке.

  • 5 и выше выводят даже отладочную информацию.

По умолчанию значение полагается равным 2.

Отладка

Хотите знать что на самом деле делает Git? Git ведёт достаточно подробный лог выполняемых действий и всё что вам нужно — включить его. Возможные значения приведённых ниже переменных следующие:

  • "true", "1", или "2" – вывод осуществляется в стандартный поток ошибок (stderr).

  • Абсолютный путь, начинающийся с / – вывод будет производиться в указанный файл.

GIT_TRACE задаёт журналирование действий, не подпадающий под какую-либо определённую категорию. Это включает в себя разворачивание алиасов и вызовы внешних программ.

$ GIT_TRACE=true git lga
20:12:49.877982 git.c:554               trace: exec: 'git-lga'
20:12:49.878369 run-command.c:341       trace: run_command: 'git-lga'
20:12:49.879529 git.c:282               trace: alias expansion: lga => 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.879885 git.c:349               trace: built-in: git 'log' '--graph' '--pretty=oneline' '--abbrev-commit' '--decorate' '--all'
20:12:49.899217 run-command.c:341       trace: run_command: 'less'
20:12:49.899675 run-command.c:192       trace: exec: 'less'

GIT_TRACE_PACK_ACCESS задаёт журналирование обращений к pack-файлам. При этом первое выводимое значение – файл, к которому происходит обращение, а второе значение – смещение внутри этого файла.

$ GIT_TRACE_PACK_ACCESS=true git status
20:10:12.081397 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 12
20:10:12.081886 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 34662
20:10:12.082115 sha1_file.c:2088        .git/objects/pack/pack-c3fa...291e.pack 35175
# […]
20:10:12.087398 sha1_file.c:2088        .git/objects/pack/pack-e80e...e3d2.pack 56914983
20:10:12.087419 sha1_file.c:2088        .git/objects/pack/pack-e80e...e3d2.pack 14303666
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

GIT_TRACE_PACKET задаёт журналирование пакетов при операциях с сетью.

$ GIT_TRACE_PACKET=true git ls-remote origin
20:15:14.867043 pkt-line.c:46           packet:          git< # service=git-upload-pack
20:15:14.867071 pkt-line.c:46           packet:          git< 0000
20:15:14.867079 pkt-line.c:46           packet:          git< 97b8860c071898d9e162678ea1035a8ced2f8b1f HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2.0.4
20:15:14.867088 pkt-line.c:46           packet:          git< 0f20ae29889d61f2e93ae00fd34f1cdb53285702 refs/heads/ab/add-interactive-show-diff-func-name
20:15:14.867094 pkt-line.c:46           packet:          git< 36dc827bc9d17f80ed4f326de21247a5d1341fbc refs/heads/ah/doc-gitk-config
# […]

GIT_TRACE_PERFORMANCE задаёт журналирование данных о производительности. Вывод показывает, как долго выполнялись те или иные действия.

$ GIT_TRACE_PERFORMANCE=true git gc
20:18:19.499676 trace.c:414             performance: 0.374835000 s: git command: 'git' 'pack-refs' '--all' '--prune'
20:18:19.845585 trace.c:414             performance: 0.343020000 s: git command: 'git' 'reflog' 'expire' '--all'
Counting objects: 170994, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (43413/43413), done.
Writing objects: 100% (170994/170994), done.
Total 170994 (delta 126176), reused 170524 (delta 125706)
20:18:23.567927 trace.c:414             performance: 3.715349000 s: git command: 'git' 'pack-objects' '--keep-true-parents' '--honor-pack-keep' '--non-empty' '--all' '--reflog' '--unpack-unreachable=2.weeks.ago' '--local' '--delta-base-offset' '.git/objects/pack/.tmp-49190-pack'
20:18:23.584728 trace.c:414             performance: 0.000910000 s: git command: 'git' 'prune-packed'
20:18:23.605218 trace.c:414             performance: 0.017972000 s: git command: 'git' 'update-server-info'
20:18:23.606342 trace.c:414             performance: 3.756312000 s: git command: 'git' 'repack' '-d' '-l' '-A' '--unpack-unreachable=2.weeks.ago'
Checking connectivity: 170994, done.
20:18:25.225424 trace.c:414             performance: 1.616423000 s: git command: 'git' 'prune' '--expire' '2.weeks.ago'
20:18:25.232403 trace.c:414             performance: 0.001051000 s: git command: 'git' 'rerere' 'gc'
20:18:25.233159 trace.c:414             performance: 6.112217000 s: git command: 'git' 'gc'

GIT_TRACE_SETUP задаёт журналирование информации о репозитории и окружении, в котором выполняется сам Git.

$ GIT_TRACE_SETUP=true git status
20:19:47.086765 trace.c:315             setup: git_dir: .git
20:19:47.087184 trace.c:316             setup: worktree: /Users/ben/src/git
20:19:47.087191 trace.c:317             setup: cwd: /Users/ben/src/git
20:19:47.087194 trace.c:318             setup: prefix: (null)
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Разное

GIT_SSH – указанная программа (если значение задано) будет использоваться вместо ssh когда Git работает по SSH протоколу. Порядок вызова этой программы будет таков: $GIT_SSH [имя пользователя@]хост [-p <порт>] <команда>. На самом деле, это не самый простой способ настроить поведение ssh: дополнительные параметры командной строки не поддерживаются, и вам, скорее всего, придётся писать скрипт-обёртку и указать GIT_SSH на него. Возможно, проще будет использовать ~/.ssh/config.

GIT_ASKPASS заменяет значение конфигурационного параметра core.askpass. Это программа вызывается Git’ом каждый раз, когда требуется запросить у пользователя пароль. Строка с текстом запроса передаётся этой программе в качестве аргумента командной строки, а вывод значения она должна осуществлять в стандартный поток вывода (stdout). (Читайте подробнее в главе Хранилище учетных данных.)

GIT_NAMESPACE управляет доступом к ссылкам внутри пространств имён аналогично параметру --namespace. Чаще всего эта переменная используется на стороне сервера когда вы хотите хранить несколько форков одного репозитория, разделяя лишь ссылки.

GIT_FLUSH заставляет Git отключить буферизацию при записи в стандартный поток вывода (stdout). Git будет чаще сбрасывать данные на диск если значение выставлено в 1, если же оно равно 0, весь вывод будет буферизоваться. Значение, используемое по умолчанию (если ничего не задано) выбирается в зависимости от выполняемых действий и способа вывода данных.

GIT_REFLOG_ACTION задаёт подробное описание, записываемое в reflog. Например:

$ GIT_REFLOG_ACTION="my action" git commit --allow-empty -m 'my message'
[master 9e3d55a] my message
$ git reflog -1
9e3d55a HEAD@{0}: my action: my message