Skip to content

Commit 3bf12a3

Browse files
committed
Fix absolute windows file urls with extra slash
For more context see d6f90be. We however no longer implement the backslash to forward slash conversion. There is no good reason for why Git does that conversion and we do not need it to stay compatible (Git can handle both versions just fine). Additionally, the logic for the conversion was very involved and to implement it proper we would need to detect the shell we are executing in (Git performs the conversion only in bash, not in cmd/ps).
1 parent 637e1ae commit 3bf12a3

File tree

2 files changed

+25
-24
lines changed

2 files changed

+25
-24
lines changed

gix-url/src/parse/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,14 @@ fn parse_file_url(input: &BStr, protocol_colon: usize) -> Result<crate::Url, Err
183183

184184
// TODO: implement UNC path special case
185185
let windows_special_path = if cfg!(windows) {
186+
// Inputs created via url::Url::from_file_path contain an additional `/` between the
187+
// protocol and the absolute path. Make sure we ignore that first slash character to avoid
188+
// producing invalid paths.
189+
let input_after_protocol = if first_slash == 0 {
190+
&input_after_protocol[1..]
191+
} else {
192+
input_after_protocol
193+
};
186194
// parse `file://x:/path/to/git` as explained above
187195
if input_after_protocol.chars().nth(1) == Some(':') {
188196
Some(input_after_protocol)
@@ -226,7 +234,7 @@ fn parse_local(input: &BStr) -> Result<crate::Url, Error> {
226234
user: None,
227235
host: None,
228236
port: None,
229-
path: input.into(),
237+
path: input.to_owned(),
230238
})
231239
}
232240

gix-url/tests/parse/file.rs

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -130,21 +130,6 @@ fn interior_relative_file_path_without_protocol() -> crate::Result {
130130
Ok(())
131131
}
132132

133-
#[test]
134-
#[cfg(unix)]
135-
fn url_from_absolute_path() -> crate::Result {
136-
assert_url(
137-
url::Url::from_directory_path("/users/foo")
138-
.expect("valid")
139-
.to_file_path()
140-
.expect("valid path")
141-
.to_string_lossy()
142-
.as_ref(),
143-
url_alternate(Scheme::File, None, None, None, b"/users/foo/"),
144-
)?;
145-
Ok(())
146-
}
147-
148133
#[test]
149134
fn url_from_relative_path_with_colon_in_name() -> crate::Result {
150135
let url = assert_url(
@@ -173,14 +158,8 @@ mod windows {
173158
url_alternate(Scheme::File, None, None, None, b"C:\\users\\1\\"),
174159
)?;
175160
// A special hack to support URLs on windows that are prefixed with `/` even though absolute.
176-
assert_url(
177-
"file:///c:/users/2",
178-
url(Scheme::File, None, None, None, b"c:\\users\\2"),
179-
)?;
180-
assert_url(
181-
"file:///c:/users/3/",
182-
url(Scheme::File, None, None, None, b"c:\\users\\3\\"),
183-
)?;
161+
assert_url("file:///c:/users/2", url(Scheme::File, None, None, None, b"c:/users/2"))?;
162+
assert_url("file:///c:/users/3", url(Scheme::File, None, None, None, b"c:/users/3"))?;
184163
Ok(())
185164
}
186165

@@ -220,6 +199,20 @@ mod unix {
220199
use crate::parse::{assert_url, assert_url_roundtrip, url, url_alternate};
221200
use gix_url::Scheme;
222201

202+
#[test]
203+
fn url_from_absolute_path() -> crate::Result {
204+
assert_url(
205+
url::Url::from_directory_path("/users/foo")
206+
.expect("valid")
207+
.to_file_path()
208+
.expect("valid path")
209+
.to_string_lossy()
210+
.as_ref(),
211+
url_alternate(Scheme::File, None, None, None, b"/users/foo/"),
212+
)?;
213+
Ok(())
214+
}
215+
223216
#[test]
224217
fn file_path_without_protocol() -> crate::Result {
225218
let url = assert_url(

0 commit comments

Comments
 (0)