git

package
v0.0.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2025 License: MIT Imports: 10 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewCommandExecutor

func NewCommandExecutor() executor

func TruncateString

func TruncateString(s string, maxLen int) string

TruncateString helper

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

func NewClient(ctx context.Context, workDir string, config GitClientConfig) (*GitClient, error)

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) AddAll

func (c *GitClient) AddAll(ctx context.Context) error

func (*GitClient) Commit

func (c *GitClient) Commit(ctx context.Context, message string) error

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 (c *GitClient) GetCurrentBranchName(ctx context.Context) (string, error)

func (*GitClient) GetDiffCached

func (c *GitClient) GetDiffCached(ctx context.Context) (stdout, stderr string, err error)

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

func (c *GitClient) GetDiffUnstaged(ctx context.Context) (stdout, stderr string, err error)

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) GetStatus

func (c *GitClient) GetStatus(ctx context.Context) (stdout, stderr string, err error)

func (*GitClient) GetStatusShort

func (c *GitClient) GetStatusShort(ctx context.Context) (stdout, stderr string, err error)

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) GitDir

func (c *GitClient) GitDir() string

GitDir returns the path to the repository's .git directory/file.

func (*GitClient) HasStagedChanges

func (c *GitClient) HasStagedChanges(ctx context.Context) (bool, error)

func (*GitClient) IsBranchAhead

func (c *GitClient) IsBranchAhead(ctx context.Context) (bool, error)

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

func (c *GitClient) IsWorkingDirClean(ctx context.Context) (bool, error)

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

func (c *GitClient) ListUntrackedFiles(ctx context.Context) (stdout, stderr string, err error)

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

func (c *GitClient) LocalBranchExists(ctx context.Context, branchName string) (bool, error)

LocalBranchExists checks if a local branch with the given name exists.

func (*GitClient) Logger

func (c *GitClient) Logger() *slog.Logger

Logger returns the underlying logger instance.

func (*GitClient) MainBranchName

func (c *GitClient) MainBranchName() string

MainBranchName returns the configured default main branch name.

func (*GitClient) Path

func (c *GitClient) Path() string

Path returns the root path of the repository the client is managing.

func (*GitClient) PullRebase

func (c *GitClient) PullRebase(ctx context.Context, branch string) error

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

func (c *GitClient) Push(ctx context.Context, branch string) error

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

func (c *GitClient) PushAndSetUpstream(ctx context.Context, branchName string) error

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

func (c *GitClient) RemoteName() string

RemoteName returns the configured default remote name.

func (*GitClient) SwitchBranch

func (c *GitClient) SwitchBranch(ctx context.Context, branchName string) error

SwitchBranch switches the working directory to the specified existing local branch.

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL