Walk an operand nested on another filesystem with -x (closes #106)
check / check (push) Canceled after 0s

With -x, an operand under another operand is kept and walked on its
own when it is a directory on a different filesystem than the deepest
kept operand above it, or a regular file in such a directory, since
that operand's walk does not reach it. Below a kept operand, the rule
keeping records under a directory -x did not enter covers only
directories its own walk did not enter, so records of files gone from
it are deleted.

The new tests stub the devices and share their scan steps with the
test for #99, whose comment no
longer claims it runs every phase. The startWalk comment is rewrapped.

Model: opus-5-5
This commit is contained in:
2026-10-14 19:07:23 +00:00
parent 80bd7c0999
commit c8c7882cc7
4 changed files with 304 additions and 47 deletions
+10 -5
View File
@@ -398,7 +398,10 @@ results do not depend on the working directory. All operands belong to a single
scan and are enumerated concurrently: every operand seeds the shared walk worker
pool. Overlapping operands are harmless — an operand that duplicates another or
lies under another is dropped before walking, so every file is reached exactly
once and produces one database record.
once and produces one database record. With `-x`, though, an operand under
another one is kept and walked on its own when it is a directory on a different
filesystem than the operand covering it, or a regular file in such a directory,
because the walk of the covering operand does not reach it.
An operand that is a symlink (never followed, not even as an operand), socket,
FIFO, or device node, or a directory named `.zfs`, is not scanned. `scan` prints
@@ -451,7 +454,8 @@ operands:
directory is on another filesystem than its operand counts as outside the
scanned operands: it is not deleted, and its size joins the size census. A
filesystem mounted under an operand can therefore be scanned on its own
schedule into the same database.
schedule into the same database. Records below an operand at or inside such a
directory are not kept this way, since that operand's own walk verifies them.
`scan` runs **four sequential phases over the whole scan**. Parallelism lives
inside each phase; batched database writes begin during the hash phase:
@@ -518,9 +522,10 @@ Rules for the walk:
- Filesystem boundaries are crossed by default. With `-x` (long form
`--one-file-system`, following the GNU `du`/`rsync` convention), never descend
into a directory on a different filesystem than its `PATH` operand; each
operand is bounded by its own filesystem. The records below such a directory
count as outside the scanned operands, as described in "`scan` mode" above:
they are not deleted, and their sizes join the size census.
operand is bounded by its own filesystem. The records below such a directory,
unless they lie below an operand at or inside that directory, count as outside
the scanned operands, as described in "`scan` mode" above: they are not
deleted, and their sizes join the size census.
- On any per-path error (permission denied, file vanished between passes,
unreadable): print a one-line warning to stderr, skip the path, and continue.
Per-file errors never abort the run; the final summary reports how many were