Skip to content

Support Jujutsu (jj) repositories in flake evaluation #15651

@BohdanTkachenko

Description

@BohdanTkachenko

Is your feature request related to a problem?

Nix flakes don't work correctly with Jujutsu repositories that aren't using colocated git mode (jj git init --colocate). Without a .git/ directory, Nix falls back to the path fetcher, which copies the entire working directory — including build artifacts and untracked files — into the store, with no filtering.

This also affects JJ workspaces (jj workspace add). Even in a colocated git repo, new workspaces only get a .jj/ directory — no .git/ — so flake evaluation breaks in workspaces even when the main working copy works fine.

The root cause is that GitInputScheme detects repos by the presence of .git/, and GitRepo::getWorkdirInfo() relies on libgit2's git_status_foreach_ext() to enumerate tracked files. Non-colocated JJ repos have no git index to query.

Proposed solution

Add a JjInputScheme that detects .jj/ directories, similar to how MercurialInputScheme detects .hg/ and shells out to hg. It would use the jj CLI for all operations:

  • jj file list — tracked files (replaces git_status_foreach_ext)
  • jj diff — summary — dirty/modified file status
  • jj log — rev info, commit metadata
  • jj cat / jj file show — reading file contents

This approach is backend-agnostic. JJ currently supports both a Git backend and a Google's internal Piper backend, and a native backend may be added in the future. Shelling out to the CLI avoids coupling to any particular storage implementation.

The mercurial fetcher (mercurial.cc) provides direct precedent for this pattern.

Alternative solutions

Hybrid: extend the existing git fetcher with JJ-aware overrides. When JJ uses a git backend, the git object store lives at .jj/repo/store/git/. A JjRepo subclass of GitRepo could open that store via libgit2 and inherit all the existing tree hashing, NAR conversion, and object access code — only overriding getWorkdirInfo() and getWorkdirRef() to shell out to jj instead of querying the git index. This avoids duplicating any git logic, but couples to JJ's git backend and would break for non-git backends.

Recommend colocated mode (do nothing). JJ's jj git init --colocate maintains a real .git/ alongside .jj/, so the existing git fetcher works unchanged. This is what most JJ+Nix users do today. Zero maintenance burden, but doesn't help users who prefer or need non-colocated mode, and doesn't solve the workspace problem.

Additional context

Checklist


Add 👍 to issues you find important.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureFeature request or proposal
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions