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.
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/, andGitRepo::getWorkdirInfo()relies onlibgit2'sgit_status_foreach_ext()to enumerate tracked files. Non-colocated JJ repos have no git index to query.Proposed solution
Add a
JjInputSchemethat detects.jj/directories, similar to howMercurialInputSchemedetects.hg/and shells out to hg. It would use the jj CLI for all operations:jj file list— tracked files (replacesgit_status_foreach_ext)jj diff— summary — dirty/modified file statusjj log— rev info, commit metadatajj cat/jj file show— reading file contentsThis 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 vialibgit2and inherit all the existing tree hashing, NAR conversion, and object access code — only overridinggetWorkdirInfo()andgetWorkdirRef()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 --colocatemaintains 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.