import { first } from "../db";
import { notFoundError } from "../errors";
import { loadRepo, repoPermission } from "../repos";
import { diffTreesCached } from "./diff";
import { compareCommits } from "./history";
import { assertVisibleRevision } from "./reachable";
import { listRefs, resolveRevision } from "./refs";
import type { ResolvedRevision } from "./refs";
import { withStore } from "./store";
import type { Comparison } from "./history";
import type { DiffResult, RepoRow, Viewer } from "~/lib/types";
export type BranchComparison = {
base: ResolvedRevision;
head: ResolvedRevision;
headRepo: RepoRow;
comparison: Comparison;
diff: DiffResult;
baseBranches: string[];
headBranches: string[];
};
/** Resolves an `owner:branch` head to a fork the viewer can read; bare names stay in the base repository. */
async function resolveHead(base: RepoRow, head: string, viewer: Viewer | null) {
const separator = head.indexOf(":");
if (separator === -1) return { repo: base, ref: head };
const owner = head.slice(0, separator);
const ref = head.slice(separator + 1);
const forks = await first<{ name: string }>(
`SELECT r.name FROM repos r JOIN accounts a ON a.id = r.owner_id WHERE a.name = ? AND (r.id = ? OR r.fork_of_id = ? OR r.id = ?)`,
owner,
base.id,
base.id,
base.fork_of_id ?? "",
);
if (!forks) throw notFoundError("No fork found for that owner");
const repo = await loadRepo(owner, forks.name);
if (!repo || (await repoPermission(repo, viewer)) === "none") throw notFoundError("Head repository not found");
return { repo, ref };
}