authorgravatar for gamer392@yandex.ruAnton Bezdenezhnykh <gamer392@yandex.ru> 2026-09-26 09:14:20+05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-25 23:14:20-05:00
log29a32660d3cb2ade1f13283f889b519f73b24fbd
treecbec1de02a65765ff1bb6799684364620aa2d94c
parentdd8332da57355bccd7e666289267f2c94597debd
signature Signed by PGP key B5690EEEBB952194

fix(git): exclude SSH ports from provider URLs (#12537)


2 files changed, 23 insertions(+), 1 deletions(-)

packages/shared/src/sourceControl.test.ts+17
...@@ -110,6 +110,23 @@ describe("detectSourceControlProviderFromRemoteUrl", () => {...@@ -110,6 +110,23 @@ describe("detectSourceControlProviderFromRemoteUrl", () => {
110 });110 });
111 });111 });
112112
113 it("does not reuse SSH ports for HTTPS provider URLs", () => {
114 expect(
115 detectSourceControlProviderFromRemoteUrl("ssh://git@gitlab.example.test:24/group/repo.git"),
116 ).toEqual({
117 kind: "gitlab",
118 name: "GitLab Self-Hosted",
119 baseUrl: "https://gitlab.example.test",
120 });
121 expect(
122 detectSourceControlProviderFromRemoteUrl("ssh://git@code.example.test:24/team/project.git"),
123 ).toEqual({
124 kind: "unknown",
125 name: "code.example.test",
126 baseUrl: "https://code.example.test",
127 });
128 });
129
113 it("matches self-hosted providers by complete DNS labels", () => {130 it("matches self-hosted providers by complete DNS labels", () => {
114 expect(131 expect(
115 detectSourceControlProviderFromRemoteUrl("https://github.example.com/owner/repo.git")?.kind,132 detectSourceControlProviderFromRemoteUrl("https://github.example.com/owner/repo.git")?.kind,
packages/shared/src/sourceControl.ts+6-1
...@@ -146,6 +146,10 @@ export function isSshRemoteUrl(remoteUrl: string): boolean {...@@ -146,6 +146,10 @@ export function isSshRemoteUrl(remoteUrl: string): boolean {
146 return SCP_SSH_REMOTE_PATTERN.test(trimmed) || trimmed.toLowerCase().startsWith("ssh://");146 return SCP_SSH_REMOTE_PATTERN.test(trimmed) || trimmed.toLowerCase().startsWith("ssh://");
147}147}
148148
149/**
150 * Extracts the normalized host used for provider detection. SCP-style and SSH remotes return the
151 * hostname only, while other URL schemes retain explicit ports for non-default web endpoints.
152 */
149function parseRemoteHost(remoteUrl: string): string | null {153function parseRemoteHost(remoteUrl: string): string | null {
150 const trimmed = remoteUrl.trim();154 const trimmed = remoteUrl.trim();
151 if (trimmed.length === 0) {155 if (trimmed.length === 0) {
...@@ -158,7 +162,8 @@ function parseRemoteHost(remoteUrl: string): string | null {...@@ -158,7 +162,8 @@ function parseRemoteHost(remoteUrl: string): string | null {
158 }162 }
159163
160 try {164 try {
161 return new URL(trimmed).host.toLowerCase();165 const url = new URL(trimmed);
166 return (url.protocol === "ssh:" ? url.hostname : url.host).toLowerCase();
162 } catch {167 } catch {
163 return null;168 return null;
164 }169 }