(Human intro)
I have some custom instructions for Claude to work around some jj "gotchas". I asked Opus to draft issues for any genuine ones that seemed like they might be unintended.
(Opus 5.5 High)
Description
A snapshot misses an edit that leaves a file's size and mtime unchanged, so the working-copy commit no longer matches the file on disk. The next checkout then treats the file as unmodified and replaces or deletes it, and the edit is lost: it was never recorded in any commit, so the operation log can't restore it.
This comes up in practice whenever a tool restores modification times: extracting a tar or git archive output over the working copy, rsync -t, cp -p, or a script that builds a tree for jj to snapshot. Files whose content changed but whose size happens to match are silently left out of @.
Steps to Reproduce the Problem
jj git init repro && cd repro
echo aaaa > f && touch -d 2020-01-01 f && jj commit -m one
echo bbbb > f && touch -d 2020-01-01 f
jj st
jj new 'root()'
lsExpected Behavior
jj st lists f as modified, and jj new 'root()' leaves the bbbb content recorded in the abandoned working-copy commit (or refuses to discard it).
Actual Behavior
jj st prints The working copy has no changes., and jj new 'root()' deletes f:
Working copy (@) now at: wmwmvlus 2a16ee9a (empty) (no description set)
Parent commit (@-) : zzzzzzzz 00000000 (empty) (no description set)
Added 0 files, modified 0 files, removed 1 filesNo commit contains bbbb. Checking out any commit where f differs overwrites it the same way.
Suggested fix
Also compare the file's ctime (and perhaps inode) recorded at the last snapshot, as Git does: a program can set mtime freely, but any write or utimes call updates ctime, so a changed ctime marks the file for a content check. Git offers core.trustctime = false for filesystems or tools that change ctime spuriously; a similar setting could cover those cases.
Specifications
- Platform: Linux (Ubuntu on WSL2)
- Version: jj 0.46.0
Activity
0No activity yet.