import type { MergeConflict } from "../git/merge";
const MARKER_START = /^<{7}(?: |\n|$)/;
const MARKER_MIDDLE = /^={7}\n?$/;
const MARKER_END = /^>{7}(?: |\n|$)/;
const LINE = /[^\n]*\n|[^\n]+$/g;
/**
* Resolves every conflict block in merged marker text by keeping the `ours` side, leaving the cleanly
* merged lines around it untouched. Returns null when the markers don't parse into `expected` blocks
* (for example when the file itself contained marker-like lines), so the caller can treat it as a conflict.
*/
export function keepOurs(text: string, expected: number): string | null {
const out: string[] = [];
let state: "outside" | "ours" | "theirs" = "outside";
let blocks = 0;
for (const line of text.match(LINE) ?? []) {
if (state === "outside") {
if (MARKER_START.test(line)) state = "ours";
else if (MARKER_MIDDLE.test(line) || MARKER_END.test(line)) return null;
else out.push(line);
} else if (state === "ours") {
if (MARKER_MIDDLE.test(line)) state = "theirs";
else if (MARKER_START.test(line) || MARKER_END.test(line)) return null;
else out.push(line);
} else if (MARKER_END.test(line)) {
state = "outside";
blocks++;
} else if (MARKER_START.test(line) || MARKER_MIDDLE.test(line)) {
return null;
}
}
return state === "outside" && blocks === expected ? out.join("") : null;
}
/**
* Replacement contents that resolve text conflicts in favor of `ours`. Conflicts without marker text
* already resolve in the merged tree: binary and file/directory keep `ours`, modify/delete keeps the
* modified file so no edit is lost.
* Null when some text conflict could not be resolved mechanically.