testCrissCrossMergeBases

tcmts.store.test.history.testCrissCrossMergeBases · #ffbmozzu · term

Criss-cross merges (two branches that merged each other) leave several best common ancestors: all of them, oldest first, the newest being the merge base.

import { a, b, open } from "#codebase/tcmts/store/test/history";
import assert from "node:assert/strict";

export const testCrissCrossMergeBases = () => {
  const s = open();
  s.transaction(() => s.addName("x", a, "term", "add"));
  const root = s.head();
  s.endBatch();
  s.createBranch("side");
  s.addName("y", a, "term", "add y");
  const main1 = s.head();
  s.endBatch();
  s.switchBranch("side");
  s.addName("z", b, "term", "add z");
  const side1 = s.head();
  s.endBatch();
  s.transaction(() => {
    s.addParent(main1);
    s.addName("y", a, "term", "merge main");
  });
  const side2 = s.head();
  s.endBatch();
  s.switchBranch("main");
  s.transaction(() => {
    s.addParent(side1);
    s.addName("z", b, "term", "merge side");
    s.addName("w", b, "term", "merge side"); // (merged differently: the same merge would be the same causal)
  });
  const main2 = s.head();
  assert.notEqual(main2, side2);

  const bases = s.mergeBases(main2, side2);
  assert.deepEqual(
    [...bases].sort(),
    [main1, side1].sort(),
    "both first changes, not the root behind them",
  );
  assert.ok(s.causal(bases[0]!)!.ts <= s.causal(bases[1]!)!.ts, "oldest first");
  assert.equal(s.mergeBase(main2, side2), bases[1]);
  assert.deepEqual(
    s.mergeBases([main1], [side1]),
    [root],
    "each side's own first change has the root in common",
  );
  assert.deepEqual(
    s.mergeBases([main1, side1], [side2]).sort(),
    [main1, side1].sort(),
    "several heads on a side",
  );
}

uses