Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed
- 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)

## [4.10.30] - 2026-02-12

### Added
Expand Down
20 changes: 20 additions & 0 deletions packages/backend/src/repoCompileUtils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,26 @@ describe('compileGenericGitHostConfig_file', () => {
expect(result.warnings[0]).toContain('/path/to/invalid/repo');
expect(result.warnings[0]).toContain('not a git repository');
});

test('should decode URL-encoded characters in origin url pathname', async () => {
mockedGlob.mockResolvedValue(['/path/to/repo-with-spaces']);
mockedIsPathAValidGitRepoRoot.mockResolvedValue(true);
// URL with %20 (encoded space) in the pathname
mockedGetOriginUrl.mockResolvedValue('https://github.com/test/Project%20Name%20With%20Spaces.git');

const config = {
type: 'git' as const,
url: 'file:///path/to/repo-with-spaces',
};

const result = await compileGenericGitHostConfig_file(config, 1);

expect(result.repoData).toHaveLength(1);
expect(result.warnings).toHaveLength(0);
// The repo name should have decoded spaces, not %20
expect(result.repoData[0].name).toBe('github.com/test/Project Name With Spaces');
expect(result.repoData[0].displayName).toBe('github.com/test/Project Name With Spaces');
});
});

describe('compileGenericGitHostConfig_url', () => {
Expand Down
4 changes: 3 additions & 1 deletion packages/backend/src/repoCompileUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,9 @@ export const compileGenericGitHostConfig_file = async (
// 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$/, ''));
// Decode URL-encoded characters (e.g., %20 -> space) to ensure consistent repo names
const decodedPathname = decodeURIComponent(remoteUrl.pathname);
const repoName = path.join(hostWithPort, decodedPathname.replace(/\.git$/, ''));

const repo: RepoData = {
external_codeHostType: 'genericGitHost',
Expand Down