diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f5763de4bb..48216414da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -611,6 +611,8 @@ jobs: env: PY_COLORS: 1 + MSYS2_ARG_CONV_EXCL: "*" + MSYS2_ENV_CONV_EXCL: "*" defaults: run: diff --git a/docs/installation.rst b/docs/installation.rst index 143533f7b2..ce85060ac3 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -327,6 +327,29 @@ Install the dependencies with the provided script:: ./scripts/msys2-install-deps +.. _msys2_path_translation: + +MSYS2 Path Translation +++++++++++++++++++++++ + +When running Borg within an MSYS2 environment, the shell +automatically translates POSIX-style paths (like ``/tmp`` or ``/C/Users``) to +Windows paths (like ``C:\msys64\tmp`` or ``C:\Users``) before they reach the +Borg process. + +This behavior can result in absolute Windows paths being stored in your backups, +which may not be what you intended if you use POSIX paths for portability. + +To disable this automatic translation for Borg, you can use environment variables +to exclude everything from conversion. Similarly, MSYS2 also translates +environment variables that look like paths. To disable this generally for Borg, +set both variables:: + + export MSYS2_ARG_CONV_EXCL="*" + export MSYS2_ENV_CONV_EXCL="*" + +For more details, see the `MSYS2 documentation on filesystem paths `__. + Windows 10's Linux Subsystem ++++++++++++++++++++++++++++ diff --git a/src/borg/archiver/__init__.py b/src/borg/archiver/__init__.py index 834bf7b5cf..438f0ea37c 100644 --- a/src/borg/archiver/__init__.py +++ b/src/borg/archiver/__init__.py @@ -46,6 +46,7 @@ from ..helpers import ErrorIgnoringTextIOWrapper from ..helpers import msgpack from ..helpers import sig_int + from ..platformflags import is_win32, is_msystem from ..remote import RemoteRepository from ..selftest import selftest except BaseException: @@ -455,7 +456,14 @@ def parse_args(self, args=None): return args def prerun_checks(self, logger, is_serve): - + if not is_serve: + if is_win32 and is_msystem: + if "MSYS2_ARG_CONV_EXCL" not in os.environ or "MSYS2_ENV_CONV_EXCL" not in os.environ: + logger.warning( + "MSYS2 path translation is active. This can cause POSIX paths to be mangled into " + "Windows paths in archives. Consider setting MSYS2_ARG_CONV_EXCL='*' and " + "MSYS2_ENV_CONV_EXCL='*'. See https://www.msys2.org/docs/filesystem-paths/ for details." + ) selftest(logger) def _setup_implied_logging(self, args): diff --git a/src/borg/platformflags.py b/src/borg/platformflags.py index 9abf7d0652..cc84f7c7ac 100644 --- a/src/borg/platformflags.py +++ b/src/borg/platformflags.py @@ -4,6 +4,7 @@ Use these flags instead of sys.platform.startswith('') or try/except. """ +import os import sys is_win32 = sys.platform.startswith("win32") @@ -15,3 +16,6 @@ is_openbsd = sys.platform.startswith("openbsd") is_darwin = sys.platform.startswith("darwin") is_haiku = sys.platform.startswith("haiku") + +# MSYS2 (on Windows) +is_msystem = is_win32 and "MSYSTEM" in os.environ