testMergeAfterASquashedLandingLeavesNothingStale
Work kept on a branch after its squashed landing, while main moved on: merging main in starts from the landing (merged into the branch when it landed), so a name the branch changed again isn't a conflict with its own landed version, and what uses what both sides re-hashed follows to the merged version: nothing is left using a version nothing names.
import { okIn, tcmIn, tempDir } from "#codebase/tcmts/cli/test/e2e/harness"; import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; export const testMergeAfterASquashedLandingLeavesNothingStale = () => { const dir = tempDir("merge after squash"); const tcm = (...args: string[]) => okIn(dir, ...args); const update = (code: string) => { fs.writeFileSync(path.join(dir, "scratch.ts"), `// tcm: namespace lib\n${code}\n`); tcm("update"); }; tcm("init"); update(`export const a = () => 1;\nexport const b = () => 10;`); update(`import { a, b } from "#codebase/lib"; export const handlers = () => a() + b(); export const dispatch = () => handlers() * 2;`); tcm("branch", "feature"); tcm("switch", "feature"); update(`export const b = () => 20;`); tcm("switch", "main"); // (main moved meanwhile: the landing is an entry of main's, not a fast-forward to the branch) update(`export const c = () => 0;`); tcm("merge", "feature", "--squash", "-m", "b is twenty"); update(`export const a = () => 3;`); tcm("switch", "feature"); update(`export const b = () => 30;`); const merged = tcmIn(dir, "merge", "main"); assert.equal(merged.status, 0, merged.out); assert.doesNotMatch(merged.out, /unnamed version|conflict/); // main's a (3) and the branch's newer b (30), through handlers assert.equal(tcm("run", "lib.dispatch").trim(), "66"); assert.match(tcm("todo"), /nothing to do/); // and it lands again, squashed tcm("switch", "main"); const again = tcmIn(dir, "merge", "feature", "--squash", "-m", "b is thirty"); assert.equal(again.status, 0, again.out); assert.equal(tcm("run", "lib.dispatch").trim(), "66"); }