Fix rollback leaving directories apply created (#838) - #846
Merged
Mikola Lysenko (mikolalysenko) merged 3 commits intoOct 5, 2026
Merged
Conversation
Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
marked this pull request as ready for review
October 5, 2026 11:02
Collaborator
Author
|
BugBot review Generated by Claude Code |
Regression tests for #838: rolling back a patch that added files under new directories must remove those directories again, including a __pycache__ that only holds bytecode for the deleted module. Assisted-by: Claude Code:claude-opus-5-5
Rolling back or removing a patch that added files under new directories deleted the files but left the directories. In site-packages an empty leftover directory still imports as a namespace package, so code probing for the module saw it as present. Rollback now removes the deleted module's stale __pycache__ bytecode and then every parent that is left empty, deepest first, stopping at the package root. Symlinked directories are never removed or walked through, and read-only parents are relaxed just for the rmdir. Fixes #838 Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko)
force-pushed
the
agent/fix-rollback-prune-created-dirs
branch
from
October 5, 2026 11:06
9bb3d4c to
e08b11d
Compare
Collaborator
Author
|
BugBot review Generated by Claude Code |
Collaborator
Author
|
BugBot review Generated by Claude Code |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit e08b11d. Configure here.
Collaborator
Author
|
Ready for review.
Generated by Claude Code |
Tanmay Singla (Tanmay182003)
approved these changes
Oct 5, 2026
Mikola Lysenko (mikolalysenko)
deleted the
agent/fix-rollback-prune-created-dirs
branch
October 5, 2026 13:20
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
LLM Description written by Claude Code:claude-opus-5-5
Fixes #838
Root cause
Agent-mode
applycreates missing parent directories (create_dir_allinapply_file_patch_at) for files a patch adds. The agent-mode rollback engine (rollback_package_patch, used byrollbackandremove, and fanned out to pnpm/vlt store copies) deleted those files with a singleremove_fileand never pruned the directories. In site-packages, an empty leftover directory still imports as a PEP 420 namespace package, soimport six_safe/find_speckept succeeding after a "successful" rollback.Fix
crates/socket-patch-core/src/patch/rollback.rsis the only file changed. After deleting a patch-added file, a newprune_emptied_parentsstep:__pycache__/<stem>.*.pycbytecode for a deleted.pyfile, then the__pycache__directory if it is now empty;DirWriteGuardapply uses, then restores their mode;Apply doesn't record which directories it created. The test is "empty once the patch's files are gone": a package directory that holds only patch-added files cannot have existed with content before the patch.
Tests (red → green)
New unit tests in
rollback.rs, landed in a commit of their own (Test rollback prunes dirs apply created) before the fix. On that commit,cargo test -p socket-patch-core --lib rollback::tests::test_rollback_new_filefailed 5 tests and passed 1 (the symlink guard case, because nothing was pruned at all). With the fix, all 46rollback::testspass:test_rollback_new_file_prunes_created_top_level_dir: Agent-mode rollback / remove of a PyPI patch that added a file in a new directory leaves the empty directory in site-packages, so Python still imports it as a namespace package #838 top-levelsix_safe/__init__.pytest_rollback_new_file_prunes_nested_dirs_and_stale_pycache: Agent-mode rollback / remove of a PyPI patch that added a file in a new directory leaves the empty directory in site-packages, so Python still imports it as a namespace package #838 nestedsix_safe/sub/__init__.pyplus leftover__pycache__test_rollback_new_file_keeps_dirs_that_are_not_empty: unrelated files and other modules' bytecode survivetest_rollback_new_files_sharing_a_created_dir_prune_it: several added files in one new directorytest_rollback_new_file_prune_never_follows_a_symlinked_dirtest_rollback_new_file_prunes_created_dir_under_readonly_root: Go-cache 0o555 root, mode restoredLocal checks:
cargo clippy --workspace --all-features -D warningsis clean.rustfmt --checkonrollback.rsis clean.cargo test --workspace --all-features --no-fail-fast: every failure is environmental. The sandbox runs as root, so read-only-chmod tests can't fail their writes, and the self-update/notifier fixtures need exec, network or a tty. None of those tests touch rollback.CI on e08b11d is green: all suites completed with none failed. Bugbot's first review raised one finding, Windows junctions. That was a false positive: Rust's
FileType::is_dir()is false for name-surrogate reparse points. Evidence is in the thread, which is now resolved. Bugbot's re-review of e08b11d found no new issues.Per-issue checklist:
test_rollback_new_file_prunes_created_top_level_dir__pycache__→test_rollback_new_file_prunes_nested_dirs_and_stale_pycacheremove→ goes through the samerollback_package_patchengine asrollbackNot covered: files a patch adds are still not added to
.dist-info/RECORD, sopip uninstallwithout a rollback leaves them behind (the related point in #838). That is a separate apply-side change and is not claimed here.🤖 Generated with Claude Code
Generated by Claude Code