Conversation
The journal reverses a move through rename_path, whose copy fallback fired only for an rclone EINVAL or a WebDAV EIO, so undoing a move onto a USB stick, another partition or tmpfs answered "Invalid cross-device link" and, because the entry was already popped, the next undo reached an older operation. copyfile.rs's move_any copies and removes on EXDEV going out; rename_path now takes the same copy_then_remove arm on EXDEV coming back, which keeps the exclusive create, the partial cleanup and the rename-kept rule the two measured mounts already use. The errno is pinned in a unit test, and tests/ops.sh moves a file and a tree from the fixture root onto a /dev/shm tmpfs and undoes them, the pair drag.sh R7 already relies on; on the old code the undo answered a rename error and both sources stayed gone. LR-T: cargo test (442 passed); ./tests/ops.sh (all checks passed, and its new scenario fails on the unfixed binary) LR-D: a move to another filesystem could not be undone and the failed undo spent the journal entry LR-K: src/backend/renamecompat.rs; src/backend/undo.rs; tests/ops.sh; docs/protocol.md Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnB5YmkdfX8Yri7gSGuAWf
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 2 included reviews per hour; 1 remains after this review. 📝 WalkthroughWalkthroughThe rename compatibility logic now treats ChangesCross-filesystem move handling
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk: ⚪ Minimal · up to Cross-filesystem moves and their undo operations now use the established copy-and-remove behavior, restoring moved files and directories without leaving destination copies. The change is ready to merge. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 2 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Eleven fixes over 0.1.6, each on its own branch and open as a PR against upstream (thisisgm#86 to thisisgm#96), merged here so a build carries them together. Cargo.toml, Cargo.lock and the source PKGBUILD move together, as for 0.1.6. LR-T: cargo test (448 passed, 0 warnings debug and release); ./tests/run-all.sh (23 run, the 4 failures are this box's: expect not installed, media fixture not built); ./tools/flea-qmllint-gate; ./tools/flea-file-budget (0 over cap) LR-D: the 0.1.7 release of the fork with the eleven bug-hunt fixes LR-K: Cargo.toml; Cargo.lock; PKGBUILD Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnB5YmkdfX8Yri7gSGuAWf
Upstream moved 188 commits and two releases while these sat as open PRs (thisisgm#86 to thisisgm#96). Seven files conflicted and all seven are resolved toward upstream's newer shape: - Cargo.toml, Cargo.lock and PKGBUILD take 0.2.1, so the fork carries upstream's version and not the fork-local 0.1.7. - renamecompat.rs is taken wholesale: upstream fixed the cross-device undo itself (thisisgm#86), inline in rename_path rather than in the fallback predicate, so that fix is superseded and its duplicate const would no longer compile. The tests/ops.sh scenario stays, because it drives the real reversal across tmpfs and a disk rather than the predicate. - trash.rs folds the already-gone partition into upstream's new trash_checked, keeping its validate_sources calls (thisisgm#88). - Ops.js startRename takes upstream's every-view signature and guards the row it was actually asked for; Filter.cursorShown generalises to rowShown(pane, row) so an explicit menu row is checked too (thisisgm#92). - Tabs.js keeps the search re-list and the listRequests selection guard on top of upstream's Startup.newTabPath destination (thisisgm#91, thisisgm#93, thisisgm#94). LR-T: ./tests/js.sh (3,106 checks, 0 failed) LR-D: the fork was two releases behind while its ten fixes were still unmerged upstream LR-K: src/backend/trash.rs; ui/js/Tabs.js; ui/js/Ops.js; ui/js/Filter.js; src/backend/renamecompat.rs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AnB5YmkdfX8Yri7gSGuAWf
|
Superseded by |
The bug
Move a file from a real disk onto a USB stick, another partition or tmpfs, then press undo. The reversal answered
{"t":"error","where":"rename",...,"msg":"Invalid cross-device link (os error 18)"}and the file stayed where it was moved to. BecauseJournal::undopops the entry before reversing it, the entry was also spent: the next undo reached an older operation.The forward path already knows a cross-filesystem move is a copy and a remove (
copyfile.rs'smove_anyonEXDEV). The reverse path goes throughrenamecompat::rename_path, whose copy fallback only fired for an rcloneEINVALor a WebDAVEIO.The fix
needs_copy_fallbackanswers true forEXDEV, so the reversal takes the samecopy_then_removearm the two measured mounts use: exclusive create, partial cleanup on a failed copy, and therename-keptrule when the source will not go.docs/protocol.md'sundosection says a move that crossed filesystems copies back the way it went out.Tests
renamecompat.rs, alongside the existing WebDAV and rclone predicate tests.tests/ops.shgains a scenario that moves a file and a nested tree from the fixture root onto a/dev/shmtmpfs root and undoes them, using the same self-marked tmpfs root patterntests/drag.shR7 uses, with the device check that proves the two really are different filesystems. On the unfixed binary the scenario fails four checks: the undo answers a rename error and both sources stay gone.cargo test: 442 passed, zero warnings in debug and release.🤖 Generated with Claude Code
https://claude.ai/code/session_01AnB5YmkdfX8Yri7gSGuAWf
Summary by CodeRabbit
Bug Fixes
Tests