Recovering a Single File from Jujutsu's Operation Log

Today I learned how to recover a single file from jj’s operation log without rewinding the whole repo. I thought I’d lost a 76-line markdown file of review notes: it wasn’t in my working copy, and no commit in jj log had it. A jj op restore of the operation before the loss would have brought it back, but it would also have rolled the entire repo to that point, unwinding everything I’d done since.

There’s a better lever:

jj --at-op=<op-id> file show <path>

This reads a file as it existed at a specific operation and prints it to stdout, without changing anything in the current state. Pipe it to disk and you have the file back, everything else intact:

jj op log                                                    # find the op before the loss
jj --at-op=e4d291fce44a file show feature-x-review.md > feature-x-review.md

The mechanism is unsurprising once you see it: jj snapshots your working copy on every command, so file contents live in many prior operations even when no current commit references them. jj op log is the index; --at-op is the read primitive that doesn’t move anything.

Two levers, different blast radius

WantUse
Rewind the whole repo to a pointjj op restore <op-id>
Read a single file as it was thenjj --at-op=<op-id> file show <path>

jj op restore is right when everything you want is at that point. --at-op file show is right when you only want one piece of it.

Gotchas / Notes

  • The operation log is a queryable archive of every snapshot, which is what makes targeted reads like this possible.
  • Worth knowing about before you need it. It’s far harder to think of when you’re already panicking about a lost file.