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