Skip to content

Commit 97f8882

Browse files
authored
Merge pull request #2319 from gavenren/fix/join-path-leading-separators
fix(util): preserve separators before relative path tokens
2 parents cfb222f + f5335a3 commit 97f8882

2 files changed

Lines changed: 27 additions & 5 deletions

File tree

‎git/util.py‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,15 +235,16 @@ def stream_copy(source: SupportsRead[AnyStr], destination: SupportsWrite[AnyStr]
235235

236236
def join_path(a: PathLike, *p: PathLike) -> PathLike:
237237
R"""Join path tokens together similar to osp.join, but always use ``/`` instead of
238-
possibly ``\`` on Windows."""
238+
possibly ``\`` on Windows.
239+
240+
Later tokens are treated as relative, even when they start with ``/``.
241+
"""
239242
path = os.fspath(a)
240243
for b in p:
241-
b = os.fspath(b)
244+
b = os.fspath(b).lstrip("/")
242245
if not b:
243246
continue
244-
if b.startswith("/"):
245-
path += b[1:]
246-
elif path == "" or path.endswith("/"):
247+
if path == "" or path.endswith("/"):
247248
path += b
248249
else:
249250
path += "/" + b

‎test/test_util.py‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
decygpath,
3939
get_user_id,
4040
is_cygwin_git,
41+
join_path,
4142
remove_password_if_present,
4243
rmtree,
4344
)
@@ -46,6 +47,26 @@
4647
from test.lib import TestBase, requires_symlinks, with_rw_repo
4748

4849

50+
@pytest.mark.parametrize(
51+
"parts, expected",
52+
[
53+
(("parent", "/child"), "parent/child"),
54+
(("parent", "/child", "/leaf"), "parent/child/leaf"),
55+
((pathlib.Path("parent"), "/child"), "parent/child"),
56+
(("parent/", "/child"), "parent/child"),
57+
(("parent", "child"), "parent/child"),
58+
(("", "/child"), "child"),
59+
(("/", "/child"), "/child"),
60+
(("parent", "", "child"), "parent/child"),
61+
(("parent", "//child"), "parent/child"),
62+
(("/parent/", "///child"), "/parent/child"),
63+
(("parent", "///"), "parent"),
64+
],
65+
)
66+
def test_join_path_keeps_later_tokens_relative(parts, expected):
67+
assert join_path(*parts) == expected
68+
69+
4970
@pytest.fixture
5071
def tmp_path(request):
5172
# Unreadable files and symlinks cannot be copied by native fixture tooling.

0 commit comments

Comments
 (0)