Skip to content

Git Integration

Eshan Roy edited this page Jun 16, 2026 · 2 revisions

Git Integration

M31A wraps git operations in a dedicated package that provides a safe, structured interface for all git interactions: commits, diffs, branches, stashing, remotes, and bisecting.

Source: internal/git/git.go

Git Wrapper

type Git struct {
    workDir string
}

All git commands are executed via exec.Command("git", args...) with the working directory set to the project root.

Operations

Repository Management

Method Description
Init() Initialize a new git repository
IsRepo() Check if working directory is a git repository
WorkDir() Return the working directory path
AbsPath(rel) Resolve a relative path within the working directory

Staging and Committing

Method Description
Add(paths...) Stage specific paths
AddAll() Stage all changes (git add -A)
Commit(message) Stage all + commit (full worktree)
CommitStaged(message) Commit only already-staged changes, returns hash
CommitWithFiles(message, paths...) Stage specific files + commit, returns hash

Commit messages are sanitized:

  • Newlines replaced with spaces (prevents fake trailers)
  • Carriage returns removed
  • Capped at 200 characters

Diff Operations

Method Description
Diff(target...) Flexible diff (0 args = working tree, 1 = ref vs HEAD, 2 = ref vs ref)
DiffRefs(ref1, ref2) Diff between two refs with validation
DiffStat(target...) Summary statistics of changes
DiffStaged() Diff of staged but uncommitted changes
DiffFile(path, status) Per-file diff (handles untracked files via --no-index)

Git refs are validated to prevent injection:

  • Rejects refs starting with --
  • Rejects refs containing ..
  • Rejects refs containing null bytes or newlines

Status

Method Description
Status() Raw git status output
StatusPorcelain() Structured file statuses with diff stats
HasUncommittedChanges() Check for any uncommitted changes
IsDirty() Alias for HasUncommittedChanges()

StatusPorcelain() runs git status --porcelain and git diff --numstat HEAD concurrently for better performance. Returns structured FileStatus entries:

type FileStatus struct {
    Status    string // "M", "A", "D", "R", "C", "U", "?"
    Path      string
    OldPath   string // for renames
    Additions int
    Deletions int
}

Branching

Method Description
CurrentBranch() Current branch name
CreateBranch(name) Create a new branch
CheckoutBranch(name, create) Checkout (optionally create) a branch
BranchList() List all local branches

History

Method Description
HeadHash() Current HEAD commit SHA
Log(lastN) Last N commits (newest first)
LogAll() Full commit history
LogSince(time) Commits since a timestamp
CountCommits(start, end) Count commits between two hashes
RevParse(ref) Resolve a ref to its full SHA

Log output uses a custom format (%H§%h§%an§%s§%aI) with § as delimiter for reliable parsing.

Reset Operations

Method Description Safety
ResetSoft(commit) git reset --soft Creates m31a-backup-pre-reset branch
ResetHard(commit) git reset --hard Creates m31a-backup-pre-reset branch

Both reset operations create a backup branch before executing, providing rollback safety.

Stashing

Method Description
StashPush(message) Save changes to stash
StashPop() Apply most recent stash
StashList() List stash entries
StashApply(index) Apply a specific stash entry

Remote Operations

Method Description
Fetch(remote) Fetch from remote (default: origin)
Pull(remote, branch, rebase) Pull with optional rebase
Push(remote, branch) Push to remote
RemoteTracking() Get upstream tracking branch

Tags and Merges

Method Description
Tag(name, msg) Create lightweight or annotated tag
Merge(branch) Merge a branch into current

User Configuration

Method Description
ConfigUser(name, email) Set repository-local git user

Usage in Workflow

The git wrapper is used across multiple workflow phases:

Phase Git Operations
Initialize HeadHash() for rollback baseline
Execute CommitWithFiles() per completed task
Verify DiffStat() for change statistics
Ship CommitStaged() for final commit, DiffStat() for summary
Rollback ResetSoft(), ResetHard(), StashPush(), StashPop()
Bisect Run() for bisect loop, DiffRefs() for result

Clone this wiki locally