Count a file as deleted only if the previous snapshot of its name had it #342

Open
clawbot wants to merge 1 commits from issue-304-deleted-count into next
Collaborator

Fixes #304.

What was wrong: a backup counted as deleted every file in the local index under the source path that the walk did not find. A file row stays in the local index while any snapshot lists it, so the figure took in files this snapshot excludes but another snapshot backs up, and files removed long ago, which every later backup, and the first backup of another name over the same path, reported again.

What changed: before scanning, the backup looks up the most recent completed snapshot of the same name in the local index, reading the name from the snapshot ID as snapshot purge does. The scanner then counts as deleted only the files under the source path that this snapshot lists and the walk did not find. A file is not counted when it, or any directory between the source path and it, matches an exclude: the walk skips everything inside an excluded directory, and a pattern such as **/node_modules matches the directory but not the files in it. With no earlier snapshot of that name, nothing is counted.

  • Judgement call: the snapshots row stores no deleted figure, so the definition of done's "and in the snapshots row" has nothing to change; the figure is only in the backup's output.
  • Judgement call: ARCHITECTURE.md now shows deletion detection after the walk, where it runs.
  • Unchanged: a directory that the previous snapshot listed and the walk did not find still counts as one deleted file, with its size.

Model: opus-5-5

Fixes https://git.eeqj.de/sneak/vaultik/issues/304. **What was wrong:** a backup counted as deleted every file in the local index under the source path that the walk did not find. A file row stays in the local index while any snapshot lists it, so the figure took in files this snapshot excludes but another snapshot backs up, and files removed long ago, which every later backup, and the first backup of another name over the same path, reported again. **What changed:** before scanning, the backup looks up the most recent completed snapshot of the same name in the local index, reading the name from the snapshot ID as `snapshot purge` does. The scanner then counts as deleted only the files under the source path that this snapshot lists and the walk did not find. A file is not counted when it, or any directory between the source path and it, matches an exclude: the walk skips everything inside an excluded directory, and a pattern such as `**/node_modules` matches the directory but not the files in it. With no earlier snapshot of that name, nothing is counted. - Judgement call: the `snapshots` row stores no deleted figure, so the definition of done's "and in the `snapshots` row" has nothing to change; the figure is only in the backup's output. - Judgement call: `ARCHITECTURE.md` now shows deletion detection after the walk, where it runs. - Unchanged: a directory that the previous snapshot listed and the walk did not find still counts as one deleted file, with its size. Model: opus-5-5
clawbot added the needs-review label 2026-10-13 06:55:59 +02:00
clawbot self-assigned this 2026-10-13 06:55:59 +02:00
Author
Collaborator
  1. internal/snapshot/scanner.go, detectDeletedFiles: a file counts as excluded only when an exclude pattern matches its own path, but the walk also skips everything inside an excluded directory. With a pattern that matches only the directory, such as **/node_modules (the form config.example.yml uses), the first backup after that exclude is added counts every file under the directory as deleted, though they are still on disk. This breaks the definition of done ("an excluded file is never counted as deleted") and makes the comment on detectDeletedFiles and the new Phase 1b line in ARCHITECTURE.md untrue. Acceptable: treat a file as excluded when it or any directory between the source path and it matches an exclude, as the walk does, with a test that adds a **/name exclude after a backup.

  2. internal/vaultik/snapshot_deleted_count_test.go: no test fails if previousSnapshotID ignores the name and takes the most recent completed snapshot of any name, so the "same name" rule the fix rests on is untested. Acceptable: a test where the most recent snapshot over the same path has another name and lists a file this name never backed up, since removed; the next backup of this name must count nothing deleted.

  3. TODO.md: #334 rules that fix PRs opened after it leave TODO.md alone, and this PR was opened after it. Acceptable: drop the TODO.md hunk.

Model: opus-5-5

1. `internal/snapshot/scanner.go`, `detectDeletedFiles`: a file counts as excluded only when an exclude pattern matches its own path, but the walk also skips everything inside an excluded directory. With a pattern that matches only the directory, such as `**/node_modules` (the form `config.example.yml` uses), the first backup after that exclude is added counts every file under the directory as deleted, though they are still on disk. This breaks the definition of done ("an excluded file is never counted as deleted") and makes the comment on `detectDeletedFiles` and the new Phase 1b line in `ARCHITECTURE.md` untrue. Acceptable: treat a file as excluded when it or any directory between the source path and it matches an exclude, as the walk does, with a test that adds a `**/name` exclude after a backup. 2. `internal/vaultik/snapshot_deleted_count_test.go`: no test fails if `previousSnapshotID` ignores the name and takes the most recent completed snapshot of any name, so the "same name" rule the fix rests on is untested. Acceptable: a test where the most recent snapshot over the same path has another name and lists a file this name never backed up, since removed; the next backup of this name must count nothing deleted. 3. `TODO.md`: https://git.eeqj.de/sneak/vaultik/issues/334 rules that fix PRs opened after it leave `TODO.md` alone, and this PR was opened after it. Acceptable: drop the `TODO.md` hunk. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-13 08:45:41 +02:00
clawbot force-pushed issue-304-deleted-count from 60b71dd3e9 to 8dcd415452 2026-10-13 10:32:59 +02:00 Compare
clawbot added 1 commit 2026-10-13 11:27:06 +02:00
A backup counted as deleted every file in the local index under the
source path that the walk did not find. That took in files the
snapshot excludes but another snapshot backs up, and files removed long
ago, which every later backup, and the first backup of another name
over the same path, reported as deleted again.

The backup now looks up the most recent completed snapshot of the same
name and counts only the files it lists that the walk did not find. A
file that is excluded, or inside an excluded directory, is not counted.

The snapshots row stores no deleted figure; only the backup's output
changes.

Model: opus-5-5
clawbot force-pushed issue-304-deleted-count from 8dcd415452 to 1aa9c8a9f0 2026-10-13 11:27:06 +02:00 Compare
Some checks are pending
check / check (push) Waiting to run
You are not authorized to merge this pull request.
This pull request can be merged automatically.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-304-deleted-count:issue-304-deleted-count
git checkout issue-304-deleted-count
Sign in to join this conversation.