Skip to content

Commit c396b2d

Browse files
chore(worker): Improve git operation perf (#791)
1 parent ce4ee31 commit c396b2d

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1212
- Added endpoint for searching commit history for a git repository. [#625](https://github.com/sourcebot-dev/sourcebot/pull/625)
1313
- Added `pushedAt` field to the Repo table to track when a repository last was committed to across all branches. [#790](https://github.com/sourcebot-dev/sourcebot/pull/790)
1414

15+
### Changed
16+
- Added commit graph generation to improve performance for commit traversal operations. [#791](https://github.com/sourcebot-dev/sourcebot/pull/791)
17+
1518
## [4.10.17] - 2026-01-23
1619

1720
### Fixed

docs/docs/connections/local-repos.mdx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ To get Sourcebot to index these repositories:
5555

5656
## Examples
5757

58-
5958
<AccordionGroup>
6059
<Accordion title="Sync individual repo">
6160
```json
@@ -76,6 +75,22 @@ To get Sourcebot to index these repositories:
7675
</Accordion>
7776
</AccordionGroup>
7877

78+
## Optimizing git operations
79+
80+
Sourcebot performs a number of operations that require traversing a repository's entire commit history (e.g., `git rev-list --count HEAD`). These operations can be slow in repositories with a large number of commits.
81+
82+
Typically, a [commit graph](https://git-scm.com/docs/commit-graph) is generated to speed up these operations (see [#791](https://github.com/sourcebot-dev/sourcebot/pull/791)). However, since local repositories are treated as read-only, Sourcebot **will not** generate a commit graph for them.
83+
84+
A commit graph can be manually generated by running the following command in the repository's root directory:
85+
```sh
86+
git commit-graph write --reachable
87+
```
88+
89+
The commit graph can be updated when fetching with `--write-commit-graph`:
90+
```sh
91+
git fetch --write-commit-graph
92+
```
93+
7994
## Schema reference
8095

8196
<Accordion title="Reference">

packages/backend/src/git.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ export const cloneRepository = async (
8282
keys: ["remote.origin.url"],
8383
signal,
8484
});
85+
86+
// @note: operations that need to iterate over a lot of commits (e.g., rev-list --count)
87+
// can be slow on larger repositories. Commit graphs are a acceleration structure that
88+
// speed up these operations.
89+
// @see: https://git-scm.com/docs/commit-graph
90+
await writeCommitGraph({ path, signal });
8591
} catch (error: unknown) {
8692
const baseLog = `Failed to clone repository: ${path}`;
8793

@@ -121,7 +127,10 @@ export const fetchRepository = async (
121127
cloneUrl,
122128
"+refs/heads/*:refs/heads/*",
123129
"--prune",
124-
"--progress"
130+
"--progress",
131+
// On fetch, ensure the commit graph is up to date.
132+
// @see: https://git-scm.com/docs/commit-graph
133+
"--write-commit-graph"
125134
]);
126135

127136
// Update HEAD to match the remote's default branch. This handles the case where the remote's
@@ -405,3 +414,27 @@ export const getLatestCommitTimestamp = async ({
405414
return undefined;
406415
}
407416
}
417+
418+
/**
419+
* Writes or updates the commit-graph file for the repository.
420+
* This pre-computes commit metadata to speed up operations like
421+
* rev-list --count, log, and merge-base.
422+
*/
423+
export const writeCommitGraph = async ({
424+
path,
425+
onProgress,
426+
signal,
427+
}: {
428+
path: string,
429+
onProgress?: onProgressFn,
430+
signal?: AbortSignal,
431+
}): Promise<void> => {
432+
const git = createGitClientForPath(path, onProgress, signal);
433+
434+
try {
435+
await git.raw(['commit-graph', 'write', '--reachable']);
436+
} catch (error) {
437+
// Don't throw an exception here since this is just a performance optimization.
438+
logger.debug(`Failed to write commit-graph for ${path}:`, error);
439+
}
440+
}

0 commit comments

Comments
 (0)