Fall back to rm when a fuzzy-dedup delete target isn't tracked in beets

A handful of confirmed candidates reference files that are no longer in
the beets DB (removed by some other pass, or never re-imported after a
move) but are still sitting on disk -- beet remove can't match them by
id or path either way, so they failed forever. If the file still exists
after a "No matching items found" error, remove it directly instead of
counting it as a failure. Applies to both --apply and --apply-pairs.
This commit is contained in:
andrew
2026-07-09 11:23:10 -06:00
parent 59c369c9e2
commit ed0b08967e
+28 -5
View File
@@ -180,9 +180,22 @@ def _apply_pairs(pairs_file: str, emit_json: bool) -> int:
capture_output=True, text=True,
)
if result.returncode != 0:
print(f" FAILED: {delete_path}{result.stderr.strip()}", file=sys.stderr)
failed += 1
continue
if "No matching items found" in result.stderr and os.path.exists(delete_path):
# Not tracked in beets at all (e.g. it was already removed
# from the DB by some other pass, or never re-imported after
# a move) but the duplicate file itself is still sitting on
# disk -- `beet remove` can never match it by id or path
# either way, so just remove the file directly.
try:
os.remove(delete_path)
except OSError as exc:
print(f" FAILED: {delete_path} — not in beets, then rm failed: {exc}", file=sys.stderr)
failed += 1
continue
else:
print(f" FAILED: {delete_path}{result.stderr.strip()}", file=sys.stderr)
failed += 1
continue
print(f" DELETE {delete_path}")
deleted += 1
if emit_json:
@@ -372,8 +385,18 @@ def main() -> int:
capture_output=True, text=True,
)
if result.returncode != 0:
print(f" FAILED: {path}{result.stderr.strip()}", file=sys.stderr)
failed += 1
if "No matching items found" in result.stderr and os.path.exists(path):
# Item was already gone from beets by the time we got here
# (e.g. removed by an earlier pass) but the file is still on
# disk -- remove it directly instead of counting it failed.
try:
os.remove(path)
except OSError as exc:
print(f" FAILED: {path} — not in beets, then rm failed: {exc}", file=sys.stderr)
failed += 1
else:
print(f" FAILED: {path}{result.stderr.strip()}", file=sys.stderr)
failed += 1
deleted = len(delete_targets) - failed - skipped_unconfirmed
print(f"[fuzzy-dupes] done. {deleted} deleted, {failed} failed, {skipped_unconfirmed} skipped (unconfirmed).")
return 1 if failed else 0