tailscale/tailscale · error
getting git hash: %w
Error message
getting git hash: %w
What it means
You are in a repo whose module path is not tailscale.com, so mkversion treats it as a repo that imports tailscale.com and records its commit hash (OtherHash) via `git rev-parse HEAD`. This error means that command failed in your repo - classically because HEAD is unborn (the repo was `git init`ed but has zero commits) or points at a missing/corrupt ref.
Source
Thrown at version/mkversion/mkversion.go:149
if modPath == "" {
return VersionInfo{}, fmt.Errorf("no module path in go.mod")
}
if modPath == "tailscale.com" {
// Invoked in the tailscale.com repo directly, just no further info to
// collect.
v, err := infoFromDir(gitRoot)
if err != nil {
return VersionInfo{}, err
}
return mkOutput(v)
}
// We seem to be in a repo that imports tailscale.com. Find the
// tailscale.com repo and collect additional info from it.
otherHash, err := runner.output("git", "rev-parse", "HEAD")
if err != nil {
return VersionInfo{}, fmt.Errorf("getting git hash: %w", err)
}
otherDate, err := runner.output("git", "log", "-n1", "--format=%ct", "HEAD")
if err != nil {
return VersionInfo{}, fmt.Errorf("getting git date: %w", err)
}
// Note, this mechanism doesn't correctly support go.mod replacements,
// or go workdirs. We only parse out the commit ref from go.mod's
// "require" line, nothing else.
tailscaleRef, err := tailscaleModuleRef(modBs)
if err != nil {
return VersionInfo{}, err
}
v, err := infoFromCache(tailscaleRef, runner)
if err != nil {
return VersionInfo{}, err
}View on GitHub (pinned to 6e0912f979)
Solutions
- Create at least one commit (`git commit --allow-empty -m init`) so HEAD resolves
- Reproduce manually with `git rev-parse HEAD` in the repo root to see git's exact complaint
- If the ref is broken, check `git fsck` and reset HEAD to a valid branch/commit
Example fix
# before $ git rev-parse HEAD fatal: ambiguous argument 'HEAD': unknown revision # after $ git add -A && git commit -m 'first commit' $ git rev-parse HEAD 9ae23b5...
Defensive patterns
Strategy: validation
Validate before calling
// Require a resolvable HEAD before version collection.
if err := exec.Command("git", "-C", dir, "rev-parse", "--verify", "HEAD").Run(); err != nil {
return fmt.Errorf("repo has no commits; commit before building: %w", err)
}
v, err := mkversion.InfoFrom(dir) Type guard
func isGitHashError(err error) bool {
return err != nil && strings.Contains(err.Error(), "getting git hash:")
} Try / catch
v, err := mkversion.InfoFrom(dir)
if err != nil {
if isGitHashError(err) {
return fmt.Errorf("make an initial commit, then rebuild: %w", err)
}
return err
} Prevention
- Commit before building in fresh repos (CI: fail fast if `git rev-parse HEAD` errors)
- Avoid building from repos in a detached/corrupt ref state
When it happens
Trigger: InfoFrom run in a freshly initialized repo with no commits ('fatal: your current branch 'main' does not have any commits yet'), a detached HEAD pointing to a pruned ref, or a corrupted object database.
Common situations: CI pipelines that build an experimental repo before its first commit; local scratch repos that import tailscale.com; aggressively pruned/gc'd clones.
Related errors
- getting git date: %w
- finding git root: %w
- Could not parse otherDate %q: %w
- cloning tailscale.com repo failed
- updating OSS repo failed
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/4e77700e6f1ebe0f.
Report an issue: GitHub.