Documentation
¶
Overview ¶
Package git provides Git operations including repository management, worktree creation, branch operations, commits, and command execution.
Core types:
- Context: Git repository context with worktree and branch operations
- CommandRunner: Interface for executing git commands (with mock for testing)
- BranchNamer: Generates branch names from tickets/descriptions
- CommitMessage: Conventional commit message builder
Example usage:
ctx := git.NewContext("/path/to/repo")
worktree, err := ctx.CreateWorktree("feature/my-branch")
defer ctx.CleanupWorktree(worktree)
err = ctx.Commit("Add feature", "file1.go", "file2.go")
Index ¶
- Variables
- func CleanBranch(s string) string
- func ContextWithGit(ctx context.Context, gc *Context) context.Context
- func ParseBranch(branch string) (branchType, identifier, extra string)
- func SanitizeBranchName(branch string) string
- func Slugify(s string) string
- type BranchNamer
- type CommandError
- type CommandRunner
- type CommitAndPushResult
- type CommitConfig
- type CommitMessage
- func (c *CommitMessage) String() string
- func (c *CommitMessage) Validate() error
- func (c *CommitMessage) WithBody(body string) *CommitMessage
- func (c *CommitMessage) WithBreaking() *CommitMessage
- func (c *CommitMessage) WithCoAuthor(email string) *CommitMessage
- func (c *CommitMessage) WithScope(scope string) *CommitMessage
- func (c *CommitMessage) WithTicketRef(ref string) *CommitMessage
- func (c *CommitMessage) WithTicketRefs(refs ...string) *CommitMessage
- func (c *CommitMessage) WithoutGeneratedBy() *CommitMessage
- type CommitResult
- type CommitType
- type Context
- func (g *Context) BranchExists(name string) bool
- func (g *Context) Checkout(ref string) error
- func (g *Context) CheckoutNew(name string) error
- func (g *Context) CheckoutNewAt(name, ref string) error
- func (g *Context) CleanupWorktree(worktreePath string) error
- func (g *Context) Commit(message string) error
- func (g *Context) CommitAll(message string) (*CommitResult, error)
- func (g *Context) CommitAllAndPush(message string) (*CommitAndPushResult, error)
- func (g *Context) CommitAndPushTo(message, remote string) (*CommitAndPushResult, error)
- func (g *Context) CreateBranch(name string) error
- func (g *Context) CreateWorktree(branch string) (string, error)
- func (g *Context) CurrentBranch() (string, error)
- func (g *Context) DeleteBranch(name string, force bool) error
- func (g *Context) Diff(base, head string) (string, error)
- func (g *Context) DiffStaged() (string, error)
- func (g *Context) Fetch(remote string) error
- func (g *Context) GetRemoteURL(remote string) (string, error)
- func (g *Context) GetWorktree(branch string) (*WorktreeInfo, error)
- func (g *Context) GetWorktreeByPath(path string) (*WorktreeInfo, error)
- func (g *Context) HeadCommit() (string, error)
- func (g *Context) InWorktree(worktreePath string) *Context
- func (g *Context) IsBranchPushed(branch string) bool
- func (g *Context) IsClean() (bool, error)
- func (g *Context) ListWorktrees() ([]WorktreeInfo, error)
- func (g *Context) PruneWorktrees() error
- func (g *Context) Pull(remote, branch string) error
- func (g *Context) Push(remote, branch string, setUpstream bool) error
- func (g *Context) PushCurrent() (*PushResult, error)
- func (g *Context) PushCurrentTo(remote string) (*PushResult, error)
- func (g *Context) RepoPath() string
- func (g *Context) RunGit(args ...string) (string, error)
- func (g *Context) Stage(files ...string) error
- func (g *Context) StageAll() error
- func (g *Context) Status() (string, error)
- func (g *Context) WorkDir() string
- func (g *Context) WorktreeDir() string
- type Error
- type ExecRunner
- type MockCall
- type MockResponse
- type MockResponseBuilder
- type MockRunner
- func (m *MockRunner) CallCount(name string) int
- func (m *MockRunner) OnAnyCommand() *MockResponseBuilder
- func (m *MockRunner) OnCommand(name string, args ...string) *MockResponseBuilder
- func (m *MockRunner) Run(workDir, name string, args ...string) (string, error)
- func (m *MockRunner) WasCalled(name string, args ...string) bool
- type Option
- type PushResult
- type SequentialMockRunner
- type WorktreeInfo
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotGitRepo indicates the path is not a git repository. ErrNotGitRepo = errors.New("not a git repository") // ErrWorktreeExists indicates a worktree already exists for the branch. ErrWorktreeExists = errors.New("worktree already exists for this branch") // ErrWorktreeNotFound indicates the worktree does not exist. ErrWorktreeNotFound = errors.New("worktree not found") // ErrBranchExists indicates the branch already exists. ErrBranchExists = errors.New("branch already exists") // ErrBranchNotFound indicates the branch does not exist. ErrBranchNotFound = errors.New("branch not found") // ErrGitDirty indicates the working directory has uncommitted changes. ErrGitDirty = errors.New("working directory has uncommitted changes") // ErrNothingToCommit indicates there are no staged changes to commit. ErrNothingToCommit = errors.New("nothing to commit") // ErrPushFailed indicates a push operation failed. ErrPushFailed = errors.New("push failed") // ErrMergeConflict indicates a merge conflict occurred. ErrMergeConflict = errors.New("merge conflict") )
Git operation errors.
Functions ¶
func ContextWithGit ¶
ContextWithGit adds a git Context to a context.Context. Use GitFromContext to retrieve it.
Example:
gitCtx, _ := git.NewContext(".")
ctx := git.ContextWithGit(context.Background(), gitCtx)
// Pass ctx to functions that need git access
func ParseBranch ¶
ParseBranch extracts components from a branch name. Returns (type, identifier, extra) where extra is any additional suffix.
func SanitizeBranchName ¶
SanitizeBranchName converts a branch name to a safe directory name.
Types ¶
type BranchNamer ¶
type BranchNamer struct {
TypePrefix string // Branch type prefix (e.g., "feature", "bugfix", "devflow")
IncludeTitle bool // Whether to include title slug in branch name
MaxLength int // Maximum branch name length
}
BranchNamer generates branch names following conventions.
func DefaultBranchNamer ¶
func DefaultBranchNamer() *BranchNamer
DefaultBranchNamer returns a namer with default settings.
func (*BranchNamer) ForBugfix ¶
func (n *BranchNamer) ForBugfix(ticketID, description string) string
ForBugfix generates a bugfix branch name. Example: "TK-422", "auth-crash" -> "bugfix/tk-422-auth-crash"
func (*BranchNamer) ForFeature ¶
func (n *BranchNamer) ForFeature(name string) string
ForFeature generates a simple feature branch name. Example: "add-caching" -> "feature/add-caching"
func (*BranchNamer) ForTicket ¶
func (n *BranchNamer) ForTicket(ticketID, title string) string
ForTicket generates a branch name from a ticket ID and title. Example: "TK-421", "Add User Authentication" -> "feature/tk-421-add-user-authentication"
func (*BranchNamer) ForWorkflow ¶
func (n *BranchNamer) ForWorkflow(workflowID, identifier string) string
ForWorkflow generates a branch name for automated workflow runs. Example: "ticket-to-pr", "TK-421" -> "devflow/ticket-to-pr-tk-421-1734567890"
type CommandError ¶
CommandError represents a command execution error.
func (*CommandError) Error ¶
func (e *CommandError) Error() string
func (*CommandError) Unwrap ¶
func (e *CommandError) Unwrap() error
type CommandRunner ¶
type CommandRunner interface {
// Run executes a command and returns the trimmed stdout.
// workDir is the working directory for the command.
// If the command fails, it returns the stderr/stdout as the error message.
Run(workDir string, name string, args ...string) (stdout string, err error)
}
CommandRunner executes shell commands. This interface allows mocking command execution in tests.
type CommitAndPushResult ¶
type CommitAndPushResult struct {
Commit *CommitResult
Push *PushResult
}
CommitAndPushResult contains the result of a commit and push operation.
type CommitConfig ¶
type CommitConfig struct {
IncludeGeneratedBy bool // Include "Generated-By: devflow" footer
TicketRefPrefix string // Prefix for ticket refs ("Refs:", "Fixes:", "Closes:")
RequireTicketRef bool // Require at least one ticket reference
}
CommitConfig configures commit message formatting.
func DefaultCommitConfig ¶
func DefaultCommitConfig() CommitConfig
DefaultCommitConfig returns the default commit configuration.
type CommitMessage ¶
type CommitMessage struct {
Type CommitType // Required: type of change (feat, fix, etc.)
Scope string // Optional: area of codebase affected
Subject string // Required: short description (imperative mood)
Body string // Optional: detailed explanation
TicketRefs []string // Optional: ticket references (TK-421, ISSUE-123)
CoAuthors []string // Optional: co-author emails
GeneratedBy string // Optional: tool that generated the commit
Breaking bool // Whether this is a breaking change
}
CommitMessage represents a structured commit message following conventional commits.
func NewCommitMessage ¶
func NewCommitMessage(typ CommitType, subject string) *CommitMessage
NewCommitMessage creates a commit message with the devflow marker.
func (*CommitMessage) String ¶
func (c *CommitMessage) String() string
String formats the commit message following conventional commit format.
func (*CommitMessage) Validate ¶
func (c *CommitMessage) Validate() error
Validate checks if the commit message is valid.
func (*CommitMessage) WithBody ¶
func (c *CommitMessage) WithBody(body string) *CommitMessage
WithBody adds a body to the commit message.
func (*CommitMessage) WithBreaking ¶
func (c *CommitMessage) WithBreaking() *CommitMessage
WithBreaking marks this as a breaking change.
func (*CommitMessage) WithCoAuthor ¶
func (c *CommitMessage) WithCoAuthor(email string) *CommitMessage
WithCoAuthor adds a co-author.
func (*CommitMessage) WithScope ¶
func (c *CommitMessage) WithScope(scope string) *CommitMessage
WithScope adds a scope to the commit message.
func (*CommitMessage) WithTicketRef ¶
func (c *CommitMessage) WithTicketRef(ref string) *CommitMessage
WithTicketRef adds a ticket reference.
func (*CommitMessage) WithTicketRefs ¶
func (c *CommitMessage) WithTicketRefs(refs ...string) *CommitMessage
WithTicketRefs adds multiple ticket references.
func (*CommitMessage) WithoutGeneratedBy ¶
func (c *CommitMessage) WithoutGeneratedBy() *CommitMessage
WithoutGeneratedBy removes the Generated-By footer.
type CommitResult ¶
type CommitResult struct {
SHA string // Full commit SHA
Branch string // Branch name
Message string // Commit message
Date time.Time // Commit timestamp
}
CommitResult contains the result of a commit operation.
type CommitType ¶
type CommitType string
CommitType represents the type of change in a commit.
const ( CommitTypeFeat CommitType = "feat" CommitTypeFix CommitType = "fix" CommitTypeDocs CommitType = "docs" CommitTypeStyle CommitType = "style" CommitTypeRefactor CommitType = "refactor" CommitTypePerf CommitType = "perf" CommitTypeTest CommitType = "test" CommitTypeBuild CommitType = "build" CommitTypeCI CommitType = "ci" CommitTypeChore CommitType = "chore" CommitTypeRevert CommitType = "revert" )
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
Context manages git operations for a repository.
func GitFromContext ¶
GitFromContext retrieves a git Context from a context.Context. Returns nil if no git Context is present.
Example:
func doWork(ctx context.Context) error {
gitCtx := git.GitFromContext(ctx)
if gitCtx == nil {
return errors.New("git context required")
}
return gitCtx.CommitAll("message")
}
func MustGitFromContext ¶
MustGitFromContext retrieves a git Context or panics. Use in code where git context is required and missing is a programming error.
func NewContext ¶
NewContext creates a new git context for the repository. It validates that the path is a git repository and applies any options.
func (*Context) BranchExists ¶
BranchExists checks if a branch exists.
func (*Context) CheckoutNew ¶
CheckoutNew creates and checks out a new branch at the current HEAD. This is a convenience method combining CreateBranch + Checkout.
func (*Context) CheckoutNewAt ¶
CheckoutNewAt creates and checks out a new branch at the specified ref.
func (*Context) CleanupWorktree ¶
CleanupWorktree removes a worktree and its registration. If force is true, removes even with uncommitted changes.
func (*Context) Commit ¶
Commit creates a commit with the given message. Returns ErrNothingToCommit if there are no staged changes.
func (*Context) CommitAll ¶
func (g *Context) CommitAll(message string) (*CommitResult, error)
CommitAll stages all changes and commits with the given message. Returns ErrNothingToCommit if there are no changes to commit. This is a convenience method combining StageAll + Commit + HeadCommit + CurrentBranch.
func (*Context) CommitAllAndPush ¶
func (g *Context) CommitAllAndPush(message string) (*CommitAndPushResult, error)
CommitAllAndPush stages all changes, commits, and pushes to origin. This is the most common workflow: save work and push it. If push fails, returns partial result with the commit info.
func (*Context) CommitAndPushTo ¶
func (g *Context) CommitAndPushTo(message, remote string) (*CommitAndPushResult, error)
CommitAndPushTo stages all changes, commits, and pushes to the specified remote.
func (*Context) CreateBranch ¶
CreateBranch creates a new branch at HEAD.
func (*Context) CreateWorktree ¶
CreateWorktree creates an isolated worktree for the branch. If the branch doesn't exist, it will be created. Returns the path to the worktree directory.
func (*Context) CurrentBranch ¶
CurrentBranch returns the current branch name.
func (*Context) DeleteBranch ¶
DeleteBranch deletes a branch. If force is true, uses -D instead of -d.
func (*Context) DiffStaged ¶
DiffStaged returns the diff of staged changes.
func (*Context) GetRemoteURL ¶
GetRemoteURL returns the URL of the specified remote.
func (*Context) GetWorktree ¶
func (g *Context) GetWorktree(branch string) (*WorktreeInfo, error)
GetWorktree returns information about a specific worktree by branch name.
func (*Context) GetWorktreeByPath ¶
func (g *Context) GetWorktreeByPath(path string) (*WorktreeInfo, error)
GetWorktreeByPath returns information about a specific worktree by path.
func (*Context) HeadCommit ¶
HeadCommit returns the current HEAD commit SHA.
func (*Context) InWorktree ¶
InWorktree returns a new Context that operates in the specified worktree.
func (*Context) IsBranchPushed ¶
IsBranchPushed checks if the branch exists on the remote.
func (*Context) ListWorktrees ¶
func (g *Context) ListWorktrees() ([]WorktreeInfo, error)
ListWorktrees returns all active worktrees.
func (*Context) PruneWorktrees ¶
PruneWorktrees removes stale worktree administrative files.
func (*Context) Push ¶
Push pushes the branch to the remote. If setUpstream is true, uses -u to set upstream tracking.
func (*Context) PushCurrent ¶
func (g *Context) PushCurrent() (*PushResult, error)
PushCurrent pushes the current branch to origin. Automatically sets upstream tracking if the branch hasn't been pushed before. This is a convenience method that handles the common case of pushing work.
func (*Context) PushCurrentTo ¶
func (g *Context) PushCurrentTo(remote string) (*PushResult, error)
PushCurrentTo pushes the current branch to the specified remote. Automatically sets upstream tracking if needed.
func (*Context) RunGit ¶
RunGit executes a git command and returns stdout. This is the public version of runGit for use by external packages.
func (*Context) WorkDir ¶
WorkDir returns the current working directory for git commands. This is the repo path unless working in a worktree.
func (*Context) WorktreeDir ¶
WorktreeDir returns the path to the worktrees directory.
type Error ¶
type Error struct {
Op string // Operation that failed (e.g., "commit", "push")
Cmd string // Git command that was run
Output string // Combined stdout/stderr output
Err error // Underlying error
}
Error wraps a git command error with context.
type ExecRunner ¶
type ExecRunner struct{}
ExecRunner is the default CommandRunner using exec.Command.
type MockResponse ¶
MockResponse represents a mock command response.
type MockResponseBuilder ¶
type MockResponseBuilder struct {
// contains filtered or unexported fields
}
MockResponseBuilder builds mock responses.
func (*MockResponseBuilder) Return ¶
func (b *MockResponseBuilder) Return(stdout string, err error) *MockRunner
Return sets the response for this command.
type MockRunner ¶
type MockRunner struct {
// Responses maps "command args..." to predefined responses.
// Use "*" as a wildcard for any command.
Responses map[string]MockResponse
// Calls records all commands that were executed.
Calls []MockCall
// DefaultResponse is returned when no specific response is configured.
DefaultResponse MockResponse
}
MockRunner is a test double for CommandRunner. It allows configuring responses for specific commands.
func NewMockRunner ¶
func NewMockRunner() *MockRunner
NewMockRunner creates a new MockRunner with empty responses.
func (*MockRunner) CallCount ¶
func (m *MockRunner) CallCount(name string) int
CallCount returns the number of times a command was called.
func (*MockRunner) OnAnyCommand ¶
func (m *MockRunner) OnAnyCommand() *MockResponseBuilder
OnAnyCommand configures a response for any command.
func (*MockRunner) OnCommand ¶
func (m *MockRunner) OnCommand(name string, args ...string) *MockResponseBuilder
OnCommand configures a response for a specific command. Example: runner.OnCommand("git", "status", "--short").Return("M file.go", nil)
type Option ¶
type Option func(*Context)
Option configures Context.
func WithRunner ¶
func WithRunner(runner CommandRunner) Option
WithRunner sets a custom command runner for git operations. This is primarily used for testing to inject mock command execution.
func WithWorktreeDir ¶
WithWorktreeDir sets the directory where worktrees are created. Default is ".worktrees" relative to the repository root.
type PushResult ¶
type PushResult struct {
Remote string // Remote name (e.g., "origin")
Branch string // Branch that was pushed
SHA string // Commit SHA that was pushed
SetUpstream bool // Whether upstream tracking was set
URL string // Remote URL (for reference)
}
PushResult contains the result of a push operation.
type SequentialMockRunner ¶
type SequentialMockRunner struct {
Calls []MockCall
// contains filtered or unexported fields
}
SequentialMockRunner is a mock runner that returns responses in order.
func NewSequentialMockRunner ¶
func NewSequentialMockRunner() *SequentialMockRunner
NewSequentialMockRunner creates a new SequentialMockRunner.
func (*SequentialMockRunner) AddOutput ¶
func (m *SequentialMockRunner) AddOutput(stdout string, err error) *SequentialMockRunner
AddOutput adds a response to the queue.
func (*SequentialMockRunner) AddOutputError ¶
func (m *SequentialMockRunner) AddOutputError(stdout, errOutput string, err error) *SequentialMockRunner
AddOutputError adds a response with custom error output.
type WorktreeInfo ¶
type WorktreeInfo struct {
Path string // Filesystem path to the worktree
Branch string // Branch checked out in the worktree
Commit string // HEAD commit SHA
}
WorktreeInfo represents an active git worktree.