git

package
v0.17.15 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Overview

Package git provides low-level Git operations, including repository access, branch operations, commit information, PR operations, and metadata management.

Package git provides low-level Git operations.

It wraps git command execution and provides a Go-friendly interface for:

  • Branch management (create, delete, checkout, rename)
  • Commit operations (commit, amend, cherry-pick)
  • Repo state queries (status, diff, log, refs)
  • Remote operations (push, fetch, pull)
  • Metadata management (PR info, stack relationships)

This package should be the only place where direct git commands are executed.

Package git provides a wrapper around git commands and go-git for repository operations.

Index

Constants

View Source
const (
	// MetadataRefPrefix is the prefix for Git refs where branch metadata is stored
	MetadataRefPrefix = "refs/stackit/metadata/"
	// LocalMetadataRefPrefix is the prefix for Git refs where local-only branch metadata is stored
	LocalMetadataRefPrefix = "refs/stackit/local-metadata/"
)
View Source
const (
	// StackMetaRefPrefix is the prefix for Git refs where stack metadata is stored
	StackMetaRefPrefix = "refs/stackit/stacks/"
	// RemoteStackMetaRefPrefix is the prefix for remote stack metadata refs (fetched from remote)
	RemoteStackMetaRefPrefix = "refs/stackit/remote-stacks/"
)
View Source
const DefaultCommandTimeout = 5 * time.Minute

DefaultCommandTimeout is the default timeout for git commands

View Source
const DefaultRemote = "origin"

DefaultRemote is the default name for the remote repository

View Source
const MaxRerereContinueIterations = 1000

MaxRerereContinueIterations caps the auto-continue loop so a pathological rebase cannot spin forever. Real rebases finish in far fewer iterations.

View Source
const WorktreeRefPrefix = "refs/stackit/worktrees/"

WorktreeRefPrefix is the prefix for Git refs where worktree metadata is stored (local-only)

Variables

View Source
var ErrStaleRemoteInfo = errors.New("stale info")

ErrStaleRemoteInfo indicates that a push failed because the remote has changed

Functions

func BuildPatchFromHunks

func BuildPatchFromHunks(hunks []Hunk) string

BuildPatchFromHunks constructs a unified diff patch from selected hunks. The patch can be applied using git apply --cached to stage specific hunks. Binary files are handled separately as they have a different diff format.

func CanSplitHunk

func CanSplitHunk(hunk Hunk) bool

CanSplitHunk returns true if the hunk has context lines between changes, meaning it can be split into multiple smaller hunks. A hunk is splittable only when there's at least one context line that separates two distinct groups of changes (additions/deletions).

func CountHunkLines

func CountHunkLines(hunk Hunk) (added, removed int)

CountHunkLines returns the number of added and removed lines in a hunk

func GetCurrentDate

func GetCurrentDate() string

GetCurrentDate returns the current date and time in yyyyMMddHHmmss format in UTC

func GetGitCommonDir

func GetGitCommonDir(repoRoot string) string

GetGitCommonDir resolves the shared git directory for a repository. In a linked worktree this follows the commondir pointer back to the main repository's .git directory.

func GetGitDir

func GetGitDir(repoRoot string) string

GetGitDir resolves the actual git directory for a repository. In worktrees, .git is a file pointing to the real git directory, so we need to use git rev-parse to get the correct path.

This returns the worktree-specific git directory (use GetGitCommonDir for shared config).

func GetHunkHeader

func GetHunkHeader(hunk Hunk) string

GetHunkHeader extracts just the @@ header line from the hunk

func GetHunkPreview

func GetHunkPreview(hunk Hunk, maxLines int) (preview string, totalLines int, hasMore bool)

GetHunkPreview returns a short preview of the hunk content. maxLines specifies the maximum number of content lines to show.

func IsBranchNotFoundError

func IsBranchNotFoundError(err error) bool

IsBranchNotFoundError returns true if the error indicates that a branch was not found

func IsLocalChangesError

func IsLocalChangesError(err error) bool

IsLocalChangesError returns true if the error indicates that local changes would be overwritten

func LocalMetadataRefName

func LocalMetadataRefName(branchName string) string

LocalMetadataRefName returns the full ref name for a branch's local metadata.

func MetadataRefName

func MetadataRefName(branchName string) string

MetadataRefName returns the full ref name for a branch's metadata.

func StackMetaRefName

func StackMetaRefName(stackID string) string

StackMetaRefName returns the full ref name for a stack's metadata. Use this helper instead of concatenating StackMetaRefPrefix directly to ensure consistent ref name construction across all stack metadata operations.

Types

type BranchReader

type BranchReader interface {
	GetCurrentBranch() (string, error)
	GetAllBranchNames() ([]string, error)
	GetCurrentBranchOrSHA(ctx context.Context) (string, error)
}

BranchReader provides read access to branch information.

type BranchType

type BranchType string

BranchType indicates the type of branch

const (
	BranchTypeUser           BranchType = "user"            // Normal stacked branch
	BranchTypeUtility        BranchType = "utility"         // Created by st merge --consolidate or other internal tasks
	BranchTypeWorktreeAnchor BranchType = "worktree-anchor" // Anchor branch for worktree, has no commits
)

Branch types

type BranchWriter

type BranchWriter interface {
	CheckoutBranch(ctx context.Context, branchName string) error
	CheckoutBranchForce(ctx context.Context, branchName string) error
	CheckoutDetached(ctx context.Context, revision string) error
	CreateAndCheckoutBranch(ctx context.Context, branchName string) error
	CreateBranch(ctx context.Context, branchName, startPoint string) error
	CreateBranchForce(ctx context.Context, branchName, revision string) error
	DeleteBranch(ctx context.Context, branchName string) error
	RenameBranch(ctx context.Context, oldName, newName string) error
	UpdateBranchRef(ctx context.Context, branchName, revision string) error
}

BranchWriter handles branch lifecycle operations.

type CherryPickOperations

type CherryPickOperations interface {
	CherryPick(ctx context.Context, commitSHA, onto string) (string, error)
	CherryPickSimple(ctx context.Context, commitSHA string) error
	CherryPickAbort(ctx context.Context) error
}

CherryPickOperations handles cherry-pick operations.

type CommandError

type CommandError struct {
	Command string
	Args    []string
	Stdout  string
	Stderr  string
	Err     error
}

CommandError represents an error from a git command execution

func NewCommandError

func NewCommandError(command string, args []string, stdout, stderr string, err error) *CommandError

NewCommandError creates a new CommandError

func (*CommandError) Error

func (e *CommandError) Error() string

func (*CommandError) Unwrap

func (e *CommandError) Unwrap() error

type CommitOptions

type CommitOptions struct {
	Message     string
	Amend       bool
	NoEdit      bool
	Edit        bool
	Verbose     int
	ResetAuthor bool
	NoVerify    bool
}

CommitOptions contains options for creating a commit

type CommitReader

type CommitReader interface {
	GetRevision(branchName string) (string, error)
	GetCurrentRevision(ctx context.Context) (string, error)
	BatchGetRevisions(branchNames []string) (map[string]string, []error)
	// LoadAllBranchRevisions populates the revision cache for all local branches
	// using one batched branch-ref load. Subsequent GetRevision calls
	// for cached branches avoid go-git mutex contention entirely.
	LoadAllBranchRevisions() error
	GetCommitDate(branchName string) (time.Time, error)
	GetCommitAuthor(branchName string) (string, error)
	GetCommitRange(base, head, format string) ([]string, error)
	GetCommitRangeSHAs(base, head string) ([]string, error)
	GetCommitHistorySHAs(branchName string) ([]string, error)
	GetCommitSHA(branchName string, offset int) (string, error)
	GetCommitLog(sha, format string) (string, error)
	GetRecentCommits(branchName string, count int) ([]RecentCommit, error)
	GetCommitTemplate(ctx context.Context) (string, error)
	GetParentCommitSHA(commitSHA string) (string, error)
}

CommitReader provides read access to commit and revision information.

type CommitWriter

type CommitWriter interface {
	Commit(message string, verbose int, noVerify bool) error
	CommitWithOptions(opts CommitOptions) error
	CommitAmendNoEdit(ctx context.Context) error
}

CommitWriter handles commit creation and modification.

type ConfigStore

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

ConfigStore provides typed access to git config with a simpler interface than the full Runner. It operates directly on the repository via git commands.

func NewConfigStore

func NewConfigStore(repoRoot string) *ConfigStore

NewConfigStore creates a new ConfigStore for the given repository root.

func (*ConfigStore) Add

func (c *ConfigStore) Add(key, value string) error

Add adds a value to a multi-value config key.

func (*ConfigStore) Exists

func (c *ConfigStore) Exists(key string) bool

Exists checks if a config key exists.

func (*ConfigStore) Get

func (c *ConfigStore) Get(key string) (string, error)

Get retrieves a single config value from local git config. Returns empty string if the key doesn't exist.

func (*ConfigStore) GetAll

func (c *ConfigStore) GetAll(key string) ([]string, error)

GetAll retrieves all values for a multi-value config key. Returns empty slice if the key doesn't exist.

func (*ConfigStore) GetBool

func (c *ConfigStore) GetBool(key string) (bool, error)

GetBool retrieves a boolean config value. Returns false and no error if the key doesn't exist.

func (*ConfigStore) GetBoolWithDefault

func (c *ConfigStore) GetBoolWithDefault(key string, defaultValue bool) bool

GetBoolWithDefault retrieves a boolean config value with a default.

func (*ConfigStore) GetInt

func (c *ConfigStore) GetInt(key string) (int, error)

GetInt retrieves an integer config value. Returns 0 and no error if the key doesn't exist.

func (*ConfigStore) GetIntWithDefault

func (c *ConfigStore) GetIntWithDefault(key string, defaultValue int) int

GetIntWithDefault retrieves an integer config value with a default.

func (*ConfigStore) Set

func (c *ConfigStore) Set(key, value string) error

Set sets a config value in local git config.

func (*ConfigStore) SetBool

func (c *ConfigStore) SetBool(key string, value bool) error

SetBool sets a boolean config value.

func (*ConfigStore) SetInt

func (c *ConfigStore) SetInt(key string, value int) error

SetInt sets an integer config value.

func (*ConfigStore) Unset

func (c *ConfigStore) Unset(key string) error

Unset removes all values for a config key. Does not return an error if the key doesn't exist.

type DebugLogger

type DebugLogger interface {
	Debug(msg string, args ...any)
}

DebugLogger is an interface for logging debug messages

type DiffOperations

type DiffOperations interface {
	GetMergeBase(rev1, rev2 string) (string, error)
	GetMergeBaseByRef(ref1, ref2 string) (string, error)
	IsAncestor(ancestor, descendant string) (bool, error)
	IsMerged(ctx context.Context, branchName, target string) (bool, error)
	GetMergedBranches(ctx context.Context, target string) (map[string]bool, error)
	IsDiffEmpty(ctx context.Context, branchName, base string) (bool, error)
	GetChangedFiles(ctx context.Context, base, head string) ([]string, error)
	ShowDiff(ctx context.Context, left, right string, stat bool) (string, error)
	ShowCommits(ctx context.Context, base, head string, patch, stat bool) (string, error)
	GetDiffNumstat(base, head string) (string, error)
	GetStagedDiff(ctx context.Context, files ...string) (string, error)
	GetUnstagedDiff(ctx context.Context, files ...string) (string, error)
	// GetDiffBetween returns the raw diff between two refs, without color codes.
	// This is suitable for parsing into hunks.
	GetDiffBetween(ctx context.Context, base, head string, files ...string) (string, error)
}

DiffOperations provides access to diff and comparison operations.

type Hunk

type Hunk struct {
	File          string // File path
	OldStart      int    // Line number in old file (1-indexed)
	OldCount      int    // Number of lines in old file
	NewStart      int    // Line number in new file (1-indexed)
	NewCount      int    // Number of lines in new file
	Content       string // The actual diff content (including header)
	IndexLine     string // The index line from the diff (e.g., "index abc123..def456 100644") for --3way merging
	Binary        bool   // True if this represents a binary file change
	IsNewFile     bool   // True if this hunk is for a newly created file
	IsDeletedFile bool   // True if this hunk is for a deleted file
	FileMode      string // File mode (e.g., "100644", "100755") for new/deleted files
}

Hunk represents a single hunk of changes in a diff

func GenerateNewFileHunk

func GenerateNewFileHunk(filePath string, content []byte) Hunk

GenerateNewFileHunk creates a synthetic hunk for an untracked file. This allows new files to be included in hunk-based splitting.

func ParseDiffOutput

func ParseDiffOutput(diffOutput string) ([]Hunk, error)

ParseDiffOutput parses a diff output into structured hunks

func SplitHunk

func SplitHunk(hunk Hunk) ([]Hunk, error)

SplitHunk divides a hunk at the first context line after changes. Returns the split hunks or an error if the hunk cannot be split.

type HunkTarget

type HunkTarget struct {
	Hunk        Hunk
	CommitSHA   string
	CommitIndex int // Index in the commit list (0 = newest)
}

HunkTarget represents a hunk and its target commit

type LocalMeta

type LocalMeta struct {
	Frozen              bool   `json:"frozen,omitempty"`
	NeedsPRBodyUpdate   bool   `json:"needsPRBodyUpdate,omitempty"`
	NavigationCommentID *int64 `json:"navigationCommentId,omitempty"`
}

LocalMeta represents branch metadata that is strictly local and never pushed

type LockReason

type LockReason string

LockReason is an enum for the reason why a branch is locked

const (
	// LockReasonNone indicates the branch is not locked
	LockReasonNone LockReason = ""
	// LockReasonUser indicates the branch was manually locked by the user
	LockReasonUser LockReason = "user"
	// LockReasonConsolidating indicates the branch is being consolidated
	LockReasonConsolidating LockReason = "consolidating"
	// LockReasonDraining indicates the branch is being drained (merge drain in progress)
	LockReasonDraining LockReason = "draining"
)

func (LockReason) IsLocked

func (r LockReason) IsLocked() bool

IsLocked returns true if the lock reason indicates the branch is locked

type MergeOperations

type MergeOperations interface {
	Merge(ctx context.Context, branchName string, opts MergeOptions) error
	MergeMultiple(ctx context.Context, branches []string, opts MergeOptions) error
	IsMergeInProgress(ctx context.Context) bool
	MergeAbort(ctx context.Context) error
	GetUnmergedFiles(ctx context.Context) ([]string, error)
}

MergeOperations handles merge operations.

type MergeOptions

type MergeOptions struct {
	FFOnly  bool
	NoEdit  bool
	NoFF    bool
	Message string
}

MergeOptions contains options for merging branches

type MergedParent

type MergedParent struct {
	BranchName string  `json:"branchName"`
	PRNumber   *int    `json:"prNumber,omitempty"`
	PRState    *string `json:"prState,omitempty"` // "MERGED", "CLOSED"
}

MergedParent represents a historical parent that was merged or deleted

type Meta

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

Meta represents branch metadata stored in Git refs. Fields are unexported to enforce immutability — use getters to read and With* methods to create modified copies. Construct via NewMeta() or NewMetaFrom(MetaFields{...}).

func NewMeta

func NewMeta() *Meta

NewMeta returns a new zero-value Meta.

func NewMetaFrom

func NewMetaFrom(f MetaFields) *Meta

NewMetaFrom constructs a Meta from the given fields.

func (*Meta) GetBranchType

func (m *Meta) GetBranchType() BranchType

GetBranchType returns the branch type.

func (*Meta) GetLastModifiedAt

func (m *Meta) GetLastModifiedAt() *time.Time

GetLastModifiedAt returns a copy of the last-modified-at timestamp.

func (*Meta) GetLastModifiedBy

func (m *Meta) GetLastModifiedBy() *ModifiedBy

GetLastModifiedBy returns a shallow copy of the last-modified-by info.

func (*Meta) GetLocalOnlyHash

func (m *Meta) GetLocalOnlyHash() *string

GetLocalOnlyHash returns the local-only hash.

func (*Meta) GetLockReason

func (m *Meta) GetLockReason() LockReason

GetLockReason returns the lock reason.

func (*Meta) GetMergedDownstack

func (m *Meta) GetMergedDownstack() []MergedParent

GetMergedDownstack returns a copy of the merged downstack history.

func (*Meta) GetParentBranchName

func (m *Meta) GetParentBranchName() *string

GetParentBranchName returns the parent branch name.

func (*Meta) GetParentBranchRevision

func (m *Meta) GetParentBranchRevision() *string

GetParentBranchRevision returns the parent branch revision.

func (*Meta) GetPrInfo

func (m *Meta) GetPrInfo() *PrInfoPersistence

GetPrInfo returns a shallow copy of the PR info.

func (*Meta) GetScope

func (m *Meta) GetScope() *string

GetScope returns the scope.

func (*Meta) GetStackID

func (m *Meta) GetStackID() *string

GetStackID returns the stack ID.

func (Meta) MarshalJSON

func (m Meta) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for Meta.

func (*Meta) UnmarshalJSON

func (m *Meta) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler for Meta.

func (*Meta) WithBranchType

func (m *Meta) WithBranchType(v BranchType) *Meta

WithBranchType returns a new Meta with the branch type set.

func (*Meta) WithLastModifiedAt

func (m *Meta) WithLastModifiedAt(v *time.Time) *Meta

WithLastModifiedAt returns a new Meta with the last-modified-at timestamp set.

func (*Meta) WithLastModifiedBy

func (m *Meta) WithLastModifiedBy(v *ModifiedBy) *Meta

WithLastModifiedBy returns a new Meta with the last-modified-by info set.

func (*Meta) WithLocalOnlyHash

func (m *Meta) WithLocalOnlyHash(v *string) *Meta

WithLocalOnlyHash returns a new Meta with the local-only hash set.

func (*Meta) WithLockReason

func (m *Meta) WithLockReason(v LockReason) *Meta

WithLockReason returns a new Meta with the lock reason set.

func (*Meta) WithMergedDownstack

func (m *Meta) WithMergedDownstack(v []MergedParent) *Meta

WithMergedDownstack returns a new Meta with the merged downstack history set.

func (*Meta) WithParentBranchName

func (m *Meta) WithParentBranchName(v *string) *Meta

WithParentBranchName returns a new Meta with the parent branch name set.

func (*Meta) WithParentBranchRevision

func (m *Meta) WithParentBranchRevision(v *string) *Meta

WithParentBranchRevision returns a new Meta with the parent branch revision set.

func (*Meta) WithPrInfo

func (m *Meta) WithPrInfo(v *PrInfoPersistence) *Meta

WithPrInfo returns a new Meta with the PR info set.

func (*Meta) WithScope

func (m *Meta) WithScope(v *string) *Meta

WithScope returns a new Meta with the scope set.

func (*Meta) WithStackID

func (m *Meta) WithStackID(v *string) *Meta

WithStackID returns a new Meta with the stack ID set.

type MetaFields

type MetaFields struct {
	ParentBranchName     *string
	ParentBranchRevision *string
	PrInfo               *PrInfoPersistence
	Scope                *string
	LockReason           LockReason
	BranchType           BranchType
	LastModifiedBy       *ModifiedBy
	LastModifiedAt       *time.Time
	LocalOnlyHash        *string
	MergedDownstack      []MergedParent
	StackID              *string
}

MetaFields provides exported fields for constructing an immutable Meta. Use with NewMetaFrom to build Meta values in a single expression.

type MetadataOperations

type MetadataOperations interface {
	ReadMetadata(branchName string) (*Meta, error)
	BatchReadMetadata(branchNames []string) (map[string]*Meta, map[string]error)
	WriteMetadata(branchName string, meta *Meta) error
	DeleteMetadata(branchName string) error
	RenameMetadata(oldName, newName string) error
	ListMetadata() (map[string]string, error)
	ReadLocalMetadata(branchName string) (*LocalMeta, error)
	BatchReadLocalMetadata(branchNames []string) map[string]*LocalMeta
	WriteLocalMetadata(branchName string, meta *LocalMeta) error

	// Transaction support methods
	WriteMetadataBlob(meta *Meta) (string, error)
	WriteLocalMetadataBlob(meta *LocalMeta) (string, error)
	GetMetadataRefSHA(branchName string) string
	GetLocalMetadataRefSHA(branchName string) string

	// Cache management
	ClearMetadataCache()
}

MetadataOperations handles stackit metadata persistence.

type ModifiedBy

type ModifiedBy struct {
	GitName        string  `json:"gitName"`
	GitEmail       string  `json:"gitEmail"`
	GitHubUsername *string `json:"githubUsername,omitempty"`
}

ModifiedBy represents information about who last modified the metadata

type ObjectOperations

type ObjectOperations interface {
	CreateBlob(content string) (string, error)
	ReadBlob(sha string) (string, error)
	CatFile(sha string) (string, error)
}

ObjectOperations provides low-level Git object operations.

type PatchOperations

type PatchOperations interface {
	ApplyPatch(ctx context.Context, patchFile string, threeWay bool) error
	CheckCommutation(hunk Hunk, commitSHA, parentSHA string) (bool, error)
}

PatchOperations handles patch operations.

type PathOperations

type PathOperations interface {
	CheckoutPaths(ctx context.Context, branch string, paths []string) error
	RemovePaths(ctx context.Context, paths []string) error
}

PathOperations handles file path operations.

type PrInfoPersistence

type PrInfoPersistence struct {
	Number      *int        `json:"number,omitempty"`
	Base        *string     `json:"base,omitempty"`
	URL         *string     `json:"url,omitempty"`
	Title       *string     `json:"title,omitempty"`
	Body        *string     `json:"body,omitempty"`
	State       *string     `json:"state,omitempty"`
	IsDraft     *bool       `json:"isDraft,omitempty"`
	LockReason  *LockReason `json:"lockReason,omitempty"`
	MergeBranch *string     `json:"mergeBranch,omitempty"`
}

PrInfoPersistence represents PR information for persistence

type PullResult

type PullResult int

PullResult represents the result of a pull operation

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 PushOptions

type PushOptions struct {
	Force                     bool
	ForceWithLease            bool
	ForceWithLeaseExpectedSHA string
	NoVerify                  bool
}

PushOptions contains options for pushing a branch

type RebaseOperations

type RebaseOperations interface {
	Rebase(ctx context.Context, branchName, upstream, oldUpstream string) (RebaseOutcome, error)
	RebaseContinue(ctx context.Context) (RebaseOutcome, error)
	RebaseContinueNoEdit(ctx context.Context) (RebaseOutcome, error)
	RebaseAbort(ctx context.Context) error
	InteractiveRebase(ctx context.Context, onto string) error
	IsRebaseInProgress(ctx context.Context) bool
	GetRebaseHead() (string, error)
	CheckRebaseInProgress(ctx context.Context) error
}

RebaseOperations handles rebase operations.

type RebaseOutcome

type RebaseOutcome struct {
	Result              RebaseResult
	RerereResolvedCount int
}

RebaseOutcome represents the result of a rebase operation, including any conflicts that git rerere resolved automatically.

func AutoContinueRerereRebase

func AutoContinueRerereRebase(ctx context.Context, r Runner, originalErr error) (RebaseOutcome, []string, error)

AutoContinueRerereRebase drives `git rebase --continue` while rerere keeps all conflicts resolved (no unmerged files remain). It returns:

  • RebaseOutcome with Result=RebaseDone and the count of rerere-resolved commits when the rebase completes.
  • RebaseOutcome with Result=RebaseConflict and the list of unmerged files when rerere cannot resolve a conflict.
  • a non-nil error if `rebase --continue` fails unexpectedly or the iteration cap is hit. The originalErr is wrapped into these errors so callers keep the context that triggered auto-continue.

type RebaseResult

type RebaseResult int

RebaseResult represents the result of a rebase operation

const (
	// RebaseDone indicates the rebase was successful
	RebaseDone RebaseResult = iota
	// RebaseConflict indicates a conflict occurred during rebase
	RebaseConflict
)

type RecentCommit

type RecentCommit struct {
	SHA            string
	Subject        string
	Author         string
	Date           time.Time
	PRNumber       int              // parsed from subject suffix "(#123)" if present
	Kind           RecentCommitKind // derived from trailer metadata
	StackSize      int              // from Stackit-Stack-Size trailer (0 if absent)
	StackPRNumbers []int            // from Stackit-PRs trailer
	StackScope     string           // from Stackit-Scope trailer (empty if absent)
}

RecentCommit represents a commit from the git log with optional stack trailer metadata.

type RecentCommitKind

type RecentCommitKind string

RecentCommitKind describes the presentation type of a trunk commit.

const (
	RecentCommitKindRegular    RecentCommitKind = "regular"
	RecentCommitKindStackMerge RecentCommitKind = "stack-merge"
)

type RefOperations

type RefOperations interface {
	GetRef(name string) (string, error)
	UpdateRef(name, sha string) error
	UpdateRefWithLog(ctx context.Context, refName, sha, message string) error
	UpdateRefsBatch(ctx context.Context, updates []RefUpdate) error
	UpdateRefsBatchWithLog(ctx context.Context, updates []RefUpdate, reflogMessage string) error
	DeleteRefsBatch(ctx context.Context, refNames []string) error
	VerifyRef(ctx context.Context, refName string) error
	DeleteRef(name string) error
	ListRefs(prefix string) (map[string]string, error)
}

RefOperations provides low-level reference operations.

type RefUpdate

type RefUpdate struct {
	RefName  string
	NewSHA   string
	OldSHA   string // Optional: for optimistic locking verification
	IsDelete bool   // If true, this is a deletion instead of an update
}

RefUpdate represents a single reference update operation.

type RemoteOperations

type RemoteOperations interface {
	FetchRemoteShas(ctx context.Context, remote string) (map[string]string, error)
	GetRemoteSha(remote, branchName string) (string, error)
	GetRemoteRevision(branchName string) (string, error)
	FindRemoteBranch(ctx context.Context, remote string) (string, error)
	PushBranch(ctx context.Context, branchName, remote string, opts PushOptions) error
	PullBranch(ctx context.Context, remote, branchName string) (PullResult, error)
	Fetch(ctx context.Context, remote, branch string) error
	PushMetadataRefs(ctx context.Context, branches []string) error
	FetchMetadataRefs(ctx context.Context) error
	DeleteRemoteMetadataRef(ctx context.Context, branch string) error
	BatchDeleteRemoteMetadataRefs(ctx context.Context, branches []string) error
	TestRemoteRefCompatibility() error
	PushStackMetaRefs(ctx context.Context, stackIDs []string) error
	FetchStackMetaRefs(ctx context.Context) error
	DeleteRemoteStackMetaRefs(ctx context.Context, stackIDs []string) error
}

RemoteOperations handles interaction with remote repositories.

type Repository

type Repository struct {
	*gogit.Repository
	// contains filtered or unexported fields
}

Repository wraps a go-git repository

func OpenRepository

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

OpenRepository opens a git repository at the given path

func (*Repository) GetBranchNames

func (r *Repository) GetBranchNames() ([]string, error)

GetBranchNames returns all branch names

func (*Repository) GetCurrentBranch

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

GetCurrentBranch returns the current branch name

func (*Repository) GetReference

func (r *Repository) GetReference(name string) (*plumbing.Reference, error)

GetReference returns a reference by name

func (*Repository) GetRepoRoot

func (r *Repository) GetRepoRoot() string

GetRepoRoot returns the root directory of the repository

func (*Repository) SetConfigRaw

func (r *Repository) SetConfigRaw(raw *format.Config) error

SetConfigRaw writes an updated raw local git config while preserving the typed config fields go-git maintains for known sections.

type RepositoryReader

type RepositoryReader interface {
	GetRemote() string
	GetConfig(key string) (string, error)
	GetConfigAll(key string) ([]string, error)
	GetRepoRoot() string
	DiscoverRepoRoot() (string, error)
	// GetGitCommonDir returns the path to the shared .git directory.
	// For regular repos this is the same as .git, but for worktrees it returns
	// the main repository's .git directory (where config is stored).
	GetGitCommonDir() (string, error)
	IsInsideRepo() bool
	GetUserName(ctx context.Context) (string, error)
	GetRepoInfo(ctx context.Context) (string, string, error)
}

RepositoryReader provides read access to repository configuration and state.

type RepositoryWriter

type RepositoryWriter interface {
	InitDefaultRepo() error
	SetConfig(key, value string) error
	AddConfigValue(key, value string) error
	EnsureMetadataRefspecConfigured() error
	EnsureStackMetaRefspecConfigured() error
}

RepositoryWriter provides write access to repository configuration.

type ResetOperations

type ResetOperations interface {
	HardReset(ctx context.Context, revision string) error
	ResetMerge(ctx context.Context, revision string) error
	SoftReset(ctx context.Context, revision string) error
	MixedReset(ctx context.Context, revision string) error
}

ResetOperations handles reset operations.

type Runner

type Runner interface {
	// Repository access and configuration
	RepositoryReader
	RepositoryWriter

	// Remote operations
	RemoteOperations

	// Branch operations
	BranchReader
	BranchWriter

	// Commit and revision access
	CommitReader

	// Diff and comparison
	DiffOperations

	// Staging area
	StagingOperations

	// Commit creation
	CommitWriter

	// Advanced git operations
	RebaseOperations
	MergeOperations
	CherryPickOperations
	StashOperations
	ResetOperations
	PathOperations
	PatchOperations

	// Worktree management
	WorktreeOperations
	WorktreeRegistryOperations

	// Repository status
	StatusOperations

	// Low-level operations
	RefOperations
	ObjectOperations
	MetadataOperations
	StackMetadataOperations

	// Raw command execution
	RunGitCommandWithContext(ctx context.Context, args ...string) (string, error)
	RunGitCommandRawWithContext(ctx context.Context, args ...string) (string, error)
	RunGitCommandWithEnv(ctx context.Context, env []string, args ...string) (string, error)
	RunGitCommandInteractive(args ...string) error
	RunGHCommandWithContext(ctx context.Context, args ...string) (string, error)

	// Logging
	SetLogger(logger DebugLogger)
}

Runner defines the interface for git operations used by the engine. This allows the engine to be used with both real git and mock implementations.

Runner is a composite interface that embeds smaller, focused interfaces for better modularity and testability. Each embedded interface represents a logical grouping of related git operations.

func NewRunner

func NewRunner(logger DebugLogger) Runner

NewRunner returns a standard implementation of Runner that uses the current working directory as its repository root.

func NewRunnerWithPath

func NewRunnerWithPath(repoRoot string, logger DebugLogger) Runner

NewRunnerWithPath returns a Runner that operates on a specific repo path. This is safe for parallel tests since it doesn't rely on global state.

func NewTracingRunner

func NewTracingRunner(inner Runner, logger DebugLogger) Runner

NewTracingRunner creates a tracing wrapper around the given runner. If logger is nil, tracing is disabled but operations still delegate to inner.

type StackDescription

type StackDescription struct {
	Title       string `json:"title,omitempty"`
	Description string `json:"description,omitempty"`
}

StackDescription holds stack-level title and description. This is stored on the root branch of a stack.

func (*StackDescription) IsEmpty

func (sd *StackDescription) IsEmpty() bool

IsEmpty returns true if both title and description are empty.

type StackMeta

type StackMeta struct {
	ID          string    `json:"id"`                    // Matches ref name (timestamp-sanitized-root)
	Title       string    `json:"title,omitempty"`       // Stack title
	Description string    `json:"description,omitempty"` // Stack description
	CreatedAt   time.Time `json:"createdAt"`             // When stack was created
	CreatedBy   string    `json:"createdBy,omitempty"`   // Who created the stack (git user)
}

StackMeta represents stack-level metadata stored in Git refs. This is separate from branch metadata (Meta) and survives branch operations like merging the root branch.

func (*StackMeta) IsEmpty

func (sm *StackMeta) IsEmpty() bool

IsEmpty returns true if both title and description are empty.

func (*StackMeta) StackDescription

func (sm *StackMeta) StackDescription() *StackDescription

StackDescription returns a StackDescription from the StackMeta fields. This provides compatibility with the existing StackDescription type.

type StackMetadataOperations

type StackMetadataOperations interface {
	ReadStackMeta(stackID string) (*StackMeta, error)
	WriteStackMeta(stackID string, meta *StackMeta) error
	DeleteStackMeta(stackID string) error
	ListStackMetas() (map[string]string, error)

	// Transaction support methods
	WriteStackMetaBlob(meta *StackMeta) (string, error)
	GetStackMetaRefSHA(stackID string) string
}

StackMetadataOperations handles stack-level metadata persistence. Stack metadata is stored separately from branch metadata and survives branch operations.

type StagingOperations

type StagingOperations interface {
	StageAll(ctx context.Context) error
	StagePatch(ctx context.Context) error
	StageTracked(ctx context.Context) error
	AddAll(ctx context.Context) error
	StageChanges(ctx context.Context, opts StagingOptions) error
	HasStagedChanges(ctx context.Context) (bool, error)
	HasUnstagedChanges(ctx context.Context) (bool, error)
	HasUntrackedFiles(ctx context.Context) (bool, error)
	GetUntrackedFiles(ctx context.Context) ([]string, error)
	ParseStagedHunks(ctx context.Context) ([]Hunk, error)
	StageHunks(ctx context.Context, hunks []Hunk) error
	UnstageAll(ctx context.Context) error
}

StagingOperations handles staging area operations.

type StagingOptions

type StagingOptions struct {
	All    bool
	Update bool
	Patch  bool
}

StagingOptions defines which changes to stage

type StashOperations

type StashOperations interface {
	StashPush(ctx context.Context, message string) (string, error)
	StashPushStaged(ctx context.Context, message string) (string, error)
	StashPop(ctx context.Context) error
	ListStash(ctx context.Context) (string, error)
}

StashOperations handles stash operations.

type StatusOperations

type StatusOperations interface {
	GetStatusPorcelain(ctx context.Context) (string, error)
	GetReflog(ctx context.Context, count int, format string) (string, error)
	HasUncommittedChanges(ctx context.Context) bool
}

StatusOperations provides repository status information.

type TraceLogger

type TraceLogger interface {
	Trace(op string, durationMicros int64, success bool, err error, attrs ...slog.Attr)
}

TraceLogger is an optional interface for structured trace logging. If the logger implements this, traces use structured logging with minimal allocations.

type WorktreeMeta

type WorktreeMeta struct {
	Name         string    `json:"name,omitempty"` // User-provided name for display (new worktrees only)
	Path         string    `json:"path"`           // Absolute path to worktree
	AnchorBranch string    `json:"stackRoot"`      // Anchor branch for worktree (JSON: stackRoot for backwards compat)
	CreatedAt    time.Time `json:"createdAt"`      // When worktree was created
	MainRepoDir  string    `json:"mainRepoDir"`    // Path to main repo (for detection)
}

WorktreeMeta represents worktree tracking metadata stored in local Git refs

type WorktreeOperations

type WorktreeOperations interface {
	AddWorktree(ctx context.Context, path string, branch string, detach bool) error
	AddWorktreeWithOptions(ctx context.Context, path string, branch string, detach bool, noCheckout bool) error
	RemoveWorktree(ctx context.Context, path string) error
	ListWorktrees(ctx context.Context) ([]string, error)
	PruneWorktrees(ctx context.Context) error
	GetWorktreePathForBranch(ctx context.Context, branchName string) (string, error)
	GetWorktreeCurrentBranch(ctx context.Context, worktreePath string) (string, error)
	ResetWorktreeWorkingDir(ctx context.Context, worktreePath string) error
	WorktreeHasUncommittedChanges(ctx context.Context, worktreePath string) (bool, error)
}

WorktreeOperations handles worktree management.

type WorktreeRegistryOperations

type WorktreeRegistryOperations interface {
	ReadWorktreeMeta(stackRoot string) (*WorktreeMeta, error)
	WriteWorktreeMeta(stackRoot string, meta *WorktreeMeta) error
	DeleteWorktreeMeta(stackRoot string) error
	ListWorktreeMetas() (map[string]*WorktreeMeta, error)
}

WorktreeRegistryOperations handles stackit-managed worktree tracking (local-only refs).

Jump to

Keyboard shortcuts

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