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 в портативному профілі командної оболонки Git.

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. Якщо трапилось так, що у вас є багато проектів з файлами великого розміру та однакового вмісту, цю змінну можна використати, щоб уникнути зберігання численних копій таких файлів.

Специфікації файлів

Специфікації шляхів (pathspecs) визначають, як задаються шляхи до різноманітних компонентів 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 зазвичай робиться за допомогою git-commit-tree, яка використовує наступні змінні середовища, як основне джерело інформації, і повертається до значень змінних загальносистемних налаштувань тільки в тому випадку, коли ці змінні не задано.

GIT_AUTHOR_NAME — це сприйнятне для людини ім’я в полі “author”.

GIT_AUTHOR_EMAIL — це адреса електронної пошти поля “author”.

GIT_AUTHOR_DATE — це часова мітка коміту використана полем “author”.

GIT_COMMITTER_NAME задає сприйнятне для людини ім’я в полі “committer”.

GIT_COMMITTER_EMAIL — це адреса електронної пошти поля “committer”.

GIT_COMMITTER_DATE використовується для часової мітки в полі “committer”.

EMAIL — це запасна адреса електронної пошти для випадку, коли значення user.email в налаштуваннях не задано. Якщо цю запасну адресу не задано, то Git використовує системні ім’я користувача та мережеве ім’я комп’ютера.

Мережа

Git використовує бібліотеку curl для мережевих операцій через HTTP, отже GIT_CURL_VERBOSE вказує Git показувати всі повідомлення, які генеруються цією бібліотекою. Це схоже на старт curl -v в командному рядку.

GIT_SSL_NO_VERIFY вказує Git не перевіряти сертифікати SSL. Це може бути необхідно, якщо ви використовуєте самостійно підписаний сертифікат для обслуговування сховищ Git через HTTPS, або ви знаходитесь якраз в процесі налаштування сервера Git, але ще не встановили повноцінний сертифікат.

Якщо швидкість передачі даних деякої операції через HTTP нижча, ніж GIT_HTTP_LOW_SPEED_LIMIT байтів за секунду впродовж більш ніж GIT_HTTP_LOW_SPEED_TIME секунд, то Git скасує цю операцію. Ці значення перекривають значення налаштувань http.lowSpeedLimit та http.lowSpeedTime.

GIT_HTTP_USER_AGENT задає текстовий рядок User-Agent, який використовує Git під час мережевого спілкування через 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-файлів. Перше поле — це 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.

$ 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 [username@]host [-p <port>] <command>. Зверніть увагу, що це не найпростіший спосіб пристосувати виклик ssh; додаткові параметри командного рядка в цьому випадку не підтримуються, отже вам доведеться написати також скрипт-обгортку і встановити значення змінної GIT_SSH, що вказуватиме на цей скрипт. Простіше, напевно, використовувати файл ~/.ssh/config для цього.

GIT_ASKPASS — це переозначення змінної core.askpass в налаштуваннях. Це програма, що викликається щоразу, коли Git потрібно запитати в користувача облікові дані, та яка може очікувати на текстовий запит, як аргумент командного рядка, і повинна повернути відповідь в стандартний потік stdout. (Див. Збереження посвідчення (credential), щоб дізнатись докладніше про цю підсистему.)

GIT_NAMESPACE контролює доступ до посилань просторів імен, і еквівалентна параметру --namespace. Це в основному корисно на стороні сервера, де ви, можливо, захочете зберігати кілька форків єдиного сховища в одному сховищі, зберігаючи тільки окремо посилання на них.

GIT_FLUSH може використовуватись, щоб змусити Git вживати небуферизоване введення/виведення під час інкрементного запису в стандартний потік stdout. Значення 1 змушує Git очищувати буфер частіше, а для значення 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