Skip to content

Conversation

@ThomasWaldmann
Copy link
Member

This implementation should be good enough for our usecase (paths) and has no external dependencies.

There is also a wcwidth library which might be even better, but would add another dependency.

This commit implements a comprehensive approach to Windows path compatibility
by standardizing on forward slashes (/) for all internal path representations
while maintaining cross-platform archive compatibility.

Core Strategy:
- All internal paths now use forward slashes as separators on all platforms
- Boundary normalization: backslashes converted to forward slashes at entry
  points on Windows (filesystem paths only, not user patterns)
- Literal backslashes from POSIX archives replaced with % on Windows extraction

Key Changes:

Path Handling (helpers/fs.py):
- Added slashify(): converts backslashes to forward slashes on Windows
- Added percentify(): replaces backslashes with % for POSIX-to-Windows extraction
- Updated make_path_safe() to check for Windows-style .. patterns
- Changed get_strip_prefix() to use posixpath.normpath instead of os.path.normpath
- Updated remove_dotdot_prefixes() to use forward slashes consistently

Pattern Matching (patterns.py):
- Replaced os.path with posixpath throughout for consistent separator handling
- Updated PathFullPattern, PathPrefixPattern, FnmatchPattern, ShellPattern
- All pattern matching now uses / as separator regardless of platform
- Removed platform-specific os.sep usage

Archive Operations (archive.py, item.pyx):
- Applied slashify() to paths during archive creation on Windows
- Added percentify/slashify encoding/decoding for symlink targets
- Ensures archived paths always use forward slashes

Command Line (archiver/create_cmd.py, extract_cmd.py):
- Replaced os.path.join/normpath with posixpath equivalents
- Added slashify() for stdin-provided paths on Windows
- Updated strip_components to use / separator
- Changed PathSpec to FilesystemPathSpec for proper path handling

Repository (repository.py, legacyrepository.py):
- Replaced custom _local_abspath_to_file_url() with Path.as_uri()

Documentation (archiver/help_cmd.py):
- Clarified that all archived paths use forward slashes
- Added note about Windows absolute paths in archives (e.g., C/Windows/System32)
- Documented backslash-to-percent replacement for POSIX archives on Windows

Impact:
- Windows users can now create and extract archives with consistent path handling
- Cross-platform archives remain compatible
- Pattern matching works identically on all platforms
@codecov
Copy link

codecov bot commented Jan 31, 2026

Codecov Report

❌ Patch coverage is 92.53731% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.89%. Comparing base (85b2ca2) to head (dc65861).
⚠️ Report is 12 commits behind head on master.

Files with missing lines Patch % Lines
src/borg/helpers/fs.py 77.77% 1 Missing and 1 partial ⚠️
src/borg/helpers/parseformat.py 75.00% 1 Missing and 1 partial ⚠️
src/borg/platform/base.py 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9283      +/-   ##
==========================================
+ Coverage   75.84%   75.89%   +0.04%     
==========================================
  Files          86       86              
  Lines       14745    14758      +13     
  Branches     2194     2197       +3     
==========================================
+ Hits        11184    11200      +16     
+ Misses       2888     2884       -4     
- Partials      673      674       +1     

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

@ThomasWaldmann ThomasWaldmann force-pushed the swidth-master branch 2 times, most recently from 7562aa9 to 48387e0 Compare February 1, 2026 04:11
CI: the windows runner installs Python 3.14 now and thus we need a more recent pyinstaller to be compatible with that.
This implementation should be good enough for our usecase (paths) and has no external dependencies.

There is also a wcwidth library which might be even better, but would add another dependency.
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