Skip to content

Git - strip host:user prefix when deriving clone folder name#318518

Open
yogeshwaran-c wants to merge 1 commit into
microsoft:mainfrom
yogeshwaran-c:fix/clone-scp-ssh-url
Open

Git - strip host:user prefix when deriving clone folder name#318518
yogeshwaran-c wants to merge 1 commit into
microsoft:mainfrom
yogeshwaran-c:fix/clone-scp-ssh-url

Conversation

@yogeshwaran-c
Copy link
Copy Markdown
Contributor

Fixes #175062

Problem

Cloning an SCP-style SSH URL whose path contains no slash – for example git@versions.somedomain.net:climate-project – fails on Windows (and is awkward on macOS/Linux) because the derived clone folder name keeps the user@host: prefix verbatim:

git clone git@versions.somedomain.net:climate-project c:\Users\kit\New folder\git@versions.somedomain.net:climate-project --progress
fatal: could not create work tree dir 'c:\…\git@versions.somedomain.net:climate-project': Invalid argument

The literal : is reserved in Windows paths, and the git@host.example: prefix is meaningless inside a target directory name on any platform.

Cause

Git.clone in extensions/git/src/git.ts derives baseFolderName from the URL with:

decodeURI(url).replace(/[\/]+$/, '').replace(/^.*[\/\]/, '').replace(/\.git$/, '')

For git@host.example:repo there is no / (or \) at all, so the second replace leaves the string unchanged and the SCP [user@]host: prefix survives into the folder name.

Fix

Strip everything up to the last : as an additional step (after the slash-strip):

decodeURI(url)
    .replace(/[\/]+$/, '')
    .replace(/^.*[\/\]/, '')
    .replace(/^.*:/, '')        // NEW
    .replace(/\.git$/, '') || 'repository'

For every URL shape that previously worked, the slash-strip has already collapsed the value to the final path segment (which contains no :), so the new step is a no-op. Only SCP-style URLs without a slash in the path – the broken case – are affected.

The derivation is extracted into an exported getCloneTargetFolderName(url) helper alongside the other parsers in git.ts, and 12 unit tests are added in git.test.ts covering https, ssh://, git://, SCP-style with and without a path slash, Windows-style backslash paths, trailing slashes, and the fallback to 'repository'.

Out of scope

Full SCP-vs-URL parsing (port handling, scheme-aware logic, git-url-parse-style dependencies) is intentionally not introduced – the goal is to repair the one well-defined broken shape without changing behavior for any already-working URL.

Clone targets derived from SCP-style SSH URLs (`[user@]host:path`)
where the path contains no slash – e.g. `git@host.example:repo` –
previously kept the full `user@host.example:repo` string as the
folder name. The literal `:` is invalid in a Windows path, so
`git clone` fails with `could not create work tree dir`.

Strip everything up to the last `:` (after the existing slash-strip)
so the folder name becomes `repo`. For all standard URL shapes
the behavior is unchanged because the slash-strip already collapses
the URL to its final path segment which has no colon.

The folder-name derivation is extracted into the exported
`getCloneTargetFolderName` helper and covered by unit tests.

Fixes microsoft#175062
Copilot AI review requested due to automatic review settings May 27, 2026 06:37
@vs-code-engineering
Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

@lszomoru

Matched files:

  • extensions/git/src/git.ts
  • extensions/git/src/test/git.test.ts

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR extracts clone-target folder name derivation into a dedicated helper and adds tests to cover multiple remote URL formats, including SCP-style SSH URLs from issue #175062.

Changes:

  • Introduced getCloneTargetFolderName(url) and used it in Git.clone(...) instead of inline string manipulation.
  • Added unit tests covering common Git remote URL shapes and empty/unparseable inputs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
extensions/git/src/git.ts Adds getCloneTargetFolderName and uses it in clone() to derive the target folder name more robustly (esp. SCP-style URLs).
extensions/git/src/test/git.test.ts Adds test coverage for getCloneTargetFolderName across https/ssh/git/SCP-style/Windows-path inputs and fallback behavior.

Comment thread extensions/git/src/git.ts
*/
export function getCloneTargetFolderName(url: string): string {
return decodeURI(url)
.replace(/[\/]+$/, '')
Comment thread extensions/git/src/git.ts
Comment on lines +1046 to +1050
return decodeURI(url)
.replace(/[\/]+$/, '')
.replace(/^.*[\/\\]/, '')
.replace(/^.*:/, '')
.replace(/\.git$/, '') || 'repository';
test('Windows file path with backslashes', () => {
assert.strictEqual(getCloneTargetFolderName('C:\\Users\\me\\repo.git'), 'repo');
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Git - Clone of ssh-style URL fails b/c path does not strip username/hostname components

3 participants