Detect wider variety of usernames for SSH-based remotes (#21508)

Closes #21507

Release Notes:

- Fixed detection of git remotes when using SSH and username is not
"git".
This commit is contained in:
Nick Breaton 2024-12-05 18:23:37 -05:00 committed by GitHub
parent 28650b2fac
commit aff17322f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 2 deletions

1
Cargo.lock generated
View file

@ -5131,6 +5131,7 @@ dependencies = [
"log", "log",
"parking_lot", "parking_lot",
"pretty_assertions", "pretty_assertions",
"regex",
"rope", "rope",
"serde", "serde",
"serde_json", "serde_json",

View file

@ -21,6 +21,7 @@ gpui.workspace = true
http_client.workspace = true http_client.workspace = true
log.workspace = true log.workspace = true
parking_lot.workspace = true parking_lot.workspace = true
regex.workspace = true
rope.workspace = true rope.workspace = true
serde.workspace = true serde.workspace = true
smol.workspace = true smol.workspace = true

View file

@ -1,17 +1,23 @@
use std::sync::LazyLock;
use derive_more::Deref; use derive_more::Deref;
use regex::Regex;
use url::Url; use url::Url;
/// The URL to a Git remote. /// The URL to a Git remote.
#[derive(Debug, PartialEq, Eq, Clone, Deref)] #[derive(Debug, PartialEq, Eq, Clone, Deref)]
pub struct RemoteUrl(Url); pub struct RemoteUrl(Url);
static USERNAME_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"^[0-9a-zA-Z\-_]+@").expect("Failed to create USERNAME_REGEX"));
impl std::str::FromStr for RemoteUrl { impl std::str::FromStr for RemoteUrl {
type Err = url::ParseError; type Err = url::ParseError;
fn from_str(input: &str) -> Result<Self, Self::Err> { fn from_str(input: &str) -> Result<Self, Self::Err> {
if input.starts_with("git@") { if USERNAME_REGEX.is_match(input) {
// Rewrite remote URLs like `git@github.com:user/repo.git` to `ssh://git@github.com/user/repo.git` // Rewrite remote URLs like `git@github.com:user/repo.git` to `ssh://git@github.com/user/repo.git`
let ssh_url = input.replacen(':', "/", 1).replace("git@", "ssh://git@"); let ssh_url = format!("ssh://{}", input.replacen(':', "/", 1));
Ok(RemoteUrl(Url::parse(&ssh_url)?)) Ok(RemoteUrl(Url::parse(&ssh_url)?))
} else { } else {
Ok(RemoteUrl(Url::parse(input)?)) Ok(RemoteUrl(Url::parse(input)?))
@ -40,6 +46,12 @@ mod tests {
"github.com", "github.com",
"/octocat/zed.git", "/octocat/zed.git",
), ),
(
"org-000000@github.com:octocat/zed.git",
"ssh",
"github.com",
"/octocat/zed.git",
),
( (
"ssh://git@github.com/octocat/zed.git", "ssh://git@github.com/octocat/zed.git",
"ssh", "ssh",