Summary
Snapshot.revert() does not reliably restore modified files when the filename contains Unicode characters.
Current behavior
- Creating a new Unicode-named file and reverting works
- Modifying an existing Unicode-named file and reverting does not restore the original content
There is already a skipped regression test for this case in:
packages/opencode/test/snapshot/snapshot.test.ts
test.skip("unicode filenames modification and restore", async () => {
Suspected cause
My current suspicion is that Snapshot.revert() falls back incorrectly after git checkout fails for the target path.
In packages/opencode/src/snapshot/index.ts, patch.files are stored as absolute paths, and revert() tries to run:
git checkout <hash> -- <file>
If that checkout fails, the fallback checks whether the file existed in the snapshot with a relative path via git ls-tree. When the file did exist, the code keeps the current file instead of restoring its original contents.
That would explain why:
- new Unicode files get deleted correctly on revert
- but existing Unicode files stay modified
Repro
A minimal repro seems to already exist in the skipped test above:
- Create a tracked file with a Unicode filename
- Take a snapshot
- Modify the file contents
- Call
Snapshot.revert([patch])
- Expected: original contents restored
- Actual: modified contents remain
If this sounds like a valid bug, I can send a PR with a regression test and a fix.
Summary
Snapshot.revert()does not reliably restore modified files when the filename contains Unicode characters.Current behavior
There is already a skipped regression test for this case in:
packages/opencode/test/snapshot/snapshot.test.tsSuspected cause
My current suspicion is that
Snapshot.revert()falls back incorrectly aftergit checkoutfails for the target path.In
packages/opencode/src/snapshot/index.ts,patch.filesare stored as absolute paths, andrevert()tries to run:If that checkout fails, the fallback checks whether the file existed in the snapshot with a relative path via
git ls-tree. When the file did exist, the code keeps the current file instead of restoring its original contents.That would explain why:
Repro
A minimal repro seems to already exist in the skipped test above:
Snapshot.revert([patch])If this sounds like a valid bug, I can send a PR with a regression test and a fix.