Skip to content

Commit 78a0322

Browse files
fix(search): Fix issue with filtering on generic git repo indexed from http/https (#742)
* fix: add gitConfig for generic git host repos with URL to fix file access and search For generic git host repos with HTTP/HTTPS URLs, the gitConfig metadata was missing. This caused issues because: 1. After cloning, remote.origin.url is unset for security reasons 2. Zoekt uses gitConfig (specifically zoekt.name) to identify repos 3. Without gitConfig, zoekt couldn't properly identify the repo name This fix adds proper gitConfig metadata (zoekt.name, zoekt.web-url, etc.) to compileGenericGitHostConfig_url, similar to how other code hosts handle it. Fixes SOU-218 Co-authored-by: michael <michael@sourcebot.dev> * changelog --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent 8656d26 commit 78a0322

3 files changed

Lines changed: 84 additions & 3 deletions

File tree

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 with filtering on generic git repo indexed from http/https [#742](https://github.com/sourcebot-dev/sourcebot/pull/742)
12+
1013
## [4.10.10] - 2026-01-16
1114

1215
### Added

packages/backend/src/repoCompileUtils.test.ts

Lines changed: 72 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
import { expect, test, vi, describe, beforeEach, afterEach } from 'vitest';
2-
import { compileGenericGitHostConfig_file } from './repoCompileUtils';
2+
import { compileGenericGitHostConfig_file, compileGenericGitHostConfig_url } from './repoCompileUtils';
33

44
// Mock the git module
55
vi.mock('./git.js', () => ({
66
isPathAValidGitRepoRoot: vi.fn(),
77
getOriginUrl: vi.fn(),
8+
isUrlAValidGitRepo: vi.fn(),
89
}));
910

1011
// Mock the glob module
1112
vi.mock('glob', () => ({
1213
glob: vi.fn(),
1314
}));
1415

15-
import { isPathAValidGitRepoRoot, getOriginUrl } from './git.js';
16+
import { isPathAValidGitRepoRoot, getOriginUrl, isUrlAValidGitRepo } from './git.js';
1617
import { glob } from 'glob';
1718

1819
const mockedGlob = vi.mocked(glob);
1920
const mockedIsPathAValidGitRepoRoot = vi.mocked(isPathAValidGitRepoRoot);
2021
const mockedGetOriginUrl = vi.mocked(getOriginUrl);
22+
const mockedIsUrlAValidGitRepo = vi.mocked(isUrlAValidGitRepo);
2123

2224
describe('compileGenericGitHostConfig_file', () => {
2325
beforeEach(() => {
@@ -122,3 +124,71 @@ describe('compileGenericGitHostConfig_file', () => {
122124
expect(result.warnings[0]).toContain('not a git repository');
123125
});
124126
});
127+
128+
describe('compileGenericGitHostConfig_url', () => {
129+
beforeEach(() => {
130+
vi.clearAllMocks();
131+
});
132+
133+
afterEach(() => {
134+
vi.resetAllMocks();
135+
});
136+
137+
test('should return warning when url is not a valid git repo', async () => {
138+
mockedIsUrlAValidGitRepo.mockResolvedValue(false);
139+
140+
const config = {
141+
type: 'git' as const,
142+
url: 'https://example.com/not-a-repo',
143+
};
144+
145+
const result = await compileGenericGitHostConfig_url(config, 1);
146+
147+
expect(result.repoData).toHaveLength(0);
148+
expect(result.warnings).toHaveLength(1);
149+
expect(result.warnings[0]).toContain('not a git repository');
150+
});
151+
152+
test('should successfully compile with gitConfig when valid git repo url is found', async () => {
153+
mockedIsUrlAValidGitRepo.mockResolvedValue(true);
154+
155+
const config = {
156+
type: 'git' as const,
157+
url: 'https://git.kernel.org/pub/scm/bluetooth/bluez.git',
158+
};
159+
160+
const result = await compileGenericGitHostConfig_url(config, 1);
161+
162+
expect(result.repoData).toHaveLength(1);
163+
expect(result.warnings).toHaveLength(0);
164+
expect(result.repoData[0].cloneUrl).toBe('https://git.kernel.org/pub/scm/bluetooth/bluez.git');
165+
expect(result.repoData[0].name).toBe('git.kernel.org/pub/scm/bluetooth/bluez');
166+
167+
// Verify gitConfig is set properly (this is the key fix for SOU-218)
168+
const metadata = result.repoData[0].metadata as { gitConfig?: Record<string, string> };
169+
expect(metadata.gitConfig).toBeDefined();
170+
expect(metadata.gitConfig!['zoekt.name']).toBe('git.kernel.org/pub/scm/bluetooth/bluez');
171+
expect(metadata.gitConfig!['zoekt.web-url']).toBe('https://git.kernel.org/pub/scm/bluetooth/bluez.git');
172+
expect(metadata.gitConfig!['zoekt.display-name']).toBe('git.kernel.org/pub/scm/bluetooth/bluez');
173+
expect(metadata.gitConfig!['zoekt.archived']).toBe('0');
174+
expect(metadata.gitConfig!['zoekt.fork']).toBe('0');
175+
expect(metadata.gitConfig!['zoekt.public']).toBe('1');
176+
});
177+
178+
test('should handle url with trailing .git correctly', async () => {
179+
mockedIsUrlAValidGitRepo.mockResolvedValue(true);
180+
181+
const config = {
182+
type: 'git' as const,
183+
url: 'https://github.com/test/repo.git',
184+
};
185+
186+
const result = await compileGenericGitHostConfig_url(config, 1);
187+
188+
expect(result.repoData).toHaveLength(1);
189+
expect(result.repoData[0].name).toBe('github.com/test/repo');
190+
191+
const metadata = result.repoData[0].metadata as { gitConfig?: Record<string, string> };
192+
expect(metadata.gitConfig!['zoekt.name']).toBe('github.com/test/repo');
193+
});
194+
});

packages/backend/src/repoCompileUtils.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,9 +609,17 @@ export const compileGenericGitHostConfig_url = async (
609609
}
610610
},
611611
metadata: {
612+
gitConfig: {
613+
'zoekt.name': repoName,
614+
'zoekt.web-url': remoteUrl.toString(),
615+
'zoekt.archived': marshalBool(false),
616+
'zoekt.fork': marshalBool(false),
617+
'zoekt.public': marshalBool(true),
618+
'zoekt.display-name': repoName,
619+
},
612620
branches: config.revisions?.branches ?? undefined,
613621
tags: config.revisions?.tags ?? undefined,
614-
}
622+
} satisfies RepoMetadata,
615623
};
616624

617625
return {

0 commit comments

Comments
 (0)