Documentation
¶
Overview ¶
Package gogit provides generic, dependency-light Git ergonomics by shelling out to the git CLI: repository discovery, commit-log parsing with trailers and change stats, and repository metadata (branch, origin URL).
It is the base layer for higher-level tools — the gitscan CLI (cmd/gitscan) and domain collectors such as OmniDevX — in the same way github.com/grokify/gogithub underlies GitHub integrations.
Index ¶
- Variables
- func Discover(roots []string, maxDepth int) ([]string, error)
- func IsRepo(path string) bool
- func NormalizeRemoteURL(remote string) string
- type AIAttribution
- type AICoAuthor
- type AIModel
- type AIStats
- type AIToolPattern
- type CategoryStats
- type Commit
- func (c Commit) AICoAuthors() []AICoAuthor
- func (c Commit) AICoAuthorsWithTools(tools []AIToolPattern) []AICoAuthor
- func (c Commit) CoAuthors() []Signature
- func (c Commit) IsAIAssisted() bool
- func (c Commit) ParseConventional() *ConventionalCommit
- func (c Commit) TrailerValue(key string) string
- func (c Commit) TrailerValues(key string) []string
- type CommitStatsOptions
- type ConventionalCommit
- type LogOptions
- type ModelStats
- type MultiRepoCommitStats
- type PendingResult
- type ProgressFunc
- type PushedResult
- type Repo
- func (r *Repo) Branch(ctx context.Context) (string, error)
- func (r *Repo) CollectCommitStats(ctx context.Context, opts CommitStatsOptions) (*RepoCommitStats, error)
- func (r *Repo) HasUpstream(ctx context.Context) (bool, error)
- func (r *Repo) Log(ctx context.Context, opts LogOptions) ([]Commit, error)
- func (r *Repo) OriginURL(ctx context.Context) (string, error)
- func (r *Repo) Path() string
- func (r *Repo) PendingCommits(ctx context.Context, sinceCommit string) (PendingResult, error)
- func (r *Repo) PushedCommits(ctx context.Context, limit int) (PushedResult, error)
- func (r *Repo) Tags(ctx context.Context) ([]string, error)
- func (r *Repo) TagsWithDates(ctx context.Context) (map[string]time.Time, error)
- type RepoCommitStats
- type RepoError
- type RepoResult
- type Signature
- type ToolStats
- type Trailer
Constants ¶
This section is empty.
Variables ¶
var DefaultAITools = []AIToolPattern{ { Name: "Claude Code", Provider: "anthropic", Emails: []string{"noreply@anthropic.com"}, ModelPattern: regexp.MustCompile(`(?i)^Claude\s+(\S+\s+[\d][\d.]*)$`), }, { Name: "GitHub Copilot", Provider: "github", Emails: []string{"noreply@github.com", "copilot@github.com"}, ModelPattern: nil, }, { Name: "Gemini CLI", Provider: "google", Emails: []string{ "218195315+gemini-cli@users.noreply.github.com", "176961590+gemini-code-assist[bot]@users.noreply.github.com", "gemini-cli-agent@google.com", "gemini@google.com", }, ModelPattern: regexp.MustCompile(`(?i)^gemini[-_]?cli\s+(.+)$`), }, { Name: "Cursor", Provider: "cursor", Emails: []string{"ai@cursor.sh", "cursor@cursor.sh"}, ModelPattern: regexp.MustCompile(`(?i)^Cursor\s+(.+)$`), }, { Name: "Aider", Provider: "aider", Emails: []string{"aider@aider.chat"}, ModelPattern: nil, }, }
DefaultAITools is the canonical, built-in registry of AI coding assistants and their co-author signatures. Consumers should use MatchAITool or Commit.AICoAuthors rather than maintaining separate lists.
Functions ¶
func Discover ¶
Discover walks each root up to maxDepth directory levels (1 = direct children) and returns paths that are git repositories. Discovery does not descend into repositories, so nested checkouts and vendored trees are not double-counted.
func NormalizeRemoteURL ¶
NormalizeRemoteURL converts a git remote URL to a canonical host/path repository identifier:
https://github.com/x/y.git → github.com/x/y git@github.com:x/y.git → github.com/x/y ssh://git@github.com/x/y → github.com/x/y ssh://git@github.com:2222/x/y → github.com/x/y
An empty input returns "".
Types ¶
type AIAttribution ¶ added in v0.6.0
type AIAttribution struct {
IsAIAuthored bool `json:"isAiAuthored"`
Tools []string `json:"tools,omitempty"`
Models []AIModel `json:"models,omitempty"`
HumanAuthors []Signature `json:"humanAuthors,omitempty"`
}
AIAttribution holds the result of analyzing a commit for AI authorship.
func AnalyzeAuthorship ¶ added in v0.6.0
func AnalyzeAuthorship(c Commit) AIAttribution
AnalyzeAuthorship examines a commit's co-author trailers and returns a complete attribution breakdown: which AI tools contributed, what models were used, and which human co-authors were present. AI tools and models are recognized via the canonical registry in DefaultAITools.
Examples:
"Claude Sonnet 5 <noreply@anthropic.com>" → Tools: ["Claude Code"], Models: [{Provider: "anthropic", Model: "Sonnet 5"}]
"Claude Code <noreply@anthropic.com>" → Tools: ["Claude Code"], Models: nil (no version in name)
"github-actions[bot] <noreply@github.com>" → Tools: ["GitHub Copilot"], Models: nil
type AICoAuthor ¶ added in v0.7.0
type AICoAuthor struct {
Signature Signature `json:"signature"`
Tool string `json:"tool"` // e.g., "Claude Code", "GitHub Copilot", "Gemini CLI"
Provider string `json:"provider,omitempty"` // canonical provider slug, e.g. "anthropic"
Model string `json:"model,omitempty"` // e.g., "Sonnet 4", "Opus 4", "gemini-2.5-pro"
}
AICoAuthor represents an AI coding assistant identified from a co-author trailer.
func MatchAITool ¶ added in v0.7.0
func MatchAITool(sig Signature, tools []AIToolPattern) *AICoAuthor
MatchAITool checks if the email matches a known AI tool and extracts the model from the name if a pattern is defined.
type AIModel ¶ added in v0.6.0
type AIModel struct {
Provider string `json:"provider"`
Model string `json:"model"`
Name string `json:"name"`
}
AIModel holds a parsed AI model identity from a co-author trailer.
type AIStats ¶ added in v0.7.0
type AIStats struct {
TotalCommits int `json:"totalCommits"`
AIAssistedCount int `json:"aiAssistedCount"`
AIAssistedPct float64 `json:"aiAssistedPct"`
ByTool map[string]ToolStats `json:"byTool,omitempty"`
ByModel map[string]ModelStats `json:"byModel,omitempty"`
}
AIStats holds AI-assisted commit statistics.
type AIToolPattern ¶ added in v0.7.0
type AIToolPattern struct {
Name string // Display name, e.g., "Claude Code"
Provider string // Canonical provider slug, e.g. "anthropic"
Emails []string // Known email addresses (lowercase)
ModelPattern *regexp.Regexp
}
AIToolPattern defines how to recognize an AI tool from co-author email and extract model version from the name.
type CategoryStats ¶ added in v0.7.0
type CategoryStats struct {
Category string `json:"category"`
Commits int `json:"commits"`
Insertions int `json:"insertions"`
Deletions int `json:"deletions"`
}
CategoryStats holds commit and LOC counts for one conventional-commit category.
func (CategoryStats) NetAdditions ¶ added in v0.7.0
func (s CategoryStats) NetAdditions() int
NetAdditions returns insertions minus deletions.
type Commit ¶
type Commit struct {
Hash string `json:"hash"`
Author Signature `json:"author"`
AuthorDate time.Time `json:"authorDate"`
Committer Signature `json:"committer"`
CommitDate time.Time `json:"commitDate"`
Subject string `json:"subject"`
Trailers []Trailer `json:"trailers,omitempty"`
Insertions int `json:"insertions"`
Deletions int `json:"deletions"`
FilesChanged int `json:"filesChanged"`
}
Commit is one parsed log entry. Bodies are not extracted — subjects and trailers cover attribution and classification needs; consumers that need full messages can run git directly.
func (Commit) AICoAuthors ¶ added in v0.7.0
func (c Commit) AICoAuthors() []AICoAuthor
AICoAuthors returns AI coding assistants identified from co-author trailers. Uses DefaultAITools for recognition.
func (Commit) AICoAuthorsWithTools ¶ added in v0.7.0
func (c Commit) AICoAuthorsWithTools(tools []AIToolPattern) []AICoAuthor
AICoAuthorsWithTools returns AI coding assistants using a custom tool registry.
func (Commit) IsAIAssisted ¶ added in v0.7.0
IsAIAssisted returns true if any co-author is a recognized AI tool.
func (Commit) ParseConventional ¶ added in v0.6.0
func (c Commit) ParseConventional() *ConventionalCommit
ParseConventional parses this commit's subject as a conventional commit. Returns nil if the subject does not match.
func (Commit) TrailerValue ¶ added in v0.6.0
TrailerValue returns the first trailer value matching the given key (case-insensitive), or "" if not found.
func (Commit) TrailerValues ¶ added in v0.6.0
TrailerValues returns all trailer values matching the given key (case-insensitive).
type CommitStatsOptions ¶ added in v0.7.0
type CommitStatsOptions struct {
// Since and Until bound the commit date range (inclusive).
Since time.Time
Until time.Time
// NoMerges excludes merge commits from statistics.
NoMerges bool
// Author filters commits by author (git regex).
Author string
}
CommitStatsOptions configures commit statistics collection.
type ConventionalCommit ¶ added in v0.6.0
type ConventionalCommit struct {
Type string `json:"type"`
Scope string `json:"scope,omitempty"`
Breaking bool `json:"breaking"`
Subject string `json:"subject"`
}
ConventionalCommit holds parsed conventional commit components.
func ParseConventionalCommit ¶ added in v0.6.0
func ParseConventionalCommit(subject string) *ConventionalCommit
ParseConventionalCommit parses the subject line of a conventional commit. Returns nil if the subject does not match the pattern.
type LogOptions ¶
type LogOptions struct {
// Since and Until bound the commit date (half-open in practice: git
// treats both bounds inclusively at second resolution).
Since time.Time
Until time.Time
// SinceCommit limits output to commits reachable from HEAD but not
// from the given commit SHA (i.e., "sha..HEAD"). Used for incremental
// ingestion with high-water marks.
SinceCommit string
// Rev logs commits reachable from this revision (e.g. "origin/main" or
// "@{upstream}") instead of the default HEAD. Ignored when SinceCommit
// is set, which already pins the range to HEAD.
Rev string
// Author filters by author name or email (git regex semantics).
Author string
// NoMerges excludes merge commits.
NoMerges bool
// MaxCount caps the number of commits returned (0 = unlimited).
MaxCount int
// IncludeStats adds per-commit insertions/deletions/files-changed via
// --numstat. Costs proportionally more; leave false when not needed.
IncludeStats bool
// Reverse returns commits in chronological order (oldest first)
// instead of the default newest-first.
Reverse bool
}
LogOptions filters a commit-log query. Zero values leave a filter unset.
type ModelStats ¶ added in v0.7.0
type ModelStats struct {
Tool string `json:"tool"`
Model string `json:"model"`
Commits int `json:"commits"`
Insertions int `json:"insertions"`
Deletions int `json:"deletions"`
}
ModelStats holds per-model commit counts (tool + model).
type MultiRepoCommitStats ¶ added in v0.7.0
type MultiRepoCommitStats struct {
Since time.Time `json:"since"`
Until time.Time `json:"until"`
TotalStats CategoryStats `json:"total"`
ByCategory map[string]CategoryStats `json:"byCategory"`
AIStats AIStats `json:"aiStats"`
ByRepo []RepoCommitStats `json:"byRepo"`
Errors []RepoError `json:"errors,omitempty"`
}
MultiRepoCommitStats is the aggregated commit/LOC breakdown across multiple repositories.
func AggregateCommitStats ¶ added in v0.7.0
func AggregateCommitStats(ctx context.Context, paths []string, opts CommitStatsOptions, workers int) *MultiRepoCommitStats
AggregateCommitStats collects commit statistics across multiple repositories in parallel. Repositories that fail are recorded in Errors but don't stop the aggregation. Workers controls concurrency; 0 defaults to GOMAXPROCS.
func (*MultiRepoCommitStats) CategoryBreakdown ¶ added in v0.7.0
func (m *MultiRepoCommitStats) CategoryBreakdown() []CategoryStats
CategoryBreakdown returns categories sorted by commit count (descending).
func (*MultiRepoCommitStats) CategoryPercentages ¶ added in v0.7.0
func (m *MultiRepoCommitStats) CategoryPercentages() map[string]float64
CategoryPercentages returns categories with their percentage of total commits.
type PendingResult ¶ added in v0.10.0
type PendingResult struct {
// Commits are the pending commits, oldest first.
Commits []Commit
// Baseline is the ref the commits were computed as being ahead of: the
// configured upstream ("@{upstream}"), a remote-tracking branch (e.g.
// "origin/main"), or an explicit since-commit hash. It is empty when the
// branch has no push baseline at all — never pushed, or no upstream — in
// which case every commit reachable from HEAD is pending.
Baseline string
}
PendingResult is the outcome of a PendingCommits query.
type ProgressFunc ¶ added in v0.6.0
ProgressFunc is called during parallel operations with progress updates.
type PushedResult ¶ added in v0.10.0
type PushedResult struct {
// Commits are the pushed commits, most recent first.
Commits []Commit
// Baseline is the ref the commits were read from: the configured
// upstream ("@{upstream}") or the matching remote-tracking branch (e.g.
// "origin/main"). It is empty when the branch has no push target, in
// which case nothing has been pushed and Commits is empty.
Baseline string
}
PushedResult is the outcome of a PushedCommits query.
type Repo ¶
type Repo struct {
// contains filtered or unexported fields
}
Repo is a handle to a local git repository.
func (*Repo) CollectCommitStats ¶ added in v0.7.0
func (r *Repo) CollectCommitStats(ctx context.Context, opts CommitStatsOptions) (*RepoCommitStats, error)
CollectCommitStats aggregates commit counts and LOC by conventional-commit category for a single repository over the given time range. Non-conventional commits are grouped under "uncategorized". Returns an error if the repo cannot be read; an empty repo returns zero stats, not an error.
func (*Repo) HasUpstream ¶ added in v0.9.0
HasUpstream reports whether the repository's current branch has an upstream (remote-tracking) branch configured that resolves to a commit. A detached HEAD, a branch with no upstream, or a configured-but-missing upstream ref all return (false, nil) rather than an error.
func (*Repo) Log ¶
Log returns commits matching opts, newest first (git log order) unless Reverse is set.
func (*Repo) OriginURL ¶
OriginURL returns the raw URL of the "origin" remote, or "" when no origin is configured.
func (*Repo) PendingCommits ¶ added in v0.9.0
PendingCommits returns commits that exist locally but have not yet been pushed, oldest first, along with the baseline they were computed against.
By default the baseline is the branch's push target: its configured upstream, or failing that the matching remote-tracking branch (e.g. origin/main). When the branch has no such baseline — it was never pushed, or has no upstream configured — every commit reachable from HEAD is treated as pending and Baseline is empty. This mirrors gitscan's scan semantics, where a real branch with no upstream counts as having unpushed work. A detached HEAD has no branch to push and yields no baseline.
If sinceCommit is non-empty it overrides the baseline entirely ("sinceCommit..HEAD"), regardless of any upstream.
func (*Repo) PushedCommits ¶ added in v0.10.0
PushedCommits returns up to limit commits that have already been pushed on the current branch — those reachable from its push target (the configured upstream, or failing that the matching remote-tracking branch such as origin/main) — most recent first. A limit of zero or less returns all pushed commits.
When the branch has no push target (never pushed, no upstream), nothing is considered pushed: Commits is empty and Baseline is "". This is the mirror image of PendingCommits, which reports every commit as pending in the same situation.
type RepoCommitStats ¶ added in v0.7.0
type RepoCommitStats struct {
Path string `json:"path"`
Since time.Time `json:"since"`
Until time.Time `json:"until"`
TotalStats CategoryStats `json:"total"`
ByCategory map[string]CategoryStats `json:"byCategory"`
AIStats AIStats `json:"aiStats"`
}
RepoCommitStats is the commit/LOC breakdown for a single repository over a time range.
type RepoResult ¶ added in v0.6.0
RepoResult holds the outcome of a parallel operation on one repository.
func RunAll ¶ added in v0.6.0
func RunAll[T any](ctx context.Context, paths []string, fn func(ctx context.Context, repo *Repo) (T, error), workers int) []RepoResult[T]
RunAll executes fn on each repository path in parallel, returning results in the same order as paths. Workers controls concurrency; 0 defaults to GOMAXPROCS. If ctx is cancelled, in-flight operations finish but queued ones are skipped.
func RunAllPaths ¶ added in v0.6.0
func RunAllPaths[T any](ctx context.Context, paths []string, fn func(ctx context.Context, path string) (T, error), workers int) []RepoResult[T]
RunAllPaths executes fn on each path in parallel without requiring a git repository. This is the lower-level variant for operations that manage their own Repo lifecycle or work on non-repo directories.
func RunAllWithProgress ¶ added in v0.6.0
func RunAllWithProgress[T any](ctx context.Context, paths []string, fn func(ctx context.Context, repo *Repo) (T, error), workers int, progress ProgressFunc) []RepoResult[T]
RunAllWithProgress is like RunAll but reports progress via a callback.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
gitscan
command
|
|
|
internal
|
|
|
cliutil
Package cliutil provides small CLI-input-normalization helpers shared across gitscan's subcommands.
|
Package cliutil provides small CLI-input-normalization helpers shared across gitscan's subcommands. |
|
render
Package render formats gitscan command results for output.
|
Package render formats gitscan command results for output. |