From 790b73e2fb79f75bcebc0ca69845660a75992b9d Mon Sep 17 00:00:00 2001 From: Ibrahim Khan <2005ibrahimkhan@gmail.com> Date: Thu, 18 Jun 2026 05:52:51 -0700 Subject: [PATCH] git: Detect SCP remotes with non-standard SSH usernames (#59457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective The scp-style remote rewrite only treats a leading `user@` as SSH when the username matches `^[0-9a-zA-Z\-_]+@`. Remotes like `first.last@host:owner/repo.git` (common on self-hosted instances that authenticate as the developer) therefore fail to parse, so no hosting provider matches and Copy Permalink, git blame links, and Open in browser silently break. Extends #21508, which added `org-000000@`. ## Solution Match the scp username by exclusion (`^[^/@:]+@`): anything before the `@` that isn't the `:`/`/` delimiting host and path, mirroring git's scp syntax. The pattern stays anchored, so `scheme://user@host` URLs aren't misclassified, and it's a strict superset of the old one, so existing remotes are unaffected. ## Testing `cargo test -p git` passes, including two new `test_parsing_valid_remote_urls` cases — a dotted-username scp remote (the fix) and a `https://user@host` regression guard. `cargo fmt` and `cargo clippy -p git` are clean. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed detection of SSH git remotes whose username contains characters such as `.` (e.g. `first.last@host:owner/repo.git`), which previously broke permalinks, git blame links, and "open in browser". --------- Co-authored-by: dino --- crates/git/src/remote.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/crates/git/src/remote.rs b/crates/git/src/remote.rs index 8fb4483984..d64958503e 100644 --- a/crates/git/src/remote.rs +++ b/crates/git/src/remote.rs @@ -9,8 +9,12 @@ use url::Url; #[derive(Debug, PartialEq, Eq, Clone, Deref)] pub struct RemoteUrl(Url); +// Detect the `user@` prefix of an SCP-like remote (e.g. `git@host:path`). The +// username may contain anything but the `@`/`:`/`/` that delimit the user, +// host, and path, so match by exclusion rather than an allowlist that misses +// names like `first.last`. static USERNAME_REGEX: LazyLock = - LazyLock::new(|| Regex::new(r"^[0-9a-zA-Z\-_]+@").expect("Failed to create USERNAME_REGEX")); + LazyLock::new(|| Regex::new(r"^[^/@:]+@").expect("Failed to create USERNAME_REGEX")); impl FromStr for RemoteUrl { type Err = url::ParseError; @@ -41,6 +45,12 @@ mod tests { "github.com", "/octocat/zed.git", ), + ( + "https://jlannister@github.com/octocat/zed.git", + "https", + "github.com", + "/octocat/zed.git", + ), ( "git@github.com:octocat/zed.git", "ssh", @@ -53,6 +63,12 @@ mod tests { "github.com", "/octocat/zed.git", ), + ( + "first.last@gitlab.example.com:group/repo.git", + "ssh", + "gitlab.example.com", + "/group/repo.git", + ), ( "ssh://git@github.com/octocat/zed.git", "ssh",