MCPcopy
hub / github.com/coder/mux / normalizeRepoUrlForClone

Function normalizeRepoUrlForClone

src/node/services/projectService.ts:209–239  ·  view source on GitHub ↗

* 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)

Source from the content-addressed store, hash-verified

207 * All other inputs (HTTPS URLs, SSH URLs, SCP-style, etc.) pass through unchanged.
208 */
209function 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
241function parseScpStyleSshUrl(url: string): { host: string } | undefined {
242 const trimmedUrl = url.trim();

Callers 1

Calls 2

hasLikelySshCredentialsFunction · 0.85
testMethod · 0.80

Tested by

no test coverage detected