mirror of
https://github.com/silvanocerza/github-gitless-sync.git
synced 2026-07-22 12:10:28 +00:00
Use better diff algorithm
This commit is contained in:
parent
a0f2439b1f
commit
fd100345a3
1 changed files with 61 additions and 26 deletions
|
|
@ -9,40 +9,75 @@ export interface DiffChunk {
|
|||
function diff(oldText: string, newText: string): DiffChunk[] {
|
||||
const oldLines = oldText.split("\n");
|
||||
const newLines = newText.split("\n");
|
||||
const result: DiffChunk[] = [];
|
||||
|
||||
for (let i = 0; i < Math.max(oldLines.length, newLines.length); i++) {
|
||||
const oldLine = oldLines[i];
|
||||
const newLine = newLines[i];
|
||||
let matrix = Array(oldLines.length + 1)
|
||||
.fill(null)
|
||||
.map(() => Array(newLines.length + 1).fill(0));
|
||||
|
||||
if (!oldLine && newLine) {
|
||||
result.push({
|
||||
for (let i = 1; i <= oldLines.length; i++) matrix[i][0] = i;
|
||||
for (let j = 1; j <= newLines.length; j++) matrix[0][j] = j;
|
||||
|
||||
for (let i = 1; i <= oldLines.length; i++) {
|
||||
for (let j = 1; j <= newLines.length; j++) {
|
||||
if (oldLines[i - 1] === newLines[j - 1]) {
|
||||
matrix[i][j] = matrix[i - 1][j - 1];
|
||||
} else {
|
||||
matrix[i][j] = Math.min(
|
||||
matrix[i - 1][j] + 1, // deletion
|
||||
matrix[i][j - 1] + 1, // insertion
|
||||
matrix[i - 1][j - 1] + 1, // substitution
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const chunks: DiffChunk[] = [];
|
||||
let i = oldLines.length;
|
||||
let j = newLines.length;
|
||||
|
||||
while (i > 0 || j > 0) {
|
||||
if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
|
||||
i--;
|
||||
j--;
|
||||
continue;
|
||||
}
|
||||
|
||||
const deletion = i > 0 ? matrix[i - 1][j] : Infinity;
|
||||
const insertion = j > 0 ? matrix[i][j - 1] : Infinity;
|
||||
const substitution = i > 0 && j > 0 ? matrix[i - 1][j - 1] : Infinity;
|
||||
|
||||
if (substitution <= deletion && substitution <= insertion) {
|
||||
chunks.unshift({
|
||||
type: "modify",
|
||||
startLeftLine: i,
|
||||
endLeftLine: i + 1,
|
||||
startRightLine: j,
|
||||
endRightLine: j + 1,
|
||||
});
|
||||
i--;
|
||||
j--;
|
||||
} else if (deletion <= insertion) {
|
||||
chunks.unshift({
|
||||
type: "remove",
|
||||
startLeftLine: i,
|
||||
endLeftLine: i + 1,
|
||||
startRightLine: j + 1,
|
||||
endRightLine: j + 1,
|
||||
});
|
||||
i--;
|
||||
} else {
|
||||
chunks.unshift({
|
||||
type: "add",
|
||||
startLeftLine: i + 1,
|
||||
endLeftLine: i + 1,
|
||||
startRightLine: i + 1,
|
||||
endRightLine: i + 2,
|
||||
});
|
||||
} else if (oldLine && !newLine) {
|
||||
result.push({
|
||||
type: "remove",
|
||||
startLeftLine: i + 1,
|
||||
endLeftLine: i + 2,
|
||||
startRightLine: i + 1,
|
||||
endRightLine: i + 1,
|
||||
});
|
||||
} else if (oldLine !== newLine) {
|
||||
result.push({
|
||||
type: "modify",
|
||||
startLeftLine: i + 1,
|
||||
endLeftLine: i + 2,
|
||||
startRightLine: i + 1,
|
||||
endRightLine: i + 2,
|
||||
startRightLine: j,
|
||||
endRightLine: j + 1,
|
||||
});
|
||||
j--;
|
||||
}
|
||||
}
|
||||
// return result;
|
||||
return mergeDiffs(result);
|
||||
|
||||
return mergeDiffs(chunks);
|
||||
}
|
||||
|
||||
function mergeDiffs(chunks: DiffChunk[]): DiffChunk[] {
|
||||
|
|
|
|||
Loading…
Reference in a new issue