Skip to content

Commit 46487ae

Browse files
authored
Fix #23646: relpath recognizes Windows drive letters (#38259)
1 parent 0e15141 commit 46487ae

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

base/path.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,15 +495,23 @@ contractuser(path::AbstractString)
495495
Return a relative filepath to `path` either from the current directory or from an optional
496496
start directory. This is a path computation: the filesystem is not accessed to confirm the
497497
existence or nature of `path` or `startpath`.
498+
499+
On Windows, case sensitivity is applied to every part of the path except drive letters. If
500+
`path` and `startpath` refer to different drives, the absolute path of `path` is returned.
498501
"""
499502
function relpath(path::String, startpath::String = ".")
500503
isempty(path) && throw(ArgumentError("`path` must be specified"))
501504
isempty(startpath) && throw(ArgumentError("`startpath` must be specified"))
502505
curdir = "."
503506
pardir = ".."
504507
path == startpath && return curdir
505-
path_arr = split(abspath(path), path_separator_re)
506-
start_arr = split(abspath(startpath), path_separator_re)
508+
path_drive, path_without_drive = splitdrive(path)
509+
startpath_drive, startpath_without_drive = splitdrive(startpath)
510+
path_arr = split(abspath(path_without_drive), path_separator_re)
511+
start_arr = split(abspath(startpath_without_drive), path_separator_re)
512+
if Sys.iswindows()
513+
lowercase(path_drive) != lowercase(startpath_drive) && return abspath(path)
514+
end
507515
i = 0
508516
while i < min(length(path_arr), length(start_arr))
509517
i += 1

test/path.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,12 @@
262262
res = relpath(filep, startp)
263263
idx += 1
264264
@test res == relpath_expected_results[idx]
265+
if Sys.iswindows()
266+
@test relpath("e:$filep", "e:$startp") == relpath_expected_results[idx]
267+
@test relpath("e:$filep", "E:$startp") == relpath_expected_results[idx]
268+
@test relpath("E:$filep", "e:$startp") == relpath_expected_results[idx]
269+
@test relpath("E:$filep", "E:$startp") == relpath_expected_results[idx]
270+
end
265271
end
266272
end
267273
# Additional cases
@@ -271,6 +277,20 @@
271277
test_relpath()
272278
end
273279

280+
if Sys.iswindows()
281+
@testset "issue #23646" begin
282+
@test lowercase(relpath("E:\\a\\b", "C:\\c")) == "e:\\a\\b"
283+
@test lowercase(relpath("E:\\a\\b", "c:\\c")) == "e:\\a\\b"
284+
@test lowercase(relpath("e:\\a\\b", "C:\\c")) == "e:\\a\\b"
285+
@test lowercase(relpath("e:\\a\\b", "c:\\c")) == "e:\\a\\b"
286+
287+
@test relpath("C:\\a\\b", "c:\\a\\b") == "."
288+
@test relpath("c:\\a\\b", "C:\\a\\b") == "."
289+
@test lowercase(relpath("C:\\a\\b", "c:\\c\\d")) == "..\\..\\a\\b"
290+
@test lowercase(relpath("c:\\a\\b", "C:\\c\\d")) == "..\\..\\a\\b"
291+
end
292+
end
293+
274294
@testset "type stability" begin
275295
@test isa(joinpath(S("a"), S("b")), String)
276296
@test isa(joinpath(S(abspath("a")), S("b")), String)

0 commit comments

Comments
 (0)