Class: Woods::GitProvenance

Inherits:
Object
  • Object
show all
Defined in:
lib/woods/git_provenance.rb

Overview

Resolves git provenance (branch + commit SHA) for the extracted codebase, correctly handling linked git worktrees where .git is a file containing a gitdir: pointer rather than a directory.

The reported failure (#137): in a worktree, .git points at a real git directory that may be an absolute host path. When extraction runs somewhere that path cannot be resolved — e.g. inside a container where the host path is not mounted — plain git rev-parse fails silently and the manifest used to fall back to a baked-in GIT_BRANCH/GIT_SHA build arg, reporting a stale, misleading branch.

Resolution precedence:

  1. git -C <root> rev-parse — independent of the process working directory, and resolves a worktree’s .git-file pointer when the target git directory is reachable. This covers normal checkouts and reachable worktrees.

  2. If that fails, #fallback decides:

    • A .git entry exists at the root but git couldn’t resolve the ref (an unmounted worktree gitdir, a corrupted repo): emit UNKNOWN. A working tree whose ref can’t be determined must not be papered over with a possibly-stale build arg — that is the #137 bug.

    • No .git at the root at all (a source tarball, or a Docker COPY that excludes .git), or no git binary: the GIT_BRANCH/GIT_SHA env vars are the only provenance signal, so honor them if set, else UNKNOWN.

Examples:

provenance = Woods::GitProvenance.new(root: Rails.root)
provenance.branch  # => "main" (or "unknown")
provenance.sha     # => "a1b2c3..." (or "unknown")

Constant Summary collapse

UNKNOWN =

Sentinel emitted when provenance cannot be determined, in preference to a stale or misleading fallback value.

'unknown'

Instance Method Summary collapse

Constructor Details

#initialize(root:, env: ENV) ⇒ GitProvenance

Returns a new instance of GitProvenance.

Parameters:

  • root (String, Pathname)

    repository root (typically Rails.root)

  • env (Hash) (defaults to: ENV)

    environment source (default ENV; overridable in specs)



42
43
44
45
# File 'lib/woods/git_provenance.rb', line 42

def initialize(root:, env: ENV)
  @root = root.to_s
  @env = env
end

Instance Method Details

#branchString

Returns current branch name, or UNKNOWN.

Returns:

  • (String)

    current branch name, or UNKNOWN



48
49
50
51
52
53
54
# File 'lib/woods/git_provenance.rb', line 48

def branch
  from_git = rev_parse('--abbrev-ref', 'HEAD')
  # 'HEAD' means detached — not a branch name.
  return from_git if present?(from_git) && from_git != 'HEAD'

  fallback('GIT_BRANCH')
end

#shaString

Returns current commit SHA, or UNKNOWN.

Returns:

  • (String)

    current commit SHA, or UNKNOWN



57
58
59
60
61
62
# File 'lib/woods/git_provenance.rb', line 57

def sha
  from_git = rev_parse('HEAD')
  return from_git if present?(from_git)

  fallback('GIT_SHA')
end

#to_hHash{Symbol => String}

Returns { git_branch:, git_sha: } for the manifest.

Returns:

  • (Hash{Symbol => String})

    { git_branch:, git_sha: } for the manifest



65
66
67
# File 'lib/woods/git_provenance.rb', line 65

def to_h
  { git_branch: branch, git_sha: sha }
end