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 AIToolByEmail(email string) string
- 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 AIProvider
- 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 ProgressFunc
- 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) 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) 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", Emails: []string{"noreply@anthropic.com"}, ModelPattern: regexp.MustCompile(`(?i)^Claude\s+(.+)$`), }, { Name: "GitHub Copilot", Emails: []string{"noreply@github.com", "copilot@github.com"}, ModelPattern: nil, }, { Name: "Gemini CLI", 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", Emails: []string{"ai@cursor.sh", "cursor@cursor.sh"}, ModelPattern: regexp.MustCompile(`(?i)^Cursor\s+(.+)$`), }, { Name: "Aider", Emails: []string{"aider@aider.chat"}, ModelPattern: nil, }, }
DefaultAITools is the built-in registry of AI coding assistants.
var KnownAIProviders = []AIProvider{ { Name: "Claude Code", Provider: "anthropic", Emails: []string{"noreply@anthropic.com"}, }, { Name: "GitHub Copilot", Provider: "github", Emails: []string{"noreply@github.com", "copilot@github.com"}, }, { 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", }, }, { Name: "Cursor", Provider: "cursor", Emails: []string{"ai@cursor.sh", "cursor@cursor.sh"}, }, { Name: "Aider", Provider: "aider", Emails: []string{"aider@aider.chat"}, }, }
KnownAIProviders lists recognized AI coding assistants and their co-author signatures. This is the canonical registry; consumers should use AIProviderByEmail rather than maintaining separate lists.
Functions ¶
func AIToolByEmail ¶ added in v0.6.0
AIToolByEmail returns the tool name matching a co-author email, or "" when the email is not a known AI signature. This is a convenience wrapper around AIProviderByEmail for callers that only need the name.
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
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.
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"
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.
func ParseAIModel ¶ added in v0.6.0
ParseAIModel extracts the AI model from a co-author signature's name and email. Returns nil if the signature is not from a known AI provider or the model cannot be determined.
Examples:
"Claude Sonnet 5 <noreply@anthropic.com>" → {Provider: "anthropic", Model: "sonnet-5", Name: "Claude Sonnet 5"}
"Claude Opus 4.6 <noreply@anthropic.com>" → {Provider: "anthropic", Model: "opus-4.6", Name: "Claude Opus 4.6"}
"github-actions[bot] <noreply@github.com>" → {Provider: "github", Model: "", Name: "github-actions[bot]"}
type AIProvider ¶ added in v0.6.0
type AIProvider struct {
// Name is the display name, e.g. "Claude Code".
Name string
// Provider is the canonical provider slug, e.g. "anthropic".
Provider string
// Emails are known co-author addresses. Entries of the form
// "<id>+<slug>@users.noreply.github.com" also match any address with
// the same "+<slug>@users.noreply.github.com" suffix.
Emails []string
}
AIProvider identifies an AI coding assistant provider.
func AIProviderByEmail ¶ added in v0.6.0
func AIProviderByEmail(email string) *AIProvider
AIProviderByEmail returns the AI provider matching a co-author email, or nil when the email is not a known AI signature. Matching is case-insensitive and supports GitHub noreply suffix forms with variable user-ID prefixes.
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"
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
// 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 ProgressFunc ¶ added in v0.6.0
ProgressFunc is called during parallel operations with progress updates.
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) 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.
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.