Repository navigation
feat: keep a directory given with its subtree when archiving - #605
Open
AzmainMahatab wants to merge 1 commit into
Open
AzmainMahatab wants to merge 1 commit into
AzmainMahatab wants to merge 1 commit into
Conversation
A `ReadSource` can now give a directory node that already carries a subtree: the archiver stores that tree as it is, like a file, instead of building the directory again from entries below it. A source that knows which directories did not change since the parent snapshot can then list only the changed ones and hand over the others whole, so a backup costs what changed rather than the whole tree. Directory nodes from `LocalSource` and the other built-in sources carry no subtree, so their behaviour is unchanged. A kept directory counts as an unmodified directory in the summary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
What
A
ReadSourcemay now give a directory node whosesubtreeis already set. Thearchiver keeps that tree as it is - the node is added to its parent like a file -
instead of opening the directory and building its tree again from the entries below it.
A kept directory counts as an unmodified directory in the summary.
The change is one condition in
Archiver::archive(node.is_dir() && node.subtree.is_none())and the summary branch in
TreeArchiver::add_file.Why
A tool that already knows which directories changed since the parent snapshot (for
example a sync engine with its own record of the last snapshot) can then list only the
changed directories and pass every unchanged one as its parent node, subtree and all.
Today the public API offers no way to do that:
archivealways rebuilds every directoryfrom its entries, and the tree rewriter (
TreeModifier) is crate-private. So a backup ofa few changed files in a large tree still walks, matches and re-serializes every
directory.
Measured with a source of 200,000 files in 21,660 directories, 3 files changed:
archivearchivetimeCompatibility
LocalSource,StdinSourceandChildStdoutSourcenever set a directory's subtree, sobackups through them behave exactly as before. Only a custom
ReadSourcethat sets itsees the new behaviour, and it is responsible for the subtree being in the repository's
index - as it is for a file node's
contentit passes withopen: None.Test
test_archive_keeps_a_directory_given_with_its_subtreebacks up the tar test data, thenarchives a source giving only one of its directories, with its subtree, under a new name.
The new snapshot holds that directory with the same subtree, and the summary counts one
unmodified directory. The test fails without the change (the directory comes out empty).
On Windows, five integration tests fail on
mainwithout this change as well(
test_backup_stdin_command,test_chunker_params,test_backup_with_tar_gz_passes,test_backup_dry_run_with_tar_gz_passes,test_rewrite); they fail the same with it. Oneprune case failed once in a full parallel run and passed in three reruns.
🤖 Generated with Claude Code