Skip to content

Fix symlinked reimports deleting library files - #6993

Open
atirna wants to merge 2 commits into
beetbox:masterfrom
atirna:fix/reimport-symlink-path
Open

atirna wants to merge 2 commits into
beetbox:masterfrom
atirna:fix/reimport-symlink-path

Conversation

@atirna

@atirna atirna commented Sep 5, 2026

Copy link
Copy Markdown

Description

Reimporting a library file through a symlinked parent could treat the same file as a duplicate because its stored and imported paths used different spellings. Choosing Remove then deleted the original file.

Fixes #6930.

Why

The importer now recognizes an existing in-library file by physical identity when its exact stored path is not found. Reimport replacement and in-library moves use the same resolved containment check, so the file stays in the library while its metadata is refreshed.

Verification

  • Before: uv run pytest test/test_importer.py::ReimportTest::test_reimported_album_through_symlink_preserves_file -q failed because the reimport created a second file.
  • After: uv run pytest test/test_importer.py -k 'ReimportTest or TestImportDuplicateAlbum or TestImportDuplicateSingleton' -q passes with 32 passed and 2 skipped.

To Do

  • Documentation. (No user-facing option or configuration change.)
  • Changelog. (Bug fix only; no new user-facing behavior.)
  • Tests.

@atirna
atirna requested a review from a team as a code owner September 5, 2026 11:49
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Thank you for the PR! The changelog has not been updated, so here is a friendly reminder to check if you need to add an entry.

@codecov

codecov Bot commented Sep 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.37838% with 8 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.20%. Comparing base (ba4787f) to head (2d8f336).
⚠️ Report is 65 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
beets/importer/tasks.py 78.37% 2 Missing and 6 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #6993      +/-   ##
==========================================
+ Coverage   77.19%   77.20%   +0.01%     
==========================================
  Files         163      163              
  Lines       21789    21813      +24     
  Branches     3360     3366       +6     
==========================================
+ Hits        16820    16841      +21     
- Misses       4149     4151       +2     
- Partials      820      821       +1     
Files with missing lines Coverage Δ
beets/importer/tasks.py 92.72% <78.37%> (-0.19%) ⬇️
🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistent handling of reimporting, causing data loss, when the music dir is under a symlinked parent

1 participant