gitr 0.2.0

Async typed git CLI wrapper for agents and automation.
Documentation

gitr

CI crates.io docs.rs Coverage MSRV License

Async typed git CLI wrapper for agents and automation.

Why gitr?

Approach Async Zero C deps Worktrees Rebase Merge-tree
git2 (libgit2) ❌ needs spawn_blocking
gix (gitoxide) ⚠️ partial
gitr ✅ native

gitr shells out to the git binary and provides structured types, typed errors, and porcelain parsing. It is the only pure-Rust approach with full feature coverage for AI agent workflows.

Quick start

Add to your Cargo.toml:

[dependencies]
gitr = "0.2"

Open a repository

use gitr::Repository;

#[tokio::main]
async fn main() -> Result<(), gitr::Error> {
    let repo = Repository::open(".").await?;
    let branch = repo.current_branch().await?;
    println!("On branch: {branch}");
    Ok(())
}

Check status and commit

use gitr::Repository;

#[tokio::main]
async fn main() -> Result<(), gitr::Error> {
    let repo = Repository::open(".").await?;

    // Ensure clean working tree
    repo.ensure_clean().await?;

    // Stage, commit, push
    repo.add_all().await?;
    let sha = repo.commit("feat: agent work", &[]).await?;
    repo.push("origin", "main", false).await?;

    println!("Committed {sha}");
    Ok(())
}

Worktree workflow

use gitr::Repository;

#[tokio::main]
async fn main() -> Result<(), gitr::Error> {
    let repo = Repository::open(".").await?;

    repo.worktree_add("/tmp/wt-1", "feature-x").await?;
    let wt = repo.open_worktree("/tmp/wt-1").await?;

    wt.add_all().await?;
    wt.commit("feat: agent work in worktree", &[]).await?;

    repo.worktree_remove("/tmp/wt-1", false).await?;
    Ok(())
}

Read-only merge conflict detection

use gitr::Repository;

#[tokio::main]
async fn main() -> Result<(), gitr::Error> {
    let repo = Repository::open(".").await?;

    let result = repo.merge_tree("main", "feature-x").await?;
    if result.has_conflicts {
        println!("Conflicts: {:?}", result.conflict_files);
    } else {
        println!("Clean merge");
    }
    Ok(())
}

API overview

Repository

  • Status: ensure_clean, status, changed_files, conflicted_files, untracked_files
  • Branch: current_branch, branch_create, branch_delete, branch_exists, checkout, default_branch
  • Commit & Push: commit, push, push_force, fetch, remote_url
  • Worktree: worktree_add, worktree_remove, worktree_list, open_worktree
  • Merge & Rebase: merge, merge_tree, rebase, rebase_continue, rebase_abort
  • Stash: stash, stash_pop
  • Diff: diff, diff_files
  • Stage: add, add_all

Errors

gitr::Error (GitError) provides typed variants for every failure mode:

  • NotARepo — path lacks .git
  • GitNotFoundgit binary not in PATH
  • CommandFailed — non-zero exit with stdout/stderr captured
  • Timeout — command exceeded time budget (default 60s)
  • Dirty — working tree has changes
  • BranchExists / BranchNotFound
  • WorktreeExists
  • MergeConflicts

Feature flags

Feature Default Description
tracing Emit tracing spans for command execution.

Testing

# All tests (unit + integration + doc-tests)
cargo test --all-features

# With coverage
cargo tarpaulin --all-features --fail-under 85

# Feature powerset
cargo hack check --feature-powerset --all-targets

MSRV

Rust 1.80.

Contributing

See CONTRIBUTING.md.

Security

See SECURITY.md.

License

MIT