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

Commit 4ed1410

Browse files
committed
Merge pull request kpdecker#88 from NodeOS/splitDiffs
Split diffs based on file headers instead of 'Index:' metadata
2 parents 9aefc2a + 3ab1df8 commit 4ed1410

File tree

3 files changed

+56
-24
lines changed

3 files changed

+56
-24
lines changed

src/patch/parse.js

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,42 @@ export function parsePatch(uniDiff, options = {}) {
77
let index = {};
88
list.push(index);
99

10-
// Ignore any leading junk
10+
// Parse diff metadata
1111
while (i < diffstr.length) {
12-
if (/^(Index:|diff -r|@@)/.test(diffstr[i])) {
12+
let line = diffstr[i];
13+
14+
// File header found, end parsing diff metadata
15+
if (/^(\-\-\-|\+\+\+|@@)\s/.test(line)) {
1316
break;
1417
}
15-
i++;
16-
}
17-
18-
let header = (/^(?:Index:|diff(?: -r \w+)+) (.*)/.exec(diffstr[i]));
19-
if (header) {
20-
index.index = header[1];
21-
i++;
2218

23-
if (/^===/.test(diffstr[i])) {
24-
i++;
19+
// Diff index
20+
let header = (/^(?:Index:|diff(?: -r \w+)+)\s+(.+?)\s*$/).exec(line);
21+
if (header) {
22+
index.index = header[1];
2523
}
2624

27-
parseFileHeader(index);
28-
parseFileHeader(index);
29-
} else {
30-
// Ignore erant header components that might occur at the start of the file
31-
parseFileHeader({});
32-
parseFileHeader({});
25+
i++;
3326
}
3427

28+
// Parse file headers if they are defined. Unified diff requires them, but
29+
// there's no technical issues to have an isolated hunk without file header
30+
parseFileHeader(index);
31+
parseFileHeader(index);
32+
33+
// Parse hunks
3534
index.hunks = [];
3635

3736
while (i < diffstr.length) {
38-
if (/^(Index:|diff -r)/.test(diffstr[i])) {
37+
let line = diffstr[i];
38+
39+
if (/^(Index:|diff|\-\-\-|\+\+\+)\s/.test(line)) {
3940
break;
40-
} else if (/^@@/.test(diffstr[i])) {
41+
} else if (/^@@/.test(line)) {
4142
index.hunks.push(parseHunk());
42-
} else if (diffstr[i] && options.strict) {
43+
} else if (line && options.strict) {
4344
// Ignore unexpected content unless in strict mode
44-
throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(diffstr[i]));
45+
throw new Error('Unknown line ' + (i + 1) + ' ' + JSON.stringify(line));
4546
} else {
4647
i++;
4748
}
@@ -51,7 +52,7 @@ export function parsePatch(uniDiff, options = {}) {
5152
// Parses the --- and +++ headers, if none are found, no lines
5253
// are consumed.
5354
function parseFileHeader(index) {
54-
let fileHeader = (/^(\-\-\-|\+\+\+)\s(\S+)\s?(.*)/.exec(diffstr[i]));
55+
let fileHeader = (/^(\-\-\-|\+\+\+)\s+(\S+)\s?(.+?)\s*$/).exec(diffstr[i]);
5556
if (fileHeader) {
5657
let keyPrefix = fileHeader[1] === '---' ? 'old' : 'new';
5758
index[keyPrefix + 'FileName'] = fileHeader[2];

test/patch/apply.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,5 +554,36 @@ describe('patch/apply', function() {
554554
}
555555
});
556556
});
557+
it('should handle patches without Index', function(done) {
558+
const patch =
559+
'===================================================================\n'
560+
+ '--- test\theader1\n'
561+
+ '+++ test\theader2\n'
562+
+ '@@ -1,3 +1,4 @@\n'
563+
+ ' line2\n'
564+
+ ' line3\n'
565+
+ '+line4\n'
566+
+ ' line5\n'
567+
+ '===================================================================\n'
568+
+ '--- test2\theader1\n'
569+
+ '+++ test2\theader2\n'
570+
+ '@@ -1,3 +1,4 @@\n'
571+
+ ' foo2\n'
572+
+ ' foo3\n'
573+
+ '+foo4\n'
574+
+ ' foo5\n';
575+
576+
applyPatches(patch, {
577+
loadFile(index, callback) {
578+
callback(undefined, contents[index.oldFileName]);
579+
},
580+
patched(index, content) {
581+
expect(content)
582+
.to.equal(expected[index.newFileName])
583+
.to.not.be.undefined;
584+
},
585+
complete: done
586+
});
587+
});
557588
});
558589
});

test/patch/parse.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,8 @@ Index: test2
248248
});
249249
it('should throw on invalid input in strict mode', function() {
250250
expect(function() {
251-
parsePatch('Index: foo\nfoo', {strict: true});
252-
}).to['throw'](/Unknown line 2 "foo"/);
251+
parsePatch('Index: foo\n+++ bar\nblah', {strict: true});
252+
}).to['throw'](/Unknown line 3 "blah"/);
253253
});
254254
});
255255
});

0 commit comments

Comments
 (0)