Mission control: a busy week's earlier pushes count again
The week chart read a project's last 40 push events, which include every branch, so in a week of agent branches Monday's and Tuesday's pushes to main had already fallen out (the chart showed nothing on a day with 15 commits). It now pages back through two weeks of pushes, reads the default branch's history once, and places each push's commits at its time, instead of one history read of 60 commits per push, which also cut large pushes short.
3 files+68−170/3 viewed
| 3 | 3 | ||
| 4 | 4 | import { | |
| 5 | 5 | type Merged, | |
| 6 | + | placePushes, | |
| 6 | 7 | change, | |
| 7 | 8 | checksFact, | |
| 8 | 9 | confidenceAsk, | |
| 370 | 371 | assert.match(why, /self-hosted runner/); | |
| 371 | 372 | assert.doesNotMatch(why, /agent/); | |
| 372 | 373 | }); | |
| 374 | + | ||
| 375 | + | test("each push to the default branch places the commits it brought, at its time, from one read of the history", () => { | |
| 376 | + | const c = (hash: string, parents = ["p"], author = "Chase Pierce") => ({ hash, parents, author: { name: author } }); | |
| 377 | + | // Newest first: a Wednesday push of two, a Monday push of one, a merge, and g1t's own commit. | |
| 378 | + | const history = [c("w2"), c("w1"), c("m1"), c("merge", ["a", "b"]), c("bot", ["p"], "g1t"), c("old")]; | |
| 379 | + | const pushes = [ | |
| 380 | + | { time: "2026-10-07T12:00:00Z", data: { after: "w2", before: "m1" } }, | |
| 381 | + | { time: "2026-10-05T12:00:00Z", data: { after: "m1", before: "old" } }, | |
| 382 | + | { time: "2026-10-01T12:00:00Z", data: { after: "gone", before: "older" } }, | |
| 383 | + | ]; | |
| 384 | + | assert.deepEqual(placePushes(history, pushes), [ | |
| 385 | + | { hash: "m1", at: "2026-10-05T12:00:00Z" }, | |
| 386 | + | { hash: "w2", at: "2026-10-07T12:00:00Z" }, | |
| 387 | + | { hash: "w1", at: "2026-10-07T12:00:00Z" }, | |
| 388 | + | ]); | |
| 389 | + | }); |
| 448 | 448 | return brought.filter((commit) => commit.parents.length <= 1 && !isAgent(commit.author.name)); | |
| 449 | 449 | } | |
| 450 | 450 | ||
| 451 | + | /** | |
| 452 | + | * Each commit of `history` (newest first) a push in `pushes` (newest | |
| 453 | + | * first) brought, at that push's time. A commit pushed twice (after a | |
| 454 | + | * force push, say) counts once, at its first landing; a push whose `after` | |
| 455 | + | * is no longer in the history (rewritten) brings nothing. | |
| 456 | + | */ | |
| 457 | + | export function placePushes<C extends { hash: string; parents: string[]; author: { name: string } }>( | |
| 458 | + | history: C[], | |
| 459 | + | pushes: { time: string; data: { after: string; before?: string } }[], | |
| 460 | + | ): { hash: string; at: string }[] { | |
| 461 | + | const index = new Map(history.map((commit, i) => [commit.hash, i])); | |
| 462 | + | const seen = new Map<string, string>(); | |
| 463 | + | for (const push of [...pushes].reverse()) { | |
| 464 | + | const start = index.get(push.data.after); | |
| 465 | + | if (start === undefined) continue; | |
| 466 | + | const end = push.data.before ? index.get(push.data.before) : undefined; | |
| 467 | + | for (const commit of pushedCommits(history.slice(start, end ?? history.length), undefined)) { | |
| 468 | + | if (!seen.has(commit.hash)) seen.set(commit.hash, push.time); | |
| 469 | + | } | |
| 470 | + | } | |
| 471 | + | return [...seen].map(([hash, at]) => ({ hash, at })); | |
| 472 | + | } | |
| 473 | + | ||
| 451 | 474 | export type Merged = { | |
| 452 | 475 | repo: RepoPath; | |
| 453 | 476 | number: number; |
| 39 | 39 | import { | |
| 40 | 40 | type Fact, | |
| 41 | 41 | type Merged, | |
| 42 | − | pushedCommits, | |
| 42 | + | placePushes, | |
| 43 | 43 | type NeedRow, | |
| 44 | 44 | type QuickAction, | |
| 45 | 45 | RUN_LABEL, | |
| 152 | 152 | return data<DelegateResult>({ error: null, notStarted: refused }); | |
| 153 | 153 | } | |
| 154 | 154 | ||
| 155 | − | /** Pushes to the default branch read for the week, per project, and commits read back from each. */ | |
| 156 | − | const PUSHES_READ = 40; | |
| 157 | − | const PUSH_DEPTH = 60; | |
| 155 | + | /** | |
| 156 | + | * Push events read per project, a page at a time, back two weeks. Pushes | |
| 157 | + | * to every branch are in the log, so a fixed count (it was 40) lost a busy | |
| 158 | + | * week's earlier days to agents' branches. | |
| 159 | + | */ | |
| 160 | + | const PUSH_PAGE = 200; | |
| 161 | + | const PUSH_PAGES = 5; | |
| 162 | + | /** Commits of the default branch read once, to place each push's commits. */ | |
| 163 | + | const HISTORY_READ = 1000; | |
| 158 | 164 | ||
| 159 | 165 | /** | |
| 160 | 166 | * The commits people pushed straight to a project's default branch in the | |
| 163 | 169 | */ | |
| 164 | 170 | async function directCommits(repo: Repo, viewer: Viewer): Promise<{ hash: string; at: string }[]> { | |
| 165 | 171 | const since = Date.now() - 14 * TIME.DAY; | |
| 166 | − | const pushes = (await eventLog.list({ repoId: repo.id, types: ["git.push"], limit: PUSHES_READ })).filter( | |
| 167 | − | (event): event is G1tEvent<"git.push"> => event.type === "git.push" && event.data.defaultBranch && Date.parse(event.time) >= since, | |
| 168 | − | ); | |
| 172 | + | const pushes: G1tEvent<"git.push">[] = []; | |
| 173 | + | let before: string | undefined; | |
| 174 | + | for (let page = 0; page < PUSH_PAGES; page++) { | |
| 175 | + | const batch = await eventLog.list({ repoId: repo.id, types: ["git.push"], limit: PUSH_PAGE, ...(before ? { before } : {}) }); | |
| 176 | + | for (const event of batch) { | |
| 177 | + | if (event.type === "git.push" && event.data.defaultBranch && Date.parse(event.time) >= since) pushes.push(event as G1tEvent<"git.push">); | |
| 178 | + | } | |
| 179 | + | const oldest = batch.at(-1); | |
| 180 | + | if (batch.length < PUSH_PAGE || !oldest || Date.parse(oldest.time) < since) break; | |
| 181 | + | before = oldest.id; | |
| 182 | + | } | |
| 183 | + | if (pushes.length === 0) return []; | |
| 184 | + | // One read of the branch from the newest push back; each push brought | |
| 185 | + | // what lies between its `after` and its `before` in that history. | |
| 169 | 186 | const path = { namespace: repo.namespace, name: repo.name }; | |
| 170 | − | const read = await Promise.all( | |
| 171 | − | pushes.map(async (push) => { | |
| 172 | − | const history = await reposApi.log(path, viewer, push.data.after, PUSH_DEPTH).catch(() => null); | |
| 173 | − | return history?.ok ? pushedCommits(history.value, push.data.before).map((commit) => ({ hash: commit.hash, at: push.time })) : []; | |
| 174 | − | }), | |
| 175 | − | ); | |
| 176 | − | // A commit pushed twice (after a force push, say) counts once, at its first landing. | |
| 177 | − | const seen = new Map<string, string>(); | |
| 178 | − | for (const commit of read.flat().reverse()) if (!seen.has(commit.hash)) seen.set(commit.hash, commit.at); | |
| 179 | − | return [...seen].map(([hash, at]) => ({ hash, at })); | |
| 187 | + | const history = await reposApi.log(path, viewer, pushes[0].data.after, HISTORY_READ).catch(() => null); | |
| 188 | + | if (!history?.ok) return []; | |
| 189 | + | return placePushes(history.value, pushes); | |
| 180 | 190 | } | |
| 181 | 191 | ||
| 192 | + | ||
| 182 | 193 | export async function loader({ context, request }: Route.LoaderArgs) { | |
| 183 | 194 | const viewer = getViewer(context); | |
| 184 | 195 | if (!viewer) { |