Documentation
¶
Index ¶
- Constants
- type AddCommand
- type AddFormatOptions
- type AddOptions
- type AddResult
- type BranchDeleteOption
- type CleanCandidate
- type CleanCommand
- type CleanOptions
- type CleanReason
- type CleanResult
- type Config
- type FileSystem
- type FormatOptions
- type FormatResult
- type Formatter
- type GitError
- type GitExecutor
- type GitOp
- type GitRunner
- func (g *GitRunner) BranchDelete(branch string, opts ...BranchDeleteOption) ([]byte, error)
- func (g *GitRunner) BranchList() ([]string, error)
- func (g *GitRunner) ChangedFiles() ([]string, error)
- func (g *GitRunner) Fetch(remote string, refspec ...string) error
- func (g *GitRunner) FindRemoteForBranch(branch string) (string, error)
- func (g *GitRunner) FindRemotesForBranch(branch string) []string
- func (g *GitRunner) HasChanges() (bool, error)
- func (g *GitRunner) InDir(dir string) *GitRunner
- func (g *GitRunner) IsBranchMerged(branch, target string) (bool, error)
- func (g *GitRunner) IsBranchUpstreamGone(branch string) (bool, error)
- func (g *GitRunner) LocalBranchExists(branch string) bool
- func (g *GitRunner) Run(args ...string) ([]byte, error)
- func (g *GitRunner) StashApplyByHash(hash string) ([]byte, error)
- func (g *GitRunner) StashDropByHash(hash string) ([]byte, error)
- func (g *GitRunner) StashPopByHash(hash string) ([]byte, error)
- func (g *GitRunner) StashPush(message string, pathspecs ...string) (string, error)
- func (g *GitRunner) WorktreeAdd(path, branch string, opts ...WorktreeAddOption) ([]byte, error)
- func (g *GitRunner) WorktreeFindByBranch(branch string) (*Worktree, error)
- func (g *GitRunner) WorktreeList() ([]Worktree, error)
- func (g *GitRunner) WorktreeListBranches() ([]string, error)
- func (g *GitRunner) WorktreePrune() ([]byte, error)
- func (g *GitRunner) WorktreeRemove(path string, opts ...WorktreeRemoveOption) ([]byte, error)
- type InitCommand
- type InitFormatOptions
- type InitOptions
- type InitResult
- type ListCommand
- type ListFormatOptions
- type ListResult
- type LoadConfigResult
- type RemoveCommand
- type RemoveOptions
- type RemoveResult
- type RemovedWorktree
- type SkipReason
- type SymlinkResult
- type Worktree
- type WorktreeAddOption
- type WorktreeForceLevel
- type WorktreeRemoveOption
Constants ¶
const ( GitCmdWorktree = "worktree" GitCmdBranch = "branch" GitCmdStash = "stash" GitCmdStatus = "status" GitCmdRevParse = "rev-parse" GitCmdDiff = "diff" GitCmdFetch = "fetch" GitCmdForEachRef = "for-each-ref" )
Git command names.
const ( GitWorktreeAdd = "add" GitWorktreeRemove = "remove" GitWorktreeList = "list" GitWorktreePrune = "prune" )
Git worktree subcommands.
const ( GitStashPush = "push" GitStashApply = "apply" GitStashDrop = "drop" GitStashList = "list" )
Git stash subcommands.
const ( PorcelainWorktreePrefix = "worktree " PorcelainHEADPrefix = "HEAD " PorcelainBranchPrefix = "branch refs/heads/" PorcelainDetached = "detached" PorcelainBare = "bare" PorcelainLocked = "locked" PorcelainPrunable = "prunable" )
Porcelain output format prefixes and values.
const RefsHeadsPrefix = "refs/heads/"
RefsHeadsPrefix is the git refs prefix for local branches.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AddCommand ¶
type AddCommand struct {
FS FileSystem
Git *GitRunner
Config *Config
Sync bool
CarryFrom string
FilePatterns []string
Lock bool
LockReason string
}
AddCommand creates git worktrees with symlinks.
func NewAddCommand ¶
func NewAddCommand(fs FileSystem, git *GitRunner, cfg *Config, opts AddOptions) *AddCommand
NewAddCommand creates an AddCommand with explicit dependencies (for testing).
func NewDefaultAddCommand ¶
func NewDefaultAddCommand(cfg *Config, opts AddOptions) *AddCommand
NewDefaultAddCommand creates an AddCommand with production defaults.
type AddFormatOptions ¶
AddFormatOptions configures add output formatting.
type AddOptions ¶
type AddOptions struct {
Sync bool
CarryFrom string // empty: no carry, non-empty: resolved path to carry from
FilePatterns []string // file patterns to carry (empty means all files)
Lock bool
LockReason string
}
AddOptions holds options for the add command.
type AddResult ¶
type AddResult struct {
Branch string
WorktreePath string
Symlinks []SymlinkResult
GitOutput []byte
ChangesSynced bool
ChangesCarried bool
}
AddResult holds the result of an add operation.
func (AddResult) Format ¶
func (r AddResult) Format(opts AddFormatOptions) FormatResult
Format formats the AddResult for display.
type BranchDeleteOption ¶
type BranchDeleteOption func(*branchDeleteOptions)
BranchDeleteOption is a functional option for BranchDelete.
func WithForceDelete ¶
func WithForceDelete() BranchDeleteOption
WithForceDelete forces branch deletion even if not fully merged.
type CleanCandidate ¶
type CleanCandidate struct {
Branch string
WorktreePath string
Prunable bool
Skipped bool
SkipReason SkipReason
CleanReason CleanReason
}
CleanCandidate represents a worktree that can be cleaned.
type CleanCommand ¶
type CleanCommand struct {
FS FileSystem
Git *GitRunner
Config *Config
}
CleanCommand removes merged worktrees that are no longer needed.
func NewCleanCommand ¶
func NewCleanCommand(fs FileSystem, git *GitRunner, cfg *Config) *CleanCommand
NewCleanCommand creates a new CleanCommand with explicit dependencies. Use this for testing or when custom dependencies are needed.
func NewDefaultCleanCommand ¶
func NewDefaultCleanCommand(cfg *Config) *CleanCommand
NewDefaultCleanCommand creates a new CleanCommand with production dependencies.
func (*CleanCommand) Run ¶
func (c *CleanCommand) Run(cwd string, opts CleanOptions) (CleanResult, error)
Run analyzes worktrees and optionally removes them. cwd is the current working directory (absolute path) passed from CLI layer.
type CleanOptions ¶
type CleanOptions struct {
Yes bool // Execute without confirmation
Check bool // Show candidates only (no prompt)
Target string // Target branch for merge check (auto-detect if empty)
Verbose bool // Show skip reasons
Force WorktreeForceLevel // Force level: -f for unclean, -ff for locked
}
CleanOptions configures the clean operation.
type CleanReason ¶ added in v0.2.0
type CleanReason string
CleanReason describes why a branch is cleanable.
const ( CleanMerged CleanReason = "merged" CleanUpstreamGone CleanReason = "upstream gone" )
type CleanResult ¶
type CleanResult struct {
Candidates []CleanCandidate
Removed []RemovedWorktree
TargetBranch string
Pruned bool
Check bool // --check mode (show candidates only, no prompt)
}
CleanResult aggregates results from clean operations.
func (CleanResult) CleanableCount ¶
func (r CleanResult) CleanableCount() int
CleanableCount returns the number of worktrees that can be cleaned.
func (CleanResult) Format ¶
func (r CleanResult) Format(opts FormatOptions) FormatResult
Format formats the CleanResult for display.
type Config ¶
type Config struct {
Symlinks []string `toml:"symlinks"`
ExtraSymlinks []string `toml:"extra_symlinks"`
WorktreeDestBaseDir string `toml:"worktree_destination_base_dir"`
DefaultSource string `toml:"default_source"`
WorktreeSourceDir string // Set by LoadConfig to the config load directory
}
Config holds the merged configuration for the application. All path fields are resolved to absolute paths by LoadConfig.
type FileSystem ¶
type FileSystem interface {
Stat(name string) (fs.FileInfo, error)
Symlink(oldname, newname string) error
IsNotExist(err error) bool
Glob(dir, pattern string) ([]string, error)
MkdirAll(path string, perm fs.FileMode) error
ReadDir(name string) ([]os.DirEntry, error)
Remove(name string) error
WriteFile(name string, data []byte, perm fs.FileMode) error
}
FileSystem abstracts filesystem operations for testability.
type FormatOptions ¶
type FormatOptions struct {
Verbose bool
}
FormatOptions configures output formatting.
type FormatResult ¶
FormatResult holds formatted output strings.
type Formatter ¶
type Formatter interface {
Format(opts FormatOptions) FormatResult
}
Formatter formats command results.
type GitError ¶
GitError represents an error from a git operation with structured information.
type GitExecutor ¶
type GitExecutor interface {
// Run executes git with args and returns stdout.
Run(args ...string) ([]byte, error)
}
GitExecutor abstracts git command execution for testability. Commands are fixed to "git" - only subcommands and args are passed.
type GitRunner ¶
type GitRunner struct {
Executor GitExecutor
Dir string
}
GitRunner provides git operations using GitExecutor.
func NewGitRunner ¶
NewGitRunner creates a new GitRunner with the default executor.
func (*GitRunner) BranchDelete ¶
func (g *GitRunner) BranchDelete(branch string, opts ...BranchDeleteOption) ([]byte, error)
BranchDelete deletes a local branch. By default uses -d (safe delete). Use WithForceDelete() to use -D (force delete).
func (*GitRunner) BranchList ¶
BranchList returns all local branch names.
func (*GitRunner) ChangedFiles ¶
ChangedFiles returns a list of files with uncommitted changes including staged, unstaged, and untracked files.
func (*GitRunner) FindRemoteForBranch ¶ added in v0.3.0
FindRemoteForBranch finds the remote that has the specified branch. Returns the remote name if exactly one remote has the branch. Returns empty string if no remote has the branch. Returns error if multiple remotes have the branch (ambiguous).
func (*GitRunner) FindRemotesForBranch ¶ added in v0.3.0
FindRemotesForBranch returns all remotes that have the specified branch in local remote-tracking branches. This checks refs/remotes/*/<branch> locally without network access.
func (*GitRunner) HasChanges ¶
HasChanges checks if there are any uncommitted changes (staged, unstaged, or untracked).
func (*GitRunner) InDir ¶
InDir returns a GitRunner that executes commands in the specified directory.
func (*GitRunner) IsBranchMerged ¶
IsBranchMerged checks if branch is merged into target. First checks using git branch --merged (detects traditional merges). If not found, falls back to checking if upstream is gone (squash/rebase merges).
func (*GitRunner) IsBranchUpstreamGone ¶ added in v0.2.0
IsBranchUpstreamGone checks if the branch's upstream tracking branch is gone. This indicates the remote branch was deleted, typically after a PR merge.
func (*GitRunner) LocalBranchExists ¶ added in v0.3.0
LocalBranchExists checks if a branch exists in the local repository.
func (*GitRunner) StashApplyByHash ¶
StashApplyByHash applies the stash with the given hash without dropping it.
func (*GitRunner) StashDropByHash ¶
StashDropByHash drops the stash with the given hash.
func (*GitRunner) StashPopByHash ¶
StashPopByHash applies and drops the stash with the given hash.
func (*GitRunner) StashPush ¶
StashPush stashes changes including untracked files. If pathspecs are provided, only matching files are stashed. Returns the stash commit hash for later reference.
Race condition note: There is a small race window between "stash push" and "rev-parse stash@{0}". If another process creates a stash in this window, we may get the wrong hash. However, this window is very small (milliseconds) and acceptable in practice.
Why not use "stash create" + "stash store" pattern? "stash create" does not support -u/--include-untracked option (git limitation). It can only stash tracked file changes, not untracked files. See: https://git-scm.com/docs/git-stash
func (*GitRunner) WorktreeAdd ¶
func (g *GitRunner) WorktreeAdd(path, branch string, opts ...WorktreeAddOption) ([]byte, error)
WorktreeAdd creates a new worktree at the specified path.
func (*GitRunner) WorktreeFindByBranch ¶
WorktreeFindByBranch returns the Worktree for the given branch. Returns an error if the branch is not checked out in any worktree.
func (*GitRunner) WorktreeList ¶
WorktreeList returns all worktrees with their paths and branches.
func (*GitRunner) WorktreeListBranches ¶
WorktreeListBranches returns a list of branch names currently checked out in worktrees.
func (*GitRunner) WorktreePrune ¶
WorktreePrune removes references to worktrees that no longer exist.
func (*GitRunner) WorktreeRemove ¶
func (g *GitRunner) WorktreeRemove(path string, opts ...WorktreeRemoveOption) ([]byte, error)
WorktreeRemove removes the worktree at the given path. By default fails if there are uncommitted changes. Use WithForceRemove() to force.
type InitCommand ¶
type InitCommand struct {
FS FileSystem
}
InitCommand initializes twig configuration in a directory.
func NewDefaultInitCommand ¶
func NewDefaultInitCommand() *InitCommand
NewDefaultInitCommand creates an InitCommand with production defaults.
func NewInitCommand ¶
func NewInitCommand(fs FileSystem) *InitCommand
NewInitCommand creates an InitCommand with explicit dependencies (for testing).
func (*InitCommand) Run ¶
func (c *InitCommand) Run(dir string, opts InitOptions) (InitResult, error)
Run executes the init command.
type InitFormatOptions ¶
type InitFormatOptions struct {
Verbose bool
}
InitFormatOptions holds formatting options for InitResult.
type InitOptions ¶
type InitOptions struct {
Force bool
}
InitOptions holds options for the init command.
type InitResult ¶
type InitResult struct {
ConfigDir string
SettingsPath string
Created bool
Skipped bool
Overwritten bool
}
InitResult holds the result of the init command.
func (InitResult) Format ¶
func (r InitResult) Format(opts InitFormatOptions) FormatResult
Format formats the result for output.
type ListCommand ¶
type ListCommand struct {
Git *GitRunner
}
ListCommand lists all worktrees.
func NewDefaultListCommand ¶
func NewDefaultListCommand(dir string) *ListCommand
NewDefaultListCommand creates a ListCommand with production defaults.
func NewListCommand ¶
func NewListCommand(git *GitRunner) *ListCommand
NewListCommand creates a ListCommand with explicit dependencies (for testing).
type ListFormatOptions ¶
type ListFormatOptions struct {
Quiet bool
}
ListFormatOptions configures list output formatting.
type ListResult ¶
type ListResult struct {
Worktrees []Worktree
}
ListResult holds the result of a list operation.
func (ListResult) Format ¶
func (r ListResult) Format(opts ListFormatOptions) FormatResult
Format formats the ListResult for display.
type LoadConfigResult ¶
LoadConfigResult contains the loaded config and any warnings.
func LoadConfig ¶
func LoadConfig(dir string) (*LoadConfigResult, error)
type RemoveCommand ¶
type RemoveCommand struct {
FS FileSystem
Git *GitRunner
Config *Config
}
RemoveCommand removes git worktrees with their associated branches.
func NewDefaultRemoveCommand ¶
func NewDefaultRemoveCommand(cfg *Config) *RemoveCommand
NewDefaultRemoveCommand creates a RemoveCommand with production defaults.
func NewRemoveCommand ¶
func NewRemoveCommand(fs FileSystem, git *GitRunner, cfg *Config) *RemoveCommand
NewRemoveCommand creates a RemoveCommand with explicit dependencies.
func (*RemoveCommand) Run ¶
func (c *RemoveCommand) Run(branch string, cwd string, opts RemoveOptions) (RemovedWorktree, error)
Run removes the worktree and branch for the given branch name. cwd is used to prevent removal when inside the target worktree.
type RemoveOptions ¶
type RemoveOptions struct {
// Force specifies the force level.
// Matches git worktree behavior: -f for unclean, -f -f for locked.
Force WorktreeForceLevel
DryRun bool
}
RemoveOptions configures the remove operation.
type RemoveResult ¶
type RemoveResult struct {
Removed []RemovedWorktree
}
RemoveResult aggregates results from remove operations.
func (RemoveResult) ErrorCount ¶
func (r RemoveResult) ErrorCount() int
ErrorCount returns the number of failed removals.
func (RemoveResult) Format ¶
func (r RemoveResult) Format(opts FormatOptions) FormatResult
Format formats the RemoveResult for display.
func (RemoveResult) HasErrors ¶
func (r RemoveResult) HasErrors() bool
HasErrors returns true if any errors occurred.
type RemovedWorktree ¶
type RemovedWorktree struct {
Branch string
WorktreePath string
CleanedDirs []string // Empty parent directories that were removed
Pruned bool // Stale worktree record was pruned (directory was already deleted)
DryRun bool
GitOutput []byte
Err error // nil if success
}
RemovedWorktree holds the result of a single worktree removal.
func (RemovedWorktree) Format ¶
func (r RemovedWorktree) Format(opts FormatOptions) FormatResult
Format formats the RemovedWorktree for display.
type SkipReason ¶
type SkipReason string
SkipReason describes why a worktree was skipped.
const ( SkipNotMerged SkipReason = "not merged" SkipHasChanges SkipReason = "has uncommitted changes" SkipLocked SkipReason = "locked" SkipCurrentDir SkipReason = "current directory" SkipDetached SkipReason = "detached HEAD" )
type SymlinkResult ¶
SymlinkResult holds information about a symlink operation.
type Worktree ¶ added in v0.2.0
type Worktree struct {
Path string
Branch string
HEAD string
Detached bool
Locked bool
LockReason string
Prunable bool
PrunableReason string
Bare bool
}
Worktree holds worktree path and branch information.
type WorktreeAddOption ¶
type WorktreeAddOption func(*worktreeAddOptions)
WorktreeAddOption is a functional option for WorktreeAdd.
func WithCreateBranch ¶
func WithCreateBranch() WorktreeAddOption
WithCreateBranch creates a new branch when adding the worktree.
func WithLockReason ¶
func WithLockReason(reason string) WorktreeAddOption
WithLockReason sets the reason for locking the worktree.
type WorktreeForceLevel ¶
type WorktreeForceLevel uint8
WorktreeForceLevel represents the force level for worktree removal. Matches git worktree remove behavior.
const ( // WorktreeForceLevelNone means no force - fail on uncommitted changes or locked. WorktreeForceLevelNone WorktreeForceLevel = iota // WorktreeForceLevelUnclean removes unclean worktrees (-f). WorktreeForceLevelUnclean // WorktreeForceLevelLocked also removes locked worktrees (-f -f). WorktreeForceLevelLocked )
type WorktreeRemoveOption ¶
type WorktreeRemoveOption func(*worktreeRemoveOptions)
WorktreeRemoveOption is a functional option for WorktreeRemove.
func WithForceRemove ¶
func WithForceRemove(level WorktreeForceLevel) WorktreeRemoveOption
WithForceRemove forces worktree removal.