Documentation
¶
Overview ¶
Package git provides Git operations for managing worktrees, branches, merges, and PRs.
The package is organized into focused modules:
- service.go: GitService struct and constructor
- status.go: Worktree status, diff stats, file diffs
- commit.go: Commit operations, message generation
- merge.go: Merge and PR operations
- branch.go: Branch management, divergence checking
- github.go: GitHub issue/PR integration
Index ¶
- Constants
- func ExtractOwnerRepo(remoteURL string) string
- func GetPRLinkText(issueRef *config.IssueRef) string
- type BranchDivergence
- type CIStatus
- type DiffStats
- type FileDiff
- type GitHubIssue
- type GitService
- func (s *GitService) AbortMerge(ctx context.Context, repoPath string) error
- func (s *GitService) AddIssueLabel(ctx context.Context, repoPath string, issueNumber int, label string) error
- func (s *GitService) CheckPRChecks(ctx context.Context, repoPath, branch string) (CIStatus, error)
- func (s *GitService) CheckPRReviewDecision(ctx context.Context, repoPath, branch string) (ReviewDecision, error)
- func (s *GitService) CheckoutBranch(ctx context.Context, repoPath, branch string) error
- func (s *GitService) CheckoutBranchIgnoreWorktrees(ctx context.Context, repoPath, branch string) error
- func (s *GitService) CommentOnIssue(ctx context.Context, repoPath string, issueNumber int, body string) error
- func (s *GitService) CommitAll(ctx context.Context, worktreePath, message string) error
- func (s *GitService) CommitConflictResolution(ctx context.Context, repoPath, message string) error
- func (s *GitService) CreatePR(ctx context.Context, ...) <-chan Result
- func (s *GitService) EnsureCommitted(ctx context.Context, ch chan<- Result, worktreePath, commitMsg string) bool
- func (s *GitService) FetchGitHubIssues(ctx context.Context, repoPath string) ([]GitHubIssue, error)
- func (s *GitService) FetchGitHubIssuesWithLabel(ctx context.Context, repoPath, label string) ([]GitHubIssue, error)
- func (s *GitService) FetchPRReviewComments(ctx context.Context, repoPath, branch string) ([]PRReviewComment, error)
- func (s *GitService) GenerateBranchNamesFromOptions(ctx context.Context, options []struct{ ... }) (map[int]string, error)
- func (s *GitService) GenerateCommitMessage(ctx context.Context, worktreePath string) (string, error)
- func (s *GitService) GenerateCommitMessageWithClaude(ctx context.Context, worktreePath string) (string, error)
- func (s *GitService) GeneratePRTitleAndBodyWithIssueRef(ctx context.Context, repoPath, branch, baseBranch string, ...) (title, body string, err error)
- func (s *GitService) GetBatchPRStates(ctx context.Context, repoPath string, branches []string) (map[string]PRState, error)
- func (s *GitService) GetBatchPRStatesWithComments(ctx context.Context, repoPath string, branches []string) (map[string]PRBatchResult, error)
- func (s *GitService) GetBranchDivergence(ctx context.Context, repoPath, localBranch, remoteBranch string) (*BranchDivergence, error)
- func (s *GitService) GetConflictedFiles(ctx context.Context, repoPath string) ([]string, error)
- func (s *GitService) GetCurrentBranch(ctx context.Context, repoPath string) (string, error)
- func (s *GitService) GetDefaultBranch(ctx context.Context, repoPath string) string
- func (s *GitService) GetDiffStats(ctx context.Context, worktreePath string) (*DiffStats, error)
- func (s *GitService) GetPRState(ctx context.Context, repoPath, branch string) (PRState, error)
- func (s *GitService) GetRemoteOriginURL(ctx context.Context, repoPath string) (string, error)
- func (s *GitService) GetWorktreeStatus(ctx context.Context, worktreePath string) (*WorktreeStatus, error)
- func (s *GitService) HasRemoteOrigin(ctx context.Context, repoPath string) bool
- func (s *GitService) HasTrackingBranch(ctx context.Context, repoPath, branch string) bool
- func (s *GitService) IsMergeInProgress(ctx context.Context, repoPath string) (bool, error)
- func (s *GitService) MergePR(ctx context.Context, repoPath, branch string, deleteBranch bool, method string) error
- func (s *GitService) MergeToMain(ctx context.Context, repoPath, worktreePath, branch, commitMsg string) <-chan Result
- func (s *GitService) MergeToParent(ctx context.Context, ...) <-chan Result
- func (s *GitService) PushUpdates(ctx context.Context, repoPath, worktreePath, branch, commitMsg string) <-chan Result
- func (s *GitService) RemoteBranchExists(ctx context.Context, repoPath, remoteBranch string) bool
- func (s *GitService) RemoveIssueLabel(ctx context.Context, repoPath string, issueNumber int, label string) error
- func (s *GitService) RenameBranch(ctx context.Context, worktreePath, oldName, newName string) error
- func (s *GitService) SquashMergeToMain(ctx context.Context, repoPath, worktreePath, branch, commitMsg string) <-chan Result
- func (s *GitService) UploadTranscriptToPR(ctx context.Context, repoPath, branch, transcript string) error
- type PRBatchResult
- type PRReviewComment
- type PRState
- type Result
- type ReviewDecision
- type WorktreeStatus
Constants ¶
const ( // MaxBranchNameLength is the maximum length for auto-generated branch names. // User-provided branch names can be longer (up to MaxBranchNameValidation). MaxBranchNameLength = 50 )
Configuration constants for branch operations
const ( // MaxDiffSize is the maximum number of characters to include in a diff. // This prevents excessive memory usage when Claude is analyzing changes. // Claude's context window can handle much more, but large diffs slow down // commit message generation and rarely provide additional value. // 50KB is enough to capture meaningful changes while staying responsive. MaxDiffSize = 50000 )
Configuration constants for commit operations
Variables ¶
This section is empty.
Functions ¶
func ExtractOwnerRepo ¶
ExtractOwnerRepo extracts "owner/repo" from a git remote URL. Supports SSH (git@github.com:owner/repo.git) and HTTPS (https://github.com/owner/repo.git) formats. Returns empty string if the URL cannot be parsed.
func GetPRLinkText ¶
GetPRLinkText returns the appropriate text to add to a PR body based on the issue source. For GitHub issues: returns "\n\nFixes #123" For Asana tasks: returns "" (no auto-close support) For unknown sources: returns ""
Types ¶
type BranchDivergence ¶
type BranchDivergence struct {
Behind int // Number of commits local is behind remote
Ahead int // Number of commits local is ahead of remote
}
BranchDivergence represents the divergence between local and remote branches.
func (*BranchDivergence) CanFastForward ¶
func (d *BranchDivergence) CanFastForward() bool
CanFastForward returns true if local can fast-forward to remote (not ahead).
func (*BranchDivergence) IsDiverged ¶
func (d *BranchDivergence) IsDiverged() bool
IsDiverged returns true if the branches have diverged (both ahead and behind).
type DiffStats ¶
type DiffStats struct {
FilesChanged int // Number of files changed
Additions int // Number of lines added
Deletions int // Number of lines deleted
}
DiffStats represents the statistics of changes in a worktree
type FileDiff ¶
type FileDiff struct {
Filename string // File path relative to repo root
Status string // Status code: M (modified), A (added), D (deleted), etc.
Diff string // Diff content for this file only
}
FileDiff represents a single file's diff with its status
type GitHubIssue ¶
type GitHubIssue struct {
Number int `json:"number"`
Title string `json:"title"`
Body string `json:"body"`
URL string `json:"url"`
}
GitHubIssue represents a GitHub issue fetched via the gh CLI
type GitService ¶
type GitService struct {
// contains filtered or unexported fields
}
GitService provides git operations with explicit dependency injection. Instead of using a package-level executor variable, each GitService instance holds its own executor, enabling proper testing and avoiding global state.
func NewGitService ¶
func NewGitService() *GitService
NewGitService creates a new GitService with the default real executor.
func NewGitServiceWithExecutor ¶
func NewGitServiceWithExecutor(exec pexec.CommandExecutor) *GitService
NewGitServiceWithExecutor creates a new GitService with a custom executor. This is primarily used for testing where a mock executor is needed.
func (*GitService) AbortMerge ¶
func (s *GitService) AbortMerge(ctx context.Context, repoPath string) error
AbortMerge aborts an in-progress merge
func (*GitService) AddIssueLabel ¶
func (s *GitService) AddIssueLabel(ctx context.Context, repoPath string, issueNumber int, label string) error
AddIssueLabel adds a label to a GitHub issue using the gh CLI.
func (*GitService) CheckPRChecks ¶
CheckPRChecks checks the CI status of a PR for the given branch. Uses `gh pr checks` which returns exit code 0 if all checks pass.
func (*GitService) CheckPRReviewDecision ¶
func (s *GitService) CheckPRReviewDecision(ctx context.Context, repoPath, branch string) (ReviewDecision, error)
CheckPRReviewDecision returns the review decision for a PR by inspecting individual reviews. GitHub's reviewDecision field only works with branch protection rules, so we derive the decision ourselves by looking at each reviewer's most recent actionable review state.
func (*GitService) CheckoutBranch ¶
func (s *GitService) CheckoutBranch(ctx context.Context, repoPath, branch string) error
CheckoutBranch checks out the specified branch in the given repo. Returns an error if the checkout fails (e.g., uncommitted changes would be overwritten).
func (*GitService) CheckoutBranchIgnoreWorktrees ¶
func (s *GitService) CheckoutBranchIgnoreWorktrees(ctx context.Context, repoPath, branch string) error
CheckoutBranchIgnoreWorktrees checks out the specified branch, even if it's already checked out in another worktree. This is useful for the preview feature where we want to temporarily view a worktree's branch in the main repo.
func (*GitService) CommentOnIssue ¶
func (s *GitService) CommentOnIssue(ctx context.Context, repoPath string, issueNumber int, body string) error
CommentOnIssue leaves a comment on a GitHub issue using the gh CLI.
func (*GitService) CommitAll ¶
func (s *GitService) CommitAll(ctx context.Context, worktreePath, message string) error
CommitAll stages all changes and commits them with the given message
func (*GitService) CommitConflictResolution ¶
func (s *GitService) CommitConflictResolution(ctx context.Context, repoPath, message string) error
CommitConflictResolution stages all changes and commits with the given message. This is used after resolving merge conflicts to complete the merge.
func (*GitService) CreatePR ¶
func (s *GitService) CreatePR(ctx context.Context, repoPath, worktreePath, branch, baseBranch, commitMsg string, issueRef *config.IssueRef, sessionID string) <-chan Result
CreatePR pushes the branch and creates a pull request using gh CLI worktreePath is where Claude made changes - we commit any uncommitted changes first If commitMsg is provided and non-empty, it will be used directly instead of generating one If issueRef is provided, appropriate link text will be added to the PR body based on the source. baseBranch is the branch this PR should be compared against (typically the session's BaseBranch). sessionID is used to load and upload the session transcript as a PR comment; pass "" to skip.
func (*GitService) EnsureCommitted ¶
func (s *GitService) EnsureCommitted(ctx context.Context, ch chan<- Result, worktreePath, commitMsg string) bool
EnsureCommitted checks for uncommitted changes and commits them if present. If commitMsg is empty, it generates a commit message using Claude (with fallback). Returns true if the operation succeeded (either committed or no changes needed), false if there was an error (error is sent to the result channel).
func (*GitService) FetchGitHubIssues ¶
func (s *GitService) FetchGitHubIssues(ctx context.Context, repoPath string) ([]GitHubIssue, error)
FetchGitHubIssues fetches open issues from a GitHub repository using the gh CLI. The repoPath is used as the working directory to determine which repo to query.
func (*GitService) FetchGitHubIssuesWithLabel ¶
func (s *GitService) FetchGitHubIssuesWithLabel(ctx context.Context, repoPath, label string) ([]GitHubIssue, error)
FetchGitHubIssuesWithLabel fetches open issues with a specific label from a GitHub repository.
func (*GitService) FetchPRReviewComments ¶
func (s *GitService) FetchPRReviewComments(ctx context.Context, repoPath, branch string) ([]PRReviewComment, error)
FetchPRReviewComments fetches review comments from a pull request using the gh CLI. Returns top-level PR comments, review body comments, and inline code review comments as a flattened slice. The repoPath is used as the working directory.
func (*GitService) GenerateBranchNamesFromOptions ¶
func (s *GitService) GenerateBranchNamesFromOptions(ctx context.Context, options []struct { Number int Text string }) (map[int]string, error)
GenerateBranchNamesFromOptions uses Claude to generate short, descriptive git branch names from a list of option texts. Returns a map from option number to branch name. This batches all options into a single Claude call for efficiency.
func (*GitService) GenerateCommitMessage ¶
func (s *GitService) GenerateCommitMessage(ctx context.Context, worktreePath string) (string, error)
GenerateCommitMessage creates a commit message based on the changes (simple fallback)
func (*GitService) GenerateCommitMessageWithClaude ¶
func (s *GitService) GenerateCommitMessageWithClaude(ctx context.Context, worktreePath string) (string, error)
GenerateCommitMessageWithClaude uses Claude to generate a commit message from the diff
func (*GitService) GeneratePRTitleAndBodyWithIssueRef ¶
func (s *GitService) GeneratePRTitleAndBodyWithIssueRef(ctx context.Context, repoPath, branch, baseBranch string, issueRef *config.IssueRef) (title, body string, err error)
GeneratePRTitleAndBodyWithIssueRef uses Claude to generate a PR title and body from the branch changes. If issueRef is provided, it will add appropriate link text based on the source:
- GitHub: adds "Fixes #{number}" to auto-close the issue
- Asana: no auto-close support (Asana doesn't use commit message keywords)
baseBranch is the branch this PR will be compared against (typically the session's BaseBranch or main).
func (*GitService) GetBatchPRStates ¶
func (s *GitService) GetBatchPRStates(ctx context.Context, repoPath string, branches []string) (map[string]PRState, error)
GetBatchPRStates returns the PR states for multiple branches in a single gh CLI call. It uses `gh pr list --state all` to fetch all PRs for the repo, then matches by branch name. Branches without a matching PR are omitted from the result map.
func (*GitService) GetBatchPRStatesWithComments ¶
func (s *GitService) GetBatchPRStatesWithComments(ctx context.Context, repoPath string, branches []string) (map[string]PRBatchResult, error)
GetBatchPRStatesWithComments returns PR states and comment counts for multiple branches. Uses a single `gh pr list` call per repo. The comment count is len(comments) + len(reviews), which captures top-level PR comments and review submissions.
func (*GitService) GetBranchDivergence ¶
func (s *GitService) GetBranchDivergence(ctx context.Context, repoPath, localBranch, remoteBranch string) (*BranchDivergence, error)
GetBranchDivergence returns how many commits the local branch is behind and ahead of the remote branch. Uses git rev-list --count --left-right which outputs "behind\tahead". Returns an error if either branch doesn't exist or comparison fails.
func (*GitService) GetConflictedFiles ¶
GetConflictedFiles returns the list of files with merge conflicts in a repo
func (*GitService) GetCurrentBranch ¶
GetCurrentBranch returns the name of the currently checked out branch in the given repo/worktree. Returns an error if HEAD is detached or the command fails.
func (*GitService) GetDefaultBranch ¶
func (s *GitService) GetDefaultBranch(ctx context.Context, repoPath string) string
GetDefaultBranch returns the default branch name (main or master)
func (*GitService) GetDiffStats ¶
GetDiffStats returns the diff statistics (files changed, additions, deletions) for uncommitted changes in the given worktree.
func (*GitService) GetPRState ¶
GetPRState returns the state of a PR for the given branch using the gh CLI. Returns PRStateUnknown and an error if the PR cannot be found or gh fails.
func (*GitService) GetRemoteOriginURL ¶
GetRemoteOriginURL returns the URL of the "origin" remote.
func (*GitService) GetWorktreeStatus ¶
func (s *GitService) GetWorktreeStatus(ctx context.Context, worktreePath string) (*WorktreeStatus, error)
GetWorktreeStatus returns the status of uncommitted changes in a worktree
func (*GitService) HasRemoteOrigin ¶
func (s *GitService) HasRemoteOrigin(ctx context.Context, repoPath string) bool
HasRemoteOrigin checks if the repository has a remote named "origin"
func (*GitService) HasTrackingBranch ¶
func (s *GitService) HasTrackingBranch(ctx context.Context, repoPath, branch string) bool
HasTrackingBranch checks if the given branch has an upstream tracking branch configured. Uses git config to check for branch.<name>.remote which is set when tracking is configured.
func (*GitService) IsMergeInProgress ¶
IsMergeInProgress checks if a merge is currently in progress in the repo. It returns true if MERGE_HEAD exists (meaning there's an ongoing merge).
func (*GitService) MergePR ¶
func (s *GitService) MergePR(ctx context.Context, repoPath, branch string, deleteBranch bool, method string) error
MergePR merges a PR for the given branch using the specified merge method. Valid methods: "rebase" (default), "squash", "merge". If method is empty, defaults to "rebase". The deleteBranch parameter controls whether to delete the branch after merging. For autonomous sessions, pass false since the branch is deleted during session cleanup.
func (*GitService) MergeToMain ¶
func (s *GitService) MergeToMain(ctx context.Context, repoPath, worktreePath, branch, commitMsg string) <-chan Result
MergeToMain merges a branch into the default branch worktreePath is where Claude made changes - we commit any uncommitted changes first If commitMsg is provided and non-empty, it will be used directly instead of generating one
func (*GitService) MergeToParent ¶
func (s *GitService) MergeToParent(ctx context.Context, childWorktreePath, childBranch, parentWorktreePath, parentBranch, commitMsg string) <-chan Result
MergeToParent merges a child session's branch into its parent session's branch. This operates on the parent's worktree, merging the child's changes into it. childWorktreePath is where the child's changes are - we commit uncommitted changes first parentWorktreePath is where we perform the merge If commitMsg is provided and non-empty, it will be used directly instead of generating one
func (*GitService) PushUpdates ¶
func (s *GitService) PushUpdates(ctx context.Context, repoPath, worktreePath, branch, commitMsg string) <-chan Result
PushUpdates commits any uncommitted changes and pushes to the remote branch. This is used after a PR has been created to push additional commits based on feedback. If commitMsg is provided and non-empty, it will be used directly instead of generating one.
func (*GitService) RemoteBranchExists ¶
func (s *GitService) RemoteBranchExists(ctx context.Context, repoPath, remoteBranch string) bool
RemoteBranchExists checks if a remote branch reference exists (e.g., "origin/main"). Uses git rev-parse --verify which exits 0 if the ref exists, non-zero otherwise.
func (*GitService) RemoveIssueLabel ¶
func (s *GitService) RemoveIssueLabel(ctx context.Context, repoPath string, issueNumber int, label string) error
RemoveIssueLabel removes a label from a GitHub issue using the gh CLI.
func (*GitService) RenameBranch ¶
func (s *GitService) RenameBranch(ctx context.Context, worktreePath, oldName, newName string) error
RenameBranch renames a git branch in the given worktree. The worktree must have the branch checked out.
func (*GitService) SquashMergeToMain ¶
func (s *GitService) SquashMergeToMain(ctx context.Context, repoPath, worktreePath, branch, commitMsg string) <-chan Result
SquashMergeToMain squashes all commits from a branch into a single commit when merging to main. worktreePath is where Claude made changes - we commit any uncommitted changes first. commitMsg is required and will be used as the commit message for the squashed commit.
func (*GitService) UploadTranscriptToPR ¶
func (s *GitService) UploadTranscriptToPR(ctx context.Context, repoPath, branch, transcript string) error
UploadTranscriptToPR posts a session transcript as a comment on the PR for the given branch. The transcript is formatted as a collapsed <details> block so it does not clutter the PR.
type PRBatchResult ¶
type PRBatchResult struct {
State PRState
CommentCount int // len(comments) + len(actionable reviews) — excludes APPROVED/DISMISSED reviews
}
PRBatchResult holds the state and comment count for a PR from a batch query.
type PRReviewComment ¶
type PRReviewComment struct {
Author string // GitHub username
Body string // Comment text
Path string // File path (empty for top-level/review body comments)
Line int // Line number (0 for top-level/review body comments)
URL string // Permalink
}
PRReviewComment represents a single review comment from a GitHub pull request. This can be a top-level PR comment, a review body, or an inline code review comment.
type Result ¶
type Result struct {
Output string
Error error
Done bool
ConflictedFiles []string // Files with merge conflicts (only set on conflict)
RepoPath string // Path to the repo where conflict occurred
}
Result represents output from a git operation
type ReviewDecision ¶
type ReviewDecision string
ReviewDecision represents the GitHub PR review decision.
const ( ReviewApproved ReviewDecision = "APPROVED" ReviewChangesRequested ReviewDecision = "CHANGES_REQUESTED" ReviewNone ReviewDecision = "" // No actionable reviews yet )
type WorktreeStatus ¶
type WorktreeStatus struct {
HasChanges bool
Summary string // Short summary like "3 files changed"
Files []string // List of changed files
Diff string // Full diff output
FileDiffs []FileDiff // Per-file diffs for detailed viewing
}
WorktreeStatus represents the status of changes in a worktree