From b44222fc2b061382dc601014cde287cc41b857ca Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Thu, 17 Sep 2026 13:59:52 +0200 Subject: a duplicate test in an exclude protects like one in a rule The scopes that drive "no rule deletes a file krino found to be a duplicate" were collected from rules only. A directory whose duplicate tests lived in (exclude ...) forms had no scopes at all, so the protection never engaged: krino explain said "yes duplicate" and the next rule permanently deleted every copy. The README's promise was false in that shape, and the spec's wording permitted it. What matters is what krino knows, not which form taught it. The spec and krino.conf(5) now say so too. --- docs/design.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/design.md b/docs/design.md index 3037308..6299288 100644 --- a/docs/design.md +++ b/docs/design.md @@ -295,10 +295,12 @@ jdupes. Two rules enforce this: 1. A rule whose condition contains `(duplicate)` cannot contain a `delete` action (§4.5). -2. In a directory whose rules use `(duplicate)`, a file that is a duplicate - under any of the duplicate scopes those rules use — each distinct set of - DIRs, and the plain `(duplicate)`, looked up for the file whether or not - evaluation reached that test — gets no delete step from any rule. The +2. In a directory that uses `(duplicate)` — in a rule or in an `(exclude + ...)`, since what matters is what krino knows and not which form taught + it — a file that is a duplicate under any of the duplicate scopes that + directory uses — each distinct set of DIRs, and the plain `(duplicate)`, + looked up for the file whether or not evaluation reached that test — + gets no delete step from any rule. The plan shows the step as "skipped: a duplicate is never deleted" and the rest of the chain continues from the file's current path. This covers what rule 1 cannot see: a later rule deleting through `(matched)` or through a -- cgit v1.3