What Version Control Systems Does Tuicr Support? A Complete Technical Guide

Tuicr supports four version control systems: Jujutsu (jj), Git, Mercurial (hg), and plain file directories (no VCS), detected in that specific order through a unified VcsBackend trait architecture.

Tuicr is a terminal-based code review tool that abstracts repository operations through a pluggable backend system. Understanding what version control systems Tuicr supports is essential for developers working across different VCS workflows, as the tool automatically detects and adapts to your repository type using a prioritized detection strategy implemented in Rust.

Supported Version Control Systems in Tuicr

Tuicr currently supports four distinct version control backends, explicitly enumerated in the VcsType enum defined in src/vcs/traits.rs:

pub enum VcsType {
    Git,
    Mercurial,
    Jujutsu,
    File,
}

Each variant corresponds to a concrete implementation of the VcsBackend trait. Jujutsu receives priority detection because it uses Git as its underlying storage while adding a .jj directory. Git serves as the primary VCS for most projects, with support for both libgit2 and CLI backends. Mercurial provides fallback support for hg repositories. Finally, File mode—implemented as PrNoopVcs in src/vcs/pr_noop.rs—allows Tuicr to operate on directories without version control.

How Tuicr Detects Your Version Control System

The detection logic resides in src/vcs/mod.rs within the detect_vcs() function. This function attempts to instantiate backends in a specific sequence, returning the first successful match:

  1. Jujutsu (JjBackend::discover) — Checked first because Jujutsu repositories contain .git directories
  2. Git (GitBackend::discover) — The standard detection for Git repositories
  3. Mercurial (HgBackend::discover) — Final VCS fallback
  4. Error — Returns TuicrError::NotARepository if none match
pub fn detect_vcs(
    git_backend_preference: GitBackendPreference,
    whitespace_mode: DiffWhitespaceMode,
) -> Result<Box<dyn VcsBackend>> {
    // 1️⃣ Jujutsu
    if let Ok(backend) = JjBackend::discover(whitespace_mode) {
        return Ok(Box::new(backend));
    }
    // 2️⃣ Git
    if let Ok(backend) = GitBackend::discover(git_backend_preference, whitespace_mode) {
        return Ok(Box::new(backend));
    }
    // 3️⃣ Mercurial
    if let Ok(backend) = HgBackend::discover(whitespace_mode) {
        return Ok(Box::new(backend));
    }
    Err(TuicrError::NotARepository)
}

This detection order is critical because Jujutsu repositories are technically valid Git repositories, so checking Jujutsu first prevents misidentification.

The VcsBackend Trait Architecture

All version control systems in Tuicr implement the VcsBackend trait defined in src/vcs/traits.rs. This abstraction provides a unified API for operations including diff retrieval, context line fetching, and commit metadata access regardless of the underlying VCS.

Each backend module—src/vcs/jj/mod.rs, src/vcs/git/mod.rs, and src/vcs/hg/mod.rs—provides a discover() method that attempts to initialize the backend for the current working directory. The trait ensures that Tuicr's UI components, review logic, and forge integration remain agnostic to whether you're using Git, Jujutsu, or Mercurial.

Git Backend Implementation Details

The Git support in src/vcs/git/mod.rs offers two concrete implementations: Libgit2Backend and GitCliBackend. Tuicr automatically selects the appropriate backend based on repository features such as sparse-checkout, reftable, or split-index configurations that may not be fully supported by libgit2.

The GitBackendPreference parameter in detect_vcs() allows users to force a specific backend, though the default behavior uses the from_config() method to determine the optimal choice based on repository characteristics.

Working with Tuicr's VCS API

You can programmatically interact with Tuicr's VCS abstraction using the public API exposed in src/vcs/mod.rs.

Detecting the VCS for the Current Working Directory

use tuicr::vcs::{detect_vcs, GitBackendPreference, DiffWhitespaceMode};

fn main() -> anyhow::Result<()> {
    // Choose the backend preference (default: libgit2)
    let pref = GitBackendPreference::from_config(None);
    // Use normal whitespace comparison
    let ws = DiffWhitespaceMode::Normal;

    // Detect and obtain a boxed VcsBackend trait object
    let backend = detect_vcs(pref, ws)?;

    println!("Detected VCS: {}", backend.info().vcs_type);
    // → prints "git", "jj", "hg", or "file"
    Ok(())
}

Listing Changed File Paths

use tuicr::vcs::{ChangeKind, VcsBackend};

fn list_changed_paths(backend: &dyn VcsBackend) -> anyhow::Result<()> {
    // Show staged files
    let staged = backend.list_changed_paths(ChangeKind::Staged)?;
    // Show unstaged (including untracked) files
    let unstaged = backend.list_changed_paths(ChangeKind::Unstaged)?;

    println!("Staged files:");
    for p in staged { println!("  {}", p.display()); }

    println!("Unstaged files:");
    for p in unstaged { println!("  {}", p.display()); }

    Ok(())
}

Fetching Context Lines for Diff Gaps

use tuicr::vcs::{VcsBackend, FileStatus};

fn fetch_gap(
    backend: &dyn VcsBackend,
    path: &std::path::Path,
    start: u32,
    end: u32,
) -> anyhow::Result<()> {
    let lines = backend.fetch_context_lines(
        path,
        FileStatus::Modified,
        None,          // read from working tree
        start,
        end,
    )?;
    for line in lines {
        println!("{}: {}", line.old_lineno.unwrap_or(0), line.content);
    }
    Ok(())
}

Summary

  • Tuicr supports four version control systems: Jujutsu, Git, Mercurial, and plain file directories
  • Detection occurs in strict priority order: Jujutsu first, then Git, then Mercurial, preventing misidentification of Jujutsu repos as Git
  • The VcsBackend trait in src/vcs/traits.rs provides a unified abstraction for all VCS operations
  • Git offers dual backends (libgit2 and CLI), automatically selected in src/vcs/git/mod.rs based on repository features
  • The detect_vcs() function in src/vcs/mod.rs serves as the entry point for automatic backend instantiation

Frequently Asked Questions

Does Tuicr support Jujutsu (jj) repositories?

Yes. Tuicr explicitly supports Jujutsu and checks for it before Git during detection because Jujutsu repositories contain .git directories that would otherwise trigger Git detection. The JjBackend in src/vcs/jj/mod.rs handles Jujutsu-specific operations while leveraging the underlying Git storage for file operations.

How does Tuicr choose between libgit2 and Git CLI?

Tuicr's GitBackend in src/vcs/git/mod.rs automatically selects between Libgit2Backend and GitCliBackend based on repository features. If your repository uses advanced features like sparse-checkout, reftable, or split-index, Tuicr falls back to the CLI backend for full compatibility with Git's extended capabilities.

Can Tuicr work without a version control system?

Yes. When no repository is detected, Tuicr uses the PrNoopVcs backend from src/vcs/pr_noop.rs, which implements the VcsBackend trait as a no-op placeholder. This allows the tool to operate on plain file directories, though with limited functionality compared to full VCS integration.

What happens if multiple VCS systems are present?

Tuicr uses a first-match wins strategy in detect_vcs(). Since Jujutsu repositories are also valid Git repositories, Jujutsu is checked first to ensure correct identification. If that fails, Git is checked, followed by Mercurial. This sequential approach prevents ambiguity and ensures consistent behavior across different repository types.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →