Skip to content

Fix false repo relocation warning on macOS due to NFC/NFD path differences, fixes #2913 (1.4-maint) - #10576

Open
ThomasWaldmann wants to merge 1 commit into
borgbackup:1.4-maintfrom
ThomasWaldmann:nfd-location-2913-14
Open

ThomasWaldmann wants to merge 1 commit into
borgbackup:1.4-maintfrom
ThomasWaldmann:nfd-location-2913-14

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

Backport of #9940 to 1.4-maint. Fixes #2913.

Problem

On macOS the filesystem returns paths in NFD (decomposed) unicode form, while a path typed as a command line argument is usually in NFC (composed) form. They look identical but are byte-different, so accessing a repo whose path contains non-ASCII characters via a relative path / . / $(pwd) made borg believe the repository had been relocated and prompt "The repository at location … was previously located at …".

Fix

  • Add helpers.normalize_local_path(): NFD on macOS, no-op elsewhere.
  • Run local file locations through it in Location.canonical_path().
  • Normalize both sides of the comparison in SecurityManager.assert_location_matches() (in cache.py on 1.4), so existing NFC-form security location files still match after upgrade.

Only affects the repository location string used for the relocation check; archived file paths are unaffected.

Backport notes

Manual port: on 1.4 SecurityManager lives in cache.py and the tests in testsuite/helpers.py.

Testing

  • New tests test_normalize_local_path, test_canonical_path_unicode_normalization; testsuite/helpers.py + testsuite/cache.py pass.
  • Manual repro on macOS/APFS (repo dir created with an NFD name, accessed with an NFC argument): unpatched 1.4-maint shows the bogus relocation prompt, this branch does not.

🤖 Generated with Claude Code

…rning on macOS, fixes borgbackup#2913

On macOS the filesystem returns paths in NFD (decomposed) form, while a
path typed as a command line argument is usually in NFC (composed) form.
These look identical but are byte-different, so accessing a repo via a
relative path / `.` / `$(pwd)` after `cd` made borg believe the repository
had been relocated and prompt for confirmation.

Add helpers.normalize_local_path() (NFD on macOS, no-op elsewhere) and run
local file locations through it in Location.canonical_path(). Also normalize
both sides of the location comparison in SecurityManager.assert_location_matches()
so existing NFC-form security "location" files keep matching after upgrade.

This only affects the repository *location* string used for the security /
relocation check (and its display); archived file paths are unaffected, and
the change is a no-op on non-macOS platforms.

Backport of borgbackup#9940 (master commit 4a25abc).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.10%. Comparing base (e81a51f) to head (91a95d6).
⚠️ Report is 12 commits behind head on 1.4-maint.

Additional details and impacted files
@@              Coverage Diff              @@
##           1.4-maint   #10576      +/-   ##
=============================================
- Coverage      82.11%   82.10%   -0.02%     
=============================================
  Files             38       38              
  Lines          11485    11489       +4     
  Branches        1810     1810              
=============================================
+ Hits            9431     9433       +2     
- Misses          1468     1469       +1     
- Partials         586      587       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

This branch has not been deployed

No deployments
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.

1 participant