On this page
Package hooks discovers and executes pre-pre-push hooks that run before any network I/O, solving the SSH timeout problem when checks are long-running.
#internal/hooks
#internal/hooks
Package hooks discovers and executes pre-pre-push hooks that run before any network I/O, solving the SSH timeout problem when checks are long-running.
#HookResult
type HookResult structHookResult holds the outcome of running a single hook.
#SetOutput
func SetOutput(out, err io.Writer) func()SetOutput overrides the package-level stdout and stderr writers. Returns a restore function that resets them to their previous values.
#Discover
func Discover(gitDir string) ([]string, error)Discover finds pre-pre-push hooks in .git/hooks/. Returns executable hook paths in execution order:
- .git/hooks/pre-pre-push (single file)
- .git/hooks/pre-pre-push.d/* (lexical order, skip dot-prefixed and tilde-suffixed)
#DiscoverMulti
func DiscoverMulti(gitDirs []string) ([]string, error)DiscoverMulti discovers hooks across multiple git directories, concatenating results in order. The first gitDir's hooks come first. This supports hook cascading from parent repos into submodule pushes.
#Run
func Run(ctx context.Context, gitDir string, stdin []byte, timeoutSec int, env []string) ([]HookResult, error)Run executes all discovered hooks sequentially with the given stdin. On non-zero exit, remaining hooks are skipped. On timeout: SIGTERM, 5s grace, SIGKILL.
#RunAll
func RunAll(ctx context.Context, hookPaths []string, stdin []byte, timeoutSec int, env []string) ([]HookResult, error)RunAll executes the given hook paths sequentially with the given stdin. On non-zero exit, remaining hooks are skipped. On timeout: SIGTERM, 5s grace, SIGKILL.
#RunSingle
func RunSingle(ctx context.Context, hookPath string, stdin []byte, timeoutSec int, env []string) HookResultRunSingle executes a single hook by path.
#PlanInstall
func PlanInstall(gitDir, srcPath string) (data []byte, dest string, err error)PlanInstall reads the hook source and resolves the destination path, without mutating anything. Callers mint the mkdir/write/chmod themselves so a dry run can record the install instead of performing it.
#Install
func Install(gitDir, srcPath string) errorInstall copies a hook file to .git/hooks/ and makes it executable.
#InstallPlaceholder
func InstallPlaceholder(gitDir string) errorInstallPlaceholder writes a no-op pre-pre-push hook if one doesn't already exist.