Help us shape the future of Go! Take the 2026 Go Developer Survey

git

package
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: May 18, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package git provides Git repository operations for gh-arc. It wraps go-git library and provides fallback to git CLI for complex operations.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotARepository is returned when the path is not a git repository
	ErrNotARepository = errors.New("not a git repository")

	// ErrDetachedHead is returned when repository is in detached HEAD state
	ErrDetachedHead = errors.New("repository is in detached HEAD state")

	// ErrInvalidBranch is returned when branch name is invalid or doesn't exist
	ErrInvalidBranch = errors.New("invalid or non-existent branch")

	// ErrRemoteBranchExists indicates the remote branch already exists (race condition)
	ErrRemoteBranchExists = errors.New("remote branch already exists")

	// ErrAuthenticationFailed indicates git push failed due to authentication
	ErrAuthenticationFailed = errors.New("authentication failed")
)

Functions

func FindRepositoryRoot

func FindRepositoryRoot(startPath string) (string, error)

FindRepositoryRoot traverses up directories looking for .git folder and returns the root path of the repository.

func IsValidRepository

func IsValidRepository(path string) bool

IsValidRepository checks if the given path is a valid Git repository.

Types

type BranchInfo

type BranchInfo struct {
	Name     string // Branch name
	IsRemote bool   // True if this is a remote branch
	Hash     string // Commit SHA
}

BranchInfo represents information about a branch.

type CommitInfo

type CommitInfo struct {
	SHA     string    // Commit SHA
	Author  string    // Author name
	Email   string    // Author email
	Date    time.Time // Commit date
	Message string    // Full commit message
}

CommitInfo represents information about a commit.

type CommitMessage

type CommitMessage struct {
	Title string // First line of commit message
	Body  string // Rest of commit message (after title)
}

CommitMessage represents a parsed commit message.

func ParseCommitMessage

func ParseCommitMessage(message string) CommitMessage

ParseCommitMessage parses a commit message into title and body.

type DiffStats

type DiffStats struct {
	FilesChanged int // Number of files changed
	Additions    int // Number of lines added
	Deletions    int // Number of lines deleted
}

DiffStats represents statistics about a diff.

type FileChange

type FileChange struct {
	Path      string // File path
	OldPath   string // Old path (for renames)
	IsNew     bool   // True if file is newly created
	IsDeleted bool   // True if file is deleted
	IsRenamed bool   // True if file is renamed
	IsBinary  bool   // True if file is binary
	Additions int    // Lines added
	Deletions int    // Lines deleted
}

FileChange represents a change to a file in a diff.

type Repository

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

Repository represents a Git repository and provides methods for Git operations.

Repository is not safe for concurrent use by multiple goroutines without external synchronization. If you need to access a repository from multiple goroutines, you must coordinate access using a mutex or other synchronization mechanism.

func OpenRepository

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

OpenRepository opens a Git repository at the given path. If path is empty, it attempts to find the repository in the current directory.

func (*Repository) BranchExists

func (r *Repository) BranchExists(branchName string) (bool, error)

BranchExists checks if a branch exists (local or remote). For remote branches, use the full ref name like "origin/main". Returns true if the branch exists, false otherwise.

func (*Repository) CheckoutBranch added in v0.0.6

func (r *Repository) CheckoutBranch(branch string) error

CheckoutBranch switches to an existing local branch via git CLI.

func (*Repository) CheckoutTrackingBranch

func (r *Repository) CheckoutTrackingBranch(branchName, remoteBranch string) error

CheckoutTrackingBranch creates and checks out a local branch that tracks a remote branch. This is useful for creating a local branch from an existing remote branch. Equivalent to: git checkout -b <branchName> <remoteBranch>

func (*Repository) CountCommitsAhead

func (r *Repository) CountCommitsAhead(branchName, baseBranch string) (int, error)

CountCommitsAhead counts how many commits branchName has ahead of baseBranch. Returns 0 if branches are at the same commit or if baseBranch doesn't exist. This is useful for detecting commits on main that are ahead of origin/main.

func (*Repository) CreateBranch

func (r *Repository) CreateBranch(name string, baseBranch string) error

CreateBranch creates a new branch from the specified base branch. If baseBranch is empty, it creates from the current HEAD.

func (*Repository) DeleteLocalBranch added in v0.0.6

func (r *Repository) DeleteLocalBranch(branch string) error

DeleteLocalBranch force-deletes a local branch via git CLI. Uses -D (force) because the local tracking info may not reflect the remote merge.

func (*Repository) GetAllCommitMessages

func (r *Repository) GetAllCommitMessages(baseBranch, headBranch string) ([]string, error)

GetAllCommitMessages returns all commit messages in the range. Useful for generating PR descriptions from multiple commits. Returns empty slice if there are no commits between the branches.

func (*Repository) GetBranchSHA added in v0.0.6

func (r *Repository) GetBranchSHA(branch string) (string, error)

GetBranchSHA returns the SHA of the tip of the given branch via git rev-parse.

func (*Repository) GetChangedFiles

func (r *Repository) GetChangedFiles(base, head string) ([]string, error)

GetChangedFiles returns a list of file paths changed between two refs. This is a simpler version of GetFilesChanged that only returns file paths.

func (*Repository) GetCommitRange

func (r *Repository) GetCommitRange(baseBranch, headBranch string) ([]CommitInfo, error)

GetCommitRange returns commits between two branches. It returns commits that are in headBranch but not in baseBranch.

func (*Repository) GetCommitsBetween

func (r *Repository) GetCommitsBetween(base, head string) ([]CommitInfo, error)

GetCommitsBetween returns commits between two branch/commit references. This is similar to GetCommitRange but accepts any ref (branch, tag, commit SHA).

func (*Repository) GetCurrentBranch

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

GetCurrentBranch returns the current branch name. If the repository is in a detached HEAD state, it returns the HEAD commit SHA.

func (*Repository) GetDefaultBranch

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

GetDefaultBranch attempts to detect the default branch (main, master, or custom). It checks remote HEAD first, then falls back to common branch names.

func (*Repository) GetDiffBetween

func (r *Repository) GetDiffBetween(base, head string) (string, error)

GetDiffBetween generates a unified diff between two refs (branches, tags, or commits). Returns the diff as a string in unified diff format.

func (*Repository) GetDiffStats

func (r *Repository) GetDiffStats(base, head string) (*DiffStats, error)

GetDiffStats calculates statistics for changes between two refs.

func (*Repository) GetFilesChanged

func (r *Repository) GetFilesChanged(base, head string) ([]FileChange, error)

GetFilesChanged returns a list of files changed between two refs.

func (*Repository) GetFirstCommitMessage

func (r *Repository) GetFirstCommitMessage(baseBranch, headBranch string) (string, error)

GetFirstCommitMessage returns the message of the first commit in the range. Useful for generating PR descriptions from a single commit. Returns empty string if there are no commits between the branches.

func (*Repository) GetGitConfig

func (r *Repository) GetGitConfig(key string) (string, error)

GetGitConfig reads a git configuration value. It uses go-git's config first, then falls back to git CLI if not found.

func (*Repository) GetHeadSHA added in v0.0.6

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

GetHeadSHA returns the SHA of the current HEAD commit.

func (*Repository) GetMergeBase

func (r *Repository) GetMergeBase(ref1, ref2 string) (string, error)

GetMergeBase finds the common ancestor (merge-base) between two refs. It uses git CLI since go-git doesn't have reliable merge-base support. Returns the SHA of the common ancestor commit.

func (*Repository) GetRemoteRefAge

func (r *Repository) GetRemoteRefAge(remoteRef string) (time.Duration, error)

GetRemoteRefAge returns how long ago a remote ref was last fetched/updated. This is useful for detecting stale remote branches (e.g., origin/main hasn't been fetched in days). Returns the duration since the last update.

Example: age, err := repo.GetRemoteRefAge("origin/main")

func (*Repository) GetRepositoryState

func (r *Repository) GetRepositoryState() (*RepositoryState, error)

GetRepositoryState returns the complete state of the repository, combining all state checks into a single status struct.

func (*Repository) GetStagedDiff

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

GetStagedDiff returns the diff for staged changes (in the index).

func (*Repository) GetWorkingDiff

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

GetWorkingDiff returns the diff for unstaged changes in the working directory.

func (*Repository) GetWorkingDirectoryStatus

func (r *Repository) GetWorkingDirectoryStatus() (*WorkingDirectoryStatus, error)

GetWorkingDirectoryStatus returns the status of the working directory. Uses git CLI instead of go-git's Worktree.Status(), which has known issues with .gitignore handling, global excludes, and file permission tracking.

func (*Repository) HasUnpushedCommits

func (r *Repository) HasUnpushedCommits(branchName string) (bool, error)

HasUnpushedCommits checks if the local branch has commits that haven't been pushed to remote. Returns true if there are unpushed commits, false otherwise. If the remote branch doesn't exist yet, returns true (all local commits are "unpushed").

func (*Repository) IsAncestor

func (r *Repository) IsAncestor(ancestorRef, descendantRef string) (bool, error)

IsAncestor checks if ancestorRef is an ancestor of descendantRef Returns true if ancestorRef is reachable from descendantRef

func (*Repository) IsDetachedHead

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

IsDetachedHead checks if the repository is in a detached HEAD state.

func (*Repository) ListBranches

func (r *Repository) ListBranches(includeRemote bool) ([]BranchInfo, error)

ListBranches returns a list of all branches (local and optionally remote).

func (*Repository) Path

func (r *Repository) Path() string

Path returns the path to the repository.

func (*Repository) PullOrigin added in v0.0.6

func (r *Repository) PullOrigin(branch string) error

PullOrigin pulls the latest changes from origin for the given branch via git CLI.

func (*Repository) Push

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

Push pushes commits from the specified branch to its remote tracking branch. If the branch has no remote tracking branch, it pushes to origin with the same name. Uses context for cancellation support.

If a regular push fails due to non-fast-forward (e.g., after rebasing), it automatically retries with --force-with-lease to safely force push the changes.

func (*Repository) PushBranch

func (r *Repository) PushBranch(ctx context.Context, localRef, remoteBranch string) error

PushBranch pushes a local ref to a specific remote branch name. This is different from Push() which pushes to the tracking branch or same-named branch. Uses context for cancellation support.

Returns ErrRemoteBranchExists if the remote branch already exists (race condition). Returns ErrAuthenticationFailed if authentication fails during push.

func (*Repository) Repo

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

Repo returns the underlying go-git Repository object. This is useful for advanced operations not covered by this package.

type RepositoryState

type RepositoryState struct {
	IsValid       bool                   // True if this is a valid repository
	IsDetached    bool                   // True if HEAD is detached
	CurrentBranch string                 // Current branch name (empty if detached)
	HeadCommit    string                 // SHA of HEAD commit
	WorkingDir    WorkingDirectoryStatus // Working directory status
}

RepositoryState represents the complete state of a repository.

type WorkingDirectoryStatus

type WorkingDirectoryStatus struct {
	IsClean        bool     // True if no changes in working directory
	StagedFiles    []string // Files in staging area
	UnstagedFiles  []string // Modified files not staged
	UntrackedFiles []string // Files not tracked by git
}

WorkingDirectoryStatus represents the status of the working directory.

Jump to

Keyboard shortcuts

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