Help us shape the future of Go! Take the 2026 Go Developer Survey

gitenv

package
v1.16.0 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 4 Imported by: 2

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