git

package
v0.15.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package git provides git repository operations for auto-mr.

The package uses a hybrid approach:

  • Push operations use go-git/go-git/v5 for proper authentication handling with tokens and SSH keys
  • Cleanup operations (switch, pull, fetch, delete) use native git commands via exec.Command to match shell script behavior and prevent silent data loss

Authentication is determined automatically from the remote URL:

  • HTTPS URLs: uses GITLAB_TOKEN or GITHUB_TOKEN environment variables
  • SSH URLs: tries SSH agent first, then key files (~/.ssh/id_ed25519, id_rsa, id_ecdsa)

Usage:

repo, err := git.OpenRepository(".")
repo.SetLogger(logger)
branch, _ := repo.GetCurrentBranch()
platform, _ := repo.DetectPlatform("https://git.example.com")
repo.PushBranch(branch)

Thread Safety: Repository is not safe for concurrent use.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CleanupReport added in v0.11.0

type CleanupReport struct {
	// Step completion status
	SwitchedBranch bool
	PulledChanges  bool
	Pruned         bool
	DeletedBranch  bool

	// Errors encountered (nil if step succeeded)
	SwitchError error
	PullError   error
	PruneError  error
	DeleteError error

	// Metadata
	MainBranch string
	BranchName string
}

CleanupReport tracks the state of each cleanup operation.

func (*CleanupReport) FirstError added in v0.11.0

func (r *CleanupReport) FirstError() error

FirstError returns the first error encountered, or nil if all succeeded. Errors are returned in execution order: Switch -> Pull -> Prune -> Delete.

func (*CleanupReport) PartialSuccess added in v0.11.0

func (r *CleanupReport) PartialSuccess() bool

PartialSuccess returns true if at least one step completed successfully.

func (*CleanupReport) Success added in v0.11.0

func (r *CleanupReport) Success() bool

Success returns true if all critical steps completed successfully. Critical steps are: SwitchBranch and Pull.

type GitTimeoutError added in v0.11.0

type GitTimeoutError struct {
	Operation string
	Timeout   time.Duration
	Err       error
}

GitTimeoutError wraps timeout errors with the name of the operation that timed out and the configured timeout duration. Use errors.As to check for this error type.

func (*GitTimeoutError) Error added in v0.11.0

func (e *GitTimeoutError) Error() string

func (*GitTimeoutError) Unwrap added in v0.11.0

func (e *GitTimeoutError) Unwrap() error

type Platform

type Platform string

Platform represents a git hosting platform.

const (
	// PlatformGitLab represents GitLab hosting.
	PlatformGitLab Platform = "gitlab"
	// PlatformGitHub represents GitHub hosting.
	PlatformGitHub Platform = "github"
	// PlatformForgejo represents Forgejo (self-hosted Gitea fork) hosting.
	PlatformForgejo Platform = "forgejo"
)

type Repository

type Repository struct {
	// contains filtered or unexported fields
}

Repository wraps a go-git repository with authentication and logging. It provides both go-git-based and native git operations.

Not safe for concurrent use.

func OpenRepository

func OpenRepository(path string) (*Repository, error)

OpenRepository opens a git repository at the given path. It searches upward from path to find the .git directory and configures authentication automatically based on the remote URL. Supports both regular repositories and linked worktrees (where .git is a file).

Parameters:

  • path: any path within the git repository (absolute or relative)

Returns an error if the path is not within a git repository or authentication setup fails.

func (*Repository) Cleanup added in v0.11.0

func (r *Repository) Cleanup(ctx context.Context, mainBranch, currentBranch string) *CleanupReport

Cleanup performs post-merge cleanup operations and returns a detailed report.

This method implements a hybrid error handling strategy:

  • Critical operations (switch, pull) fail-fast - stop execution on error
  • Best-effort operations (prune, delete) continue-on-error - log warning and continue

The hybrid approach ensures that git state is valid (critical operations) while allowing recovery from network issues or minor failures (best-effort operations).

func (*Repository) DeleteBranch

func (r *Repository) DeleteBranch(ctx context.Context, branchName string) error

DeleteBranch force-deletes the specified local branch using native "git branch -D".

Parameters:

  • ctx: context for cancellation (further bounded by localGitTimeout)
  • branchName: the local branch to delete

Returns *GitTimeoutError if the operation exceeds localGitTimeout (10s).

func (*Repository) DetectPlatform

func (r *Repository) DetectPlatform(forgejoURL string) (Platform, error)

DetectPlatform determines if the repository is hosted on GitLab, GitHub, or Forgejo by inspecting the origin remote URL.

Detection order:

  1. "gitlab.com" in remote URL → PlatformGitLab
  2. "github.com" in remote URL → PlatformGitHub
  3. If forgejoURL is non-empty, the host extracted from forgejoURL is matched against the remote URL → PlatformForgejo

Returns errUnsupportedPlatform if no platform can be identified.

func (*Repository) FetchAndPrune

func (r *Repository) FetchAndPrune(ctx context.Context) error

FetchAndPrune fetches from origin and prunes deleted remote branches using native "git fetch --prune".

Parameters:

  • ctx: context for cancellation (further bounded by networkGitTimeout)

Returns *GitTimeoutError if the operation exceeds networkGitTimeout (2m).

func (*Repository) GetCommitsSinceMain

func (r *Repository) GetCommitsSinceMain(mainBranch string) ([]*object.Commit, error)

GetCommitsSinceMain returns all commits on the current branch since it diverged from the main branch. Iteration stops when the main branch HEAD commit is reached.

Parameters:

  • mainBranch: the base branch name (e.g., "main")

func (*Repository) GetCurrentBranch

func (r *Repository) GetCurrentBranch() (string, error)

GetCurrentBranch returns the short name of the currently checked out branch.

Returns errHEADNotBranch if HEAD is in detached state.

func (*Repository) GetLatestCommitMessage

func (r *Repository) GetLatestCommitMessage() (string, error)

GetLatestCommitMessage returns the full commit message of the current HEAD commit.

func (*Repository) GetMainBranch

func (r *Repository) GetMainBranch() (string, error)

GetMainBranch determines the main branch name by checking the remote HEAD reference.

It first tries go-git's remote.List for authentication consistency with push operations. If that fails (common with certain SSH configurations), it falls back to native "git ls-remote --symref" which uses the system's SSH agent and config. As a last resort, it checks for local "main" or "master" branches.

Returns errMainBranchNotFound if no method succeeds.

func (*Repository) GetRemoteURL

func (r *Repository) GetRemoteURL(remoteName string) (string, error)

GetRemoteURL returns the first URL configured for the specified remote.

Parameters:

  • remoteName: the remote name (e.g., "origin")

Returns errNoRemoteURLs if the remote has no configured URLs.

func (*Repository) GoGitRepository added in v0.6.0

func (r *Repository) GoGitRepository() *git.Repository

GoGitRepository returns the underlying go-git Repository. This is used by the commits package to retrieve commit history.

func (*Repository) HasStagedChanges

func (r *Repository) HasStagedChanges() (bool, error)

HasStagedChanges checks if there are any staged changes in the repository.

func (*Repository) Pull

func (r *Repository) Pull(ctx context.Context) error

Pull fetches and merges changes from the remote tracking branch using native "git pull".

Parameters:

  • ctx: context for cancellation (further bounded by networkGitTimeout)

Returns *GitTimeoutError if the operation exceeds networkGitTimeout (2m).

func (*Repository) PushBranch

func (r *Repository) PushBranch(branchName string) error

PushBranch pushes the specified branch to the origin remote. It first tries go-git for authentication consistency, then falls back to native "git push" which uses the system's SSH agent and config. If the branch is already up to date, no error is returned.

Parameters:

  • branchName: the local branch name to push

func (*Repository) SetLogger

func (r *Repository) SetLogger(logger *bullets.Logger)

SetLogger sets the logger for the repository.

func (*Repository) SwitchBranch

func (r *Repository) SwitchBranch(ctx context.Context, branchName string) error

SwitchBranch switches to the specified branch using native "git switch". This will fail if there are local changes that would conflict with the switch, forcing the user to handle conflicts manually (matching auto-mr.sh behavior). Untracked files are preserved.

Parameters:

  • ctx: context for cancellation (further bounded by localGitTimeout)
  • branchName: the branch to switch to

Returns *GitTimeoutError if the operation exceeds localGitTimeout (10s).

Jump to

Keyboard shortcuts

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