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

> Discover which version control systems Tuicr supports including Jujutsu Git and Mercurial Learn how Tuicr manages different VCS with its unified backend

- Repository: [Almog Gavra/tuicr](https://github.com/agavra/tuicr)
- Tags: deep-dive
- Published: 2026-08-01

---

**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`](https://github.com/agavra/tuicr/blob/main/src/vcs/traits.rs):

```rust
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`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/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

```rust
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`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/src/vcs/jj/mod.rs), [`src/vcs/git/mod.rs`](https://github.com/agavra/tuicr/blob/main/src/vcs/git/mod.rs), and [`src/vcs/hg/mod.rs`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/src/vcs/mod.rs).

### Detecting the VCS for the Current Working Directory

```rust
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

```rust
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

```rust
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`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/src/vcs/git/mod.rs) based on repository features
- The **`detect_vcs()`** function in [`src/vcs/mod.rs`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/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`](https://github.com/agavra/tuicr/blob/main/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.