1 Home
Virgil edited this page 2026-03-11 12:08:19 +00:00

go-git

Module: forge.lthn.ai/core/go-git

Git operations helper for multi-repository workflows. Provides parallel status checking, push/pull operations with SSH passphrase support, and structured error types. Used by the core dev CLI commands.

Architecture

File Purpose
git.go Status(), Push(), Pull(), PushMultiple(), RepoStatus, GitError
service.go Core DI service integration

Key Types

RepoStatus

type RepoStatus struct {
    Name      string
    Path      string
    Modified  int    // Working tree modifications
    Untracked int    // Untracked files
    Staged    int    // Staged changes
    Ahead     int    // Commits ahead of upstream
    Behind    int    // Commits behind upstream
    Branch    string
    Error     error
}

Methods: IsDirty(), HasUnpushed(), HasUnpulled().

PushResult

type PushResult struct {
    Name    string
    Path    string
    Success bool
    Error   error
}

GitError

type GitError struct {
    Args   []string // Git command arguments
    Err    error    // Underlying error
    Stderr string   // Captured stderr output
}

Implements error and Unwrap().

Operations

Function Description
Status(ctx, opts) Parallel status check across multiple repos. Parses git status --porcelain and rev-list --count.
Push(ctx, path) Push single repo (interactive, supports SSH passphrase)
Pull(ctx, path) Pull with rebase (interactive)
PushMultiple(ctx, paths, names) Sequential push of multiple repos
IsNonFastForward(err) Check if error is a non-fast-forward rejection

Usage

import "forge.lthn.ai/core/go-git"

// Check status across repos
results := git.Status(ctx, git.StatusOptions{
    Paths: []string{"/code/repo1", "/code/repo2"},
    Names: map[string]string{"/code/repo1": "repo1"},
})

for _, r := range results {
    if r.IsDirty() {
        fmt.Printf("%s: %d modified, %d untracked\n", r.Name, r.Modified, r.Untracked)
    }
    if r.HasUnpushed() {
        fmt.Printf("%s: %d ahead\n", r.Name, r.Ahead)
    }
}

// Push
err := git.Push(ctx, "/code/repo1")
if git.IsNonFastForward(err) {
    // Need to pull first
}

Implementation Notes

  • Status checks run in parallel (goroutines per repo)
  • Push/pull are sequential and interactive (stdin/stdout attached for SSH passphrase prompts)
  • Paths must be absolute (validated)
  • Ahead/behind counts gracefully handle repos with no upstream
  • Uses git subprocess (not a Go git library)

Dependencies

  • github.com/stretchr/testify — Tests only
  • No core ecosystem dependencies