takeConflicts

tcmts.cli.merge.takeConflicts · #vrrvksu3 · term · runs anywhere

Keep the conflict records another codebase has for a branch (as #ffssl7o5 gives them) for branch here, each that's well-formed. replace: they're all it has for the branch now (it was pushed); add: each is kept for a name conflicted here (on this branch, branch) that has none kept (it was pulled; a merge here keeps its own). How many were kept.

import type { Codebase } from "#codebase/tcmts/cli/codebase";
import { keyPath } from "#codebase/tcmts/cli/diff";
import { conflictAt } from "#codebase/tcmts/cli/merge";
import type { ConflictRecord } from "#codebase/tcmts/cli/merge";

export function takeConflicts(
  cb: Codebase,
  branch: string,
  records: unknown,
  how: "replace" | "add",
): number {
  const prefix = `conflict ${branch} `;
  const side = (s: unknown): ConflictRecord["ours"] | undefined => {
    const x = s as { label?: unknown; hashes?: unknown } | null;
    return x &&
      typeof x.label === "string" &&
      Array.isArray(x.hashes) &&
      x.hashes.every((h) => typeof h === "string")
      ? { label: x.label, hashes: x.hashes as string[] }
      : undefined;
  };
  const valid = Object.entries(
    records && typeof records === "object" ? (records as Record<string, unknown>) : {},
  ).flatMap(([key, r]) => {
    const x = r as { base?: unknown; ours?: unknown; theirs?: unknown } | null;
    const [ours, theirs] = [side(x?.ours), side(x?.theirs)];
    if (
      !x ||
      !ours ||
      !theirs ||
      /\n/.test(key) ||
      (x.base !== undefined && typeof x.base !== "string")
    )
      return [];
    const rec: ConflictRecord = { ...(x.base ? { base: x.base as string } : {}), ours, theirs };
    return [[key, rec] as const];
  });
  let kept = 0;
  cb.store.transaction(() => {
    if (how === "replace")
      for (const [k] of cb.store.settings(prefix))
        if (k.startsWith(prefix)) cb.store.deleteSetting(k);
    for (const [key, rec] of valid) {
      if (
        how === "add" &&
        (cb.store.getSetting(prefix + key) !== undefined || !conflictAt(cb, keyPath(key)))
      )
        continue;
      cb.store.setSetting(prefix + key, JSON.stringify(rec));
      kept++;
    }
  });
  return kept;
}

uses

used by