Repository navigation
transfers: Prevent receiver directory wiping and data loss (#240) - #263
Open
ronitgupta138 wants to merge 1 commit into
Open
ronitgupta138 wants to merge 1 commit into
ronitgupta138 wants to merge 1 commit into
Conversation
…int#240) - In receive_data(), switch from create() to replace() with REPLACE_DESTINATION so individual files overwrite cleanly without directory destruction. - In clean_existing_files() and rm_any(), do not delete entire directory trees (shutil.rmtree) when receiving folder contents, preserving pre-existing files. - In clean_current_top_dir_file(), ensure only newly created partial files are cleaned on abort, rather than nuking existing directory trees.
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.
Resolves #240
Problem & Root Cause
When transferring files or folders,
FileReceiver.clean_existing_files()calledrm_any()which executedshutil.rmtree()on the whole directoryself.save_path / namebefore receiving folder contents. This was originally done becauseGio.File.create()raisesG_IO_ERROR_EXISTSif a destination file exists.Additionally, when an interrupted transfer stopped or aborted prematurely,
clean_current_top_dir_file()resolvedabs_top_dir = self.save_path.joinpath(relative.parts[0])and executedself.rm_any(abs_top_dir)withshutil.rmtree(), permanently destroying the entire top-level directory.These behaviors caused severe, unintentional data loss:
Solution
receive_data(): Switched fromself.current_gfile.create()toself.current_gfile.replace(None, False, Gio.FileCreateFlags.REPLACE_DESTINATION, None). Incoming files now overwrite cleanly without needing directory destruction.clean_existing_files()&rm_any(): Refactoredrm_any()andclean_existing_files()to never delete directory trees (shutil.rmtree). If a target entry is a directory, it is kept intact so that existing files are preserved and transfers behave as copy operations rather than destructive overwrites.clean_current_top_dir_file(): Trackself.current_is_newand ensure only newly created partial files are unlinked on abort, rather than nuking the parent directory treeabs_top_dir.Verification Steps
clean_existing_files()runs.