26f897c1ec
release / release-please (push) Failing after 1m49s
docs / build (push) Failing after 6m34s
release / build-and-upload (arm64, linux) (push) Has been cancelled
release / build-and-upload (arm64, windows) (push) Has been cancelled
release / build-darwin (amd64, darwin) (push) Has been cancelled
release / checksums (push) Has been cancelled
release / finalize (push) Has been cancelled
release / build-darwin (arm64, darwin) (push) Has been cancelled
release / build-and-upload (amd64, linux) (push) Has been cancelled
release / build-and-upload (amd64, windows) (push) Has been cancelled
docs / deploy (push) Has been cancelled
49 lines
2.1 KiB
Go
49 lines
2.1 KiB
Go
package git
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
)
|
|
|
|
// NonInteractiveEnv returns the environment for a subprocess that may invoke
|
|
// git, with git forced into a fully non-interactive mode. It is intended for
|
|
// cmd.Env on any subprocess that may run git (our own git calls and the coding
|
|
// agents we spawn).
|
|
//
|
|
// Without these overrides, git operations such as `git rebase --continue` or
|
|
// `git commit` open $EDITOR to confirm a commit message, and remote operations
|
|
// can block on a credential prompt. In a headless agent subprocess there is no
|
|
// TTY, so the editor or prompt hangs until the agent times out. Pointing the
|
|
// editors at `true` makes git accept the existing message immediately, and
|
|
// GIT_TERMINAL_PROMPT=0 fails fast instead of blocking on credentials. The
|
|
// overrides are appended last so they win over any ambient values (exec
|
|
// resolves duplicate keys using the last occurrence).
|
|
//
|
|
// Pass the same directory assigned to cmd.Dir (or "" when it is unset). When
|
|
// cmd.Env is left nil, os/exec injects PWD=cmd.Dir automatically; assigning
|
|
// cmd.Env disables that, so callers must thread the working directory through
|
|
// here to preserve symlinked working-directory paths (for example /tmp vs
|
|
// /private/tmp on macOS, which os.Getwd reports differently depending on PWD).
|
|
func NonInteractiveEnv(dir string) []string {
|
|
env := append(os.Environ(),
|
|
"GIT_EDITOR=true",
|
|
"GIT_SEQUENCE_EDITOR=true",
|
|
"GIT_TERMINAL_PROMPT=0",
|
|
)
|
|
// Mirror os/exec, which only injects PWD when Cmd.Env is nil, skips it on
|
|
// these platforms, and absolutizes Cmd.Dir first (go.dev/issue/50599):
|
|
// POSIX defines PWD as "an absolute pathname of the current working
|
|
// directory". Injecting a relative dir verbatim (for example ".") poisons
|
|
// every descendant that trusts PWD — macOS /bin/sh is bash 3.2, whose pwd
|
|
// builtin reports "." when PWD="." leaks through git receive-pack into a
|
|
// hook, which is how the post-receive hook of issue #269 ended up passing
|
|
// `--gate .`.
|
|
if dir != "" && runtime.GOOS != "windows" && runtime.GOOS != "plan9" {
|
|
if abs, err := filepath.Abs(dir); err == nil {
|
|
env = append(env, "PWD="+abs)
|
|
}
|
|
}
|
|
return env
|
|
}
|