Remote parser truncates project paths ending in "git" when the remote has no .git suffix
Checklist
- I'm using the latest version of the extension (see the latest version in the right column of this page)
- Extension version:
mainat 2fb019cf, reproduced with the unit tests of the remote parser
- Extension version:
- I'm using the latest VS Code version (find the latest version here)
- VS Code version: not involved as far as I can tell, since
parseGitLabRemoteonly parses the remote URL string. I reproduced this with the unit tests, not in a running VS Code
- VS Code version: not involved as far as I can tell, since
- I'm using a supported version of GitLab (see README for the supported version)
- GitLab version: happens on
gitlab.com; the path is cut before any request is sent
- GitLab version: happens on
Summary
parseGitLabRemote in src/desktop/git/git_remote_parser.ts cuts the last four characters off the project path when the remote URL has no .git suffix and the project path ends in any character followed by "git", such as legit, my-git or my_git. The optional suffix in the regex is written (?:.git)? with an unescaped dot, which matches any character, and the lazy project path group ([^/]+?) lets the suffix group take those four characters. The extension then looks the project up at the truncated path.
Steps to reproduce
-
Add this row to the
it.eachtable ofshould parse %sinsrc/desktop/git/git_remote_parser.test.ts:['https://gitlab.com/group/legit', ['gitlab.com', 'gitlab.com', 'https:', 'group', 'legit']], -
Run
npx jest src/desktop/git/git_remote_parser.test.ts.
The same parse happens for a repository whose remote is, for example, https://gitlab.com/group/legit or git@gitlab.com:group/subgroup/my_git (no .git at the end): detectProjects in src/desktop/gitlab/gitlab_project_repository.ts and the account preselection in src/desktop/accounts/account_preselection_service.ts look the project up with the parsed namespaceWithPath.
What is the current bug behavior?
https://gitlab.com/group/legit parses as namespace group and project path l (group/l). https://gitlab.com/group/my-git and https://gitlab.com/group/my-git/ parse as group/my, and git@gitlab.com:group/subgroup/my_git as group/subgroup/my. The project lookup then finds nothing, so the repository is left without a GitLab project, or it finds a different project if one exists at the truncated path.
What is the expected correct behavior?
The full project path is kept: group/legit, group/my-git and group/subgroup/my_git. Only a literal .git suffix is removed, as it already is for https://gitlab.com/group/my-git.git.
Relevant logs and/or screenshots
With the row above, rows for the other three remotes and a row for https://gitlab.com/group/my-git.git (which passes), on main at 2fb019cf, jest reports for https://gitlab.com/group/legit:
- Expected - 2
+ Received + 2
Object {
"host": "gitlab.com",
"hostname": "gitlab.com",
"namespace": "group",
- "namespaceWithPath": "group/legit",
- "projectPath": "legit",
+ "namespaceWithPath": "group/l",
+ "projectPath": "l",
"protocol": "https:",
}The other three fail the same way (my, my, my instead of my-git, my-git, my_git), and the file ends with Tests: 4 failed, 30 passed, 34 total.
Possible fixes
Escape the dot at src/desktop/git/git_remote_parser.ts#L105: (?:\\.git)? inside the template literal, so that the regex reads (?:\.git)?. I am opening a merge request with this change and the test rows.
The language server has its own copy of this parser with the same pattern, at packages/core/repositories/src/git/utils/git_remote_parser.ts#L150, so it derives the same truncated path for the features it serves. It is reported in gitlab-org/editor-extensions/gitlab-lsp#3365 (closed), and gitlab-org/editor-extensions/gitlab-lsp!4523 (merged) makes the same change there.