Fix path handling regressions on Windows (#48905)
John Tur
created
https://github.com/zed-industries/zed/pull/48891 changed `find_worktree`
to use `PathStyle::strip_prefix`, which exposed this bug.
- [ ] Tests or screenshots needed?
- [X] Code Reviewed
- [X] Manual QA
Release Notes:
- N/A
Change summary
crates/util/src/paths.rs | 12 +++++++++++-
crates/workspace/src/workspace.rs | 3 ++-
2 files changed, 13 insertions(+), 2 deletions(-)
Detailed changes
@@ -428,7 +428,17 @@ impl PathStyle {
.find_map(|sep| parent.strip_suffix(sep))
.unwrap_or(parent);
let child = child.to_str()?;
- let stripped = child.strip_prefix(parent)?;
+
+ // Match behavior of std::path::Path, which is case-insensitive for drive letters (e.g., "C:" == "c:")
+ let stripped = if self.is_windows()
+ && child.as_bytes().get(1) == Some(&b':')
+ && parent.as_bytes().get(1) == Some(&b':')
+ && child.as_bytes()[0].eq_ignore_ascii_case(&parent.as_bytes()[0])
+ {
+ child[2..].strip_prefix(&parent[2..])?
+ } else {
+ child.strip_prefix(parent)?
+ };
if let Some(relative) = self
.separators()
.iter()
@@ -8354,11 +8354,12 @@ pub async fn find_existing_workspace(
let project = workspace.project.read(cx);
let path_style = workspace.path_style(cx);
!abs_paths.iter().any(|path| {
+ let path = util::paths::SanitizedPath::new(path);
project.worktrees(cx).any(|worktree| {
let worktree = worktree.read(cx);
let abs_path = worktree.abs_path();
path_style
- .strip_prefix(path, abs_path.as_ref())
+ .strip_prefix(path.as_ref(), abs_path.as_ref())
.and_then(|rel| worktree.entry_for_path(&rel))
.is_some_and(|e| e.is_dir())
})