gitenv

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package gitenv запускает git так, чтобы он работал с ТЕМ репозиторием, который назвал вызывающий, а не с тем, который назвали за него переменные окружения.

Предмет

git определяет репозиторий не только по рабочему каталогу. Если в окружении есть `GIT_DIR`, она **сильнее** рабочего каталога: `cmd.Dir = <свой каталог>` перестаёт что-либо значить, и команда работает с чужим репозиторием.

В этом дереве полтора десятка проб заводят синтетический репозиторий во временном каталоге (`git init` + `git add -A`), задавая рабочий каталог и полагаясь на то, что git определит репозиторий по нему. Допущение неверно ровно тогда, когда `go test` запущен из хука git: `git push` выставляет `GIT_DIR`, и его наследует всё, что хук запускает.

Цена измерена на дереве `release/console`, одни и те же пакеты (`./internal/repohygiene/... ./tools/...`):

                 индекс рабочей копии после   упавших пакетов
без GIT_DIR      6994 записи — цел                          0
с GIT_DIR        3 записи                                 119

Вместе с индексом в конфигурацию рабочей копии уезжали `user.name`, `user.email` и `core.bare=true` — записи фикстур, выглядевшие как чужое вмешательство в клон.

Почему следствие тихое

Падают не виновные пробы, а те, что читают состав дерева через `git ls-files` ([treecorpus]): они видят схлопнутый индекс и честно сообщают «прочитано ноль». Виновник не назван ни одной строкой вывода, а «ноль находок» превращается в «ноль прочитанного» — тот самый класс, ради различения которого эти гейты и написаны.

Граница, а не пожелание

Хук `scripts/hooks/pre-push` снимает те же переменные перед запуском проверок — это закрывает ТРИГГЕР. Пакет закрывает КЛАСС: любой другой запуск `go test` с выставленным `GIT_DIR` (из другого хука, из скрипта, из обёртки) повторил бы то же самое. Перечень переменных объявлен здесь один раз (Vars), и его совпадение с перечнем хука проверяется пробой — иначе получились бы два места об одном предмете, из которых верно одно.

Держится гейтом `internal/repohygiene` `TestGitCommandsRunWithScrubbedEnvironment`: прямой `exec.Command("git", …)` вне этого пакета — находка.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Command

func Command(dir string, args ...string) *exec.Cmd

Command собирает вызов git с рабочим каталогом dir и окружением Env.

Пустой dir означает рабочий каталог процесса — законный случай для команд, которые спрашивают про репозиторий, из которого запущен прогон (например `rev-parse HEAD` в измерителе). Отсутствие каталога здесь представимо отдельно от значения: пустая строка не является путём.

Дополнить окружение (подпись фикстуры, локаль) можно только ДОПИСЫВАНИЕМ:

cmd := gitenv.Command(dir, "commit", "-m", "x")
cmd.Env = append(cmd.Env, "GIT_AUTHOR_NAME=t")

Присваивание `cmd.Env = append(os.Environ(), …)` вернуло бы снятые переменные обратно — гейт `internal/repohygiene` это отдельно ловит.

func CommandContext

func CommandContext(ctx context.Context, dir string, args ...string) *exec.Cmd

CommandContext — то же, что Command, со сроком вызова.

func Env

func Env() []string

Env — окружение текущего процесса без переменных Vars.

func Scrub

func Scrub(env []string) []string

Scrub возвращает env без переменных Vars.

Вход не изменяется: вызывающий часто передаёт os.Environ(), и правка на месте молча меняла бы смысл соседних вызовов.

func Vars

func Vars() []string

Vars возвращает перечень снимаемых переменных — копию, чтобы вызывающий не мог изменить общий срез.

Экспортирован ради одного читателя: пробы, сверяющей этот перечень с тем, что снимает хук отправки. Прод-кода у него нет и быть не должно.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL