planMerge

tcmts.cli.merge.planMerge · #4tfw3vmt · term · runs anywhere

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { stateOf } from "#codebase/tcmts/cli/diff";
import { mergeBaseState, mergeFrom } from "#codebase/tcmts/cli/merge";
import type { MergePlan } from "#codebase/tcmts/cli/merge";

export function planMerge(cb: Codebase, ours: string, theirs: string): MergePlan {
  if (theirs === ours) throw new Error("can't merge a branch into itself");
  for (const b of [ours, theirs])
    if (!cb.store.hasBranch(b)) throw new Error(`no branch named '${b}'`);
  const [oursHead, theirsHead] = [cb.store.head(ours), cb.store.head(theirs)];
  if (cb.store.isAncestor(theirsHead, oursHead)) return { kind: "up-to-date" };
  if (cb.store.isAncestor(oursHead, theirsHead)) return { kind: "fast-forward", to: theirsHead };
  const irOf = (h: string) => cb.store.getDef(h)!.ir;
  const base = mergeBaseState(cb, oursHead, theirsHead);
  const before = stateOf(cb.store.names(ours, true));
  const theirsNow = stateOf(cb.store.names(theirs, true));
  return {
    kind: "merge",
    theirsHead,
    base,
    before,
    theirs: theirsNow,
    result: mergeFrom(base, before, theirsNow, irOf),
  };
}

uses

used by