@pierre/diffs 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AdvancedVirtualizedFileDiff.d.ts.map +1 -1
- package/dist/components/File.d.ts.map +1 -1
- package/dist/components/FileDiff.d.ts +4 -4
- package/dist/components/FileDiff.d.ts.map +1 -1
- package/dist/components/FileDiff.js.map +1 -1
- package/dist/components/UnresolvedFile.d.ts +18 -9
- package/dist/components/UnresolvedFile.d.ts.map +1 -1
- package/dist/components/UnresolvedFile.js +199 -57
- package/dist/components/UnresolvedFile.js.map +1 -1
- package/dist/components/VirtulizerDevelopment.d.ts.map +1 -1
- package/dist/constants.d.ts +5 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +7 -6
- package/dist/index.js +5 -4
- package/dist/react/UnresolvedFile.d.ts +3 -1
- package/dist/react/UnresolvedFile.d.ts.map +1 -1
- package/dist/react/UnresolvedFile.js.map +1 -1
- package/dist/react/index.d.ts +2 -2
- package/dist/react/jsx.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.d.ts +1 -1
- package/dist/react/utils/renderDiffChildren.d.ts.map +1 -1
- package/dist/react/utils/renderDiffChildren.js +6 -4
- package/dist/react/utils/renderDiffChildren.js.map +1 -1
- package/dist/react/utils/useUnresolvedFileInstance.d.ts +5 -4
- package/dist/react/utils/useUnresolvedFileInstance.d.ts.map +1 -1
- package/dist/react/utils/useUnresolvedFileInstance.js +15 -12
- package/dist/react/utils/useUnresolvedFileInstance.js.map +1 -1
- package/dist/renderers/DiffHunksRenderer.d.ts +15 -7
- package/dist/renderers/DiffHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/DiffHunksRenderer.js +9 -7
- package/dist/renderers/DiffHunksRenderer.js.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.d.ts +11 -16
- package/dist/renderers/UnresolvedFileHunksRenderer.d.ts.map +1 -1
- package/dist/renderers/UnresolvedFileHunksRenderer.js +68 -75
- package/dist/renderers/UnresolvedFileHunksRenderer.js.map +1 -1
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/preloadDiffs.d.ts +2 -2
- package/dist/ssr/preloadDiffs.d.ts.map +1 -1
- package/dist/ssr/preloadDiffs.js +4 -3
- package/dist/ssr/preloadDiffs.js.map +1 -1
- package/dist/style.js +1 -1
- package/dist/style.js.map +1 -1
- package/dist/types.d.ts +41 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/areMergeConflictActionsEqual.js +1 -1
- package/dist/utils/areMergeConflictActionsEqual.js.map +1 -1
- package/dist/utils/diffAcceptRejectHunk.d.ts +3 -2
- package/dist/utils/diffAcceptRejectHunk.d.ts.map +1 -1
- package/dist/utils/diffAcceptRejectHunk.js +24 -89
- package/dist/utils/diffAcceptRejectHunk.js.map +1 -1
- package/dist/utils/getMergeConflictActionSlotName.d.ts +4 -6
- package/dist/utils/getMergeConflictActionSlotName.d.ts.map +1 -1
- package/dist/utils/getMergeConflictActionSlotName.js +2 -2
- package/dist/utils/getMergeConflictActionSlotName.js.map +1 -1
- package/dist/utils/getMergeConflictLineTypes.d.ts +1 -2
- package/dist/utils/getMergeConflictLineTypes.d.ts.map +1 -1
- package/dist/utils/getMergeConflictLineTypes.js +7 -12
- package/dist/utils/getMergeConflictLineTypes.js.map +1 -1
- package/dist/utils/normalizeDiffResolution.d.ts +7 -0
- package/dist/utils/normalizeDiffResolution.d.ts.map +1 -0
- package/dist/utils/normalizeDiffResolution.js +11 -0
- package/dist/utils/normalizeDiffResolution.js.map +1 -0
- package/dist/utils/parseMergeConflictDiffFromFile.d.ts +16 -12
- package/dist/utils/parseMergeConflictDiffFromFile.d.ts.map +1 -1
- package/dist/utils/parseMergeConflictDiffFromFile.js +474 -117
- package/dist/utils/parseMergeConflictDiffFromFile.js.map +1 -1
- package/dist/utils/resolveConflict.d.ts +7 -0
- package/dist/utils/resolveConflict.d.ts.map +1 -0
- package/dist/utils/resolveConflict.js +23 -0
- package/dist/utils/resolveConflict.js.map +1 -0
- package/dist/utils/resolveRegion.d.ts +14 -0
- package/dist/utils/resolveRegion.d.ts.map +1 -0
- package/dist/utils/resolveRegion.js +215 -0
- package/dist/utils/resolveRegion.js.map +1 -0
- package/dist/utils/trimPatchContext.js +19 -20
- package/dist/utils/trimPatchContext.js.map +1 -1
- package/dist/worker/{wasm-BlUZCxHM.js → wasm-BaDzIkIn.js} +2 -2
- package/dist/worker/wasm-BaDzIkIn.js.map +1 -0
- package/dist/worker/worker-portable.js +4880 -4810
- package/dist/worker/worker-portable.js.map +1 -1
- package/dist/worker/worker.js.map +1 -1
- package/package.json +2 -1
- package/dist/utils/resolveMergeConflict.d.ts +0 -7
- package/dist/utils/resolveMergeConflict.d.ts.map +0 -1
- package/dist/utils/resolveMergeConflict.js +0 -30
- package/dist/utils/resolveMergeConflict.js.map +0 -1
- package/dist/worker/wasm-BlUZCxHM.js.map +0 -1
|
@@ -1,131 +1,416 @@
|
|
|
1
|
-
import { splitFileContents } from "./splitFileContents.js";
|
|
2
|
-
import { processFile } from "./parsePatchFiles.js";
|
|
3
|
-
import { getMergeConflictActionLineNumber, getMergeConflictParseResult } from "./getMergeConflictLineTypes.js";
|
|
4
|
-
|
|
5
1
|
//#region src/utils/parseMergeConflictDiffFromFile.ts
|
|
6
|
-
function getMergeConflictActionAnchor(action) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
side: "deletions",
|
|
13
|
-
lineNumber: action.currentLineNumber
|
|
2
|
+
function getMergeConflictActionAnchor(action, fileDiff) {
|
|
3
|
+
const hunk = fileDiff.hunks[action.hunkIndex];
|
|
4
|
+
if (hunk == null) return;
|
|
5
|
+
return {
|
|
6
|
+
hunkIndex: action.hunkIndex,
|
|
7
|
+
lineIndex: getUnifiedLineStartForContent(hunk, action.startContentIndex)
|
|
14
8
|
};
|
|
15
9
|
}
|
|
16
|
-
function parseMergeConflictDiffFromFile(file) {
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
let incomingLineNumberAtIndex;
|
|
45
|
-
switch (lineType) {
|
|
46
|
-
case "none":
|
|
47
|
-
currentContentChunks.push(line);
|
|
48
|
-
incomingContentChunks.push(line);
|
|
49
|
-
patchContentChunks.push(` ${line}`);
|
|
50
|
-
currentLineNumber++;
|
|
51
|
-
incomingLineNumber++;
|
|
52
|
-
currentLineNumberAtIndex = currentLineNumber;
|
|
53
|
-
incomingLineNumberAtIndex = incomingLineNumber;
|
|
54
|
-
break;
|
|
55
|
-
case "current":
|
|
56
|
-
currentContentChunks.push(line);
|
|
57
|
-
patchContentChunks.push(`-${line}`);
|
|
58
|
-
currentLineNumber++;
|
|
59
|
-
currentLineNumberAtIndex = currentLineNumber;
|
|
60
|
-
break;
|
|
61
|
-
case "incoming":
|
|
62
|
-
incomingContentChunks.push(line);
|
|
63
|
-
patchContentChunks.push(`+${line}`);
|
|
64
|
-
incomingLineNumber++;
|
|
65
|
-
incomingLineNumberAtIndex = incomingLineNumber;
|
|
66
|
-
break;
|
|
67
|
-
case "base":
|
|
68
|
-
case "marker-start":
|
|
69
|
-
case "marker-base":
|
|
70
|
-
case "marker-separator":
|
|
71
|
-
case "marker-end":
|
|
72
|
-
currentContentChunks.push(line);
|
|
73
|
-
incomingContentChunks.push(line);
|
|
74
|
-
patchContentChunks.push(` ${line}`);
|
|
75
|
-
currentLineNumber++;
|
|
76
|
-
incomingLineNumber++;
|
|
77
|
-
currentLineNumberAtIndex = currentLineNumber;
|
|
78
|
-
incomingLineNumberAtIndex = incomingLineNumber;
|
|
79
|
-
break;
|
|
80
|
-
default: assertNever(lineType);
|
|
81
|
-
}
|
|
82
|
-
if (actionLineIndexSet.has(index)) actionLineNumbersByOriginalIndex.set(index, {
|
|
83
|
-
currentLineNumber: currentLineNumberAtIndex,
|
|
84
|
-
incomingLineNumber: incomingLineNumberAtIndex
|
|
85
|
-
});
|
|
86
|
-
while (nextConflict != null && nextActionOriginalLineIndex <= index) {
|
|
87
|
-
const actionLineNumbers = actionLineNumbersByOriginalIndex.get(nextActionOriginalLineIndex);
|
|
88
|
-
actions[actionIndex] = {
|
|
89
|
-
actionOriginalLineIndex: nextActionOriginalLineIndex,
|
|
90
|
-
actionOriginalLineNumber: nextActionOriginalLineNumber,
|
|
91
|
-
currentLineNumber: actionLineNumbers?.currentLineNumber,
|
|
92
|
-
incomingLineNumber: actionLineNumbers?.incomingLineNumber,
|
|
93
|
-
conflict: nextConflict,
|
|
94
|
-
conflictIndex: nextConflict.conflictIndex
|
|
95
|
-
};
|
|
96
|
-
actionIndex++;
|
|
97
|
-
nextConflict = regions[actionIndex];
|
|
98
|
-
if (nextConflict == null) break;
|
|
99
|
-
nextActionOriginalLineNumber = actionOriginalLineNumbersByRegion[actionIndex];
|
|
100
|
-
nextActionOriginalLineIndex = actionOriginalLineIndexesByRegion[actionIndex];
|
|
10
|
+
function parseMergeConflictDiffFromFile(file, maxContextLines = 6) {
|
|
11
|
+
maxContextLines = Math.max(maxContextLines, 1);
|
|
12
|
+
const s = {
|
|
13
|
+
deletionLines: [],
|
|
14
|
+
additionLines: [],
|
|
15
|
+
conflictStack: [],
|
|
16
|
+
conflictBuilders: [],
|
|
17
|
+
actions: [],
|
|
18
|
+
hunks: [],
|
|
19
|
+
nextConflictIndex: 0,
|
|
20
|
+
splitLineCount: 0,
|
|
21
|
+
unifiedLineCount: 0,
|
|
22
|
+
lastHunkEnd: 0,
|
|
23
|
+
activeHunk: void 0,
|
|
24
|
+
maxContextLines,
|
|
25
|
+
maxContextLines2: maxContextLines * 2
|
|
26
|
+
};
|
|
27
|
+
const contents = file.contents;
|
|
28
|
+
const contentLength = contents.length;
|
|
29
|
+
if (contentLength > 0) {
|
|
30
|
+
let lineStart = 0;
|
|
31
|
+
let lineIndex = 0;
|
|
32
|
+
let newlinePos = contents.indexOf("\n", lineStart);
|
|
33
|
+
while (newlinePos !== -1) {
|
|
34
|
+
processLine(s, contents.slice(lineStart, newlinePos + 1), lineIndex);
|
|
35
|
+
lineStart = newlinePos + 1;
|
|
36
|
+
lineIndex++;
|
|
37
|
+
newlinePos = contents.indexOf("\n", lineStart);
|
|
101
38
|
}
|
|
39
|
+
if (lineStart < contentLength) processLine(s, contents.slice(lineStart), lineIndex);
|
|
40
|
+
}
|
|
41
|
+
if (s.conflictStack.length > 0) throw new Error("parseMergeConflictDiffFromFile: unfinished merge conflict marker stack");
|
|
42
|
+
if (s.activeHunk != null && s.activeHunk.hunkContent.length > 0) {
|
|
43
|
+
flushBufferedContext(s, s.activeHunk, "trailing");
|
|
44
|
+
finalizeActiveHunk(s);
|
|
45
|
+
}
|
|
46
|
+
for (let conflictIndex = 0; conflictIndex < s.conflictBuilders.length; conflictIndex++) {
|
|
47
|
+
const builder = s.conflictBuilders[conflictIndex];
|
|
48
|
+
if (builder == null || !builder.completed) throw new Error(`parseMergeConflictDiffFromFile: failed to build merge conflict action ${conflictIndex}`);
|
|
49
|
+
}
|
|
50
|
+
if (s.hunks.length > 0 && s.additionLines.length > 0 && s.deletionLines.length > 0) {
|
|
51
|
+
const lastHunk = s.hunks[s.hunks.length - 1];
|
|
52
|
+
const collapsedAfter = Math.max(s.additionLines.length - (lastHunk.additionStart + lastHunk.additionCount - 1), 0);
|
|
53
|
+
s.splitLineCount += collapsedAfter;
|
|
54
|
+
s.unifiedLineCount += collapsedAfter;
|
|
102
55
|
}
|
|
103
|
-
const currentContents =
|
|
104
|
-
const incomingContents =
|
|
105
|
-
const patchContents = patchContentChunks.join("");
|
|
56
|
+
const currentContents = s.deletionLines.join("");
|
|
57
|
+
const incomingContents = s.additionLines.join("");
|
|
106
58
|
const currentFile = createResolvedConflictFile(file, "current", currentContents);
|
|
107
59
|
const incomingFile = createResolvedConflictFile(file, "incoming", incomingContents);
|
|
108
|
-
|
|
60
|
+
let type = "change";
|
|
61
|
+
if (incomingContents === "") type = "deleted";
|
|
62
|
+
else if (currentContents === "") type = "new";
|
|
63
|
+
const fileDiff = {
|
|
109
64
|
name: file.name,
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
65
|
+
prevName: void 0,
|
|
66
|
+
type,
|
|
67
|
+
hunks: s.hunks,
|
|
68
|
+
splitLineCount: s.splitLineCount,
|
|
69
|
+
unifiedLineCount: s.unifiedLineCount,
|
|
70
|
+
isPartial: false,
|
|
71
|
+
deletionLines: s.deletionLines,
|
|
72
|
+
additionLines: s.additionLines,
|
|
73
|
+
cacheKey: file.cacheKey != null ? `${file.cacheKey}:merge-conflict-diff` : void 0
|
|
74
|
+
};
|
|
120
75
|
return {
|
|
121
76
|
fileDiff,
|
|
122
77
|
currentFile,
|
|
123
78
|
incomingFile,
|
|
124
|
-
actions
|
|
79
|
+
actions: s.actions,
|
|
80
|
+
markerRows: buildMergeConflictMarkerRows(fileDiff, s.actions)
|
|
125
81
|
};
|
|
126
82
|
}
|
|
127
|
-
function
|
|
128
|
-
|
|
83
|
+
function processLine(s, line, index) {
|
|
84
|
+
const frame = s.conflictStack[s.conflictStack.length - 1];
|
|
85
|
+
if (frame == null) {
|
|
86
|
+
if (line.length >= 7 && line.charCodeAt(0) === 60 && getMergeConflictMarkerType(line) === "start") {
|
|
87
|
+
handleStartMarker(s, line, index);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
emitContextLine(s, line);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const markerType = getMergeConflictMarkerType(line);
|
|
94
|
+
if (markerType === "start") {
|
|
95
|
+
handleStartMarker(s, line, index);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (markerType === "base") {
|
|
99
|
+
frame.stage = "base";
|
|
100
|
+
frame.baseMarkerLineIndex = index;
|
|
101
|
+
frame.markerLines.base = line;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (markerType === "separator") {
|
|
105
|
+
frame.stage = "incoming";
|
|
106
|
+
frame.separatorLineIndex = index;
|
|
107
|
+
frame.markerLines.separator = line;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (markerType === "end") {
|
|
111
|
+
const completedFrame = s.conflictStack.pop();
|
|
112
|
+
if (completedFrame == null) throw new Error("parseMergeConflictDiffFromFile: encountered end marker before start marker");
|
|
113
|
+
finalizeConflict(s, completedFrame, index, line);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (frame.stage === "current") emitChangeLine(s, "deletion", line, frame.conflictIndex, "current");
|
|
117
|
+
else if (frame.stage === "base") emitContextLine(s, line, frame.conflictIndex);
|
|
118
|
+
else emitChangeLine(s, "addition", line, frame.conflictIndex, "incoming");
|
|
119
|
+
}
|
|
120
|
+
function ensureActiveHunk(s) {
|
|
121
|
+
s.activeHunk ??= createHunkBuilder(s.additionLines.length + 1, s.deletionLines.length + 1);
|
|
122
|
+
return s.activeHunk;
|
|
123
|
+
}
|
|
124
|
+
function assignConflictContent(s, conflictIndex, role, contentIndex) {
|
|
125
|
+
const builder = s.conflictBuilders[conflictIndex];
|
|
126
|
+
if (builder == null) throw new Error(`parseMergeConflictDiffFromFile: failed to locate conflict action ${conflictIndex}`);
|
|
127
|
+
const action = builder.action;
|
|
128
|
+
const hunkIndex = s.hunks.length;
|
|
129
|
+
if (action.hunkIndex < 0) action.hunkIndex = hunkIndex;
|
|
130
|
+
else if (action.hunkIndex !== hunkIndex) throw new Error(`parseMergeConflictDiffFromFile: conflict ${conflictIndex} spans multiple hunks and cannot be anchored`);
|
|
131
|
+
if (action.startContentIndex < 0) action.startContentIndex = contentIndex;
|
|
132
|
+
action.endContentIndex = contentIndex;
|
|
133
|
+
action.endMarkerContentIndex = contentIndex;
|
|
134
|
+
if (role === "current") {
|
|
135
|
+
action.currentContentIndex ??= contentIndex;
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (role === "base") {
|
|
139
|
+
action.baseContentIndex ??= contentIndex;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
action.incomingContentIndex = contentIndex;
|
|
143
|
+
}
|
|
144
|
+
function appendChangeLine(hunk, lineType, additionLineIndex, deletionLineIndex) {
|
|
145
|
+
const hunkContent = hunk.hunkContent;
|
|
146
|
+
const lastContent = hunkContent[hunkContent.length - 1];
|
|
147
|
+
if (lastContent?.type === "change") {
|
|
148
|
+
if (lineType === "addition") lastContent.additions++;
|
|
149
|
+
else lastContent.deletions++;
|
|
150
|
+
return hunkContent.length - 1;
|
|
151
|
+
}
|
|
152
|
+
hunkContent.push({
|
|
153
|
+
type: "change",
|
|
154
|
+
additions: lineType === "addition" ? 1 : 0,
|
|
155
|
+
deletions: lineType === "deletion" ? 1 : 0,
|
|
156
|
+
additionLineIndex,
|
|
157
|
+
deletionLineIndex
|
|
158
|
+
});
|
|
159
|
+
return hunkContent.length - 1;
|
|
160
|
+
}
|
|
161
|
+
function flushBufferedContext(s, hunk, mode) {
|
|
162
|
+
let count = hunk.contextBufferCount;
|
|
163
|
+
let addStart = hunk.contextBufferAdditionStart;
|
|
164
|
+
let delStart = hunk.contextBufferDeletionStart;
|
|
165
|
+
if (mode === "leading" && count > s.maxContextLines) {
|
|
166
|
+
const difference = count - s.maxContextLines;
|
|
167
|
+
addStart += difference;
|
|
168
|
+
delStart += difference;
|
|
169
|
+
count = s.maxContextLines;
|
|
170
|
+
hunk.additionStart += difference;
|
|
171
|
+
hunk.deletionStart += difference;
|
|
172
|
+
hunk.additionLineIndex += difference;
|
|
173
|
+
hunk.deletionLineIndex += difference;
|
|
174
|
+
}
|
|
175
|
+
if (mode === "trailing" && count > s.maxContextLines) count = s.maxContextLines;
|
|
176
|
+
if (count === 0) {
|
|
177
|
+
hunk.contextBufferCount = 0;
|
|
178
|
+
hunk.contextBufferBaseConflicts = void 0;
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const hunkContent = hunk.hunkContent;
|
|
182
|
+
const lastContent = hunkContent[hunkContent.length - 1];
|
|
183
|
+
let contentIndex;
|
|
184
|
+
if (lastContent?.type === "context") {
|
|
185
|
+
lastContent.lines += count;
|
|
186
|
+
contentIndex = hunkContent.length - 1;
|
|
187
|
+
} else {
|
|
188
|
+
hunkContent.push({
|
|
189
|
+
type: "context",
|
|
190
|
+
lines: count,
|
|
191
|
+
additionLineIndex: addStart,
|
|
192
|
+
deletionLineIndex: delStart
|
|
193
|
+
});
|
|
194
|
+
contentIndex = hunkContent.length - 1;
|
|
195
|
+
}
|
|
196
|
+
hunk.additionCount += count;
|
|
197
|
+
hunk.deletionCount += count;
|
|
198
|
+
const baseConflicts = hunk.contextBufferBaseConflicts;
|
|
199
|
+
if (baseConflicts != null) {
|
|
200
|
+
const bufferStartOffset = addStart - hunk.contextBufferAdditionStart;
|
|
201
|
+
for (const [offset, conflictIndex] of baseConflicts) if (offset >= bufferStartOffset && offset < bufferStartOffset + count) assignConflictContent(s, conflictIndex, "base", contentIndex);
|
|
202
|
+
}
|
|
203
|
+
hunk.contextBufferCount = 0;
|
|
204
|
+
hunk.contextBufferBaseConflicts = void 0;
|
|
205
|
+
}
|
|
206
|
+
function finalizeActiveHunk(s) {
|
|
207
|
+
if (s.activeHunk == null) return;
|
|
208
|
+
const hunk = s.activeHunk;
|
|
209
|
+
s.activeHunk = void 0;
|
|
210
|
+
if (hunk.hunkContent.length === 0) return;
|
|
211
|
+
let hunkSplitLineCount = 0;
|
|
212
|
+
let hunkUnifiedLineCount = 0;
|
|
213
|
+
for (const content of hunk.hunkContent) if (content.type === "context") {
|
|
214
|
+
hunkSplitLineCount += content.lines;
|
|
215
|
+
hunkUnifiedLineCount += content.lines;
|
|
216
|
+
} else {
|
|
217
|
+
hunkSplitLineCount += Math.max(content.additions, content.deletions);
|
|
218
|
+
hunkUnifiedLineCount += content.additions + content.deletions;
|
|
219
|
+
}
|
|
220
|
+
const collapsedBefore = Math.max(hunk.additionStart - 1 - s.lastHunkEnd, 0);
|
|
221
|
+
const finalizedHunk = {
|
|
222
|
+
collapsedBefore,
|
|
223
|
+
additionStart: hunk.additionStart,
|
|
224
|
+
additionCount: hunk.additionCount,
|
|
225
|
+
additionLines: hunk.additionLines,
|
|
226
|
+
additionLineIndex: hunk.additionLineIndex,
|
|
227
|
+
deletionStart: hunk.deletionStart,
|
|
228
|
+
deletionCount: hunk.deletionCount,
|
|
229
|
+
deletionLines: hunk.deletionLines,
|
|
230
|
+
deletionLineIndex: hunk.deletionLineIndex,
|
|
231
|
+
hunkContent: hunk.hunkContent,
|
|
232
|
+
hunkContext: void 0,
|
|
233
|
+
hunkSpecs: `@@ -${formatHunkRange(hunk.deletionStart, hunk.deletionCount)} +${formatHunkRange(hunk.additionStart, hunk.additionCount)} @@\n`,
|
|
234
|
+
splitLineStart: s.splitLineCount + collapsedBefore,
|
|
235
|
+
splitLineCount: hunkSplitLineCount,
|
|
236
|
+
unifiedLineStart: s.unifiedLineCount + collapsedBefore,
|
|
237
|
+
unifiedLineCount: hunkUnifiedLineCount,
|
|
238
|
+
noEOFCRAdditions: false,
|
|
239
|
+
noEOFCRDeletions: false
|
|
240
|
+
};
|
|
241
|
+
s.hunks.push(finalizedHunk);
|
|
242
|
+
s.splitLineCount += collapsedBefore + hunkSplitLineCount;
|
|
243
|
+
s.unifiedLineCount += collapsedBefore + hunkUnifiedLineCount;
|
|
244
|
+
s.lastHunkEnd = hunk.additionStart + hunk.additionCount - 1;
|
|
245
|
+
}
|
|
246
|
+
function splitHunkWithBufferedContext(s) {
|
|
247
|
+
if (s.activeHunk == null) return;
|
|
248
|
+
const hunk = s.activeHunk;
|
|
249
|
+
const count = hunk.contextBufferCount;
|
|
250
|
+
const omittedContextLineCount = count - s.maxContextLines2;
|
|
251
|
+
const nextAddStart = hunk.contextBufferAdditionStart + count - s.maxContextLines;
|
|
252
|
+
const nextDelStart = hunk.contextBufferDeletionStart + count - s.maxContextLines;
|
|
253
|
+
let nextBaseConflicts;
|
|
254
|
+
if (hunk.contextBufferBaseConflicts != null) {
|
|
255
|
+
const tailOffset = count - s.maxContextLines;
|
|
256
|
+
for (const [offset, ci] of hunk.contextBufferBaseConflicts) if (offset >= tailOffset) {
|
|
257
|
+
nextBaseConflicts ??= /* @__PURE__ */ new Map();
|
|
258
|
+
nextBaseConflicts.set(offset - tailOffset, ci);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
flushBufferedContext(s, hunk, "trailing");
|
|
262
|
+
const emittedAdditionCount = hunk.additionCount;
|
|
263
|
+
const emittedDeletionCount = hunk.deletionCount;
|
|
264
|
+
finalizeActiveHunk(s);
|
|
265
|
+
s.activeHunk = createHunkBuilder(hunk.additionStart + emittedAdditionCount + omittedContextLineCount, hunk.deletionStart + emittedDeletionCount + omittedContextLineCount);
|
|
266
|
+
s.activeHunk.contextBufferAdditionStart = nextAddStart;
|
|
267
|
+
s.activeHunk.contextBufferDeletionStart = nextDelStart;
|
|
268
|
+
s.activeHunk.contextBufferCount = s.maxContextLines;
|
|
269
|
+
s.activeHunk.contextBufferBaseConflicts = nextBaseConflicts;
|
|
270
|
+
}
|
|
271
|
+
function emitContextLine(s, line, baseConflictIndex = -1) {
|
|
272
|
+
const hunk = ensureActiveHunk(s);
|
|
273
|
+
if (hunk.contextBufferCount === 0) {
|
|
274
|
+
hunk.contextBufferAdditionStart = s.additionLines.length;
|
|
275
|
+
hunk.contextBufferDeletionStart = s.deletionLines.length;
|
|
276
|
+
}
|
|
277
|
+
s.additionLines.push(line);
|
|
278
|
+
s.deletionLines.push(line);
|
|
279
|
+
if (baseConflictIndex >= 0) {
|
|
280
|
+
hunk.contextBufferBaseConflicts ??= /* @__PURE__ */ new Map();
|
|
281
|
+
hunk.contextBufferBaseConflicts.set(hunk.contextBufferCount, baseConflictIndex);
|
|
282
|
+
}
|
|
283
|
+
hunk.contextBufferCount++;
|
|
284
|
+
}
|
|
285
|
+
function emitChangeLine(s, lineType, line, conflictIndex, role) {
|
|
286
|
+
let hunk = ensureActiveHunk(s);
|
|
287
|
+
if (hunk.hunkContent.length > 0 && hunk.contextBufferCount > s.maxContextLines2) {
|
|
288
|
+
splitHunkWithBufferedContext(s);
|
|
289
|
+
hunk = s.activeHunk;
|
|
290
|
+
}
|
|
291
|
+
flushBufferedContext(s, hunk, hunk.hunkContent.length === 0 ? "leading" : "before-change");
|
|
292
|
+
const additionLineIndex = s.additionLines.length;
|
|
293
|
+
const deletionLineIndex = s.deletionLines.length;
|
|
294
|
+
if (lineType === "addition") s.additionLines.push(line);
|
|
295
|
+
else s.deletionLines.push(line);
|
|
296
|
+
const contentIndex = appendChangeLine(hunk, lineType, additionLineIndex, deletionLineIndex);
|
|
297
|
+
if (lineType === "addition") {
|
|
298
|
+
hunk.additionCount++;
|
|
299
|
+
hunk.additionLines++;
|
|
300
|
+
} else {
|
|
301
|
+
hunk.deletionCount++;
|
|
302
|
+
hunk.deletionLines++;
|
|
303
|
+
}
|
|
304
|
+
assignConflictContent(s, conflictIndex, role, contentIndex);
|
|
305
|
+
}
|
|
306
|
+
function finalizeConflict(s, frame, endLineIndex, endMarkerLine) {
|
|
307
|
+
if (frame.separatorLineIndex == null || frame.markerLines.separator == null) throw new Error(`parseMergeConflictDiffFromFile: conflict ${frame.conflictIndex} is missing a separator marker`);
|
|
308
|
+
const builder = s.conflictBuilders[frame.conflictIndex];
|
|
309
|
+
if (builder == null) throw new Error(`parseMergeConflictDiffFromFile: failed to finalize conflict ${frame.conflictIndex}`);
|
|
310
|
+
const action = builder.action;
|
|
311
|
+
action.markerLines.separator = frame.markerLines.separator;
|
|
312
|
+
action.markerLines.end = endMarkerLine;
|
|
313
|
+
if (frame.markerLines.base != null) action.markerLines.base = frame.markerLines.base;
|
|
314
|
+
action.conflict = {
|
|
315
|
+
conflictIndex: frame.conflictIndex,
|
|
316
|
+
startLineIndex: frame.startLineIndex,
|
|
317
|
+
startLineNumber: frame.startLineIndex + 1,
|
|
318
|
+
separatorLineIndex: frame.separatorLineIndex,
|
|
319
|
+
separatorLineNumber: frame.separatorLineIndex + 1,
|
|
320
|
+
endLineIndex,
|
|
321
|
+
endLineNumber: endLineIndex + 1,
|
|
322
|
+
baseMarkerLineIndex: frame.baseMarkerLineIndex,
|
|
323
|
+
baseMarkerLineNumber: frame.baseMarkerLineIndex != null ? frame.baseMarkerLineIndex + 1 : void 0
|
|
324
|
+
};
|
|
325
|
+
const fallbackContentIndex = action.currentContentIndex ?? action.incomingContentIndex;
|
|
326
|
+
action.currentContentIndex ??= fallbackContentIndex;
|
|
327
|
+
action.incomingContentIndex ??= fallbackContentIndex;
|
|
328
|
+
if (action.startContentIndex < 0 && fallbackContentIndex != null) action.startContentIndex = fallbackContentIndex;
|
|
329
|
+
if (action.endContentIndex < 0 && fallbackContentIndex != null) action.endContentIndex = fallbackContentIndex;
|
|
330
|
+
if (action.endMarkerContentIndex < 0 && fallbackContentIndex != null) action.endMarkerContentIndex = fallbackContentIndex;
|
|
331
|
+
if (action.hunkIndex < 0 || action.startContentIndex < 0 || action.endContentIndex < 0 || action.endMarkerContentIndex < 0) throw new Error(`parseMergeConflictDiffFromFile: failed to anchor merge conflict ${frame.conflictIndex}`);
|
|
332
|
+
s.actions[action.conflictIndex] = action;
|
|
333
|
+
builder.completed = true;
|
|
334
|
+
}
|
|
335
|
+
function handleStartMarker(s, line, lineIndex) {
|
|
336
|
+
const conflictIndex = s.nextConflictIndex;
|
|
337
|
+
s.nextConflictIndex++;
|
|
338
|
+
s.conflictStack.push({
|
|
339
|
+
conflictIndex,
|
|
340
|
+
stage: "current",
|
|
341
|
+
startLineIndex: lineIndex,
|
|
342
|
+
markerLines: { start: line }
|
|
343
|
+
});
|
|
344
|
+
s.conflictBuilders[conflictIndex] = {
|
|
345
|
+
completed: false,
|
|
346
|
+
action: {
|
|
347
|
+
conflict: {
|
|
348
|
+
conflictIndex,
|
|
349
|
+
startLineIndex: lineIndex,
|
|
350
|
+
startLineNumber: lineIndex + 1,
|
|
351
|
+
separatorLineIndex: lineIndex,
|
|
352
|
+
separatorLineNumber: lineIndex + 1,
|
|
353
|
+
endLineIndex: lineIndex,
|
|
354
|
+
endLineNumber: lineIndex + 1,
|
|
355
|
+
baseMarkerLineIndex: void 0,
|
|
356
|
+
baseMarkerLineNumber: void 0
|
|
357
|
+
},
|
|
358
|
+
conflictIndex,
|
|
359
|
+
hunkIndex: -1,
|
|
360
|
+
startContentIndex: -1,
|
|
361
|
+
endContentIndex: -1,
|
|
362
|
+
endMarkerContentIndex: -1,
|
|
363
|
+
markerLines: {
|
|
364
|
+
start: line,
|
|
365
|
+
separator: "",
|
|
366
|
+
end: ""
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function createHunkBuilder(additionStart, deletionStart) {
|
|
372
|
+
return {
|
|
373
|
+
additionStart,
|
|
374
|
+
deletionStart,
|
|
375
|
+
additionCount: 0,
|
|
376
|
+
deletionCount: 0,
|
|
377
|
+
additionLines: 0,
|
|
378
|
+
deletionLines: 0,
|
|
379
|
+
additionLineIndex: Math.max(additionStart - 1, 0),
|
|
380
|
+
deletionLineIndex: Math.max(deletionStart - 1, 0),
|
|
381
|
+
hunkContent: [],
|
|
382
|
+
contextBufferAdditionStart: Math.max(additionStart - 1, 0),
|
|
383
|
+
contextBufferDeletionStart: Math.max(deletionStart - 1, 0),
|
|
384
|
+
contextBufferCount: 0,
|
|
385
|
+
contextBufferBaseConflicts: void 0
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function formatHunkRange(start, count) {
|
|
389
|
+
return count === 1 ? `${start}` : `${start},${count}`;
|
|
390
|
+
}
|
|
391
|
+
function getMergeConflictMarkerType(line) {
|
|
392
|
+
if (line.length < 7) return;
|
|
393
|
+
const markerCode = line.charCodeAt(0);
|
|
394
|
+
if (markerCode !== 60 && markerCode !== 62 && markerCode !== 61 && markerCode !== 124) return;
|
|
395
|
+
const lineEnd = getLineContentEndIndex(line);
|
|
396
|
+
if (lineEnd < 7) return;
|
|
397
|
+
let markerLength = 1;
|
|
398
|
+
while (markerLength < lineEnd && line.charCodeAt(markerLength) === markerCode) markerLength++;
|
|
399
|
+
if (markerLength < 7) return;
|
|
400
|
+
if (markerCode === 61) return markerLength === lineEnd ? "separator" : void 0;
|
|
401
|
+
if (markerLength !== lineEnd && !isWhitespaceCode(line.charCodeAt(markerLength))) return;
|
|
402
|
+
if (markerCode === 60) return "start";
|
|
403
|
+
if (markerCode === 62) return "end";
|
|
404
|
+
return "base";
|
|
405
|
+
}
|
|
406
|
+
function getLineContentEndIndex(line) {
|
|
407
|
+
let end = line.length;
|
|
408
|
+
if (end > 0 && line.charCodeAt(end - 1) === 10) end--;
|
|
409
|
+
if (end > 0 && line.charCodeAt(end - 1) === 13) end--;
|
|
410
|
+
return end;
|
|
411
|
+
}
|
|
412
|
+
function isWhitespaceCode(code) {
|
|
413
|
+
return code === 9 || code === 10 || code === 11 || code === 12 || code === 13 || code === 32;
|
|
129
414
|
}
|
|
130
415
|
function createResolvedConflictFile(file, side, contents) {
|
|
131
416
|
return {
|
|
@@ -134,10 +419,82 @@ function createResolvedConflictFile(file, side, contents) {
|
|
|
134
419
|
cacheKey: file.cacheKey != null ? `${file.cacheKey}:merge-conflict-${side}` : void 0
|
|
135
420
|
};
|
|
136
421
|
}
|
|
137
|
-
function
|
|
138
|
-
|
|
422
|
+
function buildMergeConflictMarkerRows(fileDiff, actions) {
|
|
423
|
+
const markerRows = [];
|
|
424
|
+
const hunkLineStartCache = new Array(fileDiff.hunks.length);
|
|
425
|
+
const getLineStart = (hunkIndex, contentIndex) => {
|
|
426
|
+
const hunk = fileDiff.hunks[hunkIndex];
|
|
427
|
+
if (hunk == null) return 0;
|
|
428
|
+
let starts = hunkLineStartCache[hunkIndex];
|
|
429
|
+
if (starts == null) {
|
|
430
|
+
starts = new Array(hunk.hunkContent.length + 1);
|
|
431
|
+
let lineIndex = hunk.unifiedLineStart;
|
|
432
|
+
starts[0] = lineIndex;
|
|
433
|
+
for (let index = 0; index < hunk.hunkContent.length; index++) {
|
|
434
|
+
const content = hunk.hunkContent[index];
|
|
435
|
+
lineIndex += content.type === "context" ? content.lines : content.deletions + content.additions;
|
|
436
|
+
starts[index + 1] = lineIndex;
|
|
437
|
+
}
|
|
438
|
+
hunkLineStartCache[hunkIndex] = starts;
|
|
439
|
+
}
|
|
440
|
+
return starts[Math.max(contentIndex, 0)] ?? hunk.unifiedLineStart;
|
|
441
|
+
};
|
|
442
|
+
const getLineEnd = (hunkIndex, contentIndex) => {
|
|
443
|
+
const lineStart = getLineStart(hunkIndex, contentIndex);
|
|
444
|
+
const lineEndExclusive = hunkLineStartCache[hunkIndex]?.[Math.max(contentIndex + 1, 0)] ?? getLineStart(hunkIndex, contentIndex + 1);
|
|
445
|
+
return Math.max(lineStart, lineEndExclusive - 1);
|
|
446
|
+
};
|
|
447
|
+
for (const action of actions) {
|
|
448
|
+
if (action == null) continue;
|
|
449
|
+
const hunk = fileDiff.hunks[action.hunkIndex];
|
|
450
|
+
if (hunk == null) continue;
|
|
451
|
+
const actionLineIndex = getLineStart(action.hunkIndex, action.startContentIndex);
|
|
452
|
+
markerRows.push(createMergeConflictMarkerRow(action, "marker-start", action.startContentIndex, action.markerLines.start, actionLineIndex));
|
|
453
|
+
if (action.baseContentIndex != null) {
|
|
454
|
+
const currentContentIndex$1 = action.currentContentIndex;
|
|
455
|
+
const incomingContentIndex = action.incomingContentIndex;
|
|
456
|
+
if (currentContentIndex$1 == null || incomingContentIndex == null) continue;
|
|
457
|
+
const baseMarkerLine = action.markerLines.base;
|
|
458
|
+
if (baseMarkerLine == null) continue;
|
|
459
|
+
const currentChange = hunk.hunkContent[currentContentIndex$1];
|
|
460
|
+
const baseContext = hunk.hunkContent[action.baseContentIndex];
|
|
461
|
+
const incomingChange = hunk.hunkContent[incomingContentIndex];
|
|
462
|
+
if (currentChange?.type !== "change" || baseContext?.type !== "context" || incomingChange?.type !== "change") continue;
|
|
463
|
+
const currentStart = getLineStart(action.hunkIndex, currentContentIndex$1);
|
|
464
|
+
const incomingStart = getLineStart(action.hunkIndex, incomingContentIndex);
|
|
465
|
+
markerRows.push(createMergeConflictMarkerRow(action, "marker-base", action.baseContentIndex, baseMarkerLine, currentStart + currentChange.deletions));
|
|
466
|
+
markerRows.push(createMergeConflictMarkerRow(action, "marker-separator", action.baseContentIndex, action.markerLines.separator, incomingStart), createMergeConflictMarkerRow(action, "marker-end", action.endMarkerContentIndex, action.markerLines.end, getLineEnd(action.hunkIndex, action.endMarkerContentIndex)));
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
469
|
+
const currentContentIndex = action.currentContentIndex;
|
|
470
|
+
if (currentContentIndex == null) continue;
|
|
471
|
+
const content = hunk.hunkContent[currentContentIndex];
|
|
472
|
+
if (content?.type !== "change") continue;
|
|
473
|
+
const contentStart = getLineStart(action.hunkIndex, currentContentIndex);
|
|
474
|
+
const separatorLineIndex = content.deletions > 0 ? contentStart + content.deletions : actionLineIndex;
|
|
475
|
+
markerRows.push(createMergeConflictMarkerRow(action, "marker-separator", currentContentIndex, action.markerLines.separator, separatorLineIndex), createMergeConflictMarkerRow(action, "marker-end", action.endMarkerContentIndex, action.markerLines.end, getLineEnd(action.hunkIndex, action.endMarkerContentIndex)));
|
|
476
|
+
}
|
|
477
|
+
return markerRows;
|
|
478
|
+
}
|
|
479
|
+
function createMergeConflictMarkerRow(action, type, contentIndex, lineText, lineIndex) {
|
|
480
|
+
return {
|
|
481
|
+
type,
|
|
482
|
+
hunkIndex: action.hunkIndex,
|
|
483
|
+
contentIndex,
|
|
484
|
+
conflictIndex: action.conflictIndex,
|
|
485
|
+
lineText,
|
|
486
|
+
lineIndex
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
function getUnifiedLineStartForContent(hunk, contentIndex) {
|
|
490
|
+
let lineIndex = hunk.unifiedLineStart;
|
|
491
|
+
for (let index = 0; index < contentIndex; index++) {
|
|
492
|
+
const content = hunk.hunkContent[index];
|
|
493
|
+
lineIndex += content.type === "context" ? content.lines : content.deletions + content.additions;
|
|
494
|
+
}
|
|
495
|
+
return lineIndex;
|
|
139
496
|
}
|
|
140
497
|
|
|
141
498
|
//#endregion
|
|
142
|
-
export { getMergeConflictActionAnchor, parseMergeConflictDiffFromFile };
|
|
499
|
+
export { buildMergeConflictMarkerRows, getMergeConflictActionAnchor, parseMergeConflictDiffFromFile };
|
|
143
500
|
//# sourceMappingURL=parseMergeConflictDiffFromFile.js.map
|