fix smart conflict

This commit is contained in:
fyears 2024-07-27 19:09:42 +08:00
parent 254231e4bd
commit ae4e67f3b4
2 changed files with 236 additions and 6 deletions

View File

@ -38,9 +38,11 @@ export function isMergable(a: Entity, b?: Entity) {
* @param b
*/
function mergeDigInModified(a: string, o: string, b: string) {
const { conflict, result } = mergeDigIn(a, o, b);
const { conflict, result } = mergeDigIn(a, o, b, {
stringSeparator: /\n/,
});
for (let index = 0; index < result.length; ++index) {
if (["<<<<<<<", "=======", ">>>>>>>"].contains(result[index])) {
if (["<<<<<<<", "=======", ">>>>>>>"].includes(result[index])) {
result[index] = "`" + result[index] + "`";
}
}
@ -72,7 +74,7 @@ function getLCSText(a: string, b: string) {
* @param b
* @returns
*/
function twoWayMerge(a: string, b: string): string {
export function twoWayMerge(a: string, b: string): string {
const aa = a.trim();
const bb = b.trim();
if (aa === "" && bb === "") {
@ -88,7 +90,10 @@ function twoWayMerge(a: string, b: string): string {
// const c = getLCSText(a, b);
// const patches = makePatches(c, a);
// const [d] = applyPatches(patches, b);
const c = getLCSText(a, b);
const c = getLCSText(a, b); //.trim();
// console.debug(`(start) LCS Text:`);
// console.debug(c);
// console.debug(`(end) LCS Text.`);
const d = mergeDigInModified(a, c, b).result.join("\n");
return d;
}
@ -100,7 +105,7 @@ function twoWayMerge(a: string, b: string): string {
* @param orig
* @returns
*/
function threeWayMerge(a: string, b: string, orig: string) {
export function threeWayMerge(a: string, b: string, orig: string) {
return mergeDigInModified(a, orig, b).result.join("\n");
}

View File

@ -1,5 +1,9 @@
import { deepStrictEqual, rejects, throws } from "assert";
import { getFileRenameForDup } from "../src/conflictLogic";
import {
getFileRenameForDup,
threeWayMerge,
twoWayMerge,
} from "../src/conflictLogic";
describe("New name is generated", () => {
it("should throw for empty file", async () => {
@ -69,3 +73,224 @@ describe("New name is generated", () => {
);
});
});
describe("Two way merge", () => {
it("should correctly merge from zero files", async () => {
const a = "aaa";
const b = "bbb";
const res = twoWayMerge(a, b);
const expected = `\`<<<<<<<\`
aaa
\`=======\`
bbb
\`>>>>>>>\``;
deepStrictEqual(expected, res);
});
it("should correctly merge from common lines", async () => {
const a = `
Something is cool. 1
Other thing is cooler.
`;
const b = `
Anything is cool. 2
Other thing is cooler.
`;
const res = twoWayMerge(a, b);
// console.log(res);
const expected = `
\`<<<<<<<\`
Something is cool. 1
\`=======\`
Anything is cool. 2
\`>>>>>>>\`
Other thing is cooler.
`;
deepStrictEqual(expected, res);
});
it("should merge by lines", async () => {
const a = `
Something is cool. 1
`;
const b = `
Something is cooler. 2
`;
const res = twoWayMerge(a, b);
// console.log(res);
const expected = `
\`<<<<<<<\`
Something is cool. 1
\`=======\`
Something is cooler. 2
\`>>>>>>>\`
`;
deepStrictEqual(expected, res);
});
});
describe("Three way merge", () => {
it("should correctly merge from zero files", async () => {
const orig = "";
const a = "aaa";
const b = "bbb";
const res = threeWayMerge(a, b, orig);
const expected = `\`<<<<<<<\`
aaa
\`=======\`
bbb
\`>>>>>>>\``;
deepStrictEqual(expected, res);
});
it("should correctly merge after adding lines on both sides", async () => {
const orig = `
* [ ] A1
* [ ] A2
* [ ] A3
`;
const a = `
* [ ] A1
* [ ] new line after A1
* [ ] A2
* [ ] A3
`;
const b = `
* [ ] A1
* [ ] A2
* [ ] New line after A2
* [ ] A3
`;
const res = threeWayMerge(a, b, orig);
// console.log(res);
const expected = `
* [ ] A1
* [ ] new line after A1
* [ ] A2
* [ ] New line after A2
* [ ] A3
`;
deepStrictEqual(expected, res);
});
it("should correctly merge after adding lines on both sides (again)", async () => {
const orig = `
* [ ]
* [ ]
* [ ] A3
`;
const a = `
* [ ]
* [ ] new line after
* [ ]
* [ ] A3
`;
const b = `
* [ ]
* [ ]
* [ ] New line after
* [ ] A3
`;
const res = threeWayMerge(a, b, orig);
// console.log(res);
const expected = `
* [ ]
* [ ] new line after
* [ ]
* [ ] New line after
* [ ] A3
`;
deepStrictEqual(expected, res);
});
it("should correctly merge after deleting lines on both sides", async () => {
const orig = `
* [ ]
* [ ]
* [ ] A3
* [ ] A4
`;
const a = `
* [ ]
* [ ] A3
* [ ] A4
`;
const b = `
* [ ]
* [ ] A3
* [ ] A4
`;
const res = threeWayMerge(a, b, orig);
// console.log(res);
const expected = `
\`<<<<<<<\`
* [ ]
\`=======\`
* [ ]
\`>>>>>>>\`
* [ ] A3
* [ ] A4
`;
deepStrictEqual(expected, res);
});
it("should correctly merge after adding on one side and deleting on other side", async () => {
const orig = `
* [ ]
* [ ] A3
* [ ] A4
`;
const a = `
* [ ]
* [ ]
* [ ] A3
* [ ] A4
`;
const b = `
* [ ] A3
* [ ] A4
`;
const res = threeWayMerge(a, b, orig);
// console.log(res);
const expected = `
\`<<<<<<<\`
* [ ]
* [ ]
\`=======\`
\`>>>>>>>\`
* [ ] A3
* [ ] A4
`;
deepStrictEqual(expected, res);
});
it("should correctly merge after adding on one side and deleting on other side (again)", async () => {
const orig = `
* [ ]
* [ ] A3
* [ ] A4
`;
const a = `
* [ ] A3
* [ ] A4
`;
const b = `
* [ ]
* [ ]
* [ ] A3
* [ ] A4
`;
const res = threeWayMerge(a, b, orig);
// console.log(res);
const expected = `
\`<<<<<<<\`
\`=======\`
* [ ]
* [ ]
\`>>>>>>>\`
* [ ] A3
* [ ] A4
`;
deepStrictEqual(expected, res);
});
});