Documentation
¶
Overview ¶
Package engine provides the core branch state management interface and implementation. It tracks branch relationships, metadata, and provides operations for querying and manipulating the branch stack. Package engine manages the state and relationships of stacked branches.
It is the core of stackit, responsible for:
- Tracking parent-child relationships between branches
- Storing and retrieving branch metadata (PR info, status, etc.)
- Managing the branch stack structure
- Coordinating branch operations like splitting, squashing, and restacking
The engine abstracts the underlying storage (git refs, notes) and provides a high-level interface for branch management.
Package engine provides undo/redo functionality through state snapshots
Index ¶
- Constants
- Variables
- func IsConcurrentModificationError(err error) bool
- type Absorber
- type ApplySplitOptions
- type BatchFreezeResult
- type BatchLockResult
- type Branch
- func (b Branch) CanModify() bool
- func (b Branch) DefaultPRBody() string
- func (b Branch) DefaultPRTitle() string
- func (b Branch) EnsureCanModify() error
- func (b Branch) Equal(other Branch) bool
- func (b Branch) GetAllCommits(format CommitFormat) ([]string, error)
- func (b Branch) GetCommitAuthor() (string, error)
- func (b Branch) GetCommitCount() (int, error)
- func (b Branch) GetCommitDate() (time.Time, error)
- func (b Branch) GetDiffStats() (added int, deleted int, err error)
- func (b Branch) GetExplicitScope() Scope
- func (b Branch) GetLockReason() LockReason
- func (b Branch) GetMergedDownstack() []git.MergedParent
- func (b Branch) GetName() string
- func (b Branch) GetPRSubmissionStatus() (PRSubmissionStatus, error)
- func (b Branch) GetParent() *Branch
- func (b Branch) GetParentOrTrunk() string
- func (b Branch) GetPrInfo() (*PrInfo, error)
- func (b Branch) GetRevision() (string, error)
- func (b Branch) GetScope() Scope
- func (b Branch) IsBranchUpToDate() bool
- func (b Branch) IsFrozen() bool
- func (b Branch) IsLocked() bool
- func (b Branch) IsTracked() bool
- func (b Branch) IsTrunk() bool
- func (b Branch) IsWorktreeAnchor() bool
- func (b Branch) ModificationBlocker() string
- func (b Branch) NeedsRestack() bool
- type BranchInfo
- type BranchMutations
- type BranchReader
- type BranchRemoteStatus
- type BranchSet
- type BranchState
- type BranchStateMap
- func (m BranchStateMap) Delete(name string)
- func (m BranchStateMap) Get(branch Branch) *BranchState
- func (m BranchStateMap) GetByName(name string) *BranchState
- func (m BranchStateMap) GetOrCreate(name string) *BranchState
- func (m BranchStateMap) Has(branch Branch) bool
- func (m BranchStateMap) HasByName(name string) bool
- func (m BranchStateMap) Set(name string, state *BranchState)
- type BranchStatus
- type BranchTracking
- type BranchWriter
- type CommitFormat
- type CommitOperations
- type ContinueRebaseResult
- type DeletionReasonKind
- type DeletionStatus
- type Engine
- type FieldDiff
- type GitDiffer
- type IndependentStack
- type Initializer
- type LockReason
- type MergeOptions
- type MetadataDiff
- type MetadataTx
- func (tx *MetadataTx) Commit(ctx context.Context) error
- func (tx *MetadataTx) DeleteLocalMeta(branch string) error
- func (tx *MetadataTx) DeleteMeta(branch string) error
- func (tx *MetadataTx) IsCommitted() bool
- func (tx *MetadataTx) Rollback()
- func (tx *MetadataTx) UpdateLocalMeta(branch string, meta *git.LocalMeta) error
- func (tx *MetadataTx) UpdateMeta(branch string, meta *git.Meta) error
- type Options
- type OrphanedMetadataAction
- type OrphanedMetadataInfo
- type PRManager
- type PRSubmissionStatus
- type PendingChange
- type PrInfo
- func NewPrInfo(number *int, title, body, state, base, url string, isDraft bool) *PrInfo
- func NewPrInfoFromMeta(meta *git.Meta) *PrInfo
- func NewPrInfoFull(number *int, title, body, state, base, url string, isDraft bool, ...) *PrInfo
- func NewPrInfoWithLockReason(number *int, title, body, state, base, url string, isDraft bool, ...) *PrInfo
- func (p *PrInfo) Base() string
- func (p *PrInfo) Body() string
- func (p *PrInfo) IsDraft() bool
- func (p *PrInfo) IsLocked() bool
- func (p *PrInfo) LockReason() LockReason
- func (p *PrInfo) MarshalJSON() ([]byte, error)
- func (p *PrInfo) MergeBranch() string
- func (p *PrInfo) Number() *int
- func (p *PrInfo) State() string
- func (p *PrInfo) Title() string
- func (p *PrInfo) URL() string
- func (p *PrInfo) WithBase(base string) *PrInfo
- func (p *PrInfo) WithBody(body string) *PrInfo
- func (p *PrInfo) WithIsDraft(isDraft bool) *PrInfo
- func (p *PrInfo) WithLockReason(reason LockReason) *PrInfo
- func (p *PrInfo) WithMergeBranch(branch string) *PrInfo
- func (p *PrInfo) WithNumber(number *int) *PrInfo
- func (p *PrInfo) WithState(state string) *PrInfo
- func (p *PrInfo) WithTitle(title string) *PrInfo
- func (p *PrInfo) WithTitleAndBody(title, body string) *PrInfo
- func (p *PrInfo) WithURL(url string) *PrInfo
- type PullResult
- type RebaseSpec
- type RebaseValidation
- type RemoteMetadataManager
- type RemoteMetadataView
- type RestackBatchResult
- type RestackBranchProgressFunc
- type RestackBranchResult
- type RestackPlan
- type RestackPlanAction
- type RestackPlanItem
- type RestackResult
- type Scope
- func (s Scope) ApplyToTitle(title string) string
- func (s Scope) Equal(other Scope) bool
- func (s Scope) IsDefined() bool
- func (s Scope) IsEmpty() bool
- func (s Scope) IsNone() bool
- func (s Scope) MarshalJSON() ([]byte, error)
- func (s Scope) String() string
- func (s Scope) TitleNeedsUpdate(title string) bool
- func (s *Scope) UnmarshalJSON(data []byte) error
- type Snapshot
- type SnapshotInfo
- type SnapshotOptions
- type SortStrategy
- type SquashOptions
- type StackGraph
- func (g *StackGraph) BranchesAtDepth(depth int) []Branch
- func (g *StackGraph) ChildBranches(branch Branch) []Branch
- func (g *StackGraph) Children(branch Branch) []string
- func (g *StackGraph) CollectBranches(root Branch) []Branch
- func (g *StackGraph) CurrentBranch() string
- func (g *StackGraph) Downstack(branch Branch, includeCurrent bool) []Branch
- func (g *StackGraph) ForEachDepth(fn func(depth int, branches []Branch) error) error
- func (g *StackGraph) FullStack(branch Branch) []Branch
- func (g *StackGraph) GetBranchesByDepth() map[int][]string
- func (g *StackGraph) GetNode(branchName string) *StackNode
- func (g *StackGraph) IsDescendant(branch Branch, potentialDescendant Branch) bool
- func (g *StackGraph) IsLeaf(branch Branch) bool
- func (g *StackGraph) IsRelated(branch1, branch2 Branch) bool
- func (g *StackGraph) MaxDepth() int
- func (g *StackGraph) Node(branch Branch) *StackNode
- func (g *StackGraph) Parent(branch Branch) string
- func (g *StackGraph) Range(branch Branch, rng StackRange) []Branch
- func (g *StackGraph) RootBranches() []string
- func (g *StackGraph) TrunkName() string
- func (g *StackGraph) Upstack(branch Branch, includeCurrent bool) []Branch
- type StackNavigator
- type StackNode
- type StackRange
- type StackRewriter
- type SyncManager
- type UndoManager
- type ValidationErrorType
- type ValidationResult
- type WorkingTree
- type WorktreeCheckoutMode
- type WorktreeEngineOptions
- type WorktreeInfo
- type WorktreeOperations
- type WorktreePruneMode
- type WorktreeRegistry
- type WorktreeSnapshot
Constants ¶
const ( // MaxRetries is the maximum number of retry attempts for transactional operations. // 5 retries with exponential backoff gives ~3 seconds total wait time. MaxRetries = 5 // RetryBaseDelay is the base delay between retry attempts. // With exponential backoff: 100ms, 200ms, 400ms, 800ms, 1600ms (capped). RetryBaseDelay = 100 * time.Millisecond )
Transaction retry configuration
const ( // DefaultMaxUndoStackDepth is the default number of snapshots we keep DefaultMaxUndoStackDepth = 10 // UndoDir is the directory where undo snapshots are stored UndoDir = ".git/stackit/undo" )
const (
// ReasonNoChanges indicates there are no changes to submit
ReasonNoChanges = "no changes"
)
Variables ¶
var ( // ErrTransactionCommitted is returned when attempting to modify a committed transaction ErrTransactionCommitted = errors.New("transaction already committed") // ErrTransactionRolledBack is returned when attempting to use a rolled-back transaction ErrTransactionRolledBack = errors.New("transaction was rolled back") )
Sentinel errors for transaction operations
Functions ¶
func IsConcurrentModificationError ¶
IsConcurrentModificationError returns true if the error indicates a concurrent modification conflict (CAS failure). This includes various git update-ref errors that occur when references are modified between read and write operations.
Types ¶
type Absorber ¶
type Absorber interface {
ApplyHunksToBranch(ctx context.Context, branch Branch, hunksByCommit map[string][]git.Hunk) error
FindTargetCommitForHunk(hunk git.Hunk, commitSHAs []string) (string, int, error)
}
Absorber applies staged hunks to appropriate commits
type ApplySplitOptions ¶
type ApplySplitOptions struct {
BranchToSplit string // The branch being split
BranchNames []string // Branch names from oldest to newest
BranchPoints []int // Commit indices (0 = HEAD, 1 = HEAD~1, etc.)
// AsSibling creates all split branches as siblings on the same parent,
// instead of creating a linear chain. When true:
// - All new branches share the same parent (the original branch's parent)
// - Branches are independent rather than stacked on each other
AsSibling bool
}
ApplySplitOptions contains options for applying a split
type BatchFreezeResult ¶
BatchFreezeResult represents the result of a batch freeze/unfreeze operation
type BatchLockResult ¶
BatchLockResult represents the result of a batch lock/unlock operation
type Branch ¶
type Branch struct {
// contains filtered or unexported fields
}
Branch represents a branch in the stack
func FilterBranches ¶
func FilterBranches(eng StackNavigator, predicate func(Branch) bool) []Branch
FilterBranches returns branches matching the predicate.
func (Branch) CanModify ¶
CanModify checks if the branch can be modified (not locked, frozen, or a worktree anchor)
func (Branch) DefaultPRBody ¶
DefaultPRBody returns the default PR body for this branch. For single commit: uses the commit body (skips subject line). For multiple commits: creates a bulleted list of subjects in chronological order.
func (Branch) DefaultPRTitle ¶
DefaultPRTitle returns the default PR title for this branch. Uses the oldest commit subject, falling back to the branch name.
func (Branch) EnsureCanModify ¶
EnsureCanModify checks if the branch can be modified and returns an error if not
func (Branch) GetAllCommits ¶
func (b Branch) GetAllCommits(format CommitFormat) ([]string, error)
GetAllCommits returns commits for this branch in various formats
func (Branch) GetCommitAuthor ¶
GetCommitAuthor returns the commit author for this branch
func (Branch) GetCommitCount ¶
GetCommitCount returns the number of commits for this branch
func (Branch) GetCommitDate ¶
GetCommitDate returns the commit date for this branch
func (Branch) GetDiffStats ¶
GetDiffStats returns the number of lines added and deleted for this branch
func (Branch) GetExplicitScope ¶
GetExplicitScope returns the explicit scope set for this branch (no inheritance)
func (Branch) GetLockReason ¶
func (b Branch) GetLockReason() LockReason
GetLockReason returns why the branch is locked
func (Branch) GetMergedDownstack ¶
func (b Branch) GetMergedDownstack() []git.MergedParent
GetMergedDownstack returns the merged downstack history for this branch
func (Branch) GetName ¶
GetName returns the branch name. This method allows Branch to implement the engine.Branch interface without creating circular dependencies.
func (Branch) GetPRSubmissionStatus ¶
func (b Branch) GetPRSubmissionStatus() (PRSubmissionStatus, error)
GetPRSubmissionStatus returns the PR submission status for this branch
func (Branch) GetParentOrTrunk ¶
GetParentOrTrunk returns the parent branch name, or trunk if no parent This is used for validation where we expect a parent to exist
func (Branch) GetRevision ¶
GetRevision returns the SHA of this branch
func (Branch) GetScope ¶
GetScope returns the scope for this branch, inheriting from parent if not set
func (Branch) IsBranchUpToDate ¶
IsBranchUpToDate checks if this branch is up to date with its parent A branch is up to date if its parent revision matches the stored parent revision
func (Branch) IsWorktreeAnchor ¶
IsWorktreeAnchor checks if the branch is a worktree anchor branch
func (Branch) ModificationBlocker ¶
ModificationBlocker returns a human-readable reason why the branch cannot be modified, or an empty string if the branch can be modified. This is useful for displaying status in UIs or logs without throwing errors.
func (Branch) NeedsRestack ¶
NeedsRestack returns true if the branch needs to be restacked onto its parent. This is the inverse of IsBranchUpToDate - a branch needs restacking when its parent has moved and the branch is no longer based on the current parent tip.
type BranchInfo ¶
type BranchInfo interface {
GetCommitDate(branch Branch) (time.Time, error)
GetCommitAuthor(branch Branch) (string, error)
GetRevision(branch Branch) (string, error)
GetCommitCount(branch Branch) (int, error)
GetDiffStats(branch Branch) (added int, deleted int, err error)
GetAllCommits(branch Branch, format CommitFormat) ([]string, error)
GetParentCommitSHA(commitSHA string) (string, error)
GetCommitSHA(branchName string, offset int) (string, error)
GetRevisionForName(branchName string) (string, error)
BatchGetRevisions(branchNames []string) (map[string]string, []error)
GetCurrentRevision(ctx context.Context) (string, error)
GetRecentTrunkCommits(count int) ([]git.RecentCommit, error)
GetReflog(ctx context.Context, count int, format string) (string, error)
// GetDivergencePoint returns the divergence point of a branch from its parent.
// Returns the ParentBranchRevision from metadata if valid, otherwise the parent's current revision.
GetDivergencePoint(branchName string) (string, error)
// PreloadBranchData batch-loads metadata and revisions for all branches
// into their respective caches. Call before parallel annotation building
// to eliminate per-branch cache misses and mutex contention.
PreloadBranchData()
}
BranchInfo provides commit and diff metadata
type BranchMutations ¶
type BranchMutations interface {
RenameBranch(ctx context.Context, oldBranch, newBranch Branch) error
DeleteBranch(ctx context.Context, branch Branch) error
DeleteBranches(ctx context.Context, branches []Branch) ([]string, error)
CheckoutBranch(ctx context.Context, branch Branch) error
CreateAndCheckoutBranch(ctx context.Context, branch Branch) error
UpdateBranchRef(ctx context.Context, branchName, revision string) error
CreateBranch(ctx context.Context, branchName string, startPoint string) error
ResetHard(ctx context.Context, revision string) error
ResetMerge(ctx context.Context, revision string) error
Merge(ctx context.Context, revision string, opts MergeOptions) error
MergeMultiple(ctx context.Context, branches []string, opts MergeOptions) error
Fetch(ctx context.Context, remote string, branch string) error
InteractiveRebase(ctx context.Context, onto string) error
}
BranchMutations handles branch lifecycle operations
type BranchReader ¶
type BranchReader interface {
StackNavigator
BranchStatus
BranchInfo
GitDiffer
WorkingTree
}
BranchReader is a composite interface for backward compatibility Prefer using the smaller, focused interfaces above for new code
type BranchRemoteStatus ¶
BranchRemoteStatus represents the relationship between a local branch and its remote counterpart
func (BranchRemoteStatus) Ahead ¶
func (s BranchRemoteStatus) Ahead() bool
Ahead returns true if the local branch has commits not yet on remote
func (BranchRemoteStatus) Behind ¶
func (s BranchRemoteStatus) Behind() bool
Behind returns true if the remote branch has commits not yet on local
func (BranchRemoteStatus) Diverged ¶
func (s BranchRemoteStatus) Diverged() bool
Diverged returns true if both local and remote have unique commits
func (BranchRemoteStatus) Matches ¶
func (s BranchRemoteStatus) Matches() bool
Matches returns true if local and remote SHAs are identical
func (BranchRemoteStatus) MissingRemote ¶
func (s BranchRemoteStatus) MissingRemote() bool
MissingRemote returns true if the branch does not exist on the remote
type BranchSet ¶
type BranchSet struct {
// contains filtered or unexported fields
}
BranchSet provides O(1) branch name lookups with a cached set. Use BranchNames() on StackNavigator to get a cached instance.
type BranchState ¶
type BranchState struct {
Parent string // Parent branch name
Scope string // Scope string (may be empty)
LockReason git.LockReason // Lock reason (empty if not locked)
Frozen bool // Whether branch is frozen (local-only state)
BranchType git.BranchType // Branch type (worktree-anchor, utility, etc.)
RemoteSHA string // Remote SHA (populated by PopulateRemoteShas)
LocalModified bool // Has local metadata changes not yet pushed
}
BranchState holds the cached metadata state for a single branch. This consolidates what was previously stored in separate maps.
func (*BranchState) GetScope ¶
func (s *BranchState) GetScope() Scope
GetScope returns the scope as a Scope type.
func (*BranchState) HasScope ¶
func (s *BranchState) HasScope() bool
HasScope returns true if this branch has an explicit scope set.
func (*BranchState) IsLocked ¶
func (s *BranchState) IsLocked() bool
IsLocked returns true if this branch is locked.
type BranchStateMap ¶
type BranchStateMap map[string]*BranchState
BranchStateMap is a map of branch names to their state.
func (BranchStateMap) Delete ¶
func (m BranchStateMap) Delete(name string)
Delete removes a branch from the map.
func (BranchStateMap) Get ¶
func (m BranchStateMap) Get(branch Branch) *BranchState
Get returns the state for a branch, or nil if not found.
func (BranchStateMap) GetByName ¶
func (m BranchStateMap) GetByName(name string) *BranchState
GetByName returns the state for a branch name, or nil if not found.
func (BranchStateMap) GetOrCreate ¶
func (m BranchStateMap) GetOrCreate(name string) *BranchState
GetOrCreate returns the state for a branch, creating it if it doesn't exist.
func (BranchStateMap) Has ¶
func (m BranchStateMap) Has(branch Branch) bool
Has returns true if the branch exists in the map.
func (BranchStateMap) HasByName ¶
func (m BranchStateMap) HasByName(name string) bool
HasByName returns true if the branch name exists in the map.
func (BranchStateMap) Set ¶
func (m BranchStateMap) Set(name string, state *BranchState)
Set sets the state for a branch.
type BranchStatus ¶
type BranchStatus interface {
GetBranch(branchName string) Branch
IsTrunk(branch Branch) bool
IsTracked(branch Branch) bool
IsUpToDate(branch Branch) bool
IsMergedIntoTrunk(ctx context.Context, branchName string) (bool, error)
IsBranchEmpty(ctx context.Context, branchName string) (bool, error)
GetDeletionStatus(ctx context.Context, branchName string) (DeletionStatus, error)
BatchGetDeletionStatuses(ctx context.Context, branchNames []string) (map[string]DeletionStatus, error)
GetScope(branch Branch) Scope
GetStackDescription(branch Branch) *git.StackDescription
IsLocked(branch Branch) bool
GetLockReason(branch Branch) LockReason
IsFrozen(branch Branch) bool
IsWorktreeAnchor(branch Branch) bool
GetBranchType(branch Branch) git.BranchType
GetPrInfo(branch Branch) (*PrInfo, error)
FindMostRecentTrackedAncestors(ctx context.Context, branchName string) ([]string, error)
GetRemote() string
GetRemoteURL(ctx context.Context) (string, error)
GetBranchRemoteDifference(branchName string) (string, error)
GetBranchRemoteStatus(branch Branch) (BranchRemoteStatus, error)
GetMergedBranches(ctx context.Context, target string) (map[string]bool, error)
}
BranchStatus provides branch state information
type BranchTracking ¶
type BranchTracking interface {
TrackBranch(ctx context.Context, branchName string, parentBranchName string) error
UntrackBranch(branchName string) error
SetParent(ctx context.Context, branch Branch, parentBranch Branch) error
// ReparentBranch changes a branch's parent while automatically preserving
// its divergence point. Preferred over SetParent for existing branches.
ReparentBranch(ctx context.Context, branch Branch, newParent Branch) error
// ReparentBranches changes multiple branches to the same new parent while
// preserving divergence points. All divergence points are captured before
// any reparenting begins.
ReparentBranches(ctx context.Context, branchNames []string, newParent Branch) error
SetScope(ctx context.Context, branch Branch, scope Scope) error
SetBranchType(branch Branch, branchType git.BranchType) error
SetLocked(ctx context.Context, branches []Branch, reason LockReason) (BatchLockResult, error)
SetFrozen(ctx context.Context, branches []Branch, frozen bool) (BatchFreezeResult, error)
// BatchMarkNeedsPRBodyUpdate marks multiple branches as needing PR body update in a single atomic operation
BatchMarkNeedsPRBodyUpdate(branchNames []string) error
// ClearNeedsPRBodyUpdate clears the PR body update flag for a branch
ClearNeedsPRBodyUpdate(branchName string) error
// GetBranchesNeedingPRBodyUpdate returns all branches that need PR body updates
GetBranchesNeedingPRBodyUpdate() []string
// GetStackDescription returns the stack description for a branch's stack.
// It first checks the stack ref, then falls back to legacy branch metadata.
GetStackDescription(branch Branch) *git.StackDescription
// SetStackDescription sets the stack description in the stack ref for a branch.
// Returns an error if the branch is not part of a tracked stack.
SetStackDescription(ctx context.Context, branch Branch, desc *git.StackDescription) error
// ClearStackDescription removes the stack description from the stack ref.
ClearStackDescription(ctx context.Context, branch Branch) error
// GenerateStackID creates a new stack ID for a new stack.
// Format: {timestamp-nanos}-{sanitized-root-branch}
GenerateStackID(rootBranch string) string
// GetStackID returns the stack ID for a branch.
// Returns empty string for untracked branches or trunk.
// For legacy branches without StackID, derives it from the stack root.
GetStackID(branch Branch) string
// EnsureStackID returns the stack ID for a branch, creating one if it doesn't exist.
// This is used for lazy creation of stack metadata when setting descriptions or scopes.
EnsureStackID(ctx context.Context, branch Branch) (string, error)
// SetStackID sets the stack ID on a branch's metadata.
SetStackID(ctx context.Context, branch Branch, stackID string) error
// CreateStackRef creates a new stack ref with the given metadata.
CreateStackRef(stackID string, meta *git.StackMeta) error
// GetStackMeta returns the stack metadata for a stack ID.
GetStackMeta(stackID string) (*git.StackMeta, error)
// SyncStackIDFromParent updates a branch's stack ID to match its parent's.
// This should be called after reparenting operations to keep stack IDs consistent.
// Returns nil if the parent is trunk (keeps existing stack ID) or if no change is needed.
SyncStackIDFromParent(ctx context.Context, branch Branch) error
}
BranchTracking handles branch tracking operations
type BranchWriter ¶
type BranchWriter interface {
BranchTracking
BranchMutations
CommitOperations
WorktreeOperations
Initializer
}
BranchWriter is a composite interface for backward compatibility Prefer using the smaller, focused interfaces above for new code
type CommitFormat ¶
type CommitFormat string
CommitFormat specifies the format for commit output
const ( // CommitFormatSHA is the full commit SHA CommitFormatSHA CommitFormat = "SHA" // Full SHA // CommitFormatReadable is a readable one-line format CommitFormatReadable CommitFormat = "READABLE" // Oneline format: "abc123 Commit message" // CommitFormatReadableWithDate includes an ISO date: "abc123\t2024-01-15T10:30:00Z\tCommit message" CommitFormatReadableWithDate CommitFormat = "READABLE_WITH_DATE" // CommitFormatMessage is the full commit message CommitFormatMessage CommitFormat = "MESSAGE" // Full commit message // CommitFormatSubject is the first line of the commit message CommitFormatSubject CommitFormat = "SUBJECT" // First line of commit message )
type CommitOperations ¶
type CommitOperations interface {
Commit(ctx context.Context, message string, verbose int, noVerify bool) error
CommitWithOptions(ctx context.Context, opts git.CommitOptions) error
StageAll(ctx context.Context) error
StagePatch(ctx context.Context) error
StageHunks(ctx context.Context, hunks []git.Hunk) error
StashPush(ctx context.Context, message string) (string, error)
StashPushStaged(ctx context.Context, message string) (string, error)
StashPop(ctx context.Context) error
}
CommitOperations handles staging and committing
type ContinueRebaseResult ¶
type ContinueRebaseResult struct {
Result int // git.RebaseResult value (0 = RebaseDone, 1 = RebaseConflict)
BranchName string // Only set if Result is RebaseDone
RerereResolvedCount int // Number of rebase continuations handled by git rerere
}
ContinueRebaseResult represents the result of continuing a rebase
type DeletionReasonKind ¶
type DeletionReasonKind string
DeletionReasonKind is a machine-readable reason for branch deletion eligibility.
const ( DeletionReasonNone DeletionReasonKind = "none" DeletionReasonClosedPR DeletionReasonKind = "closed_pr" DeletionReasonMergedPR DeletionReasonKind = "merged_pr" DeletionReasonMergedIntoTrunk DeletionReasonKind = "merged_into_trunk" DeletionReasonEmptyWithPR DeletionReasonKind = "empty_with_pr" // DeletionReasonGhost is set for branches whose metadata is still on // disk but whose git ref has been deleted out-of-band (e.g., the user // ran `git branch -D` directly). Sync synthesizes this so the metadata // gets cleaned up and surviving children get reparented past the gap. DeletionReasonGhost DeletionReasonKind = "ghost" )
type DeletionStatus ¶
type DeletionStatus struct {
SafeToDelete bool // True if the branch is merged, closed, or empty (with PR)
Reason string // Human-readable reason why it's safe (or not) to delete
Kind DeletionReasonKind // Machine-readable deletion reason
HasUnpushedChanges bool // Local branch is ahead of or diverged from remote
}
DeletionStatus represents the deletion status of a branch
type Engine ¶
type Engine interface {
BranchReader
BranchWriter
PRManager
SyncManager
StackRewriter
Absorber
UndoManager
RemoteMetadataManager
WorktreeRegistry
Git() git.Runner
// SnapshotForWorktree creates a deep copy of engine state for initializing
// worktree engines without the cost of rebuildInternal.
SnapshotForWorktree() WorktreeSnapshot
}
Engine is the core interface for branch state management It composes BranchReader, BranchWriter, PRManager, SyncManager, HistoryRewriter, and UndoManager for backward compatibility. New code should prefer using the smaller interfaces. Thread-safe: All methods are safe for concurrent use
func NewEngineForWorktree ¶
func NewEngineForWorktree(opts WorktreeEngineOptions) (Engine, error)
NewEngineForWorktree creates an engine for a worktree session using a snapshot from the parent engine. This skips rebuildInternal and maybeAutoFetchRemoteMetadata since worktrees share .git with the parent and the metadata is identical.
type GitDiffer ¶
type GitDiffer interface {
GetMergeBase(rev1, rev2 string) (string, error)
GetChangedFiles(ctx context.Context, base, head string) ([]string, error)
IsDiffEmpty(ctx context.Context, base, head string) (bool, error)
ShowDiff(ctx context.Context, left, right string, stat bool) (string, error)
ShowCommits(ctx context.Context, base, head string, patch, stat bool) (string, error)
IsAncestor(ancestor, descendant string) (bool, error)
// GetDiffBetween returns raw diff between two refs, suitable for parsing into hunks.
GetDiffBetween(ctx context.Context, base, head string, files ...string) (string, error)
}
GitDiffer handles diff and merge operations
type IndependentStack ¶
IndependentStack describes a standalone stack rooted at a direct child of trunk.
func DiscoverIndependentStacks ¶
func DiscoverIndependentStacks(eng BranchReader) []IndependentStack
DiscoverIndependentStacks returns all stacks rooted at direct children of trunk.
Each stack includes its root branch first, followed by descendants in the graph's depth-first order. Branches from separate stacks are independent of each other.
func DiscoverIndependentStacksWithSort ¶
func DiscoverIndependentStacksWithSort(eng BranchReader, strategy SortStrategy) []IndependentStack
DiscoverIndependentStacksWithSort is like DiscoverIndependentStacks, but allows callers to choose how sibling branches are ordered.
type Initializer ¶
Initializer handles repository initialization operations
type LockReason ¶
type LockReason = git.LockReason
LockReason is re-exported from git package
const ( // LockReasonNone indicates the branch is not locked LockReasonNone LockReason = git.LockReasonNone // LockReasonUser indicates the branch was manually locked by the user LockReasonUser LockReason = git.LockReasonUser // LockReasonConsolidating indicates the branch is being consolidated LockReasonConsolidating LockReason = git.LockReasonConsolidating // LockReasonDraining indicates the branch is being drained (merge drain in progress) LockReasonDraining LockReason = git.LockReasonDraining )
type MergeOptions ¶
MergeOptions contains options for merging branches
type MetadataDiff ¶
type MetadataDiff struct {
Branch string
LocalMeta *git.Meta
RemoteMeta *git.Meta
Differences []FieldDiff
HasConflict bool
}
MetadataDiff represents the differences between local and remote metadata
type MetadataTx ¶
type MetadataTx struct {
// contains filtered or unexported fields
}
MetadataTx represents an atomic metadata transaction. It batches multiple metadata updates and commits them atomically using git update-ref --stdin. All updates either succeed together or fail together.
func (*MetadataTx) Commit ¶
func (tx *MetadataTx) Commit(ctx context.Context) error
Commit atomically applies all staged metadata changes and deletions. All updates succeed together or fail together via git update-ref --stdin. On success, the in-memory cache is updated to reflect the changes.
func (*MetadataTx) DeleteLocalMeta ¶
func (tx *MetadataTx) DeleteLocalMeta(branch string) error
DeleteLocalMeta stages a local metadata deletion for atomic commit.
func (*MetadataTx) DeleteMeta ¶
func (tx *MetadataTx) DeleteMeta(branch string) error
DeleteMeta stages a metadata deletion for atomic commit. The deletion uses CAS validation to ensure the ref hasn't changed.
func (*MetadataTx) IsCommitted ¶
func (tx *MetadataTx) IsCommitted() bool
IsCommitted returns true if the transaction has been committed.
func (*MetadataTx) Rollback ¶
func (tx *MetadataTx) Rollback()
Rollback discards all staged changes without applying them.
func (*MetadataTx) UpdateLocalMeta ¶
func (tx *MetadataTx) UpdateLocalMeta(branch string, meta *git.LocalMeta) error
UpdateLocalMeta stages a local metadata update for atomic commit.
func (*MetadataTx) UpdateMeta ¶
func (tx *MetadataTx) UpdateMeta(branch string, meta *git.Meta) error
UpdateMeta stages a metadata update for atomic commit. The update is not applied until Commit() is called.
type Options ¶
type Options struct {
// RepoRoot is the root directory of the Git repository
RepoRoot string
// Trunk is the primary trunk branch name (e.g., "main", "master")
Trunk string
// MaxUndoStackDepth is the maximum number of undo snapshots to keep.
// If zero or negative, defaults to DefaultMaxUndoStackDepth (10).
MaxUndoStackDepth int
// MaxConcurrency is the maximum number of concurrent validation operations.
// If zero or negative, defaults to min(NumCPU, 8).
MaxConcurrency int
// Git is the git runner to use. If nil, a default real git runner is used.
Git git.Runner
// Writer is the output writer for warnings and informational messages.
// If nil, os.Stderr is used.
Writer io.Writer
}
Options contains configuration options for creating an Engine
type OrphanedMetadataAction ¶
type OrphanedMetadataAction string
OrphanedMetadataAction represents the action to take for orphaned metadata
const ( // OrphanedActionDelete indicates the local metadata should be deleted OrphanedActionDelete OrphanedMetadataAction = "delete" // OrphanedActionPrompt indicates the user should be prompted OrphanedActionPrompt OrphanedMetadataAction = "prompt" )
type OrphanedMetadataInfo ¶
type OrphanedMetadataInfo struct {
BranchName string
Action OrphanedMetadataAction
HasLocalChanges bool
ExistsLocally bool
LocalMeta *git.Meta
}
OrphanedMetadataInfo contains information about orphaned local metadata
type PRManager ¶
type PRManager interface {
UpsertPrInfo(ctx context.Context, branch Branch, prInfo *PrInfo) error
GetBranchRemoteStatus(branch Branch) (BranchRemoteStatus, error)
PopulateRemoteShas() error
PushBranch(ctx context.Context, branch Branch, remote string, opts git.PushOptions) error
// Navigation comment ID caching (stored in local metadata)
}
PRManager provides operations for managing pull request information Thread-safe: All methods are safe for concurrent use
type PRSubmissionStatus ¶
type PRSubmissionStatus struct {
Action string // "create", "update", or "skip"
NeedsUpdate bool // True if the branch has changes or metadata needs update
Reason string // Reason for the status
PRNumber *int
PRInfo *PrInfo
}
PRSubmissionStatus represents the submission status of a branch
type PendingChange ¶
PendingChange represents a changed file in the working directory
type PrInfo ¶
type PrInfo struct {
// contains filtered or unexported fields
}
PrInfo represents PR information for a branch PrInfo is immutable - use With* methods to create modified copies
func NewPrInfoFromMeta ¶
NewPrInfoFromMeta creates a PrInfo from git.Meta
func NewPrInfoFull ¶
func NewPrInfoFull(number *int, title, body, state, base, url string, isDraft bool, lockReason LockReason, mergeBranch string) *PrInfo
NewPrInfoFull creates a new PrInfo instance with all fields
func NewPrInfoWithLockReason ¶
func NewPrInfoWithLockReason(number *int, title, body, state, base, url string, isDraft bool, lockReason LockReason) *PrInfo
NewPrInfoWithLockReason creates a new PrInfo instance including lock reason
func (*PrInfo) LockReason ¶
func (p *PrInfo) LockReason() LockReason
LockReason returns the reason why the PR is locked
func (*PrInfo) MarshalJSON ¶
MarshalJSON implements json.Marshaler for PrInfo
func (*PrInfo) MergeBranch ¶
MergeBranch returns the name of the merge branch this PR is part of
func (*PrInfo) WithIsDraft ¶
WithIsDraft returns a new PrInfo with the isDraft field updated
func (*PrInfo) WithLockReason ¶
func (p *PrInfo) WithLockReason(reason LockReason) *PrInfo
WithLockReason returns a new PrInfo with the lockReason field updated
func (*PrInfo) WithMergeBranch ¶
WithMergeBranch returns a new PrInfo with the mergeBranch field updated
func (*PrInfo) WithNumber ¶
WithNumber returns a new PrInfo with the number field updated
func (*PrInfo) WithTitleAndBody ¶
WithTitleAndBody returns a new PrInfo with both title and body fields updated This is more efficient than chaining WithTitle().WithBody() as it only creates one copy
type PullResult ¶
type PullResult int
PullResult represents the result of pulling trunk
const ( // PullDone indicates the pull was successful PullDone PullResult = iota // PullUnneeded indicates no pull was needed PullUnneeded // PullConflict indicates a conflict occurred during pull PullConflict )
type RebaseSpec ¶
type RebaseSpec struct {
Branch string // Branch to rebase
NewParent string // New upstream to rebase onto
OldUpstream string // Current base to replay commits from
}
RebaseSpec describes a planned rebase operation
type RebaseValidation ¶
type RebaseValidation struct {
Success bool // Whether all rebases would succeed
FailedBranch string // Which branch caused the conflict (if any)
ErrorType ValidationErrorType // Type of error (conflict vs system error)
ErrorMessage string // Error message describing the failure
ConflictingFiles []string // Files that have conflicts (if ErrorType is ValidationErrorConflict)
NewSHAs map[string]string // Branch -> resulting SHA after rebase (if successful)
RerereResolved map[string]int // Branch -> number of conflicts auto-resolved by rerere during validation
}
RebaseValidation is the result of dry-run validation
type RemoteMetadataManager ¶
type RemoteMetadataManager interface {
IsRemoteSyncEnabled() bool
SetRemoteSyncEnabled(enabled bool)
SetLastModifiedBy(branchName string) error
BatchSetLastModifiedBy(branchNames []string) error
LoadRemoteMetadataCache() error
ApplyRemoteMetadataIfExists(branchName string) error
GetRemoteMetadataCache() RemoteMetadataView
ComputeMetadataDiff(branch string) (*MetadataDiff, error)
ComputeAllMetadataDiffs() ([]*MetadataDiff, error)
AcceptRemoteMetadata(branch string) error
RejectRemoteMetadata(branch string)
HasLocalModifications(branch string) bool
FindOrphanedLocalMetadata() ([]OrphanedMetadataInfo, error)
DeleteLocalMetadataHash(branchName string) error
DeleteMetadata(ctx context.Context, branchName string) error
FetchRemoteMetadata(ctx context.Context) error
ConfigureRemoteMetadataSync(ctx context.Context) error
// GetStackIDsForBranches returns the unique stack IDs for the given branches.
// This is used to determine which stack refs need to be pushed to remote.
GetStackIDsForBranches(branches []Branch) []string
}
RemoteMetadataManager provides operations for syncing branch metadata with remote
type RemoteMetadataView ¶
type RemoteMetadataView struct {
// contains filtered or unexported fields
}
RemoteMetadataView provides read-only access to the remote metadata cache. It is a lightweight snapshot — no map copying is needed because the underlying map is replaced atomically on each LoadRemoteMetadataCache call.
func (RemoteMetadataView) Get ¶
func (v RemoteMetadataView) Get(branch string) *git.Meta
Get returns the remote metadata for a branch, or nil if not present.
func (RemoteMetadataView) Has ¶
func (v RemoteMetadataView) Has(branch string) bool
Has returns true if the branch has remote metadata.
func (RemoteMetadataView) Len ¶
func (v RemoteMetadataView) Len() int
Len returns the number of entries in the cache.
type RestackBatchResult ¶
type RestackBatchResult struct {
ConflictBranch string // The branch that hit a conflict
RebasedBranchBase string // The parent revision for the conflict
RemainingBranches []string // Branches that weren't reached
Results map[string]RestackBranchResult // Results for each branch attempted
}
RestackBatchResult represents the result of restacking multiple branches
type RestackBranchProgressFunc ¶
type RestackBranchProgressFunc func(branch Branch, result RestackBranchResult)
RestackBranchProgressFunc is called after a branch has been processed during a batch restack.
type RestackBranchResult ¶
type RestackBranchResult struct {
Result RestackResult
RebasedBranchBase string // The new parent revision after successful rebase (only set if Result is RestackDone or RestackConflict)
Reparented bool // True if the branch was reparented due to merged/deleted parent
OldParent string // The old parent branch name (only set if Reparented is true)
NewParent string // The new parent branch name (only set if Reparented is true)
LockReason LockReason // Reason why the branch is locked
Frozen bool // True if the branch is frozen
RerereResolvedCount int // Number of rebase continuations handled by git rerere
}
RestackBranchResult represents the result of restacking a branch, including the rebased branch base
func (RestackBranchResult) IsLocked ¶
func (r RestackBranchResult) IsLocked() bool
IsLocked returns true if the branch is locked
type RestackPlan ¶
type RestackPlan struct {
Specs []RebaseSpec
BranchMap map[string]bool
ApplyMap map[string]bool
PlannedResults map[string]RestackBranchResult
Items map[string]RestackPlanItem
}
RestackPlan describes validation specs, pre-skipped branch results, and per-branch apply decisions for a restack operation.
type RestackPlanAction ¶
type RestackPlanAction int
RestackPlanAction describes how a planned branch should be applied.
const ( // RestackPlanApplyValidated applies a SHA produced by rebase validation. RestackPlanApplyValidated RestackPlanAction = iota // RestackPlanApplyFrozen updates a frozen branch from its remote ref. RestackPlanApplyFrozen // RestackPlanApplyAnchor updates a worktree anchor to trunk. RestackPlanApplyAnchor )
type RestackPlanItem ¶
type RestackPlanItem struct {
Branch string
NewParent string
ParentRev string
OldUpstream string
TargetRev string
Action RestackPlanAction
Skip bool
SkipResult RestackBranchResult
Reparented bool
OldParent string
}
RestackPlanItem describes how a branch should be handled during restack.
type RestackResult ¶
type RestackResult int
RestackResult represents the result of restacking a branch
const ( // RestackDone indicates the restack was successful RestackDone RestackResult = iota // RestackUnneeded indicates no restack was needed RestackUnneeded // RestackConflict indicates a conflict occurred during restack RestackConflict )
type Scope ¶
type Scope struct {
// contains filtered or unexported fields
}
Scope represents a branch scope that can be empty, a regular scope, or an inheritance breaker
func (Scope) ApplyToTitle ¶
ApplyToTitle adds or replaces a scope prefix in a title. If the title already has a scope prefix and it differs from this scope, it's replaced. If no scope prefix exists, this scope is prepended. Returns the original title if this scope is empty.
func (Scope) IsDefined ¶
IsDefined returns true if the scope has a meaningful value (not empty and not none)
func (Scope) MarshalJSON ¶
MarshalJSON implements json.Marshaler
func (Scope) TitleNeedsUpdate ¶
TitleNeedsUpdate checks if a title needs to be updated due to this scope.
func (*Scope) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler
type Snapshot ¶
type Snapshot struct {
Timestamp time.Time `json:"timestamp"`
Command string `json:"command"`
Args []string `json:"args"`
CurrentBranch string `json:"current_branch"`
BranchSHAs map[string]string `json:"branch_shas"` // branch name -> SHA
MetadataSHAs map[string]string `json:"metadata_shas"` // branch name -> metadata ref SHA
}
Snapshot represents a saved state of the repository
type SnapshotInfo ¶
type SnapshotInfo struct {
ID string // Filename without extension
Command string // Command name
Args []string // Command arguments
Timestamp time.Time // When the snapshot was taken
HeadSHA string // SHA of the current branch at snapshot time
DisplayName string // Human-readable description
}
SnapshotInfo provides metadata about a snapshot for display
type SnapshotOptions ¶
SnapshotOptions contains options for taking a snapshot
type SortStrategy ¶
type SortStrategy string
SortStrategy specifies how branches should be sorted in displays
const ( // SortStrategyAlphabetical sorts branches by name ascending (A-Z) SortStrategyAlphabetical SortStrategy = "ALPHABETICAL" // SortStrategySmart sorts branches by name descending (newest first) and hoists the active path SortStrategySmart SortStrategy = "SMART" )
type SquashOptions ¶
SquashOptions contains options for squashing commits
type StackGraph ¶
type StackGraph struct {
// contains filtered or unexported fields
}
StackGraph is an immutable snapshot of the branch stack relationships. It is built once from the engine and then used for traversals/rendering without further engine calls.
func BuildStackGraph ¶
func BuildStackGraph(eng BranchReader, strategy SortStrategy, filter func(Branch) bool) *StackGraph
BuildStackGraph constructs a StackGraph using the provided engine reader and sorting strategy. The optional filter is applied to branches; filtered-out branches are omitted along with their subtrees.
func (*StackGraph) BranchesAtDepth ¶
func (g *StackGraph) BranchesAtDepth(depth int) []Branch
BranchesAtDepth returns all branches at the specified depth. Returns nil if no branches exist at that depth.
func (*StackGraph) ChildBranches ¶
func (g *StackGraph) ChildBranches(branch Branch) []Branch
ChildBranches returns the child branches for the given branch.
func (*StackGraph) Children ¶
func (g *StackGraph) Children(branch Branch) []string
Children returns the child branch names for the given branch.
func (*StackGraph) CollectBranches ¶
func (g *StackGraph) CollectBranches(root Branch) []Branch
CollectBranches returns all branches in depth-first order starting from root. The root is included as the first element.
func (*StackGraph) CurrentBranch ¶
func (g *StackGraph) CurrentBranch() string
CurrentBranch returns the name of the currently checked-out branch.
func (*StackGraph) Downstack ¶
func (g *StackGraph) Downstack(branch Branch, includeCurrent bool) []Branch
Downstack returns parents of the branch (downstack).
func (*StackGraph) ForEachDepth ¶
func (g *StackGraph) ForEachDepth(fn func(depth int, branches []Branch) error) error
ForEachDepth iterates over branches grouped by depth, calling fn for each depth level. The function receives the depth (0 = trunk level) and branches at that depth. If fn returns an error, iteration stops and that error is returned. Branches at the same depth can be processed in parallel by fn. This is useful for operations like restacking where parents must complete before children.
func (*StackGraph) FullStack ¶
func (g *StackGraph) FullStack(branch Branch) []Branch
FullStack returns the entire stack (parents + current + children).
func (*StackGraph) GetBranchesByDepth ¶
func (g *StackGraph) GetBranchesByDepth() map[int][]string
GetBranchesByDepth returns a map from depth to branch names at that depth. This is useful for parallel operations where branches at the same depth are independent.
func (*StackGraph) GetNode ¶
func (g *StackGraph) GetNode(branchName string) *StackNode
GetNode returns the StackNode for a branch by name, or nil if not found.
func (*StackGraph) IsDescendant ¶
func (g *StackGraph) IsDescendant(branch Branch, potentialDescendant Branch) bool
IsDescendant returns true if potentialDescendant is a descendant of branch. This is useful for cycle detection when moving branches.
func (*StackGraph) IsLeaf ¶
func (g *StackGraph) IsLeaf(branch Branch) bool
IsLeaf returns true if the branch has no children in the graph.
Note: Returns true if the branch is not in the graph (nil node). Callers that need fail-safe behavior (treating unknown branches as non-leaves) should check GetNode() first, as AllBranchesAreLeaves does.
func (*StackGraph) IsRelated ¶
func (g *StackGraph) IsRelated(branch1, branch2 Branch) bool
IsRelated returns true if either branch is an ancestor or descendant of the other.
func (*StackGraph) MaxDepth ¶
func (g *StackGraph) MaxDepth() int
MaxDepth returns the maximum depth in the graph. Returns -1 if the graph is empty.
func (*StackGraph) Node ¶
func (g *StackGraph) Node(branch Branch) *StackNode
Node returns the StackNode for the given branch.
func (*StackGraph) Parent ¶
func (g *StackGraph) Parent(branch Branch) string
Parent returns the parent branch name (empty string if none).
func (*StackGraph) Range ¶
func (g *StackGraph) Range(branch Branch, rng StackRange) []Branch
Range returns branches matching the provided StackRange, ordered the same as the legacy GetRelativeStack implementation: ancestors (oldest to nearest), current, then descendants. Descendants are traversed depth-first using the graph's pre-sorted children.
func (*StackGraph) RootBranches ¶
func (g *StackGraph) RootBranches() []string
RootBranches returns all root branch names (branches with no parent in the graph).
func (*StackGraph) TrunkName ¶
func (g *StackGraph) TrunkName() string
TrunkName returns the trunk/main branch name.
type StackNavigator ¶
type StackNavigator interface {
}
StackNavigator handles stack relationship queries
type StackRange ¶
StackRange specifies the range of branches to include in stack operations
func StackRangeDownstack ¶
func StackRangeDownstack(includeCurrent bool) StackRange
StackRangeDownstack returns a range for parents (downstack) traversal.
func StackRangeFull ¶
func StackRangeFull() StackRange
StackRangeFull returns a range for full stack (parents + current + children).
func StackRangeUpstack ¶
func StackRangeUpstack(includeCurrent bool) StackRange
StackRangeUpstack returns a range for children (upstack) traversal.
type StackRewriter ¶
type StackRewriter interface {
// SquashCurrentBranch squashes commits on the current branch
SquashCurrentBranch(ctx context.Context, opts SquashOptions) error
// ApplySplitToCommits creates branches at specified commit points
ApplySplitToCommits(ctx context.Context, opts ApplySplitOptions) error
// Detach detaches HEAD to a specific revision
Detach(ctx context.Context, revision string) error
// DetachAndResetBranchChanges detaches and resets branch changes
DetachAndResetBranchChanges(ctx context.Context, branchName string) error
// ForceCheckoutBranch force checks out a branch
ForceCheckoutBranch(ctx context.Context, branch Branch) error
}
StackRewriter provides operations for modifying commit history and branch structure Thread-safe: All methods are safe for concurrent use
type SyncManager ¶
type SyncManager interface {
// Sync operations
PullTrunk(ctx context.Context) (PullResult, error)
ResetTrunkToRemote(ctx context.Context) error
PlanRestack(ctx context.Context, branches []Branch) (*RestackPlan, error)
RestackBranches(ctx context.Context, branches []Branch) (RestackBatchResult, error)
RestackBranchesWithProgress(ctx context.Context, branches []Branch, progress RestackBranchProgressFunc) (RestackBatchResult, error)
RestackBranchesWithValidatedRebases(ctx context.Context, branches []Branch, validation *RebaseValidation, progress RestackBranchProgressFunc) (RestackBatchResult, error)
RestackBranchesWithValidatedPlan(ctx context.Context, branches []Branch, validation *RebaseValidation, plan *RestackPlan, progress RestackBranchProgressFunc) (RestackBatchResult, error)
ContinueRebase(ctx context.Context, branchName string, rebasedBranchBase string) (ContinueRebaseResult, error)
Rebase(ctx context.Context, branchName, upstream, oldUpstream string) (RestackResult, error)
// Validation
ValidateRebases(ctx context.Context, specs []RebaseSpec) (*RebaseValidation, error)
ValidateRebasesParallel(ctx context.Context, specs []RebaseSpec) (*RebaseValidation, error)
}
SyncManager provides operations for syncing and restacking branches Thread-safe: All methods are safe for concurrent use
type UndoManager ¶
type UndoManager interface {
TakeSnapshot(opts SnapshotOptions) error
GetSnapshots() ([]SnapshotInfo, error)
LoadSnapshot(snapshotID string) (*Snapshot, error)
RestoreSnapshot(ctx context.Context, snapshotID string) error
}
UndoManager provides operations for undo/redo functionality Thread-safe: All methods are safe for concurrent use
type ValidationErrorType ¶
type ValidationErrorType int
ValidationErrorType distinguishes between conflict errors and system errors
const ( // ValidationErrorNone indicates no error occurred ValidationErrorNone ValidationErrorType = iota // ValidationErrorConflict indicates a merge conflict occurred ValidationErrorConflict // ValidationErrorSystem indicates a system error (not a conflict) ValidationErrorSystem )
type ValidationResult ¶
type ValidationResult int
ValidationResult represents the validation state of a branch
const ( // ValidationResultValid indicates the branch is valid ValidationResultValid ValidationResult = iota // ValidationResultInvalidParent indicates the branch has an invalid parent ValidationResultInvalidParent // ValidationResultBadParentRevision indicates the branch has a bad parent revision ValidationResultBadParentRevision // ValidationResultBadParentName indicates the branch has a bad parent name ValidationResultBadParentName // ValidationResultTrunk indicates the branch is a trunk ValidationResultTrunk )
type WorkingTree ¶
type WorkingTree interface {
HasStagedChanges(ctx context.Context) (bool, error)
HasUnstagedChanges(ctx context.Context) (bool, error)
HasUntrackedFiles(ctx context.Context) (bool, error)
GetUnstagedDiff(ctx context.Context, files ...string) (string, error)
GetUntrackedFileHunks(ctx context.Context) ([]git.Hunk, error)
GetPendingChanges(ctx context.Context) ([]PendingChange, error)
GetCommitTemplate(ctx context.Context) (string, error)
GetUnmergedFiles(ctx context.Context) ([]string, error)
ParseStagedHunks(ctx context.Context) ([]git.Hunk, error)
ListWorktrees(ctx context.Context) ([]string, error)
IsRebaseInProgress(ctx context.Context) bool
GetRebaseHead() (string, error)
HasUncommittedChanges(ctx context.Context) bool
CheckoutPaths(ctx context.Context, branch string, pathspecs []string) error
RemovePaths(ctx context.Context, pathspecs []string) error
StashList(ctx context.Context) (string, error)
}
WorkingTree handles worktree and staging area operations
type WorktreeCheckoutMode ¶
type WorktreeCheckoutMode int
WorktreeCheckoutMode specifies how files are checked out in a worktree.
const ( // WorktreeCheckoutFull checks out all files (default behavior). WorktreeCheckoutFull WorktreeCheckoutMode = iota // WorktreeCheckoutShallow creates a worktree without checking out files. // This is faster for validation-only operations that don't need actual files. WorktreeCheckoutShallow )
type WorktreeEngineOptions ¶
type WorktreeEngineOptions struct {
// WorktreePath is the root directory of the worktree.
WorktreePath string
// Snapshot is the parent engine's state snapshot.
Snapshot WorktreeSnapshot
// Writer is the output writer for warnings. If nil, os.Stderr is used.
Writer io.Writer
}
WorktreeEngineOptions configures NewEngineForWorktree.
type WorktreeInfo ¶
type WorktreeInfo struct {
Name string // User-provided name for display (empty for legacy worktrees)
Path string // Absolute path to worktree
AnchorBranch string // Anchor branch name (stack root for legacy worktrees)
CreatedAt time.Time // When worktree was created
MainRepoDir string // Path to main repo
}
WorktreeInfo represents information about a stackit-managed worktree
type WorktreeOperations ¶
type WorktreeOperations interface {
AddWorktree(ctx context.Context, path string, branch string, detach bool) error
RemoveWorktree(ctx context.Context, path string) error
CreateTemporaryWorktree(ctx context.Context, branch string, prefix string) (path string, cleanup func(), err error)
// CreateTemporaryWorktreeSkipPrune is like CreateTemporaryWorktree but skips the automatic
// PruneWorktrees() call. Use this when creating multiple worktrees in parallel after
// manually calling PruneWorktrees() once, to avoid race conditions.
CreateTemporaryWorktreeSkipPrune(ctx context.Context, branch string, prefix string) (path string, cleanup func(), err error)
PruneWorktrees(ctx context.Context) error
}
WorktreeOperations handles worktree management
type WorktreePruneMode ¶
type WorktreePruneMode int
WorktreePruneMode specifies whether to prune stale worktrees before creation.
const ( // WorktreePruneAuto prunes stale worktrees before creating a new one (default). WorktreePruneAuto WorktreePruneMode = iota // WorktreePruneSkip skips pruning. Use when the caller has already pruned // (e.g., parallel worktree creation). WorktreePruneSkip )
type WorktreeRegistry ¶
type WorktreeRegistry interface {
// RegisterWorktree registers a worktree for a stack root
RegisterWorktree(stackRoot string, path string) error
// RegisterWorktreeWithName registers a worktree with a user-friendly name
RegisterWorktreeWithName(anchorBranch string, path string, name string) error
// UnregisterWorktree removes worktree registration for a stack root
UnregisterWorktree(stackRoot string) error
// GetWorktreeForStack returns worktree info for a stack root, or nil if none
GetWorktreeForStack(stackRoot string) (*WorktreeInfo, error)
// ListManagedWorktrees returns all stackit-managed worktrees
ListManagedWorktrees() ([]WorktreeInfo, error)
// GetStackRootForBranch returns the stack root for a given branch
GetStackRootForBranch(branch Branch) string
// IsInManagedWorktree checks if the current directory is a stackit-managed worktree
// Returns true and worktree info if in a managed worktree, false otherwise
IsInManagedWorktree() (bool, *WorktreeInfo, error)
}
WorktreeRegistry handles stackit-managed worktree tracking
type WorktreeSnapshot ¶
type WorktreeSnapshot struct {
Trunk string
Branches []string
BranchState BranchStateMap
ChildrenMap map[string][]string
RemoteMetaCache map[string]*git.Meta
MaxConcurrency int
}
WorktreeSnapshot holds a deep copy of engine state for initializing worktree engines. This avoids the cost of rebuildInternal (which reads all branches + metadata from git) since worktrees share .git with the parent and the data is identical.
Source Files
¶
- branch_set.go
- engine.go
- engine_absorb.go
- engine_branch_info.go
- engine_branch_status.go
- engine_git_ops.go
- engine_impl.go
- engine_internal.go
- engine_pr.go
- engine_reader.go
- engine_split.go
- engine_squash.go
- engine_sync.go
- engine_writer.go
- independent_stack.go
- interfaces.go
- metadata_store.go
- rebase_validator.go
- remote_sync.go
- restack_plan.go
- stack_graph.go
- stack_range.go
- state_core.go
- transaction.go
- types.go
- undo.go