git

package
v0.17.9 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNoGitHubAuth = errors.New("no GitHub authentication available")

ErrNoGitHubAuth is the sentinel returned when neither a GH_TOKEN nor the gh CLI are available for PR creation. The wrapped error message contains the exact gh pr create command the user can run manually.

View Source
var GetDefaultBranch = func(ctx context.Context, repoDir string) (string, error) {
	cmd := exec.CommandContext(ctx, "git", "symbolic-ref", "--short", "refs/remotes/origin/HEAD")
	cmd.Dir = repoDir
	out, err := cmd.Output()
	if err != nil {
		return "main", nil
	}
	return strings.TrimSpace(string(out)), nil
}

GetDefaultBranch returns the default branch name for the repo rooted at repoDir. By default it reads

git symbolic-ref refs/remotes/origin/HEAD

and falls back to "main". Tests may override this variable.

View Source
var GitHubAPIBaseURL = "https://api.github.com"

GitHubAPIBaseURL is the base URL for the GitHub REST API. Tests may override it to point at an httptest server.

View Source
var PushBranch = func(ctx context.Context, repoDir, head string) error {
	cmd := exec.CommandContext(ctx, "git", "push", "-u", "origin", head)
	cmd.Dir = repoDir
	out, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("push branch %q to origin: %w (output: %s)", head, err, strings.TrimSpace(string(out)))
	}
	return nil
}

PushBranch executes "git push -u origin <head>". Tests may override this variable to avoid network access.

NOTE: intentionally exported only for testability — follow the same pattern as RunGhCommand / GetDefaultBranch. Not safe for concurrent writes; override in init() or TestMain, not mid-flight.

View Source
var RunGhCommand = func(ctx context.Context, dir string, args ...string) ([]byte, error) {
	cmd := exec.CommandContext(ctx, "gh", args...)
	cmd.Dir = dir
	out, err := cmd.CombinedOutput()
	return out, err
}

RunGhCommand is the function used to invoke the gh CLI. The default implementation simply calls exec.CommandContext("gh", args...). Tests may override this variable to avoid a real binary.

NOTE: this variable is intentionally not safe for concurrent writes — override it in init() or TestMain, not mid-flight.

Functions

func AddAllAndCommit

func AddAllAndCommit(dir, message string, timeoutSeconds int) error

AddAllAndCommit commits all staged changes inside dir with the provided message (non-interactive). dir MUST be non-empty.

func AddAndCommitFile

func AddAndCommitFile(dir, newFilename, message string) error

AddAndCommitFile stages the specified file and commits it with the given message inside dir. dir MUST be non-empty — passing "" would let the operation hit the test process's CWD (the host repo on developer machines) and is refused by SafeGitCmd under `go test`.

func CheckStagedChanges

func CheckStagedChanges(dir string) error

CheckStagedChanges verifies if there are staged changes in the given directory. If dir is empty, it runs in the process CWD.

func CleanCommitMessage

func CleanCommitMessage(message string) string

CleanCommitMessage cleans up LLM-generated commit messages

func CommittedFilePaths added in v0.16.18

func CommittedFilePaths(workDir string) (map[string]bool, error)

CommittedFilePaths returns a set of absolute filesystem paths for files that are tracked by git AND whose working-tree content is identical to HEAD (committed-clean). This is the batch equivalent of IsFileContentCommitted: instead of two subprocess calls per file, it runs just two commands total (git ls-files + git diff --name-only HEAD) and builds the full set in one pass.

All git commands are run with cmd.Dir=workDir so the function does not depend on the process CWD — it resolves the repo containing workDir regardless of where the agent process is running.

Callers use this to identify working-tree deltas caused by git operations (merge, checkout, reset, pull) that should NOT be recorded as recoverable agent edits — a file whose post-operation content matches HEAD was aligned to a committed state by git, not edited by the agent, so there is nothing legitimate to "recover" back to.

Returns (nil, nil) when workDir is not inside a git repository — no git protection applies and callers should record all deltas.

func GetFileGitPath

func GetFileGitPath(filename string) (string, error)

GetFileGitPath returns the path of the given filename relative to the Git repository root.

func GetGitRemoteURL

func GetGitRemoteURL() (string, error)

GetGitRemoteURL returns the remote URL of the current Git repository.

func GetGitRootDir

func GetGitRootDir() (string, error)

GetGitRootDir returns the absolute path to the root directory of the current Git repository.

func GetGitStatus

func GetGitStatus() (currentBranch string, uncommittedChanges int, stagedChanges int, err error)

GetGitStatus returns the current branch, number of uncommitted changes, and number of staged changes.

func GetRecentFileLog

func GetRecentFileLog(filePath string, limit int) (string, error)

GetRecentFileLog returns a short summary of recent commits for a file

func GetRecentTouchedFiles

func GetRecentTouchedFiles(numCommits int) ([]string, error)

GetRecentTouchedFiles returns a de-duplicated list of files touched in the last N commits

func GetStagedChanges

func GetStagedChanges() (string, error)

GetStagedChanges returns detailed information about staged changes in the repository.

func GetStagedDiff

func GetStagedDiff(dir string) (string, error)

GetStagedDiff returns the diff of staged changes in the given directory. If dir is empty, it runs in the process CWD.

func GetUncommittedChanges

func GetUncommittedChanges() (string, error)

GetUncommittedChanges returns detailed information about uncommitted changes in the repository.

func IsFileContentCommitted added in v0.16.18

func IsFileContentCommitted(filePath string) (bool, error)

IsFileContentCommitted reports whether the working-tree version of filePath matches what is recorded at git HEAD — i.e. the file is tracked by git AND has no uncommitted modifications. This is the git-awareness primitive used by the revert/recover staleness guards to refuse rolling back work that the user has intentionally committed to version control.

Semantics:

  • Not a git repo (GetGitRootDir fails) → (false, nil): no git protection applies; callers fall back to the content-only check.
  • File not tracked by git (untracked, or HEAD:<path> unknown) → (false, nil): no git protection; content check applies.
  • File tracked and working tree matches HEAD → (true, nil): PROTECTED — the content is committed; reverting to an older snapshot would silently undo committed work.
  • File tracked but differs from HEAD (uncommitted modifications) → (false, nil): not protected; the content-only staleness check still decides.

The check is performed in two steps:

  1. `git ls-files --error-unmatch <relpath>` verifies the file is tracked by git. Untracked files exit non-zero.
  2. `git diff --quiet HEAD -- <relpath>` confirms the working-tree copy is identical to HEAD. Both are read-only commands, so SafeGitCmd is invoked with dir="" (matching the existing GetGitStatus / GetUncommittedChanges pattern), which is not blocked by the test-mode mutating-command guard.

Step 1 is critical: `git diff --quiet HEAD -- <path>` alone returns exit 0 for UNTRACKED files because `git diff` does not include untracked files in its comparison. Without the tracked-file gate, a freshly-created (but never `git add`ed) file would be incorrectly reported as committed-clean, breaking the staleness guard.

Any unexpected git error is returned as (false, err) so callers can fall back to the conservative content-only behavior rather than blocking legitimate reverts.

func NormalizeShortTitle

func NormalizeShortTitle(raw string) string

func ParseCommitMessage

func ParseCommitMessage(commitMessage string) (string, string, error)

ParseCommitMessage parses a commit message into note and description

func ParseGitHubRemoteURL added in v0.16.12

func ParseGitHubRemoteURL(remoteURL string) (owner, repo string, err error)

ParseGitHubRemoteURL extracts the owner and repository name from a GitHub remote URL. It supports both HTTPS and SSH formats:

https://github.com/owner/repo.git     -> owner, repo
git@github.com:owner/repo.git         -> owner, repo

Returns an error for non-GitHub remotes or unrecognised formats.

func PerformGitCommit

func PerformGitCommit(dir, message string) error

PerformGitCommit executes the git commit command safely using stdin inside dir. dir MUST be non-empty — see SafeGitCmd for why an empty dir is refused under `go test`.

func SafeGitCmd added in v0.16.4

func SafeGitCmd(dir string, args ...string) *exec.Cmd

SafeGitCmd constructs an *exec.Cmd for a git invocation with built-in test-mode safety:

  • Production: behaves like exec.Command("git", args...) with cmd.Dir set to dir when dir != "".
  • Test mode (`go test`): when dir is empty AND the subcommand is mutating, returns a Cmd that points at an unrunnable sentinel path so the test fails loudly instead of mutating the host repo.

Pass dir="" only for read-only commands (status, diff, log, …) when you intentionally want the process CWD. Mutating commands MUST supply a working directory.

func TruncateRunes

func TruncateRunes(s string, max int) string

func WrapText

func WrapText(text string, lineLength int) string

Types

type CommitExecutor

type CommitExecutor struct {
	Client           api.ClientInterface
	UserMessage      string
	UserInstructions string
	// Dir is the working directory for git commands. If empty, the current directory is used.
	Dir string
	// contains filtered or unexported fields
}

CommitExecutor provides methods for executing git commits with message generation.

func NewCommitExecutor

func NewCommitExecutor(client api.ClientInterface, userMessage, userInstructions string) *CommitExecutor

NewCommitExecutor creates a new commit executor with the given configuration.

func NewCommitExecutorInDir

func NewCommitExecutorInDir(client api.ClientInterface, userMessage, userInstructions, dir string) *CommitExecutor

NewCommitExecutorInDir creates a new commit executor that runs git commands in the specified directory.

func NewCommitExecutorWithSecurityCheck

func NewCommitExecutorWithSecurityCheck(client api.ClientInterface, userMessage, userInstructions string, secretCheck SecretCheckHandler) *CommitExecutor

NewCommitExecutorWithSecurityCheck creates a CommitExecutor with a security check callback.

func (*CommitExecutor) ExecuteCommit

func (e *CommitExecutor) ExecuteCommit() (string, error)

ExecuteCommit performs the complete commit operation: 1. Gets staged files and validates there are changes 2. Gets the current branch name 3. Parses file changes into structured format 4. Gets the staged diff 5. Generates commit message (using provided message, LLM, or fallback) 6. Creates commit using a secure temp file 7. Returns the commit hash

This function is designed to be reusable by both the commit tool and commit flow.

type CommitFileChange

type CommitFileChange struct {
	Status string
	Path   string
}

CommitFileChange describes a staged file with git status code.

type CommitMessageOptions

type CommitMessageOptions struct {
	Diff             string
	Branch           string
	FileChanges      []CommitFileChange
	UserInstructions string
}

CommitMessageOptions configures commit message generation behavior.

type CommitMessageResult

type CommitMessageResult struct {
	Message      string
	ApproxTokens int
	Warnings     []string
}

CommitMessageResult contains generated message and diagnostics.

func GenerateCommitMessageFromStagedDiff

func GenerateCommitMessageFromStagedDiff(client api.ClientInterface, opts CommitMessageOptions) (*CommitMessageResult, error)

GenerateCommitMessageFromStagedDiff generates commit text using the same two-pass title+description algorithm used by /commit.

type CommitOptions

type CommitOptions struct {
	SkipPrompt   bool
	AllowSecrets bool
	Model        string
}

CommitOptions contains options for commit operations

type CommitSecurityResult

type CommitSecurityResult struct {
	HasConcerns bool
	Concerns    []security.DetectedSecret
}

CommitSecurityResult holds the result of security checking staged files.

func CheckStagedFilesForSecurityCredentials

func CheckStagedFilesForSecurityCredentials(logger *utils.Logger, dir string) CommitSecurityResult

CheckStagedFilesForSecurityCredentials checks staged files for security credentials and returns a detailed result with the specific concerns found.

type PullRequestRequest added in v0.16.12

type PullRequestRequest struct {
	Title     string // PR title (required)
	Body      string // PR body; synthesised from commits when empty
	Base      string // target branch; default = repo default branch
	Head      string // source branch; default = current HEAD branch
	Draft     bool
	Reviewers []string // usernames (API-only; ignored by gh CLI fallback)
}

PullRequestRequest describes a pull request to create.

type PullRequestResult added in v0.16.12

type PullRequestResult struct {
	URL    string `json:"html_url"`
	Number int    `json:"number"`
	State  string `json:"state"` // "open" or "closed"
}

PullRequestResult holds the outcome of a successful PR creation.

func CreatePullRequest added in v0.16.12

func CreatePullRequest(ctx context.Context, repoDir string, req PullRequestRequest) (*PullRequestResult, error)

CreatePullRequest creates a pull request on GitHub for the given repoDir.

Resolution order:

  1. GitHub REST API (credential store → GH_TOKEN env var)
  2. gh pr create shell-out (fallback when no token available)
  3. Structured error with the exact gh command the user can run manually

If req.Head is empty, the current branch name is used. If req.Base is empty, the repository's default branch is inferred. If req.Body is empty, a body is synthesised from commit messages between base and head.

type SecretCheckHandler

type SecretCheckHandler func(securityResult CommitSecurityResult) bool

SecretCheckHandler is a callback for handling detected secrets in commit flow. It receives the security result and returns whether to proceed with the commit. Return true to proceed, false to abort.

Jump to

Keyboard shortcuts

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