From 8e3e6b8129adec7c752a14a55f63e7626c6e323a Mon Sep 17 00:00:00 2001 From: John Tur Date: Tue, 10 Feb 2026 22:23:13 -0500 Subject: [PATCH] Fix path handling regressions on Windows (#48905) 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 --- crates/util/src/paths.rs | 12 +++++++++++- crates/workspace/src/workspace.rs | 3 ++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/util/src/paths.rs b/crates/util/src/paths.rs index f010ff57c636f40de50a06baefd99c9ee43728f9..f96e37b348ddf487821f69ba00fea1f1c838d4c8 100644 --- a/crates/util/src/paths.rs +++ b/crates/util/src/paths.rs @@ -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() diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 1c42d4250d94ea5e728055a6035010df039b00e2..019329a8a8b932b6f1dddd056322acfad6932f6a 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -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()) })