Skip to content

Commit 16398ab

Browse files
fix: decode URL-encoded characters in local repo remote URLs
Fixes issue where local repos with URL-encoded spaces (e.g., %20) in their remote.origin.url would fail to load tree preview and not be indexed correctly. The root cause was that GitUrlParse doesn't decode URL-encoded characters, so repo names were stored with %20 instead of spaces, causing lookup failures. Added decodeURIComponent() to decode the pathname before creating repo names, ensuring consistent naming throughout the application. Fixes #898 Co-authored-by: Brendan Kellam <brendan-kellam@users.noreply.github.com>
1 parent 06acea2 commit 16398ab

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
- Fixed issue where local repos with URL-encoded spaces in remote URLs would fail to load tree preview and index correctly. [#898](https://github.com/sourcebot-dev/sourcebot/issues/898)
12+
1013
## [4.10.30] - 2026-02-12
1114

1215
### Added

packages/backend/src/repoCompileUtils.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,26 @@ describe('compileGenericGitHostConfig_file', () => {
143143
expect(result.warnings[0]).toContain('/path/to/invalid/repo');
144144
expect(result.warnings[0]).toContain('not a git repository');
145145
});
146+
147+
test('should decode URL-encoded characters in origin url pathname', async () => {
148+
mockedGlob.mockResolvedValue(['/path/to/repo-with-spaces']);
149+
mockedIsPathAValidGitRepoRoot.mockResolvedValue(true);
150+
// URL with %20 (encoded space) in the pathname
151+
mockedGetOriginUrl.mockResolvedValue('https://github.com/test/Project%20Name%20With%20Spaces.git');
152+
153+
const config = {
154+
type: 'git' as const,
155+
url: 'file:///path/to/repo-with-spaces',
156+
};
157+
158+
const result = await compileGenericGitHostConfig_file(config, 1);
159+
160+
expect(result.repoData).toHaveLength(1);
161+
expect(result.warnings).toHaveLength(0);
162+
// The repo name should have decoded spaces, not %20
163+
expect(result.repoData[0].name).toBe('github.com/test/Project Name With Spaces');
164+
expect(result.repoData[0].displayName).toBe('github.com/test/Project Name With Spaces');
165+
});
146166
});
147167

148168
describe('compileGenericGitHostConfig_url', () => {

packages/backend/src/repoCompileUtils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,9 @@ export const compileGenericGitHostConfig_file = async (
586586
// the host:port directly from the raw URL to match zoekt's behavior.
587587
// For non-HTTP URLs, remoteUrl.host preserves non-default ports (e.g., ssh://host:22/).
588588
const hostWithPort = extractHostWithPort(origin) ?? remoteUrl.host;
589-
const repoName = path.join(hostWithPort, remoteUrl.pathname.replace(/\.git$/, ''));
589+
// Decode URL-encoded characters (e.g., %20 -> space) to ensure consistent repo names
590+
const decodedPathname = decodeURIComponent(remoteUrl.pathname);
591+
const repoName = path.join(hostWithPort, decodedPathname.replace(/\.git$/, ''));
590592

591593
const repo: RepoData = {
592594
external_codeHostType: 'genericGitHost',

0 commit comments

Comments
 (0)