… on Windows
On Windows, os.path.relpath raises ValueError when the path and the
current working directory are on different drives (e.g. config on C:\
but the git repository root is on D:\). _adjust_args_and_chdir called
os.path.relpath unconditionally after chdir-ing to the git root, so
running pre-commit with --config pointing to a different drive crashed
with a ValueError instead of falling back gracefully.
Add a _relpath() helper that catches ValueError and returns the original
(absolute) path. Replace all four os.path.relpath() call-sites in
_adjust_args_and_chdir with _relpath() so that cross-drive paths are
kept as absolute paths rather than raising an unhandled exception.
Fixes pre-commit#2530
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fixes #2530.
Problem
On Windows, os.path.relpath raises ValueError when the start path
and the target path are on different drives — for example when
--config points to C:\configs\pre-commit-config.yaml but the git
repository root is on D:\.
_adjust_args_and_chdir calls os.path.relpath unconditionally after
os.chdir(toplevel), so the combination of a cross-drive config (or
--commit-msg-filename / try-repo repo path) and a git repo on a
different drive crashed with an unhandled ValueError instead of
falling back gracefully.
Fix
Add a _relpath() helper that wraps os.path.relpath and catches
ValueError, returning the original path unchanged (keeping it
absolute). All four os.path.relpath call-sites in
_adjust_args_and_chdir are replaced with _relpath().
On same-drive paths the behaviour is identical to before. On
cross-drive paths the absolute path is preserved, which is valid since
absolute paths work regardless of the current directory.
Tests
directly verifies _relpath returns the original path when
os.path.relpath raises ValueError.
normal (non-Windows-cross-drive) code path still works.
All existing main_test.py tests continue to pass (30 passed, 1
skipped on non-Windows).