Git
Chapters ▾ 2nd Edition

10.8 Git изнутри - Переменные окружения

Переменные окружения

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

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

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

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

HOME обычно не рассматривается в качестве изменяемого параметра (чересчур много вещей от него зависят), но именно тут Git ищет глобальный файл конфигурации. Если вам нужна по-настоящему портируемая версия 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-dir, но ничего из --work-tree, GIT_WORK_TREE или core.worktree не задано, то текущая директория будет считаться корневой.

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