Documentation
¶
Overview ¶
Package worktree manages git worktrees for parallel epic execution.
Worktrees allow tk run to execute multiple epics simultaneously in isolated working directories, each with its own branch. This prevents conflicts between concurrent agents working on different tasks.
Worktree Lifecycle ¶
Each epic gets its own worktree under .claude/worktrees/tk-<epic-id>/ with a corresponding branch named worktree-tk-<epic-id>. The branch is created from the current HEAD (usually main) when the worktree is created.
After an epic completes successfully, its worktree can be merged back to main and then cleaned up.
Usage ¶
manager, err := worktree.NewManager("/path/to/repo")
if err != nil {
log.Fatal(err)
}
// Create worktree for an epic
wt, err := manager.Create("abc123")
if err != nil {
log.Fatal(err)
}
// Work in wt.Path...
// Clean up when done
if err := manager.Remove("abc123"); err != nil {
log.Fatal(err)
}
Package worktree provides git worktree management for isolated feature development.
Index ¶
- Constants
- Variables
- func Branch(epicID string) string
- func EnsureGitignore(repoRoot string) (bool, error)
- func Name(epicID string) string
- func Path(repoRoot, epicID string) string
- type ConflictHandler
- func (h *ConflictHandler) CheckResolved(epicID string) bool
- func (h *ConflictHandler) ClearConflict(epicID string)
- func (h *ConflictHandler) GetActiveConflicts() []*ConflictState
- func (h *ConflictHandler) GetConflict(epicID string) *ConflictState
- func (h *ConflictHandler) HandleConflict(wt *Worktree, conflicts []string, targetBranch string) *ConflictState
- func (h *ConflictHandler) HasConflict(epicID string) bool
- type ConflictState
- type Manager
- func (m *Manager) AutoCommitTickFiles() error
- func (m *Manager) Create(epicID string) (*Worktree, error)
- func (m *Manager) Exists(epicID string) bool
- func (m *Manager) Get(epicID string) (*Worktree, error)
- func (m *Manager) IsDirty() (bool, []string, error)
- func (m *Manager) IsOnlyTickFilesDirty(dirtyFiles []string) (bool, []string)
- func (m *Manager) List() ([]*Worktree, error)
- func (m *Manager) Prune() error
- func (m *Manager) Remove(epicID string) error
- type MergeManager
- type MergeOptions
- type MergeResult
- type Worktree
Constants ¶
const BranchPrefix = "worktree-" + WorktreeNamePrefix
BranchPrefix is the prefix for worktree branch names.
const DefaultWorktreeDir = ".claude/worktrees"
DefaultWorktreeDir is the default directory name for storing worktrees.
const WorktreeNamePrefix = "tk-"
WorktreeNamePrefix keeps tk-managed Claude worktrees isolated from unrelated native Claude worktrees the user may create manually.
Variables ¶
var ErrMergeConflict = errors.New("merge conflict")
ErrMergeConflict is returned when a merge cannot be completed due to conflicts.
var ErrNoMergeInProgress = errors.New("no merge in progress")
ErrNoMergeInProgress is returned when trying to abort with no merge in progress.
var ErrNoTargetBranch = errors.New("no target branch specified and no parent branch recorded")
ErrNoTargetBranch is returned when no target branch is specified and no parent branch is recorded.
var ErrNotGitRepo = errors.New("not a git repository")
ErrNotGitRepo is returned when the directory is not a git repository.
var ErrParentBranchNotFound = errors.New("parent branch no longer exists")
ErrParentBranchNotFound is returned when the parent branch no longer exists.
var ErrWorktreeExists = errors.New("worktree already exists")
ErrWorktreeExists is returned when a worktree already exists for the epic.
var ErrWorktreeNotFound = errors.New("worktree not found")
ErrWorktreeNotFound is returned when a worktree doesn't exist for the epic.
Functions ¶
func EnsureGitignore ¶
EnsureGitignore checks if .claude/worktrees/ is in .gitignore and adds it if not. Creates .gitignore if it doesn't exist. Returns true if .gitignore was modified.
Types ¶
type ConflictHandler ¶
type ConflictHandler struct {
// contains filtered or unexported fields
}
ConflictHandler manages the conflict lifecycle. It tracks active conflicts and checks for resolution.
func NewConflictHandler ¶
func NewConflictHandler(repoRoot string, merge *MergeManager) *ConflictHandler
NewConflictHandler creates a conflict handler for the given repository.
func (*ConflictHandler) CheckResolved ¶
func (h *ConflictHandler) CheckResolved(epicID string) bool
CheckResolved checks if a conflict has been manually resolved. User resolves by:
- cd to main repo
- git checkout main
- git merge <worktree branch>
- Resolve conflicts
- git commit
Returns true if the worktree branch is now merged into main.
func (*ConflictHandler) ClearConflict ¶
func (h *ConflictHandler) ClearConflict(epicID string)
ClearConflict removes a conflict from tracking (e.g., after worktree cleanup).
func (*ConflictHandler) GetActiveConflicts ¶
func (h *ConflictHandler) GetActiveConflicts() []*ConflictState
GetActiveConflicts returns all unresolved conflicts. Returns a copy of the conflict states to avoid races.
func (*ConflictHandler) GetConflict ¶
func (h *ConflictHandler) GetConflict(epicID string) *ConflictState
GetConflict returns the conflict state for a specific epic, or nil if none.
func (*ConflictHandler) HandleConflict ¶
func (h *ConflictHandler) HandleConflict(wt *Worktree, conflicts []string, targetBranch string) *ConflictState
HandleConflict is called when a merge fails due to conflict. It aborts the merge (to clean up git state) but leaves the worktree intact for user inspection. Returns ConflictState for tracking/display. The targetBranch parameter is the branch that was being merged into (from MergeResult.TargetBranch).
func (*ConflictHandler) HasConflict ¶
func (h *ConflictHandler) HasConflict(epicID string) bool
HasConflict checks if a specific epic has an active conflict.
type ConflictState ¶
type ConflictState struct {
EpicID string // Epic that had the conflict
Branch string // Branch name (e.g., worktree-tk-abc123)
Conflicts []string // List of conflicting files
WorktreePath string // Worktree path (preserved for inspection)
DetectedAt time.Time // When conflict was detected
TargetBranch string // Branch that was being merged into (e.g., main, feature/auth)
}
ConflictState tracks an unresolved merge conflict.
func (*ConflictState) ConflictInfo ¶
func (s *ConflictState) ConflictInfo() string
ConflictInfo returns a human-readable summary of the conflict.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager handles git worktree lifecycle.
func NewManager ¶
NewManager creates a worktree manager for the given repository. Returns error if not a git repository.
func (*Manager) AutoCommitTickFiles ¶
AutoCommitTickFiles commits only .tick/ files with a standard commit message. Returns nil if successful, error otherwise.
func (*Manager) Create ¶
Create creates a new worktree for an epic. Branch name: worktree-tk-<epic-id> Path: <repoRoot>/.claude/worktrees/tk-<epic-id> Creates branch from current HEAD if it doesn't exist.
func (*Manager) IsDirty ¶
IsDirty checks if the main repository has uncommitted changes. Returns true if there are modified, staged, or untracked files (excluding .claude/worktrees/).
func (*Manager) IsOnlyTickFilesDirty ¶
IsOnlyTickFilesDirty checks if only .tick/ files are dirty. Returns true if all dirty files are in .tick/ directory, false if there are other dirty files. Also returns the list of dirty tick files.
type MergeManager ¶
type MergeManager struct {
// contains filtered or unexported fields
}
MergeManager handles merging worktree branches to their target branch.
func NewMergeManager ¶
func NewMergeManager(repoRoot string) (*MergeManager, error)
NewMergeManager creates a merge manager for the given repository. Auto-detects the main branch name (main or master).
func (*MergeManager) AbortMerge ¶
func (m *MergeManager) AbortMerge() error
AbortMerge aborts an in-progress merge.
func (*MergeManager) HasConflict ¶
func (m *MergeManager) HasConflict() bool
HasConflict checks if there's an unresolved merge in progress.
func (*MergeManager) MainBranch ¶
func (m *MergeManager) MainBranch() string
MainBranch returns the detected main branch name.
func (*MergeManager) Merge ¶
func (m *MergeManager) Merge(wt *Worktree, opts MergeOptions) (*MergeResult, error)
Merge merges the worktree branch into the target branch. Must be called from main repo (not worktree). Returns MergeResult with conflict details if merge fails.
Target branch resolution: 1. If opts.TargetBranch is set, use it 2. Else if wt.ParentBranch is set, use it 3. Else return ErrNoTargetBranch
type MergeOptions ¶ added in v0.9.0
type MergeOptions struct {
TargetBranch string // Target branch to merge into (overrides worktree's ParentBranch)
}
MergeOptions contains options for the Merge operation.
type MergeResult ¶
type MergeResult struct {
Success bool // True if merge completed successfully
Merged bool // True if merge was performed (not just fast-forward check)
Conflicts []string // List of conflicting files if any
MergeCommit string // Commit hash of merge commit (if success)
ErrorMessage string // Error details if failed
TargetBranch string // The branch that was merged into
}
MergeResult represents the outcome of a merge attempt.
type Worktree ¶
type Worktree struct {
Path string // Absolute path to worktree directory
Branch string // Branch name (e.g., worktree-tk-abc123)
EpicID string // Associated epic ID
Created time.Time // When worktree was created
ParentBranch string // Branch from which this worktree was created
}
Worktree represents an active git worktree.