Documentation
¶
Overview ¶
Package git provides low-level Git operations, including repository access, branch operations, commit information, PR operations, and metadata management.
Package git provides a wrapper around the git CLI for repository operations.
Index ¶
- Constants
- Variables
- func BranchFetchRefspec(remote, branch string) string
- func BuildPatchFromHunks(hunks []Hunk) string
- func CanSplitHunk(h Hunk) bool
- func CollapsedMessage(c RecentCommit, prTitles map[int]string) string
- func ConstituentPRTitles(c RecentCommit, prTitles map[int]string) map[int]string
- func CountHunkLines(h Hunk) (added, removed int)
- func GetCurrentDate() string
- func GetGitCommonDir(repoRoot string) string
- func GetGitDir(repoRoot string) string
- func GetHunkHeader(h Hunk) string
- func GetHunkPreview(h Hunk, maxLines int) (string, int, bool)
- func IsBranchNotFoundError(err error) bool
- func IsLocalChangesError(err error) bool
- func IsMainWorktree(worktreePath, repoRoot string) bool
- func LocalMetadataRefName(branchName string) string
- func MetadataRefName(branchName string) string
- func PRTitleNumbers(commits []RecentCommit) []int
- func StackMetaRefName(stackID string) string
- type BranchReader
- type BranchType
- type BranchWriter
- type CherryPickOperations
- type CommandError
- type CommitOptions
- type CommitReader
- type CommitWriter
- type ConfigStore
- func (c *ConfigStore) Add(key, value string) error
- func (c *ConfigStore) Exists(key string) bool
- func (c *ConfigStore) Get(key string) (string, error)
- func (c *ConfigStore) GetAll(key string) ([]string, error)
- func (c *ConfigStore) GetBool(key string) (bool, error)
- func (c *ConfigStore) GetBoolWithDefault(key string, defaultValue bool) bool
- func (c *ConfigStore) GetInt(key string) (int, error)
- func (c *ConfigStore) GetIntWithDefault(key string, defaultValue int) int
- func (c *ConfigStore) Set(key, value string) error
- func (c *ConfigStore) SetBool(key string, value bool) error
- func (c *ConfigStore) SetInt(key string, value int) error
- func (c *ConfigStore) Unset(key string) error
- type DebugLogger
- type DiffOperations
- type Hunk
- func (h Hunk) CanSplit() bool
- func (h Hunk) Header() string
- func (h Hunk) LineCounts() (added, removed int)
- func (h Hunk) NewFileContent() string
- func (h Hunk) Overlaps(other Hunk) bool
- func (h Hunk) Preview(maxLines int) (preview string, totalLines int, hasMore bool)
- func (h Hunk) Split() (Hunks, error)
- type HunkTarget
- type Hunks
- type LocalMeta
- type LocalMetaMap
- type LockReason
- type MergeOperations
- type MergeOptions
- type MergedParent
- type Meta
- func (m *Meta) GetBranchType() BranchType
- func (m *Meta) GetLastModifiedAt() *time.Time
- func (m *Meta) GetLastModifiedBy() *ModifiedBy
- func (m *Meta) GetLocalOnlyHash() *string
- func (m *Meta) GetLockReason() LockReason
- func (m *Meta) GetMergedDownstack() []MergedParent
- func (m *Meta) GetParentBranchName() *string
- func (m *Meta) GetParentBranchRevision() *string
- func (m *Meta) GetPrInfo() *PrInfoPersistence
- func (m *Meta) GetScope() *string
- func (m *Meta) GetStackID() *string
- func (m Meta) MarshalJSON() ([]byte, error)
- func (m *Meta) UnmarshalJSON(data []byte) error
- func (m *Meta) WithBranchType(v BranchType) *Meta
- func (m *Meta) WithLastModifiedAt(v *time.Time) *Meta
- func (m *Meta) WithLastModifiedBy(v *ModifiedBy) *Meta
- func (m *Meta) WithLocalOnlyHash(v *string) *Meta
- func (m *Meta) WithLockReason(v LockReason) *Meta
- func (m *Meta) WithMergedDownstack(v []MergedParent) *Meta
- func (m *Meta) WithParentBranchName(v *string) *Meta
- func (m *Meta) WithParentBranchRevision(v *string) *Meta
- func (m *Meta) WithPrInfo(v *PrInfoPersistence) *Meta
- func (m *Meta) WithScope(v *string) *Meta
- func (m *Meta) WithStackID(v *string) *Meta
- type MetaFields
- type MetadataCacheSummary
- type MetadataOperations
- type ModifiedBy
- type ObjectOperations
- type PRState
- type PatchOperations
- type PathOperations
- type PrInfoPersistence
- type PullResult
- type PushOptions
- type PushSpec
- type RebaseOperations
- type RebaseOutcome
- type RebaseResult
- type RecentCommit
- type RecentCommitKind
- type RecentCommits
- type RefDecoration
- type RefOperations
- type RefUpdate
- type RemoteOperations
- type RepositoryReader
- type RepositoryWriter
- type ResetOperations
- type RevRange
- type Runner
- type SquashMergeCache
- type StackDescription
- type StackMeta
- type StackMetadataOperations
- type StagingOperations
- type StagingOptions
- type StashOperations
- type StatusOperations
- type Worktree
- type WorktreeDetachMode
- type WorktreeList
- type WorktreeMeta
- type WorktreeOperations
- type WorktreeRegistryOperations
Constants ¶
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/" )
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/" )
const CommandWaitDelay = 10 * time.Second
CommandWaitDelay bounds how long we wait for a killed git/gh subprocess to release its stdio pipes before force-closing them. Without it, a `git fetch` can spawn an `ssh` grandchild that inherits the captured stdout/stderr pipe; when the context deadline kills git, ssh keeps the pipe open and cmd.Run() blocks indefinitely — the command times out but never returns, which is the hang-until-reboot behind issue #1330. Setting WaitDelay makes Go force-close the pipes shortly after the kill so Run() always returns.
const DefaultCommandTimeout = 5 * time.Minute
DefaultCommandTimeout is the default timeout for git commands
const DefaultRemote = "origin"
DefaultRemote is the default name for the remote repository
const MaxRerereContinueIterations = 1000
MaxRerereContinueIterations caps the auto-continue loop so a pathological rebase cannot spin forever. Real rebases finish in far fewer iterations.
const WorktreeRefPrefix = "refs/stackit/worktrees/"
WorktreeRefPrefix is the prefix for Git refs where worktree metadata is stored (local-only)
Variables ¶
var ErrStaleRemoteInfo = errors.New("stale info")
ErrStaleRemoteInfo indicates that a push failed because the remote has changed
Functions ¶
func BranchFetchRefspec ¶ added in v0.19.0
BranchFetchRefspec builds the refspec used to fetch a remote branch into its remote-tracking ref. The leading '+' forces the update so a force-pushed remote branch (whose new tip is not a descendant of the previously fetched tip) still updates refs/remotes/<remote>/<branch>, instead of failing the fetch as a non-fast-forward update. This mirrors the '+' in Git's default "+refs/heads/*:refs/remotes/origin/*" fetch refspec.
func BuildPatchFromHunks ¶
BuildPatchFromHunks is retained for callers that have not migrated to Hunks.Patch.
func CanSplitHunk ¶
CanSplitHunk is retained for callers that have not migrated to Hunk.CanSplit.
func CollapsedMessage ¶ added in v0.21.0
func CollapsedMessage(c RecentCommit, prTitles map[int]string) string
CollapsedMessage is retained for callers that have not migrated to RecentCommit.DisplayMessage.
func ConstituentPRTitles ¶ added in v0.21.0
func ConstituentPRTitles(c RecentCommit, prTitles map[int]string) map[int]string
ConstituentPRTitles is retained for callers that have not migrated to RecentCommit.ConstituentPRTitles.
func CountHunkLines ¶
CountHunkLines is retained for callers that have not migrated to Hunk.LineCounts.
func GetCurrentDate ¶
func GetCurrentDate() string
GetCurrentDate returns the current date and time in yyyyMMddHHmmss format in UTC
func GetGitCommonDir ¶
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 ¶
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 ¶
GetHunkHeader is retained for callers that have not migrated to Hunk.Header.
func GetHunkPreview ¶
GetHunkPreview is retained for callers that have not migrated to Hunk.Preview.
func IsBranchNotFoundError ¶
IsBranchNotFoundError returns true if the error indicates that a branch was not found
func IsLocalChangesError ¶
IsLocalChangesError returns true if the error indicates that local changes would be overwritten
func IsMainWorktree ¶ added in v0.22.0
IsMainWorktree reports whether worktreePath is the repo's main worktree (repoRoot), resolving symlinks on both sides for comparison (e.g. /var vs /private/var on macOS).
func LocalMetadataRefName ¶
LocalMetadataRefName returns the full ref name for a branch's local metadata.
func MetadataRefName ¶
MetadataRefName returns the full ref name for a branch's metadata.
func PRTitleNumbers ¶ added in v0.21.0
func PRTitleNumbers(commits []RecentCommit) []int
PRTitleNumbers is retained for callers that have not migrated to RecentCommits.PRTitleNumbers.
func StackMetaRefName ¶
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(ctx context.Context) ([]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 ¶
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)
GetCommitDate(branchName string) (time.Time, error)
GetCommitAuthor(branchName string) (string, error)
GetCommitRange(ctx context.Context, base, head, format string) ([]string, error)
GetCommitRangeSHAs(ctx context.Context, rr RevRange) ([]string, error)
GetCommitHistorySHAs(ctx context.Context, branchName string) ([]string, error)
GetCommitSHA(branchName string, offset int) (string, error)
GetCommitLog(sha, format string) (string, error)
GetRecentCommits(ctx context.Context, branchName string, count int) ([]RecentCommit, error)
GetRecentCommitsInRange(ctx context.Context, revRange string) ([]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. Implemented via direct `git config` invocations rather than parsing the config file in process.
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, reading git's merged config (system → global → local) — the same precedence `git config --get` applies when invoked from inside the repo. Returns empty string if the key isn't set in any scope. Use this for keys whose canonical home is often the user's global config (e.g. user.name, user.email).
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 ¶
DebugLogger is an interface for logging messages from the git layer. Despite its name, it carries both debug and informational events; the latter is used for instrumentation lines (cache stats, batch-load timings) that should be visible at the default log level.
type DiffOperations ¶
type DiffOperations interface {
GetMergeBase(ctx context.Context, rev1, rev2 string) (string, error)
GetMergeBaseByRef(ctx context.Context, ref1, ref2 string) (string, error)
IsAncestor(ctx context.Context, ancestor, descendant string) (bool, error)
IsMerged(ctx context.Context, branchName, target string) (bool, error)
IsSquashMerged(ctx context.Context, branchName, target string, cache *SquashMergeCache) (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, rr RevRange) ([]string, error)
ShowDiff(ctx context.Context, left, right string, stat bool) (string, error)
ShowCommits(ctx context.Context, rr RevRange, patch, stat bool) (string, error)
GetDiffNumstat(rr RevRange) (string, error)
GetStagedDiff(ctx context.Context, files ...string) (string, error)
GetUnstagedDiff(ctx context.Context, files ...string) (string, error)
// GetUnstagedDiffBinary is like GetUnstagedDiff but includes full binary
// content (`git diff --binary`) so the result can be reapplied with
// `git apply`.
GetUnstagedDiffBinary(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, rr RevRange, 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 ¶
GenerateNewFileHunk creates a synthetic hunk for an untracked file. This allows new files to be included in hunk-based splitting.
func (Hunk) CanSplit ¶ added in v0.22.0
CanSplit 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 (Hunk) LineCounts ¶ added in v0.22.0
CountHunkLines returns the number of added and removed lines in a hunk
func (Hunk) NewFileContent ¶ added in v0.22.0
NewFileContent extracts the file content from a new file hunk. It parses the unified diff format and returns only the added lines (without the + prefix). Respects the "\ No newline at end of file" marker to preserve files without trailing newlines.
func (Hunk) Overlaps ¶ added in v0.22.0
Overlaps reports whether two hunks have overlapping line ranges. It includes a safety margin to account for git context lines.
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 Hunks ¶ added in v0.22.0
type Hunks []Hunk
Hunks is an ordered collection of diff hunks.
func ParseDiffOutput ¶
ParseDiffOutput parses a diff output into structured hunks
type LocalMeta ¶
type LocalMeta struct {
Frozen bool `json:"frozen,omitempty"`
NeedsPRBodyUpdate bool `json:"needsPRBodyUpdate,omitempty"`
}
LocalMeta represents branch metadata that is strictly local and never pushed
type LocalMetaMap ¶ added in v0.22.0
LocalMetaMap is branch name -> local metadata, as returned by the batch local-metadata readers.
func (LocalMetaMap) Get ¶ added in v0.22.0
func (m LocalMetaMap) Get(branchName string) *LocalMeta
Get returns the local metadata for a branch, or nil if absent. Safe to call on a nil map.
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 ¶
MergeOptions contains options for merging branches
type MergedParent ¶
type MergedParent struct {
BranchName string `json:"branchName"`
PRNumber *int `json:"prNumber,omitempty"`
PRState *PRState `json:"prState,omitempty"` // MERGED or 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 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 ¶
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 ¶
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 ¶
GetParentBranchName returns the parent branch name.
func (*Meta) GetParentBranchRevision ¶
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) MarshalJSON ¶
MarshalJSON implements json.Marshaler for Meta.
func (*Meta) UnmarshalJSON ¶
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 ¶
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 ¶
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 ¶
WithParentBranchName returns a new Meta with the parent branch name set.
func (*Meta) WithParentBranchRevision ¶
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) WithStackID ¶
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 MetadataCacheSummary ¶ added in v0.18.0
MetadataCacheSummary captures cumulative metadata-cache activity since process start. Used by tests and by the runner to log periodic stats.
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(ctx context.Context, branchName string) error
RenameMetadata(oldName, newName string) error
ListMetadata() (map[string]string, error)
ReadLocalMetadata(branchName string) (*LocalMeta, error)
BatchReadLocalMetadata(branchNames []string) LocalMetaMap
WriteLocalMetadata(branchName string, meta *LocalMeta) error
// Transaction support methods. The batch forms marshal each entry and
// forward to CreateBlobsBatch — call them with len(metas) >= 1 from
// engine_writer.go and transaction.go's commit path. ctx is honored for
// the underlying git hash-object invocation.
WriteMetadataBlobsBatch(ctx context.Context, metas []*Meta) ([]string, error)
WriteLocalMetadataBlobsBatch(ctx context.Context, metas []*LocalMeta) ([]string, error)
GetMetadataRefSHA(branchName string) string
GetLocalMetadataRefSHA(branchName string) string
// Cache management
ClearMetadataCache()
// MetadataCacheStats returns cumulative cache hit/miss counts since process start.
// Used by tests and instrumentation to verify lazy-load behavior.
MetadataCacheStats() MetadataCacheSummary
}
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)
// CreateBlobsBatch writes N blobs in a single `git hash-object` invocation.
// Returns SHAs in input order. For small N (<3) callers should still use
// CreateBlob — the temp-file staging required by the batch path only pays
// off once per-blob subprocess overhead would dominate. ctx is honored for
// the underlying git invocation so long-running batches can be canceled.
CreateBlobsBatch(ctx context.Context, contents []string) ([]string, error)
ReadBlob(sha string) (string, error)
CatFile(sha string) (string, error)
}
ObjectOperations provides low-level Git object operations.
type PRState ¶ added in v0.22.0
type PRState string
PRState is a GitHub pull-request state as reported by the API (GraphQL uppercase form). Empty means unknown.
type PatchOperations ¶
type PatchOperations interface {
ApplyPatch(ctx context.Context, patchFile string, threeWay bool) error
// ApplyPatchToWorktree applies a patch (read from stdin) to the working
// tree only, never the index. It applies atomically or fails leaving the
// working tree untouched, so it can never write conflict markers.
ApplyPatchToWorktree(ctx context.Context, patch string) 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"`
BaseSHA *string `json:"baseSHA,omitempty"`
URL *string `json:"url,omitempty"`
Title *string `json:"title,omitempty"`
Body *string `json:"body,omitempty"`
State *PRState `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 PushSpec ¶ added in v0.19.1
type PushSpec struct {
BranchName string
// ExpectedRemoteSHA is the SHA the remote ref is expected to be at, used for
// force-with-lease. An empty value means the branch is not expected to exist
// on the remote yet (a create); the lease then asserts the ref is absent.
ExpectedRemoteSHA string
}
PushSpec describes a single branch to push as part of a batched PushBranches call.
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.
func (RecentCommit) ConstituentPRTitles ¶ added in v0.22.0
func (c RecentCommit) ConstituentPRTitles(prTitles map[int]string) map[int]string
ConstituentPRTitles returns the subset of prTitles keyed by a stack-merge's constituent PR numbers, or nil when the commit is not a stack-merge or no titles apply.
func (RecentCommit) DisplayMessage ¶ added in v0.22.0
func (c RecentCommit) DisplayMessage(prTitles map[int]string) string
DisplayMessage returns the display message for a commit: a stack-merge uses its consolidation PR's title when available, replacing the raw "Merge pull request #N from ..." subject; everything else falls back to the commit subject.
type RecentCommitKind ¶
type RecentCommitKind string
RecentCommitKind describes the presentation type of a trunk commit.
const ( RecentCommitKindRegular RecentCommitKind = "regular" RecentCommitKindStackMerge RecentCommitKind = "stack-merge" )
type RecentCommits ¶ added in v0.22.0
type RecentCommits []RecentCommit
RecentCommits is an ordered collection of commits returned from git log.
func CollapseStackMerges ¶ added in v0.20.0
func CollapseStackMerges(commits []RecentCommit) RecentCommits
CollapseStackMerges is retained for callers that have not migrated to RecentCommits.Collapse.
func (RecentCommits) Collapse ¶ added in v0.22.0
func (commits RecentCommits) Collapse() RecentCommits
Collapse returns the commits with constituent-PR commits dropped when their PR number is already represented by a stack-merge consolidation commit in the same slice. Input order is preserved.
It is the dedup half shared by the HTTP "recently merged" mapper and the `stackit log` command, so both collapse consolidated stacks identically. Presentation shaping (terminal vs JSX) stays with each caller; the PR-title enrichment they both need lives in PRTitleNumbers / CollapsedMessage / ConstituentPRTitles below.
func (RecentCommits) PRTitleNumbers ¶ added in v0.22.0
func (commits RecentCommits) PRTitleNumbers() []int
PRTitleNumbers returns the unique PR numbers whose titles are needed to enrich the given commits: for each stack-merge, its consolidation PR plus its constituent PRs. Regular (non-stack) commits contribute nothing — their PR title is never displayed — so callers don't over-fetch. Order is first-seen stable. Safe to call on either the raw or the collapsed slice: collapse only drops covered regular commits, never stack-merges, so both yield the same set.
type RefDecoration ¶ added in v0.21.0
type RefDecoration struct {
Name string // short ref name, e.g. "main" or "v1.4.0"
IsTag bool // true for refs/tags/*, false for refs/heads/*
}
RefDecoration is a single local ref (branch head or tag) pointing at a commit. It backs git-log-style "(main, tag: v1.4.0)" annotations.
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(ctx context.Context, name string) error
ListRefs(prefix string) (map[string]string, error)
// RefDecorations returns local branch and tag refs grouped by the commit SHA
// they point at, dereferencing annotated tags to the wrapped commit.
RefDecorations() (map[string][]RefDecoration, 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
PushBranches(ctx context.Context, remote string, specs []PushSpec, opts PushOptions) map[string]error
PullBranch(ctx context.Context, remote, branchName string) (PullResult, error)
UpdateBranchFromRemote(ctx context.Context, remote, branchName string) (PullResult, error)
Fetch(ctx context.Context, remote, branch string) error
FetchRefSpecs(ctx context.Context, remote string, refspecs []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(ctx context.Context) 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 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 RevRange ¶ added in v0.22.0
RevRange is a base..head revision range. Functions that walk or diff a range take it instead of two adjacent strings so the direction is explicit at every call site — transposed base/head reads wrong instead of silently reversing the diff.
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.
type SquashMergeCache ¶ added in v0.21.0
type SquashMergeCache struct {
// contains filtered or unexported fields
}
SquashMergeCache memoizes immutable commit patch IDs for one higher-level operation. Create one at the operation boundary and pass it through repeated IsSquashMerged calls that scan the same target history.
func NewSquashMergeCache ¶ added in v0.21.0
func NewSquashMergeCache() *SquashMergeCache
NewSquashMergeCache creates an operation-scoped cache for repeated IsSquashMerged checks against overlapping target history.
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) 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(ctx context.Context, 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 ¶
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)
StashDrop(ctx context.Context, ref string) error
StashPop(ctx context.Context) error
StashPopRef(ctx context.Context, ref string) 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 WorktreeDetachMode ¶ added in v0.21.0
type WorktreeDetachMode int
WorktreeDetachMode controls whether a new worktree checks out its branch normally or at a detached HEAD (`git worktree add --detach`).
const ( // WorktreeAttached checks out the branch normally (HEAD attached to it). WorktreeAttached WorktreeDetachMode = iota // WorktreeDetached adds the worktree at a detached HEAD. WorktreeDetached )
type WorktreeList ¶ added in v0.18.0
type WorktreeList []Worktree
WorktreeList is the parsed result of one `git worktree list --porcelain` invocation. Callers should pass it down per-batch instead of calling ListWorktrees per branch — see PathForBranch for the common lookup.
func (WorktreeList) PathForBranch ¶ added in v0.18.0
func (l WorktreeList) PathForBranch(branchName string) string
PathForBranch returns the worktree path where branchName is checked out, or "" if no worktree currently has it.
func (WorktreeList) Paths ¶ added in v0.18.0
func (l WorktreeList) Paths() []string
Paths returns just the worktree paths.
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 WorktreeDetachMode) error
AddWorktreeWithOptions(ctx context.Context, path string, branch string, detach WorktreeDetachMode, noCheckout bool) error
RemoveWorktree(ctx context.Context, path string) error
ForceRemoveWorktree(ctx context.Context, path string) error
ListWorktrees(ctx context.Context) (WorktreeList, 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(ctx context.Context, stackRoot string) error
ListWorktreeMetas() (map[string]*WorktreeMeta, error)
}
WorktreeRegistryOperations handles stackit-managed worktree tracking (local-only refs).
Source Files
¶
- absorb.go
- branch_ops.go
- branches.go
- cherry_pick.go
- commit.go
- commit_info.go
- commit_range.go
- config.go
- diff.go
- errors.go
- gitdir.go
- hunk_split.go
- hunks.go
- interfaces.go
- merge_base.go
- merge_detection.go
- meta_accessors.go
- metadata.go
- metadata_cache.go
- object_reader.go
- pull.go
- push.go
- rebase.go
- recent_commits.go
- ref_decorations.go
- remote.go
- repo.go
- reset.go
- runner.go
- stack_metadata.go
- staging.go
- stash.go
- trunk_collapse.go
- worktree.go