import { env } from "cloudflare:workers";
import { repoDb } from "../scoped-db";
import { pullBaseRepoIds } from "../pull-scope";
import { notFoundError } from "../errors";
import { loadRepoById } from "../repos";
import { canBridge, canBridgeBase, isPullHeadRepo } from "./bridge-policy";
import { reachableViaFetch } from "./commit-graph";
import { listRefs } from "./refs";
import type { ResolvedRevision } from "./refs";
import { withStore } from "./store";
import type { GitStore } from "./store";
import type { CommitSummary, RepoRow } from "~/lib/types";
const MAX_COMMIT_READS = 3000;
const MAX_LOG_PAGES = 10;
const LOG_PAGE = 1000;
const MAX_TIPS = 50;
const MAX_PULL_CANDIDATES = 5;
/** Commits are only reachable from descendants, which are (nearly always) committed later. Allow skew. */
const CLOCK_SKEW_MS = 24 * 60 * 60 * 1000;
const REACHABLE_TTL_SECONDS = 60 * 60 * 24;
const UNREACHABLE_TTL_SECONDS = 5 * 60;
type ReachRepo = Pick<RepoRow, "id" | "artifacts_name" | "default_branch" | "artifacts_remote">;
/** First-parent history of the default branch, paged server-side by Artifacts: cheap for most links. */
async function onDefaultBranch(store: GitStore, branch: string, target: CommitSummary): Promise<boolean> {
for (let page = 0; page < MAX_LOG_PAGES; page++) {
const commits = await store.log(branch, LOG_PAGE, page * LOG_PAGE);
if (commits.some((commit) => commit.sha === target.sha)) return true;
const oldest = commits.at(-1);
if (commits.length < LOG_PAGE || !oldest || oldest.committedAt < target.committedAt - CLOCK_SKEW_MS) return false;
}
return false;
}
/** Date-pruned walk from every visible tip: stops descending once commits are older than the target. */
async function fromTips(store: GitStore, tips: string[], target: CommitSummary): Promise<boolean> {
const cutoff = target.committedAt - CLOCK_SKEW_MS;
const seen = new Set<string>();