Parse binary patch diffs
This commit is contained in:
parent
1b9200b201
commit
0f2d650436
2 changed files with 130 additions and 24 deletions
|
|
@ -32,6 +32,9 @@
|
||||||
var oldLine2 = null; // Used for combined diff
|
var oldLine2 = null; // Used for combined diff
|
||||||
var newLine = null;
|
var newLine = null;
|
||||||
|
|
||||||
|
var possibleOldName;
|
||||||
|
var possibleNewName;
|
||||||
|
|
||||||
/* Diff Header */
|
/* Diff Header */
|
||||||
var oldFileNameHeader = '--- ';
|
var oldFileNameHeader = '--- ';
|
||||||
var newFileNameHeader = '+++ ';
|
var newFileNameHeader = '+++ ';
|
||||||
|
|
@ -50,10 +53,23 @@
|
||||||
* if it has name (to avoid binary files errors)
|
* if it has name (to avoid binary files errors)
|
||||||
*/
|
*/
|
||||||
function saveFile() {
|
function saveFile() {
|
||||||
if (currentFile && currentFile.newName) {
|
if (currentFile) {
|
||||||
files.push(currentFile);
|
if (!currentFile.oldName) {
|
||||||
currentFile = null;
|
currentFile.oldName = possibleOldName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!currentFile.newName) {
|
||||||
|
currentFile.newName = possibleNewName;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentFile.newName) {
|
||||||
|
files.push(currentFile);
|
||||||
|
currentFile = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
possibleOldName = undefined;
|
||||||
|
possibleNewName = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create file structure */
|
/* Create file structure */
|
||||||
|
|
@ -196,6 +212,7 @@
|
||||||
var index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/;
|
var index = /^index ([0-9a-z]+)\.\.([0-9a-z]+)\s*(\d{6})?/;
|
||||||
|
|
||||||
var binaryFiles = /^Binary files (.*) and (.*) differ/;
|
var binaryFiles = /^Binary files (.*) and (.*) differ/;
|
||||||
|
var binaryDiff = /^GIT binary patch/;
|
||||||
|
|
||||||
/* Combined Diff */
|
/* Combined Diff */
|
||||||
var combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/;
|
var combinedIndex = /^index ([0-9a-z]+),([0-9a-z]+)\.\.([0-9a-z]+)/;
|
||||||
|
|
@ -211,12 +228,23 @@
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used to store regex capture groups
|
||||||
|
var values;
|
||||||
|
|
||||||
var prevLine = diffLines[lineIndex - 1];
|
var prevLine = diffLines[lineIndex - 1];
|
||||||
var nxtLine = diffLines[lineIndex + 1];
|
var nxtLine = diffLines[lineIndex + 1];
|
||||||
var afterNxtLine = diffLines[lineIndex + 2];
|
var afterNxtLine = diffLines[lineIndex + 2];
|
||||||
|
|
||||||
if (utils.startsWith(line, 'diff')) {
|
if (utils.startsWith(line, 'diff')) {
|
||||||
startFile();
|
startFile();
|
||||||
|
|
||||||
|
// diff --git a/blocked_delta_results.png b/blocked_delta_results.png
|
||||||
|
var gitDiffStart = /^diff --git "?(.+)"? "?(.+)"?/;
|
||||||
|
if ((values = gitDiffStart.exec(line))) {
|
||||||
|
possibleOldName = _getFilename(null, values[1], config.dstPrefix);
|
||||||
|
possibleNewName = _getFilename(null, values[2], config.srcPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
currentFile.isGitDiff = true;
|
currentFile.isGitDiff = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -234,8 +262,6 @@
|
||||||
startFile();
|
startFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
var values;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need to make sure that we have the three lines of the header.
|
* We need to make sure that we have the three lines of the header.
|
||||||
* This avoids cases like the ones described in:
|
* This avoids cases like the ones described in:
|
||||||
|
|
@ -328,8 +354,12 @@
|
||||||
currentFile.isRename = true;
|
currentFile.isRename = true;
|
||||||
} else if ((values = binaryFiles.exec(line))) {
|
} else if ((values = binaryFiles.exec(line))) {
|
||||||
currentFile.isBinary = true;
|
currentFile.isBinary = true;
|
||||||
currentFile.oldName = _getFilename(null, values[1], [config.srcPrefix]);
|
currentFile.oldName = _getFilename(null, values[1], config.srcPrefix);
|
||||||
currentFile.newName = _getFilename(null, values[2], [config.dstPrefix]);
|
currentFile.newName = _getFilename(null, values[2], config.dstPrefix);
|
||||||
|
startBlock('Binary file');
|
||||||
|
} else if ((values = binaryDiff.exec(line))) {
|
||||||
|
currentFile.isBinary = true;
|
||||||
|
startBlock(line);
|
||||||
} else if ((values = similarityIndex.exec(line))) {
|
} else if ((values = similarityIndex.exec(line))) {
|
||||||
currentFile.unchangedPercentage = values[1];
|
currentFile.unchangedPercentage = values[1];
|
||||||
} else if ((values = dissimilarityIndex.exec(line))) {
|
} else if ((values = dissimilarityIndex.exec(line))) {
|
||||||
|
|
@ -369,26 +399,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSrcFilename(line, cfg) {
|
function getSrcFilename(line, cfg) {
|
||||||
var prefixes = ['a/', 'i/', 'w/', 'c/', 'o/'];
|
return _getFilename('---', line, cfg.srcPrefix);
|
||||||
|
|
||||||
if (cfg.srcPrefix) {
|
|
||||||
prefixes.push(cfg.srcPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _getFilename('---', line, prefixes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDstFilename(line, cfg) {
|
function getDstFilename(line, cfg) {
|
||||||
var prefixes = ['b/', 'i/', 'w/', 'c/', 'o/'];
|
return _getFilename('\\+\\+\\+', line, cfg.dstPrefix);
|
||||||
|
|
||||||
if (cfg.dstPrefix) {
|
|
||||||
prefixes.push(cfg.dstPrefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _getFilename('\\+\\+\\+', line, prefixes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function _getFilename(linePrefix, line, prefixes) {
|
function _getFilename(linePrefix, line, extraPrefix) {
|
||||||
|
var prefixes = ['a/', 'b/', 'i/', 'w/', 'c/', 'o/'];
|
||||||
|
if (extraPrefix) {
|
||||||
|
prefixes.push(extraPrefix);
|
||||||
|
}
|
||||||
|
|
||||||
var FilenameRegExp;
|
var FilenameRegExp;
|
||||||
if (linePrefix) {
|
if (linePrefix) {
|
||||||
FilenameRegExp = new RegExp('^' + linePrefix + ' "?(.+?)"?$');
|
FilenameRegExp = new RegExp('^' + linePrefix + ' "?(.+?)"?$');
|
||||||
|
|
|
||||||
|
|
@ -627,10 +627,23 @@ describe('DiffParser', function() {
|
||||||
'diff --git "\ttardis.png" "\ttardis.png"\n' +
|
'diff --git "\ttardis.png" "\ttardis.png"\n' +
|
||||||
'new file mode 100644\n' +
|
'new file mode 100644\n' +
|
||||||
'index 0000000..d503a29\n' +
|
'index 0000000..d503a29\n' +
|
||||||
'Binary files /dev/null and "\ttardis.png" differ\n';
|
'Binary files /dev/null and "\ttardis.png" differ\n' +
|
||||||
|
'diff --git a/src/test-bar.js b/src/test-baz.js\n' +
|
||||||
|
'similarity index 98%\n' +
|
||||||
|
'rename from src/test-bar.js\n' +
|
||||||
|
'rename to src/test-baz.js\n' +
|
||||||
|
'index e01513b..f14a870 100644\n' +
|
||||||
|
'--- a/src/test-bar.js\n' +
|
||||||
|
'+++ b/src/test-baz.js\n' +
|
||||||
|
'@@ -1,4 +1,32 @@\n' +
|
||||||
|
' function foo() {\n' +
|
||||||
|
'-var bar = "Whoops!";\n' +
|
||||||
|
'+var baz = "Whoops!";\n' +
|
||||||
|
' }\n' +
|
||||||
|
' ';
|
||||||
|
|
||||||
var result = DiffParser.generateDiffJson(diff, {'srcPrefix': '\t', 'dstPrefix': '\t'});
|
var result = DiffParser.generateDiffJson(diff, {'srcPrefix': '\t', 'dstPrefix': '\t'});
|
||||||
assert.equal(2, result.length);
|
assert.equal(3, result.length);
|
||||||
|
|
||||||
var file1 = result[0];
|
var file1 = result[0];
|
||||||
assert.equal(2, file1.addedLines);
|
assert.equal(2, file1.addedLines);
|
||||||
|
|
@ -644,6 +657,76 @@ describe('DiffParser', function() {
|
||||||
var file2 = result[1];
|
var file2 = result[1];
|
||||||
assert.equal('/dev/null', file2.oldName);
|
assert.equal('/dev/null', file2.oldName);
|
||||||
assert.equal('tardis.png', file2.newName);
|
assert.equal('tardis.png', file2.newName);
|
||||||
|
|
||||||
|
var file3 = result[2];
|
||||||
|
assert.equal(1, file3.addedLines);
|
||||||
|
assert.equal(1, file3.deletedLines);
|
||||||
|
assert.equal('src/test-bar.js', file3.oldName);
|
||||||
|
assert.equal('src/test-baz.js', file3.newName);
|
||||||
|
assert.equal(1, file3.blocks.length);
|
||||||
|
assert.equal(5, file3.blocks[0].lines.length);
|
||||||
|
var linesContent = file3.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
assert.deepEqual(linesContent,
|
||||||
|
[' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse binary with content', function() {
|
||||||
|
var diff =
|
||||||
|
'diff --git a/favicon.png b/favicon.png\n' +
|
||||||
|
'deleted file mode 100644\n' +
|
||||||
|
'index 2a9d516a5647205d7be510dd0dff93a3663eff6f..0000000000000000000000000000000000000000\n' +
|
||||||
|
'GIT binary patch\n' +
|
||||||
|
'literal 0\n' +
|
||||||
|
'HcmV?d00001\n' +
|
||||||
|
'\n' +
|
||||||
|
'literal 471\n' +
|
||||||
|
'zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf<Z~8yL>4nJ\n' +
|
||||||
|
'za0`Jj<E6WGe}IBwC9V-A&PAz-C7Jno3L%-fsSJk3`UaNzMkcGzh!g=;$beJ?=ckpF\n' +
|
||||||
|
'zCl;kLIHu$$r7E~(7NwTw7iAYKI0u`(*t4mJfq_xq)5S5wqIc=!hrWj$cv|<b{x!c(\n' +
|
||||||
|
'z;3r#y;31Y&=1q>qPVOAS4ANVKzqmCp=Cty@U^(7zk!jHsvT~YI{F^=Ex6g|gox78w\n' +
|
||||||
|
'z+Sn2Du3GS9U7qU`1*NYYlJi3u-!<?H-eky}wyIIL;8VU@wCDrb0``&v(jQ*DWSR4K\n' +
|
||||||
|
'zPq(3;isEyho{emNa=%%!jDPE`l3u;5d=q=<+v8kO-=C`*G#t-*AiE-D>-_B#8k9H0\n' +
|
||||||
|
'zGl{FnZs<2$wz5^=Q2h-1XI^s{LQL1#T4epqNPC%Orl(tD_@!*EY++~^Lt2<2&!&%=\n' +
|
||||||
|
'z`m>(TYj6uS7jDdt=eH>iOyQg(QMR<-Fw8)Dk^ZG)XQTuzEgl{`GpS?Cfq9818R9~=\n' +
|
||||||
|
'z{&h9@9n8F^?|qusoPy{k#%tVHzu7H$t26CR`BJZk*Ixf&u36WuS=?6m2^ho-p00i_\n' +
|
||||||
|
'I>zopr0Nz-&lmGw#\n' +
|
||||||
|
'diff --git a/src/test-bar.js b/src/test-baz.js\n' +
|
||||||
|
'similarity index 98%\n' +
|
||||||
|
'rename from src/test-bar.js\n' +
|
||||||
|
'rename to src/test-baz.js\n' +
|
||||||
|
'index e01513b..f14a870 100644\n' +
|
||||||
|
'--- a/src/test-bar.js\n' +
|
||||||
|
'+++ b/src/test-baz.js\n' +
|
||||||
|
'@@ -1,4 +1,32 @@\n' +
|
||||||
|
' function foo() {\n' +
|
||||||
|
'-var bar = "Whoops!";\n' +
|
||||||
|
'+var baz = "Whoops!";\n' +
|
||||||
|
' }\n' +
|
||||||
|
' ';
|
||||||
|
|
||||||
|
var result = DiffParser.generateDiffJson(diff);
|
||||||
|
assert.equal(2, result.length);
|
||||||
|
|
||||||
|
var file1 = result[0];
|
||||||
|
assert.equal('favicon.png', file1.oldName);
|
||||||
|
assert.equal('favicon.png', file1.newName);
|
||||||
|
assert.equal(1, file1.blocks.length);
|
||||||
|
assert.equal(0, file1.blocks[0].lines.length);
|
||||||
|
|
||||||
|
var file2 = result[1];
|
||||||
|
assert.equal(1, file2.addedLines);
|
||||||
|
assert.equal(1, file2.deletedLines);
|
||||||
|
assert.equal('src/test-bar.js', file2.oldName);
|
||||||
|
assert.equal('src/test-baz.js', file2.newName);
|
||||||
|
assert.equal(1, file2.blocks.length);
|
||||||
|
assert.equal(5, file2.blocks[0].lines.length);
|
||||||
|
var linesContent = file2.blocks[0].lines.map(function(line) {
|
||||||
|
return line.content;
|
||||||
|
});
|
||||||
|
assert.deepEqual(linesContent,
|
||||||
|
[' function foo() {', '-var bar = "Whoops!";', '+var baz = "Whoops!";', ' }', ' ']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue