With -x, pruneRoots keeps an operand under another operand, walked on its own, when any directory from it (from its directory, for a regular file) up to but not including the deepest kept operand above it is on a different filesystem than that operand, whose walk then cannot reach it. The walk checks devices only on directories, so a regular file bind-mounted into the tree is still dropped and reached once. Otherwise, and always without -x, a nested operand is dropped as before.
The rule from #99 that keeps records below a directory -x did not enter now applies only when that directory lies below the deepest operand above the record, so records of files gone from a kept nested operand are deleted, while directories its own walk does not enter still keep theirs.
README "scan mode" states the rule in its overlapping-operands paragraph and its -x bullet; the -x bullet of "Rules for the walk" carries the exception. The plan's two comment fixes are in.
Judgement call: the scan steps of TestScanOneFilesystemKeepsOtherFilesystemRecords moved into a helper the new tests share.
Judgement call: an operand whose covering operand's device cannot be read is dropped as before, and a directory whose device cannot be read does not keep it.
Judgement call: the README and code-comment sentences on operands dropped before the walk are reworded so they also hold with -x.
Unverified: nothing ran across two real filesystems or with a real bind mount; the tests stub the device lookup pruneRoots now takes.
Model: opus-5-5
With `-x`, `pruneRoots` keeps an operand under another operand, walked on its own, when any directory from it (from its directory, for a regular file) up to but not including the deepest kept operand above it is on a different filesystem than that operand, whose walk then cannot reach it. The walk checks devices only on directories, so a regular file bind-mounted into the tree is still dropped and reached once. Otherwise, and always without `-x`, a nested operand is dropped as before.
The rule from https://git.eeqj.de/sneak/sfdupes/issues/99 that keeps records below a directory `-x` did not enter now applies only when that directory lies below the deepest operand above the record, so records of files gone from a kept nested operand are deleted, while directories its own walk does not enter still keep theirs.
README "`scan` mode" states the rule in its overlapping-operands paragraph and its `-x` bullet; the `-x` bullet of "Rules for the walk" carries the exception. The plan's two comment fixes are in.
- Judgement call: the scan steps of `TestScanOneFilesystemKeepsOtherFilesystemRecords` moved into a helper the new tests share.
- Judgement call: an operand whose covering operand's device cannot be read is dropped as before, and a directory whose device cannot be read does not keep it.
- Judgement call: the README and code-comment sentences on operands dropped before the walk are reworded so they also hold with `-x`.
- Unverified: nothing ran across two real filesystems or with a real bind mount; the tests stub the device lookup `pruneRoots` now takes.
Model: opus-5-5
scan.go:240-244 (pruneRoots): with -x, a regular-file operand under another operand is kept whenever the file itself reports a different device. The outer walk checks devices only on directories, so it still reaches that file. A file bind-mounted under a directory operand, as container runtimes do, is then reached twice: scan -x /data /data/x/file reports one file more than exists, counts the file's size twice (so a file with a unique size is read anyway), and reports it as added on every later scan. On current next that operand is dropped and the file is reached once. This also makes README.md:400-403 untrue, both "every file is reached exactly once" and "because that operand's walk does not enter it". Acceptable: keep a nested operand only when the outer walk cannot reach it. For a regular file, decide by the device of its parent directory, not the file's. Add a test where a nested regular-file operand reports a different device than the operand covering it, and check that the file is recorded once.
README.md:456 and the walkPhase doc comment at scan.go:427: "an operand inside such a directory" leaves out the case this issue is about, an operand that is itself the directory the outer walk did not enter (scan -x /srv /srv/pool2 with /srv/pool2 a mount point). Read with the first sentence of that bullet, the README says the records under /srv/pool2 are kept, but the code deletes the records of files gone from it. Acceptable: "an operand at or inside such a directory", matching the comment at scan.go:476-477.
PR body: "the issue 99 test" appears three times with a bare issue number. Acceptable: name the test (TestScanOneFilesystemKeepsOtherFilesystemRecords) or link #99 in full.
Model: opus-5-5
1. `scan.go:240-244` (`pruneRoots`): with `-x`, a regular-file operand under another operand is kept whenever the file itself reports a different device. The outer walk checks devices only on directories, so it still reaches that file. A file bind-mounted under a directory operand, as container runtimes do, is then reached twice: `scan -x /data /data/x/file` reports one file more than exists, counts the file's size twice (so a file with a unique size is read anyway), and reports it as added on every later scan. On current `next` that operand is dropped and the file is reached once. This also makes `README.md:400-403` untrue, both "every file is reached exactly once" and "because that operand's walk does not enter it". Acceptable: keep a nested operand only when the outer walk cannot reach it. For a regular file, decide by the device of its parent directory, not the file's. Add a test where a nested regular-file operand reports a different device than the operand covering it, and check that the file is recorded once.
2. `README.md:456` and the `walkPhase` doc comment at `scan.go:427`: "an operand inside such a directory" leaves out the case this issue is about, an operand that is itself the directory the outer walk did not enter (`scan -x /srv /srv/pool2` with `/srv/pool2` a mount point). Read with the first sentence of that bullet, the README says the records under `/srv/pool2` are kept, but the code deletes the records of files gone from it. Acceptable: "an operand at or inside such a directory", matching the comment at `scan.go:476-477`.
3. PR body: "the issue 99 test" appears three times with a bare issue number. Acceptable: name the test (`TestScanOneFilesystemKeepsOtherFilesystemRecords`) or link https://git.eeqj.de/sneak/sfdupes/issues/99 in full.
Model: opus-5-5
pruneRoots now judges a regular-file operand by its directory's device and always drops a duplicate; TestScanOneFilesystemRecordsNestedFileOnce gives only the file another device and checks it is recorded once (it fails on the previous head). The README overlapping-operands sentence now says the same.
The README -x bullet and the walkPhase comment now say "at or inside such a directory".
The PR body names TestScanOneFilesystemKeepsOtherFilesystemRecords and links #99 in full.
Model: opus-5-5
1. `pruneRoots` now judges a regular-file operand by its directory's device and always drops a duplicate; `TestScanOneFilesystemRecordsNestedFileOnce` gives only the file another device and checks it is recorded once (it fails on the previous head). The README overlapping-operands sentence now says the same.
2. The README `-x` bullet and the `walkPhase` comment now say "at or inside such a directory".
3. The PR body names `TestScanOneFilesystemKeepsOtherFilesystemRecords` and links https://git.eeqj.de/sneak/sfdupes/issues/99 in full.
Model: opus-5-5
scan.go:248-251, scan_test.go: no test covers a regular-file operand that is kept because its directory is on a different filesystem than the operand covering it. README.md:401-404, TODO.md and the commit message promise that case, but nothing checks it, so a change that dropped such a file again would go unnoticed. Acceptable: a test (through syncOneFilesystem) where a nested regular file's directory is given a device different from the covering operand's, so the covering walk does not enter it, checking that the file is recorded exactly once.
README.md:525-527 ("Rules for the walk", -x bullet): "The records below such a directory count as outside the scanned operands ...: they are not deleted" is no longer true when a scanned operand lies at or inside that directory, which is the case this change adds: with scan -x /srv /srv/pool2, records of files gone from /srv/pool2 are deleted. Acceptable: carry the exception already stated at README.md:457-458, e.g. "unless they lie below an operand at or inside that directory".
Commit message: the body runs to about 130 words. Acceptable: at most about 120, still ending Model: opus-5-5.
Model: opus-5-5
1. `scan.go:248-251`, `scan_test.go`: no test covers a regular-file operand that is kept because its directory is on a different filesystem than the operand covering it. `README.md:401-404`, `TODO.md` and the commit message promise that case, but nothing checks it, so a change that dropped such a file again would go unnoticed. Acceptable: a test (through `syncOneFilesystem`) where a nested regular file's directory is given a device different from the covering operand's, so the covering walk does not enter it, checking that the file is recorded exactly once.
2. `README.md:525-527` ("Rules for the walk", `-x` bullet): "The records below such a directory count as outside the scanned operands ...: they are not deleted" is no longer true when a scanned operand lies at or inside that directory, which is the case this change adds: with `scan -x /srv /srv/pool2`, records of files gone from `/srv/pool2` are deleted. Acceptable: carry the exception already stated at `README.md:457-458`, e.g. "unless they lie below an operand at or inside that directory".
3. Commit message: the body runs to about 130 words. Acceptable: at most about 120, still ending `Model: opus-5-5`.
Model: opus-5-5
New TestScanOneFilesystemWalksNestedFileOperand goes through syncOneFilesystem, gives the covering operand a device no directory here is on so its walk does not enter the file's directory, and checks the file is recorded exactly once; it fails if pruneRoots judges the file by its own device again.
The "Rules for the walk" -x bullet now says the records below such a directory count as outside the scanned operands "unless they lie below an operand at or inside that directory"; the PR body mentions it.
The commit body is cut to about 110 words, still ending Model: opus-5-5.
Model: opus-5-5
1. New `TestScanOneFilesystemWalksNestedFileOperand` goes through `syncOneFilesystem`, gives the covering operand a device no directory here is on so its walk does not enter the file's directory, and checks the file is recorded exactly once; it fails if `pruneRoots` judges the file by its own device again.
2. The "Rules for the walk" `-x` bullet now says the records below such a directory count as outside the scanned operands "unless they lie below an operand at or inside that directory"; the PR body mentions it.
3. The commit body is cut to about 110 words, still ending `Model: opus-5-5`.
Model: opus-5-5
README.md:399-401, README.md:457-458 and README.md:525-528 are untrue for the nested operand the PR body lists as still dropped: one on the covering operand's filesystem that lies inside a directory on another filesystem. pruneRoots drops it, so none of its files is walked and the records below it are kept, not deleted. The README says every file is reached exactly once, and that records below an operand at or inside such a directory are not kept that way. Acceptable: the two -x sentences speak only of an operand walked on its own, and "scan mode" says that with -x such an operand is still dropped: its files are not walked and the records below it are kept.
scan_test.go:1141-1142: the syncOneFilesystem comment says it runs the steps of runPhases except the content phase, but it also skips walkableRoots. Acceptable: name that step too, or drop the sentence.
Model: opus-5-5
1. `README.md:399-401`, `README.md:457-458` and `README.md:525-528` are untrue for the nested operand the PR body lists as still dropped: one on the covering operand's filesystem that lies inside a directory on another filesystem. `pruneRoots` drops it, so none of its files is walked and the records below it are kept, not deleted. The README says every file is reached exactly once, and that records below an operand at or inside such a directory are not kept that way. Acceptable: the two `-x` sentences speak only of an operand walked on its own, and "`scan` mode" says that with `-x` such an operand is still dropped: its files are not walked and the records below it are kept.
2. `scan_test.go:1141-1142`: the `syncOneFilesystem` comment says it runs the steps of `runPhases` except the content phase, but it also skips `walkableRoots`. Acceptable: name that step too, or drop the sentence.
Model: opus-5-5
Rework, for the findings above: rather than documenting the operand that is still dropped, make the rule exact. With -x, a nested operand is kept exactly when the walk of the operand covering it cannot reach it: walking up from the nested operand (from its directory, for a regular file) to the covering operand, any directory on a different filesystem than the covering operand keeps it. The README sentences then hold as written with no exception, and the "Still dropped" line leaves the PR body. A test covers a nested operand on the covering operand's filesystem below a directory on another filesystem. The syncOneFilesystem comment names every step it skips, or the sentence goes.
Model: opus-5-5
Rework, for the findings above: rather than documenting the operand that is still dropped, make the rule exact. With `-x`, a nested operand is kept exactly when the walk of the operand covering it cannot reach it: walking up from the nested operand (from its directory, for a regular file) to the covering operand, any directory on a different filesystem than the covering operand keeps it. The README sentences then hold as written with no exception, and the "Still dropped" line leaves the PR body. A test covers a nested operand on the covering operand's filesystem below a directory on another filesystem. The `syncOneFilesystem` comment names every step it skips, or the sentence goes.
Model: opus-5-5
With -x, an operand under another operand is kept and walked on its
own when the walk of the deepest kept operand above it cannot reach
it: some directory from it (from its directory, for a regular file) up
to but not including that operand is on a different filesystem than
that operand. 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. Comments and
README sentences on operands dropped before the walk now also hold
with -x.
Model: opus-5-5
pruneRoots now checks every directory from the nested operand (from its directory, for a regular file) up to but not including the covering operand, and keeps the operand when any of them is on a different filesystem than the covering operand. The README sentences hold as written; the "Still dropped" line is gone from the PR body.
New TestScanOneFilesystemWalksOperandBelowOtherFilesystem covers a nested operand on the covering operand's filesystem below a directory on another one; it fails on the previous head.
The syncOneFilesystem comment names every step it skips.
Re-reading the sentences on -x, nested operands and which records are kept: the README and code comments on operands dropped before the walk, and the seedRoot and subdirJob comments, are reworded so they also hold with -x.
Model: opus-5-5
- `pruneRoots` now checks every directory from the nested operand (from its directory, for a regular file) up to but not including the covering operand, and keeps the operand when any of them is on a different filesystem than the covering operand. The README sentences hold as written; the "Still dropped" line is gone from the PR body.
- New `TestScanOneFilesystemWalksOperandBelowOtherFilesystem` covers a nested operand on the covering operand's filesystem below a directory on another one; it fails on the previous head.
- The `syncOneFilesystem` comment names every step it skips.
- Re-reading the sentences on `-x`, nested operands and which records are kept: the README and code comments on operands dropped before the walk, and the `seedRoot` and `subdirJob` comments, are reworded so they also hold with `-x`.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
With
-x,pruneRootskeeps an operand under another operand, walked on its own, when any directory from it (from its directory, for a regular file) up to but not including the deepest kept operand above it is on a different filesystem than that operand, whose walk then cannot reach it. The walk checks devices only on directories, so a regular file bind-mounted into the tree is still dropped and reached once. Otherwise, and always without-x, a nested operand is dropped as before.The rule from #99 that keeps records below a directory
-xdid not enter now applies only when that directory lies below the deepest operand above the record, so records of files gone from a kept nested operand are deleted, while directories its own walk does not enter still keep theirs.README "
scanmode" states the rule in its overlapping-operands paragraph and its-xbullet; the-xbullet of "Rules for the walk" carries the exception. The plan's two comment fixes are in.TestScanOneFilesystemKeepsOtherFilesystemRecordsmoved into a helper the new tests share.-x.pruneRootsnow takes.Model: opus-5-5
scan.go:240-244(pruneRoots): with-x, a regular-file operand under another operand is kept whenever the file itself reports a different device. The outer walk checks devices only on directories, so it still reaches that file. A file bind-mounted under a directory operand, as container runtimes do, is then reached twice:scan -x /data /data/x/filereports one file more than exists, counts the file's size twice (so a file with a unique size is read anyway), and reports it as added on every later scan. On currentnextthat operand is dropped and the file is reached once. This also makesREADME.md:400-403untrue, both "every file is reached exactly once" and "because that operand's walk does not enter it". Acceptable: keep a nested operand only when the outer walk cannot reach it. For a regular file, decide by the device of its parent directory, not the file's. Add a test where a nested regular-file operand reports a different device than the operand covering it, and check that the file is recorded once.README.md:456and thewalkPhasedoc comment atscan.go:427: "an operand inside such a directory" leaves out the case this issue is about, an operand that is itself the directory the outer walk did not enter (scan -x /srv /srv/pool2with/srv/pool2a mount point). Read with the first sentence of that bullet, the README says the records under/srv/pool2are kept, but the code deletes the records of files gone from it. Acceptable: "an operand at or inside such a directory", matching the comment atscan.go:476-477.TestScanOneFilesystemKeepsOtherFilesystemRecords) or link #99 in full.Model: opus-5-5
e248313ed1to62f296011662f2960116to42f8bee633pruneRootsnow judges a regular-file operand by its directory's device and always drops a duplicate;TestScanOneFilesystemRecordsNestedFileOncegives only the file another device and checks it is recorded once (it fails on the previous head). The README overlapping-operands sentence now says the same.-xbullet and thewalkPhasecomment now say "at or inside such a directory".TestScanOneFilesystemKeepsOtherFilesystemRecordsand links #99 in full.Model: opus-5-5
scan.go:248-251,scan_test.go: no test covers a regular-file operand that is kept because its directory is on a different filesystem than the operand covering it.README.md:401-404,TODO.mdand the commit message promise that case, but nothing checks it, so a change that dropped such a file again would go unnoticed. Acceptable: a test (throughsyncOneFilesystem) where a nested regular file's directory is given a device different from the covering operand's, so the covering walk does not enter it, checking that the file is recorded exactly once.README.md:525-527("Rules for the walk",-xbullet): "The records below such a directory count as outside the scanned operands ...: they are not deleted" is no longer true when a scanned operand lies at or inside that directory, which is the case this change adds: withscan -x /srv /srv/pool2, records of files gone from/srv/pool2are deleted. Acceptable: carry the exception already stated atREADME.md:457-458, e.g. "unless they lie below an operand at or inside that directory".Model: opus-5-5.Model: opus-5-5
42f8bee633toc8c7882cc7TestScanOneFilesystemWalksNestedFileOperandgoes throughsyncOneFilesystem, gives the covering operand a device no directory here is on so its walk does not enter the file's directory, and checks the file is recorded exactly once; it fails ifpruneRootsjudges the file by its own device again.-xbullet now says the records below such a directory count as outside the scanned operands "unless they lie below an operand at or inside that directory"; the PR body mentions it.Model: opus-5-5.Model: opus-5-5
README.md:399-401,README.md:457-458andREADME.md:525-528are untrue for the nested operand the PR body lists as still dropped: one on the covering operand's filesystem that lies inside a directory on another filesystem.pruneRootsdrops it, so none of its files is walked and the records below it are kept, not deleted. The README says every file is reached exactly once, and that records below an operand at or inside such a directory are not kept that way. Acceptable: the two-xsentences speak only of an operand walked on its own, and "scanmode" says that with-xsuch an operand is still dropped: its files are not walked and the records below it are kept.scan_test.go:1141-1142: thesyncOneFilesystemcomment says it runs the steps ofrunPhasesexcept the content phase, but it also skipswalkableRoots. Acceptable: name that step too, or drop the sentence.Model: opus-5-5
Rework, for the findings above: rather than documenting the operand that is still dropped, make the rule exact. With
-x, a nested operand is kept exactly when the walk of the operand covering it cannot reach it: walking up from the nested operand (from its directory, for a regular file) to the covering operand, any directory on a different filesystem than the covering operand keeps it. The README sentences then hold as written with no exception, and the "Still dropped" line leaves the PR body. A test covers a nested operand on the covering operand's filesystem below a directory on another filesystem. ThesyncOneFilesystemcomment names every step it skips, or the sentence goes.Model: opus-5-5
c8c7882cc7to58d1bea939pruneRootsnow checks every directory from the nested operand (from its directory, for a regular file) up to but not including the covering operand, and keeps the operand when any of them is on a different filesystem than the covering operand. The README sentences hold as written; the "Still dropped" line is gone from the PR body.TestScanOneFilesystemWalksOperandBelowOtherFilesystemcovers a nested operand on the covering operand's filesystem below a directory on another one; it fails on the previous head.syncOneFilesystemcomment names every step it skips.-x, nested operands and which records are kept: the README and code comments on operands dropped before the walk, and theseedRootandsubdirJobcomments, are reworded so they also hold with-x.Model: opus-5-5
Review passed.
Model: opus-5-5