diff --git a/http-client/lib/repo.ts b/http-client/lib/repo.ts index e349fe1cc..217d9097d 100644 --- a/http-client/lib/repo.ts +++ b/http-client/lib/repo.ts @@ -1,4 +1,6 @@ import type { Fetcher, RequestOptions } from "./fetcher.js"; + +import { ResponseError } from "./fetcher.js"; import type { Commit, Commits } from "./repo/commit.js"; import type { Issue } from "./repo/issue.js"; import type { Patch } from "./repo/patch.js"; @@ -136,6 +138,8 @@ const treeStatsSchema = object({ export type TreeStats = z.infer; +const commitCountSchema = object({ commits: number() }); + export type Tree = z.infer; const treeSchema = object({ @@ -337,6 +341,33 @@ export class Client { return tree; } + public async getCommitCountBySha( + rid: string, + sha: string, + options?: RequestOptions, + ): Promise { + try { + const { commits } = await this.#fetcher.fetchOk( + { + method: "GET", + path: `repos/${rid}/stats/commits/${sha}`, + options, + }, + commitCountSchema, + ); + return commits; + } catch (error) { + // Older nodes don't serve the dedicated commit-count endpoint, so fall + // back to the tree stats endpoint, which also returns the commit count. + // TODO: Drop this fallback once enough nodes serve /stats/commits. + if (error instanceof ResponseError && error.status === 404) { + const stats = await this.getTreeStatsBySha(rid, sha, options); + return stats.commits; + } + throw error; + } + } + public async getAllRemotes( rid: string, options?: RequestOptions, diff --git a/http-client/tests/repo.test.ts b/http-client/tests/repo.test.ts index e676a34b9..96435309e 100644 --- a/http-client/tests/repo.test.ts +++ b/http-client/tests/repo.test.ts @@ -48,6 +48,10 @@ describe("repo", () => { await api.repo.getTreeStatsBySha(sourceBrowsingRid, aliceMainHead); }); + test("#getCommitCountBySha(rid, sha)", async () => { + await api.repo.getCommitCountBySha(sourceBrowsingRid, aliceMainHead); + }); + test("#getTree(rid, sha, path)", async () => { await api.repo.getTree(sourceBrowsingRid, aliceMainHead, "src"); }); diff --git a/src/views/repos/History.svelte b/src/views/repos/History.svelte index 2eb518aa3..717648eb1 100644 --- a/src/views/repos/History.svelte +++ b/src/views/repos/History.svelte @@ -47,8 +47,8 @@ let totalCommits: number | undefined = undefined; function fetchTotalCommits(rid: string, sha: string) { - void api.repo.getTreeStatsBySha(rid, sha).then(stats => { - totalCommits = stats.commits; + void api.repo.getCommitCountBySha(rid, sha).then(commits => { + totalCommits = commits; }); } diff --git a/src/views/repos/Source/Header.svelte b/src/views/repos/Source/Header.svelte index 3baed4ffb..d4bea54d3 100644 --- a/src/views/repos/Source/Header.svelte +++ b/src/views/repos/Source/Header.svelte @@ -40,9 +40,9 @@ if (cached !== undefined) { commitCount = cached; } else { - void api.repo.getTreeStatsBySha(rid, sha).then(stats => { - commitCountCache[sha] = stats.commits; - commitCount = stats.commits; + void api.repo.getCommitCountBySha(rid, sha).then(commits => { + commitCountCache[sha] = commits; + commitCount = commits; }); } }