Skip to content
This repository was archived by the owner on Jan 14, 2019. It is now read-only.

Commit 53bf384

Browse files
Haitao Likpdecker
Haitao Li
authored andcommitted
count oldLines and newLines when there are conflicts
1 parent 9e24284 commit 53bf384

File tree

2 files changed

+200
-20
lines changed

2 files changed

+200
-20
lines changed

src/patch/merge.js

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,17 @@ import {parsePatch} from './parse';
44
import {arrayEqual, arrayStartsWith} from '../util/array';
55

66
export function calcLineCount(hunk) {
7-
let conflicted = false;
7+
const {oldLines, newLines} = calcOldNewLineCount(hunk.lines);
88

9-
hunk.oldLines = 0;
10-
hunk.newLines = 0;
11-
12-
hunk.lines.forEach(function(line) {
13-
if (typeof line !== 'string') {
14-
conflicted = true;
15-
return;
16-
}
17-
18-
if (line[0] === '+' || line[0] === ' ') {
19-
hunk.newLines++;
20-
}
21-
if (line[0] === '-' || line[0] === ' ') {
22-
hunk.oldLines++;
23-
}
24-
});
25-
26-
if (conflicted) {
9+
if (oldLines !== undefined) {
10+
hunk.oldLines = oldLines;
11+
} else {
2712
delete hunk.oldLines;
13+
}
14+
15+
if (newLines !== undefined) {
16+
hunk.newLines = newLines;
17+
} else {
2818
delete hunk.newLines;
2919
}
3020
}
@@ -347,3 +337,40 @@ function skipRemoveSuperset(state, removeChanges, delta) {
347337
state.index += delta;
348338
return true;
349339
}
340+
341+
function calcOldNewLineCount(lines) {
342+
let oldLines = 0;
343+
let newLines = 0;
344+
345+
lines.forEach(function(line) {
346+
if (typeof line !== 'string') {
347+
let myCount = calcOldNewLineCount(line.mine);
348+
let theirCount = calcOldNewLineCount(line.theirs);
349+
350+
if (oldLines !== undefined) {
351+
if (myCount.oldLines === theirCount.oldLines) {
352+
oldLines += myCount.oldLines;
353+
} else {
354+
oldLines = undefined;
355+
}
356+
}
357+
358+
if (newLines !== undefined) {
359+
if (myCount.newLines === theirCount.newLines) {
360+
newLines += myCount.newLines;
361+
} else {
362+
newLines = undefined;
363+
}
364+
}
365+
} else {
366+
if (newLines !== undefined && (line[0] === '+' || line[0] === ' ')) {
367+
newLines++;
368+
}
369+
if (oldLines !== undefined && (line[0] === '-' || line[0] === ' ')) {
370+
oldLines++;
371+
}
372+
}
373+
});
374+
375+
return {oldLines, newLines};
376+
}

test/patch/merge.js

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,9 @@ describe('patch/merge', function() {
354354
{
355355
conflict: true,
356356
oldStart: 1,
357+
oldLines: 6,
357358
newStart: 1,
359+
newLines: 3,
358360
lines: [
359361
' line2',
360362
' line3',
@@ -407,6 +409,7 @@ describe('patch/merge', function() {
407409
conflict: true,
408410
oldStart: 1,
409411
newStart: 1,
412+
newLines: 4,
410413
lines: [
411414
' line2',
412415
' line3',
@@ -454,6 +457,7 @@ describe('patch/merge', function() {
454457
{
455458
conflict: true,
456459
oldStart: 1,
460+
oldLines: 3,
457461
newStart: 1,
458462
lines: [
459463
' line2',
@@ -499,6 +503,7 @@ describe('patch/merge', function() {
499503
{
500504
conflict: true,
501505
oldStart: 1,
506+
oldLines: 3,
502507
newStart: 1,
503508
lines: [
504509
' line2',
@@ -538,6 +543,7 @@ describe('patch/merge', function() {
538543
{
539544
conflict: true,
540545
oldStart: 1,
546+
oldLines: 2,
541547
newStart: 1,
542548
lines: [
543549
' line2',
@@ -829,6 +835,7 @@ describe('patch/merge', function() {
829835
{
830836
conflict: true,
831837
oldStart: 1,
838+
oldLines: 4,
832839
newStart: 1,
833840
lines: [
834841
'-line2',
@@ -936,6 +943,7 @@ describe('patch/merge', function() {
936943
{
937944
conflict: true,
938945
oldStart: 1,
946+
oldLines: 6,
939947
newStart: 1,
940948
lines: [
941949
'-line2',
@@ -1003,7 +1011,150 @@ describe('patch/merge', function() {
10031011
swapConflicts(expected);
10041012
expect(merge(theirs, mine)).to.eql(expected);
10051013
});
1006-
it('should conflict context mismatch', function() {
1014+
1015+
it('should handle multiple conflicts in one hunk', function() {
1016+
const mine =
1017+
'@@ -1,10 +1,10 @@\n'
1018+
+ ' line1\n'
1019+
+ '-line2\n'
1020+
+ '+line2-1\n'
1021+
+ ' line3\n'
1022+
+ ' line4\n'
1023+
+ ' line5\n'
1024+
+ '-line6\n'
1025+
+ '+line6-1\n'
1026+
+ ' line7\n';
1027+
const theirs =
1028+
'@@ -1,10 +1,10 @@\n'
1029+
+ ' line1\n'
1030+
+ '-line2\n'
1031+
+ '+line2-2\n'
1032+
+ ' line3\n'
1033+
+ ' line4\n'
1034+
+ ' line5\n'
1035+
+ '-line6\n'
1036+
+ '+line6-2\n'
1037+
+ ' line7\n';
1038+
const expected = {
1039+
hunks: [
1040+
{
1041+
conflict: true,
1042+
oldStart: 1,
1043+
oldLines: 7,
1044+
newStart: 1,
1045+
newLines: 7,
1046+
lines: [
1047+
' line1',
1048+
{
1049+
conflict: true,
1050+
mine: [
1051+
'-line2',
1052+
'+line2-1'
1053+
],
1054+
theirs: [
1055+
'-line2',
1056+
'+line2-2'
1057+
]
1058+
},
1059+
' line3',
1060+
' line4',
1061+
' line5',
1062+
{
1063+
conflict: true,
1064+
mine: [
1065+
'-line6',
1066+
'+line6-1'
1067+
],
1068+
theirs: [
1069+
'-line6',
1070+
'+line6-2'
1071+
]
1072+
},
1073+
' line7'
1074+
]
1075+
}
1076+
]
1077+
};
1078+
1079+
expect(merge(mine, theirs)).to.eql(expected);
1080+
1081+
swapConflicts(expected);
1082+
expect(merge(theirs, mine)).to.eql(expected);
1083+
});
1084+
1085+
it('should remove oldLines if base differs', function() {
1086+
const mine =
1087+
'@@ -1,10 +1,10 @@\n'
1088+
+ ' line1\n'
1089+
+ '-line2\n'
1090+
+ '-line2-0\n'
1091+
+ '+line2-1\n'
1092+
+ ' line3\n'
1093+
+ ' line4\n'
1094+
+ ' line5\n'
1095+
+ '-line6\n'
1096+
+ '+line6-1\n'
1097+
+ ' line7\n';
1098+
const theirs =
1099+
'@@ -1,10 +1,10 @@\n'
1100+
+ ' line1\n'
1101+
+ '-line2\n'
1102+
+ '+line2-2\n'
1103+
+ '+line2-3\n'
1104+
+ ' line3\n'
1105+
+ ' line4\n'
1106+
+ ' line5\n'
1107+
+ '-line6\n'
1108+
+ '+line6-2\n'
1109+
+ ' line7\n';
1110+
const expected = {
1111+
hunks: [
1112+
{
1113+
conflict: true,
1114+
oldStart: 1,
1115+
newStart: 1,
1116+
lines: [
1117+
' line1',
1118+
{
1119+
conflict: true,
1120+
mine: [
1121+
'-line2',
1122+
'-line2-0',
1123+
'+line2-1'
1124+
],
1125+
theirs: [
1126+
'-line2',
1127+
'+line2-2',
1128+
'+line2-3'
1129+
]
1130+
},
1131+
' line3',
1132+
' line4',
1133+
' line5',
1134+
{
1135+
conflict: true,
1136+
mine: [
1137+
'-line6',
1138+
'+line6-1'
1139+
],
1140+
theirs: [
1141+
'-line6',
1142+
'+line6-2'
1143+
]
1144+
},
1145+
' line7'
1146+
]
1147+
}
1148+
]
1149+
};
1150+
1151+
expect(merge(mine, theirs)).to.eql(expected);
1152+
1153+
swapConflicts(expected);
1154+
expect(merge(theirs, mine)).to.eql(expected);
1155+
});
1156+
1157+
it('should handle multiple conflict sections', function() {
10071158
const mine =
10081159
'@@ -1,3 +1,4 @@\n'
10091160
+ ' line2\n'
@@ -1017,7 +1168,9 @@ describe('patch/merge', function() {
10171168
{
10181169
conflict: true,
10191170
oldStart: 1,
1171+
oldLines: 2,
10201172
newStart: 1,
1173+
newLines: 2,
10211174
lines: [
10221175
{
10231176
conflict: true,

0 commit comments

Comments
 (0)