diff --git a/CHANGELOG.md b/CHANGELOG.md index 76dcd736d..48424f725 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bumped AI SDK and associated packages version. [#752](https://github.com/sourcebot-dev/sourcebot/pull/752) - Bumped Node.js version to v24. [#753](https://github.com/sourcebot-dev/sourcebot/pull/753) -### Fixed +### Fixes +- Fix autocomplete when repo includes default port [#762](https://github.com/sourcebot-dev/sourcebot/pull/762) - Fixed "Repository not found for file: x" error when searching in orphaned shards. [#761](https://github.com/sourcebot-dev/sourcebot/pull/761) ## [4.10.12] - 2026-01-16 diff --git a/packages/backend/src/repoCompileUtils.test.ts b/packages/backend/src/repoCompileUtils.test.ts index 3c80fc62f..89fb61719 100644 --- a/packages/backend/src/repoCompileUtils.test.ts +++ b/packages/backend/src/repoCompileUtils.test.ts @@ -99,6 +99,25 @@ describe('compileGenericGitHostConfig_file', () => { expect(result.repoData[0].name).toBe('github.com/test/repo'); }); + test('should include port in repo name when origin url has a port', async () => { + mockedGlob.mockResolvedValue(['/path/to/valid/repo']); + mockedIsPathAValidGitRepoRoot.mockResolvedValue(true); + mockedGetOriginUrl.mockResolvedValue('https://git.kernel.org:443/pub/scm/bluetooth/bluez.git'); + + const config = { + type: 'git' as const, + url: 'file:///path/to/valid/repo', + }; + + const result = await compileGenericGitHostConfig_file(config, 1); + + expect(result.repoData).toHaveLength(1); + expect(result.warnings).toHaveLength(0); + expect(result.repoData[0].cloneUrl).toBe('file:///path/to/valid/repo'); + // The name should include the port to match what zoekt derives from the origin URL + expect(result.repoData[0].name).toBe('git.kernel.org:443/pub/scm/bluetooth/bluez'); + }); + test('should return warnings for invalid repos and success for valid ones', async () => { mockedGlob.mockResolvedValue(['/path/to/valid/repo', '/path/to/invalid/repo']); mockedIsPathAValidGitRepoRoot.mockImplementation(async ({ path }) => { diff --git a/packages/backend/src/repoCompileUtils.ts b/packages/backend/src/repoCompileUtils.ts index 678ef6ea8..148118338 100644 --- a/packages/backend/src/repoCompileUtils.ts +++ b/packages/backend/src/repoCompileUtils.ts @@ -31,6 +31,23 @@ const logger = createLogger('repo-compile-utils'); const MAX_CONCURRENT_GIT_OPERATIONS = 100; const gitOperationLimit = pLimit(MAX_CONCURRENT_GIT_OPERATIONS); +/** + * Extracts the host with port from an HTTP(S) URL string, preserving the port + * even if it's a default port (e.g., 443 for https, 80 for http). + * + * This is needed because JavaScript URL parsers normalize URLs and strip default + * ports, but Go's url.Parse preserves them. Since zoekt uses Go, we need to match + * its behavior for repo name derivation. + * + * @param url - The URL string to extract host:port from + * @returns The host with port if present (e.g., "example.com:443"), or null if not an HTTP(S) URL + */ +const extractHostWithPort = (url: string): string | null => { + // Match http(s):// URLs: protocol://host(:port)/path + const match = url.match(/^https?:\/\/([^/?#]+)/i); + return match ? match[1] : null; +}; + type CompileResult = { repoData: RepoData[], warnings: string[], @@ -515,7 +532,12 @@ export const compileGenericGitHostConfig_file = async ( // @note: matches the naming here: // https://github.com/sourcebot-dev/zoekt/blob/main/gitindex/index.go#L293 - const repoName = path.join(remoteUrl.host, remoteUrl.pathname.replace(/\.git$/, '')); + // Go's url.URL.Host includes the port if present (even default ports like 443), + // but JS URL parsers normalize and strip default ports. We need to extract + // the host:port directly from the raw URL to match zoekt's behavior. + // For non-HTTP URLs, remoteUrl.host preserves non-default ports (e.g., ssh://host:22/). + const hostWithPort = extractHostWithPort(origin) ?? remoteUrl.host; + const repoName = path.join(hostWithPort, remoteUrl.pathname.replace(/\.git$/, '')); const repo: RepoData = { external_codeHostType: 'genericGitHost',