safegit

module
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: MIT

README

safegit

Go CLI wrapper around git for safe concurrent multi-agent use.

The problem

When multiple AI agent sessions share a single git repository, they race on .git/index. Two agents staging files at the same time produce mixed commits -- files from one agent leak into another's commit, or writes are silently lost. Standard git has no built-in isolation for this scenario.

The solution

safegit wraps git plumbing commands behind a two-phase commit pipeline that keeps every invocation isolated. Per-invocation temporary index files prevent staging races. Ref updates use per-ref locks with compare-and-swap (CAS) retry, so concurrent commits to the same branch serialize correctly. An append-only operation log records every mutation. The output is standard git commits -- teammates, CI, and code review tools see nothing unusual.

Install

From source (requires Go 1.24+):

go install github.com/smm-h/safegit/cmd/safegit@latest

Pre-built binaries are available on GitHub Releases via goreleaser.

Quick start

cd your-repo
safegit commit -m "add feature X" -- src/foo.go src/bar.go
safegit push

safegit auto-initializes on first use (creates .git/safegit/). Use safegit doctor --uninstall to remove safegit from a repo.

Key commands

Command Description
commit Stage files and commit atomically (--amend to amend/reword)
undo Reverse the last commit/amend/reword via oplog
push Push with pre-pre-push hooks and retry logic
hook Manage pre-pre-push hooks (list, run, install)
doctor Health checks and repair (--fix to garbage-collect)
config Show or set configuration values
unlock Release a stale ref lock

Tree-mutating commands (checkout, pull, merge, rebase, reset, bisect, cherry-pick, revert) are passed through with coordination guards.

How it works

The commit pipeline has two phases. Phase A (parallel-safe) creates a temporary index, stages the requested files into it, and builds the tree object -- all without touching the shared .git/index. Phase B acquires a per-ref lock, reads the current tip, creates the commit with that parent, and updates the ref using CAS. If the ref moved between read and write, Phase B retries from the new tip (re-parenting the commit) with random jitter to avoid thundering-herd stampedes under heavy concurrency.

See design.md for the full architecture specification.

Configuration

Run safegit config to view all settings, or safegit config <key> <value> to change one.

Key Default Description
commit.casMaxAttempts 5 Max CAS retry attempts for ref updates
lock.acquireTimeoutSeconds 30 Timeout waiting for a per-ref lock
hooks.preprepush.timeoutSeconds 1800 Timeout for pre-pre-push hook execution
push.retryAttempts 3 Number of push retry attempts
log.maxSizeMB 100 Max operation log size before rotation

Configuration is stored in .git/safegit/config.json. Remove the entire .git/safegit/ directory to return to vanilla git.

Known limitations

  • Same-machine concurrency only. Lock staleness detection uses PID liveness checks and hostname comparison. On network filesystems (NFS, CIFS), safegit doctor warns about reduced lock atomicity guarantees. Cross-machine lock reclaim is refused when the hostname doesn't match.
  • PID reuse. On Linux, safegit compares process start time against lock creation time via /proc to detect PID reuse. On other platforms, a reused PID could keep an orphan lock alive until the lock timeout expires. Use safegit unlock --force to clear a stuck lock.
  • Linux and macOS only. Windows is not supported (Unix-only syscalls for locking, signals, process management). WSL (Windows Subsystem for Linux) works since it runs the Linux binary natively.

License

MIT

Directories

Path Synopsis
cmd
safegit command
internal
commit
Amend and Reword implement tip-commit rewriting with CAS safety.
Amend and Reword implement tip-commit rewriting with CAS safety.
coord
Package coord implements the coordination layer for concurrent agents.
Package coord implements the coordination layer for concurrent agents.
git
Package git wraps os/exec calls to the git binary.
Package git wraps os/exec calls to the git binary.
hooks
Package hooks discovers and executes pre-pre-push hooks.
Package hooks discovers and executes pre-pre-push hooks.
index
Package index manages per-invocation temporary git indexes.
Package index manages per-invocation temporary git indexes.
lock
Package lock provides ref-lock primitives for concurrent ref updates.
Package lock provides ref-lock primitives for concurrent ref updates.
oplog
Package oplog implements the JSONL operation log.
Package oplog implements the JSONL operation log.
repo
Package repo manages the .git/safegit/ data directory.
Package repo manages the .git/safegit/ data directory.
stage
Package stage implements hunk-level staging against temporary indexes.
Package stage implements hunk-level staging against temporary indexes.
testutil
Package testutil provides shared test helpers for creating temporary git repos.
Package testutil provides shared test helpers for creating temporary git repos.

Jump to

Keyboard shortcuts

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