// The default branch of a repository whose HEAD dangles (its first push had no main). Run with `bun test`. import assert from "node:assert/strict"; import { execFileSync } from "node:child_process"; import { mkdtempSync, rmSync } from "node:fs"; import os from "node:os"; import path from "node:path"; import { after, before, test } from "node:test"; const tmp = mkdtempSync(path.join(os.tmpdir(), "vectrum-default-branch-test-")); process.env.DATA_ROOT = path.join(tmp, "data"); const sh = (cwd: string, ...args: string[]) => execFileSync("git", args, { cwd, encoding: "utf8", stdio: "pipe" }); let git: typeof import("./git"); let repo: string; let work: string; /** Commits on `branch` in the work tree and pushes it, a second later than the last so dates order them. */ let clock = 1_700_000_000; function pushBranch(branch: string) { sh(work, "checkout", "-q", "-B", branch); const date = `${clock++} +0000`; execFileSync("git", ["-c", "user.name=a", "-c", "user.email=a@x", "commit", "-q", "--allow-empty", "-m", branch], { cwd: work, env: { ...process.env, GIT_AUTHOR_DATE: date, GIT_COMMITTER_DATE: date }, }); sh(work, "push", "-q", repo, `${branch}:refs/heads/${branch}`); } before(async () => { git = await import("./git"); repo = path.join(tmp, "srv.git"); await git.initBareRepo(repo); work = path.join(tmp, "work"); sh(tmp, "init", "-q", "-b", "start", work); }); after(() => rmSync(tmp, { recursive: true, force: true })); test("without main, master wins over a more recently changed branch, and gets pinned", async () => { pushBranch("feature"); await git.pinDefaultBranch(repo); assert.equal(await git.defaultBranch(repo), "feature"); assert.equal(sh(repo, "symbolic-ref", "HEAD").trim(), "refs/heads/main", "HEAD stays dangling without main or master"); pushBranch("master"); pushBranch("settings-parity"); assert.equal(await git.defaultBranch(repo), "master"); await git.pinDefaultBranch(repo); assert.equal(sh(repo, "symbolic-ref", "HEAD").trim(), "refs/heads/master"); // Once pinned, a later main doesn't take over. pushBranch("main"); await git.pinDefaultBranch(repo); assert.equal(await git.defaultBranch(repo), "master"); }); test("the default branch can be changed, but only to a branch that exists", async () => { await git.setDefaultBranch(repo, "feature"); assert.equal(await git.defaultBranch(repo), "feature"); await git.pinDefaultBranch(repo); assert.equal(await git.defaultBranch(repo), "feature"); await assert.rejects(git.setDefaultBranch(repo, "nope"), git.GitError); await assert.rejects(git.setDefaultBranch(repo, "--output=/tmp/x"), git.GitError); assert.equal(await git.defaultBranch(repo), "feature"); });