Documentation
¶
Overview ¶
Package git provides a high-level client for interacting with Git repositories programmatically from Go applications. It abstracts the direct execution of 'git' command-line operations, offering a more Go-idiomatic API.
The primary entry point for using this package is the GitClient type, which is instantiated via the NewClient function. The client requires a working directory to determine the repository context and can be configured using GitClientConfig.
Key features include:
- Repository context detection (finding .git and top-level directories).
- Execution of common Git commands (status, commit, add, branch, etc.) through structured methods.
- Abstraction over command execution, allowing for custom executors (primarily for testing).
- Integration with structured logging via the slog package.
Usage Example:
// Assume globalLogger is an initialized *slog.Logger
ctx := context.Background()
workDir, _ := os.Getwd()
gitCfg := git.GitClientConfig{
Logger: globalLogger,
// Other configurations can be set here
}
client, err := git.NewClient(ctx, workDir, gitCfg)
if err != nil {
log.Fatalf("Failed to create Git client: %v", err)
}
branch, err := client.GetCurrentBranchName(ctx)
if err != nil {
log.Printf("Error getting branch: %v", err)
} else {
log.Printf("Current branch: %s", branch)
}
Error Handling:
Methods on the GitClient typically return an error as their last argument if an operation fails. Errors can originate from underlying git command failures, invalid input, or issues with the repository state. It's important for callers to check these errors.
Logging:
The GitClient uses an slog.Logger instance provided via GitClientConfig. This allows for consistent, structured logging of its operations, which can be directed to various outputs (e.g., console, files, AI-consumable streams) by configuring the logger's handlers at the application level.
Testing:
The GitClient is designed with testability in mind. The GitClientConfig.Executor field allows injecting a mock 'executor' interface, enabling unit tests for client methods without relying on an actual 'git' executable or a live repository.
Index ¶
- func NewCommandExecutor() executor
- func TruncateString(s string, maxLen int) string
- type GitClient
- func (c *GitClient) AddAll(ctx context.Context) error
- func (c *GitClient) Commit(ctx context.Context, message string) error
- func (c *GitClient) CreateAndSwitchBranch(ctx context.Context, newBranchName string, baseBranch string) error
- func (c *GitClient) GetCurrentBranchName(ctx context.Context) (string, error)
- func (c *GitClient) GetDiffCached(ctx context.Context) (stdout, stderr string, err error)
- func (c *GitClient) GetDiffUnstaged(ctx context.Context) (stdout, stderr string, err error)
- func (c *GitClient) GetStatus(ctx context.Context) (stdout, stderr string, err error)
- func (c *GitClient) GetStatusShort(ctx context.Context) (stdout, stderr string, err error)
- func (c *GitClient) GitDir() string
- func (c *GitClient) HasStagedChanges(ctx context.Context) (bool, error)
- func (c *GitClient) IsBranchAhead(ctx context.Context) (bool, error)
- func (c *GitClient) IsWorkingDirClean(ctx context.Context) (bool, error)
- func (c *GitClient) ListTrackedAndCachedFiles(ctx context.Context) (stdout, stderr string, err error)
- func (c *GitClient) ListUntrackedFiles(ctx context.Context) (stdout, stderr string, err error)
- func (c *GitClient) LocalBranchExists(ctx context.Context, branchName string) (bool, error)
- func (c *GitClient) Logger() *slog.Logger
- func (c *GitClient) MainBranchName() string
- func (c *GitClient) Path() string
- func (c *GitClient) PullRebase(ctx context.Context, branch string) error
- func (c *GitClient) Push(ctx context.Context, branch string) error
- func (c *GitClient) PushAndSetUpstream(ctx context.Context, branchName string) error
- func (c *GitClient) RemoteName() string
- func (c *GitClient) SwitchBranch(ctx context.Context, branchName string) error
- type GitClientConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewCommandExecutor ¶
func NewCommandExecutor() executor
Types ¶
type GitClient ¶
type GitClient struct {
// contains filtered or unexported fields
}
GitClient provides methods for interacting with a Git repository. Instances should be created via NewClient.
func NewClient ¶
NewClient creates and initializes a new GitClient for the Git repository located at or containing the specified workDir. If workDir is an empty string, the current working directory (os.Getwd()) is used as the starting point to find the repository root. The provided context (ctx) is used for initial setup commands (e.g., 'git rev-parse') and can be used for cancellation.
It returns an initialized GitClient or an error if setup fails. Errors can occur if: - The workDir (or current directory if workDir is empty) is not within a Git repository. - The configured 'git' executable (from GitClientConfig.GitExecutable or system PATH) is not found. - The GitClientConfig is invalid after defaults are applied. - Underlying 'git rev-parse' commands fail during setup.
func (*GitClient) CreateAndSwitchBranch ¶
func (c *GitClient) CreateAndSwitchBranch(ctx context.Context, newBranchName string, baseBranch string) error
CreateAndSwitchBranch creates a new local branch from the specified base branch (or current HEAD if baseBranch is empty) and switches to it. Equivalent to `git switch -c <newBranch> [baseBranch]`.
func (*GitClient) GetCurrentBranchName ¶
func (*GitClient) GetDiffCached ¶
GetDiffCached retrieves the diff between the Git index (staged changes) and the HEAD commit. Returns stdout, stderr, and error. Exit code 1 from `git diff` indicates differences were found and is not treated as an execution error by this function itself.
func (*GitClient) GetDiffUnstaged ¶
GetDiffUnstaged retrieves the diff between the working directory and the Git index (unstaged changes). Returns stdout, stderr, and error. Exit code 1 from `git diff` indicates differences were found and is not treated as an execution error by this function itself.
func (*GitClient) GetStatusShort ¶
GetStatusShort retrieves the output of `git status --short`. This provides a concise summary of changed files (staged, unstaged, untracked). Returns stdout, stderr, and any execution error.
func (*GitClient) HasStagedChanges ¶
func (*GitClient) IsBranchAhead ¶
IsBranchAhead checks if the current local branch is ahead of its upstream remote. It parses the output of `git status -sb`. Returns true if ahead, false otherwise. Returns an error if status cannot be checked.
func (*GitClient) IsWorkingDirClean ¶
IsWorkingDirClean checks if the working directory has no staged, unstaged, or untracked changes. Returns true if clean, false otherwise. Returns an error if any underlying git command fails unexpectedly.
func (*GitClient) ListTrackedAndCachedFiles ¶
func (c *GitClient) ListTrackedAndCachedFiles(ctx context.Context) (stdout, stderr string, err error)
ListTrackedAndCachedFiles retrieves a list of files known to Git (tracked or staged/cached), respecting .gitignore rules handled by git itself. Includes 'other' (untracked) files too, basically mirroring `git ls-files -co --exclude-standard`. Returns the list as a single string (each file on a newline), stderr output, and any error.
func (*GitClient) ListUntrackedFiles ¶
ListUntrackedFiles retrieves a list of untracked files in the repository, respecting .gitignore. Returns the list as a string (each file on a newline), stderr output, and any error.
func (*GitClient) LocalBranchExists ¶
LocalBranchExists checks if a local branch with the given name exists.
func (*GitClient) MainBranchName ¶
MainBranchName returns the configured default main branch name.
func (*GitClient) PullRebase ¶
PullRebase executes `git pull --rebase [remote] [branch]` using the client's configured default remote and the specified branch. Returns an error if the command fails (e.g., conflicts, network issues).
func (*GitClient) Push ¶
Push executes `git push [remote] [branch]` using the client's configured default remote and the specified *local* branch name to push. If branch is empty, attempts to push the current branch based on Git's default behavior. Returns an error if the push fails. Handles "Everything up-to-date" gracefully.
func (*GitClient) PushAndSetUpstream ¶
PushAndSetUpstream pushes the specified local branch to the default remote and sets the upstream tracking configuration. Equivalent to `git push --set-upstream <remote> <branch>`.
func (*GitClient) RemoteName ¶
RemoteName returns the configured default remote name.
type GitClientConfig ¶
type GitClientConfig struct {
// GitExecutable is the path to the Git executable.
// If empty, "git" will be looked up in PATH.
GitExecutable string
// DefaultRemoteName specifies the default remote to use (e.g., "origin").
DefaultRemoteName string
// DefaultMainBranchName specifies the default main branch name (e.g., "main", "master").
DefaultMainBranchName string
// Logger is the structured logger instance for the client's operations.
// If nil, a default discard logger will be used.
Logger *slog.Logger
// Executor is an optional custom executor for testing or specialized execution.
// If nil, a default commandExecutor will be used.
Executor executor
}
GitClientConfig holds configuration for the GitClient.