* Normalize a repo URL so git clone receives a valid remote. * Expands "owner/repo" shorthand to either SSH or HTTPS based on likely local credentials. * All other inputs (HTTPS URLs, SSH URLs, SCP-style, etc.) pass through unchanged.
(repoUrl: string)
| 207 | * All other inputs (HTTPS URLs, SSH URLs, SCP-style, etc.) pass through unchanged. |
| 208 | */ |
| 209 | function normalizeRepoUrlForClone(repoUrl: string): string { |
| 210 | const trimmedRepoUrl = repoUrl.trim(); |
| 211 | const shorthandCandidate = trimmedRepoUrl.replace(/[\\/]+$/, ""); |
| 212 | |
| 213 | // owner/repo shorthand: exactly two non-empty segments separated by a single slash, |
| 214 | // where the first segment looks like a GitHub username (letters, digits, hyphens). |
| 215 | // Excludes local paths like ../repo, ./foo, foo/bar/baz, and absolute paths. |
| 216 | // Note: bare `foo/bar` style local relative paths are intentionally treated as GitHub |
| 217 | // shorthand here because this function is only called from the Clone dialog, which is |
| 218 | // specifically for remote repos. Users cloning local repos should use the "Local folder" tab. |
| 219 | if (GITHUB_SHORTHAND_PATTERN.test(shorthandCandidate)) { |
| 220 | // Strip existing .git suffix before appending to avoid double .git (e.g. owner/repo.git → owner/repo.git.git) |
| 221 | const withoutGitSuffix = shorthandCandidate.replace(/\.git$/i, ""); |
| 222 | |
| 223 | // Prefer SSH for shorthand only when the current session has an active SSH agent. |
| 224 | // This avoids assuming GitHub access from unrelated key files on disk. |
| 225 | if (hasLikelySshCredentials()) { |
| 226 | return `git@github.com:${withoutGitSuffix}.git`; |
| 227 | } |
| 228 | |
| 229 | return `https://github.com/${withoutGitSuffix}.git`; |
| 230 | } |
| 231 | |
| 232 | // Strip query strings and fragments only from URL-like inputs (protocol:// or git@), |
| 233 | // not from local paths where # and ? may be valid filename characters. |
| 234 | if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(trimmedRepoUrl) || trimmedRepoUrl.startsWith("git@")) { |
| 235 | return trimmedRepoUrl.replace(/[?#].*$/, ""); |
| 236 | } |
| 237 | |
| 238 | return trimmedRepoUrl; |
| 239 | } |
| 240 | |
| 241 | function parseScpStyleSshUrl(url: string): { host: string } | undefined { |
| 242 | const trimmedUrl = url.trim(); |
no test coverage detected