#291: - Compile --exclude/--include/--exclude-from/--include-from into the SAME ordered rule list as --filter/-f (first match wins), so the common `--include='*.txt' --exclude='*'` idiom and include-alone semantics match rsync. The legacy per-kind scanner arrays are no longer applied. - -x/--one-file-system emits the cross-device mount-point directory entry (empty) instead of dropping it, in both the sequential and parallel scanners. - Stop passing the legacy arrays to the scanner; document -f is --filter. #292: - New src/shared/format.c/.h: rsync "big_num" (comma-grouped integers) and decimal -h human sizes, %M/%t timestamp, and the STATUS_DEST_INFO codec. - Receiver answers each STATUS_CHECK with a pre-transfer destination snapshot (new report_dest_info wire field + STATUS_DEST_INFO, PROTOCOL_VERSION 2.23.0) so the sender can render true itemize columns. - Itemize now emits rsync-correct update/type chars and c/s/t/p/o/g columns for files, dirs, symlinks and hard links, comparing size/time/perms/owner/ group against the reported destination. - --out-format gains %i %n %f %l %b %M %t %o %p %B %U %G %L; %f is the relative display path, %M the YYYY/MM/DD-HH:MM:SS form, %b the literal bytes sent. - --list-only prints transfer-relative names, directory entries and ls-style grouped sizes. - --stats prints rsync's multi-line block on stdout; -h uses decimal units. Tests: unit tests for the filter ordering, format primitives, itemize columns; integration + differential tests against real rsync 3.4.1 for itemize/out-format/list-only/selection and -x. Golden wire len/hash and protocol version strings updated for 2.23.0.
This commit is contained in:
+34
-3
@@ -644,17 +644,19 @@ static void test_scanner_one_file_system_cross_device() {
|
||||
EXPECT_EQ_INT(seq_off_rc, 0);
|
||||
EXPECT_TRUE(seq_off_found);
|
||||
EXPECT_EQ_INT(seq_off_total, 2);
|
||||
/* Sequential: with -x the cross-device subtree is dropped, keep.txt remains. */
|
||||
/* Sequential: with -x the cross-device subtree is not descended into, but
|
||||
* rsync-compatible behavior still emits the mount-point directory entry as an
|
||||
* empty directory File, so keep.txt plus that entry are present. */
|
||||
EXPECT_EQ_INT(seq_on_rc, 0);
|
||||
EXPECT_FALSE(seq_on_found);
|
||||
EXPECT_EQ_INT(seq_on_total, 1);
|
||||
EXPECT_EQ_INT(seq_on_total, 2);
|
||||
/* Parallel: same behavior, worker path (depth > 1). */
|
||||
EXPECT_EQ_INT(par_off_rc, 0);
|
||||
EXPECT_TRUE(par_off_found);
|
||||
EXPECT_EQ_INT(par_off_total, 2);
|
||||
EXPECT_EQ_INT(par_on_rc, 0);
|
||||
EXPECT_FALSE(par_on_found);
|
||||
EXPECT_EQ_INT(par_on_total, 1);
|
||||
EXPECT_EQ_INT(par_on_total, 2);
|
||||
}
|
||||
|
||||
/* Collect emitted file paths (relative to `root`) from a sequential scan.
|
||||
@@ -884,6 +886,35 @@ static void test_filter_rules(bool parallel) {
|
||||
free_paths(paths, count);
|
||||
filter_rule_list_free(base);
|
||||
|
||||
/* The common include idiom (the exact rule order the CLI compiles from
|
||||
* --include='*.txt' --exclude='*'): only .txt files survive. */
|
||||
const char* idiom[] = {"+ *.txt", "- *"};
|
||||
base = filter_base_build(idiom, 2, false, err, sizeof(err));
|
||||
EXPECT_NOT_NULL(base);
|
||||
options.base_filters = base;
|
||||
rc = parallel ? collect_files_parallel(root, &options, &paths, &count)
|
||||
: collect_files(root, &options, &paths, &count);
|
||||
EXPECT_EQ_INT(rc, 0);
|
||||
EXPECT_EQ_INT(count, 2);
|
||||
EXPECT_TRUE(has_path(paths, count, "a.txt"));
|
||||
EXPECT_TRUE(has_path(paths, count, "c.txt"));
|
||||
EXPECT_FALSE(has_path(paths, count, "b.tmp"));
|
||||
free_paths(paths, count);
|
||||
filter_rule_list_free(base);
|
||||
|
||||
/* An include rule alone is NOT a mandatory whitelist (rsync semantics): only
|
||||
* the matching file is affected, everything else is still transferred. */
|
||||
const char* include_alone[] = {"+ *.txt"};
|
||||
base = filter_base_build(include_alone, 1, false, err, sizeof(err));
|
||||
EXPECT_NOT_NULL(base);
|
||||
options.base_filters = base;
|
||||
rc = parallel ? collect_files_parallel(root, &options, &paths, &count)
|
||||
: collect_files(root, &options, &paths, &count);
|
||||
EXPECT_EQ_INT(rc, 0);
|
||||
EXPECT_EQ_INT(count, 3);
|
||||
free_paths(paths, count);
|
||||
filter_rule_list_free(base);
|
||||
|
||||
unlink("test_scan_filter/a.txt");
|
||||
unlink("test_scan_filter/b.tmp");
|
||||
unlink("test_scan_filter/c.txt");
|
||||
|
||||
Reference in New Issue
Block a user