`jj` is convinced that files in nested repositories are deleted
Description
Steps to Reproduce the Problem
I have a pre-existing jj repo (colocated). When I updated to jj 0.36.0, it became convinced that certain files are deleted. I haven't touched those files in a long time, and certainly wasn't deleting them when things became confused. Attempts to unconvince it don't seem to do anything.
Expected Behavior
jj status shows a empty changeset.
Actual Behavior
jj status believes that files are deleted in the working copy:
$ jj status
Working copy changes:
D 2016/01/.gitignore
D 2016/01/Cargo.toml
D 2016/01/data
D 2016/01/input
D 2016/01/src/main.rs
D 2016/02/.gitignore
D 2016/02/Cargo.toml
D 2016/02/data
D 2016/02/src/main.rs
Working copy (@) : tptnwvmm d6c99976 (no description set)
Parent commit (@-): vltytlls d0cb0bc2 main* | 2025, day 10
Those files are not deleted; for example:
$ ls -lh 2016/02/Cargo.toml
-rw-r--r-- 1 mkeeter staff 111B Jan 18 2020 2016/02/Cargo.toml
I can't abandon the commit:
$ jj abandon
Abandoned 1 commits:
tptnwvmm d6c99976 (no description set)
Working copy (@) now at: vrnwwkwx ada9391f (empty) (no description set)
Parent commit (@-) : vltytlls d0cb0bc2 main* | 2025, day 10
Added 9 files, modified 0 files, removed 0 files
Warning: 9 of those updates were skipped because there were conflicting changes in the working copy.
Hint: Inspect the changes compared to the intended target with `jj diff --from ada9391fc0d3`.
Discard the conflicting changes with `jj restore --from ada9391fc0d3`.
Following the instructions to discard the conflicting change also don't help:
$ jj restore --from ada9391fc0d3 .
Working copy (@) now at: vrnwwkwx 4b8a1481 (empty) (no description set)
Parent commit (@-) : vltytlls d0cb0bc2 main* | 2025, day 10
Added 9 files, modified 0 files, removed 0 files
Warning: 9 of those updates were skipped because there were conflicting changes in the working copy.
Hint: Inspect the changes compared to the intended target with `jj diff --from 4b8a14812dbb`.
Discard the conflicting changes with `jj restore --from 4b8a14812dbb`.
Specifications
- Platform: 0.36.0
- Version: macOS
I have attached a snapshot of the confused repo, including the .git and .jj folders!
Even weirder: if I delete the .jj folder then run jj git init again, it comes back with these files marked as deleted:
$ rm -rf .jj
$ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
$ jj
Error: There is no jj repo in "."
Hint: It looks like this is a git repo. You can create a jj repo backed by it by running this:
jj git init
$ jj git init
Done importing changes from the underlying Git repo.
Hint: The following remote bookmarks aren't associated with the existing local bookmarks:
main@origin
Hint: Run the following command to keep local bookmarks updated on future pulls:
jj bookmark track main@origin
Initialized repo in "."
Hint: Running `git clean -xdf` will remove `.jj/`!
$ jj st
Working copy changes:
D 2016/01/.gitignore
D 2016/01/Cargo.toml
D 2016/01/data
D 2016/01/input
D 2016/01/src/main.rs
D 2016/02/.gitignore
D 2016/02/Cargo.toml
D 2016/02/data
D 2016/02/src/main.rs
Working copy (@) : otrmvwzs c8e61b31 (no description set)
Parent commit (@-): vltytlls d0cb0bc2 main main@origin | 2025, day 10
Doing a fresh clone of the repo fixes it, so the haunting must be in the .git state
Version 0.36.0 had the change about subrepos. Perhaps the /.gitignore is matching /.git?
Sub-repos are no longer tracked. Any directory containing .jj or .git is ignored. Note that Git submodules are unaffected by this.
At the same time (I guess not merged yet though), is something about submodules being listed as deleted.
aha, there are spurious .git directories in those two folders:
$ find . -name ".git"
./2016/02/.git
./2016/01/.git
./.git
This is a weird failure mode, but jj seems to be working as intended.
I'm fine with either closing this issue or leaving it open to track better error reporting of this case.
There's a discussion about this behavior change.
https://github.com/jj-vcs/jj/pull/8157#discussion_r2571482171
We can add config knob or jj file track flag to track files in nested repository, but I'm not sure if this is a common request.
@mkeeter I also encountered this after updating 0.36.0, thanks for making a thread about this! Saved me lots of time figuring out what went wrong.
I've hit this is issue too. In my case, its in fixture files for a CLI that interacts with git. I've had to add code to make sure the .git folder does not stick around...
I'm pretty sure I ran into this issue as well on the rust-lang/rust repo. Only solution I could find to recover from this issue was downgrading back to 0.35.0
❯ jj st
Working copy changes:
D library/stdarch/.git-blame-ignore-revs
D library/stdarch/.github/workflows/main.yml
D library/stdarch/.github/workflows/rustc-pull.yml
...skipping...
D library/stdarch/rustfmt.toml
D library/stdarch/triagebot.toml
D library/stdarch/vendor.yml
Working copy (@) : wwsrstmv cdd640d2 staging
Parent commit (@-): soqpoquu b9863538 (empty) megamerge
I don't usually mess with our git subtrees but this seems to document how we use them: https://rustc-dev-guide.rust-lang.org/external-repos.html#external-dependencies-subtrees. Not really sure how to make these play nice with the updated jj default.
❯ cat ./library/stdarch/.git
───────┬───────────────────────────────────────────
│ File: ./library/stdarch/.git
───────┼───────────────────────────────────────────
1 │ gitdir: ../../.git/modules/library/stdarch
───────┴───────────────────────────────────────────
The thing I really don't understand is why this only seems to impact the stdarch subtree and why none of the other subtrees are showing up as deleted despite clearly having .git files
❯ find . -name ".git"
./src/doc/book/.git
./src/doc/edition-guide/.git
./src/doc/nomicon/.git
./src/doc/embedded-book/.git
./src/doc/reference/.git
./src/doc/rust-by-example/.git
./src/llvm-project/.git
./src/gcc/.git
./src/tools/rustc-perf/.git
./src/tools/cargo/.git
./src/tools/enzyme/.git
./.git
./library/stdarch/.git
./library/backtrace/.git