git

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Feb 26, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package git provides Git repository operations, including worktree management.

This is a Tier 1 (Leaf) package:

  • It imports ONLY stdlib and go-git packages
  • It does NOT import any internal packages
  • Directory/layout concerns are provided by caller interfaces

The package follows the Facade pattern with domain-specific sub-managers:

  • GitManager is the top-level facade owning the repository
  • WorktreeManager handles linked worktree operations

Dependency Inversion: GitManager defines WorktreeDirProvider, implemented by callers so this package stays independent of external config/layout concerns.

Package git provides Git repository operations, including worktree management. This is a Tier 1 (Leaf) package — it imports only stdlib and go-git, NOT any internal packages.

Index

Constants

This section is empty.

Variables

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

	// ErrBranchNotFound is returned when a branch ref does not exist.
	ErrBranchNotFound = errors.New("branch not found")

	// ErrBranchNotMerged is returned when a branch has commits not reachable from HEAD.
	ErrBranchNotMerged = errors.New("branch not fully merged")

	// ErrIsCurrentBranch is returned when attempting to delete the currently checked-out branch.
	ErrIsCurrentBranch = errors.New("cannot delete the currently checked out branch")

	// ErrBranchAlreadyExists is returned when creating a branch that already exists.
	ErrBranchAlreadyExists = errors.New("branch already exists")
)

Functions

func IsInsideWorktree

func IsInsideWorktree(path string) (bool, error)

IsInsideWorktree checks if the given path is inside a git worktree (not the main repository worktree).

Types

type GitManager

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

GitManager is the top-level facade for git operations. It owns the repository handle and provides access to domain-specific sub-managers.

func NewGitManager

func NewGitManager(path string) (*GitManager, error)

NewGitManager opens the git repository containing the given path. It walks up the directory tree to find the repository root.

Returns ErrNotRepository (wrapped) if path is not inside a git repository.

func NewGitManagerWithRepo

func NewGitManagerWithRepo(repo *gogit.Repository, repoRoot string) *GitManager

NewGitManagerWithRepo creates a GitManager from an existing go-git Repository. This is primarily used for testing with in-memory repositories. The repoRoot parameter should be the logical root directory (can be a fake path for testing).

func (*GitManager) BranchExists

func (g *GitManager) BranchExists(branch string) (bool, error)

BranchExists checks if a branch exists in the repository.

func (*GitManager) CreateBranch added in v0.2.0

func (g *GitManager) CreateBranch(branch, base string) error

CreateBranch creates a new branch pointing at the given base ref. If base is empty, the branch is created from HEAD. Returns ErrBranchAlreadyExists if the branch already exists.

func (*GitManager) DeleteBranch added in v0.1.2

func (g *GitManager) DeleteBranch(branch string) error

DeleteBranch deletes a branch ref and its config (equivalent to `git branch -d`). Returns ErrIsCurrentBranch if the branch is the currently checked-out branch. Returns ErrBranchNotMerged if the branch has unmerged commits relative to HEAD. Returns ErrBranchNotFound if the branch doesn't exist.

func (*GitManager) GetCurrentBranch

func (g *GitManager) GetCurrentBranch() (string, error)

GetCurrentBranch returns the current branch name of the repository. Returns empty string and no error for detached HEAD state.

func (*GitManager) GitDir added in v0.3.0

func (g *GitManager) GitDir() string

GitDir returns the absolute path to the .git directory. Returns empty string if the storer is not filesystem-backed (e.g., in-memory repos).

func (*GitManager) IsWorktreeLocked added in v0.3.0

func (g *GitManager) IsWorktreeLocked(slug string) (bool, error)

IsWorktreeLocked checks if a worktree has a lock file (.git/worktrees/<slug>/locked). Locked worktrees are protected from pruning per git convention. Returns (locked, error). Error is non-nil for unexpected filesystem errors (permissions, etc.) — callers should not assume absence on error.

func (*GitManager) ListWorktrees

func (g *GitManager) ListWorktrees(entries []WorktreeDirEntry) ([]WorktreeInfo, error)

ListWorktrees returns information about all linked worktrees. Worktrees that have errors reading their info will have the Error field set.

Parameters:

  • entries: Worktree directory entries from the provider (name, slug, path)

The function matches entries to git worktree metadata by slug (which matches the go-git worktree name). Entries without corresponding git metadata are included with an error, as are entries that can't be opened.

func (*GitManager) RemoveWorktree

func (g *GitManager) RemoveWorktree(dirs WorktreeDirProvider, branch string) error

RemoveWorktree removes a worktree (both git metadata and directory).

Parameters:

  • dirs: Provider for worktree directory management
  • branch: Branch/worktree name to remove

func (*GitManager) RepoRoot

func (g *GitManager) RepoRoot() string

RepoRoot returns the root directory of the git repository.

func (*GitManager) Repository

func (g *GitManager) Repository() *gogit.Repository

Repository returns the underlying go-git Repository. Use this for operations not covered by the sub-managers.

func (*GitManager) ResolveRef

func (g *GitManager) ResolveRef(ref string) (plumbing.Hash, error)

ResolveRef resolves a reference (branch, tag, commit) to a commit hash.

func (*GitManager) SetupWorktree

func (g *GitManager) SetupWorktree(dirs WorktreeDirProvider, branch, base string) (string, error)

SetupWorktree creates or gets a worktree for the given branch. It orchestrates: directory creation (via provider) + git worktree add.

Parameters:

  • dirs: Provider for worktree directory management
  • branch: Branch name to check out (created if doesn't exist)
  • base: Base ref to create branch from (empty string uses HEAD)

Returns the worktree path ready for mounting.

func (*GitManager) Worktrees

func (g *GitManager) Worktrees() (*WorktreeManager, error)

Worktrees returns the WorktreeManager for linked worktree operations. The manager is lazily initialized on first access. Returns an error if the repository's storage doesn't support worktrees.

type WorktreeDirEntry

type WorktreeDirEntry struct {
	// Name is the original name (typically a branch name with slashes).
	Name string
	// Slug is the filesystem-safe version of the name.
	Slug string
	// Path is the absolute filesystem path to the worktree directory.
	Path string
}

WorktreeDirEntry contains information about a worktree directory. This is the directory-level info (name, slug, path), separate from git metadata.

type WorktreeDirProvider

type WorktreeDirProvider interface {
	// GetOrCreateWorktreeDir returns the path to a worktree directory,
	// creating it if it doesn't exist. The name is typically a branch name
	// which will be slugified for filesystem safety.
	GetOrCreateWorktreeDir(name string) (string, error)

	// GetWorktreeDir returns the path to an existing worktree directory.
	// Returns an error if the worktree directory doesn't exist.
	GetWorktreeDir(name string) (string, error)

	// DeleteWorktreeDir removes a worktree directory.
	// Returns an error if the directory doesn't exist.
	DeleteWorktreeDir(name string) error
}

WorktreeDirProvider manages worktree directories for callers. Defined here for dependency inversion so the git package remains unconcerned with caller configuration/layout details.

type WorktreeInfo

type WorktreeInfo struct {
	// Name is the worktree name (typically the branch name).
	Name string

	// Slug is the caller-provided identifier for this worktree entry.
	// Preserved from WorktreeDirEntry to avoid re-computation.
	Slug string

	// Path is the filesystem path to the worktree directory.
	Path string

	// Head is the commit hash the worktree is checked out to.
	Head plumbing.Hash

	// Branch is the branch reference if the worktree is not detached.
	// Empty string for detached HEAD state.
	Branch string

	// IsDetached indicates whether the worktree has a detached HEAD.
	IsDetached bool

	// Error indicates any error encountered while reading worktree info.
	// If non-nil, other fields may be incomplete/zero-valued.
	Error error
}

WorktreeInfo contains information about a git worktree.

type WorktreeManager

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

WorktreeManager manages linked worktrees for a git repository. It wraps the experimental x/plumbing/worktree package from go-git.

func (*WorktreeManager) Add

func (w *WorktreeManager) Add(path, name string, commit plumbing.Hash) error

Add creates a linked worktree at the given path, checking out the specified commit. If commit is zero, HEAD is used.

The name parameter is used to identify the worktree in git's metadata (stored in .git/worktrees/<name>/).

func (*WorktreeManager) AddDetached

func (w *WorktreeManager) AddDetached(path, name string, commit plumbing.Hash) error

AddDetached creates a linked worktree with a detached HEAD. If commit is zero, HEAD is used.

func (*WorktreeManager) AddWithExistingBranch

func (w *WorktreeManager) AddWithExistingBranch(path, name string, branch plumbing.ReferenceName) error

AddWithExistingBranch creates a linked worktree that checks out an existing branch. Unlike AddWithNewBranch, this does NOT try to create a new branch.

Use this when the branch already exists and you want to create a worktree for it. The branch MUST exist; this method does not verify branch existence (caller's responsibility).

func (*WorktreeManager) AddWithNewBranch

func (w *WorktreeManager) AddWithNewBranch(path, name string, branch plumbing.ReferenceName, base plumbing.Hash) error

AddWithNewBranch creates a linked worktree at the given path and creates a new branch. It creates the worktree with a detached HEAD, then creates the branch pointing to base (or HEAD if base is zero), and checks out the branch.

IMPORTANT: We use AddDetached first to avoid go-git's default behavior of creating a branch named after the worktree name. This prevents the bug where slashed branch names like "feature/foo" would also create a slugified branch "feature-foo".

func (*WorktreeManager) Exists

func (w *WorktreeManager) Exists(name string) (bool, error)

Exists checks if a worktree with the given name exists in git's metadata.

func (*WorktreeManager) List

func (w *WorktreeManager) List() ([]string, error)

List returns the names of all linked worktrees.

func (*WorktreeManager) Open

func (w *WorktreeManager) Open(path string) (*gogit.Repository, error)

Open opens a linked worktree as a full *git.Repository. The path must point to an existing worktree directory.

func (*WorktreeManager) Remove

func (w *WorktreeManager) Remove(name string) error

Remove deletes the worktree metadata from .git/worktrees/. It does NOT delete the worktree directory on disk — that's the caller's responsibility.

Directories

Path Synopsis
Package gittest provides test utilities for the git package.
Package gittest provides test utilities for the git package.

Jump to

Keyboard shortcuts

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