1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
ac0345 Tucker McKnight
import _ from 'lodash';
import * as Diff from 'diff';
const getGitDiffsFromPatchText = (patchText) => {
const lines = patchText.split("\n");
const hunks = [];
let previousHunk = -1;
const filenameRegex = RegExp(/diff --git a\/(.*?) b\/(.*?)/);
const lineNumberRegex = RegExp(/@@ -(.*?)[,| ].*/);
let previousFilename = '';
let currentFilename = '';
let skipFourStartingAt = -1;
lines.forEach((line, index) => {
if (line.startsWith("diff")) {
previousFilename = currentFilename;
currentFilename = line.match(filenameRegex)[1];
if (previousHunk !== -1) {
skipFourStartingAt = index;
}
}
if (line.startsWith("@@") || index == lines.length - 1) {
if (previousHunk === -1) {
previousHunk = index;
return;
}
let hunkEndIndex = index + 1;
if (skipFourStartingAt !== -1 && skipFourStartingAt < hunkEndIndex) {
hunkEndIndex = skipFourStartingAt;
skipFourStartingAt = -1;
}
const lastHunk = lines.slice(previousHunk, hunkEndIndex);
let lastHunkBefore = lastHunk.filter(line => line.startsWith("-")).map(str => str.replace("-", "")).join("\n");
let lastHunkAfter = lastHunk.filter(line => line.startsWith("+")).map(str => str.replace("+", "")).join("\n");
lastHunkBefore = _.escape(lastHunkBefore);
lastHunkAfter = _.escape(lastHunkAfter);
const changeObject = Diff.diffWordsWithSpace(lastHunkBefore, lastHunkAfter);
let previousText = "";
let afterText = "";
changeObject.forEach((obj) => {
if (!obj.added && !obj.removed) {
previousText = previousText + obj.value;
afterText = afterText + obj.value;
}
if (obj.added) {
afterText = afterText + "<mark>" + obj.value + "</mark>";
}
if (obj.removed) {
previousText = previousText + "<mark>" + obj.value + "</mark>";
}
});
hunks.push({
file: previousFilename !== '' ? previousFilename : currentFilename,
lineNumber: parseInt(lines[previousHunk].match(lineNumberRegex)[1]),
previousText,
afterText,
});
previousFilename = '';
previousHunk = index;
}
});
return hunks;
};
/** @hidden */
const getDarcsDiffsFromPatchText = (patchText) => {
const lines = patchText.split("\n");
const hunks = [];
let previousHunk = -1;
lines.forEach((line, index) => {
if (line.startsWith("hunk") || index === lines.length - 1) {
if (previousHunk === -1) {
previousHunk = index;
return;
}
// get diff from previous hunk to this next one
const lastHunk = lines.slice(previousHunk, index + 1); // slice is non-inclusive for the end argument
let lastHunkBefore = lastHunk.filter(line => line.startsWith("-")).map(str => str.replace("-", "")).join("\n");
let lastHunkAfter = lastHunk.filter(line => line.startsWith("+")).map(str => str.replace("+", "")).join("\n");
lastHunkBefore = _.escape(lastHunkBefore);
lastHunkAfter = _.escape(lastHunkAfter);
let filename = lines[previousHunk].replace("hunk ./", "");
const changeObject = Diff.diffWords(lastHunkBefore, lastHunkAfter);
let previousText = "";
let afterText = "";
changeObject.forEach((obj) => {
if (!obj.added && !obj.removed) {
previousText = previousText + obj.value;
afterText = afterText + obj.value;
}
if (obj.added) {
afterText = afterText + "<mark>" + obj.value + "</mark>";
}
if (obj.removed) {
previousText = previousText + "<mark>" + obj.value + "</mark>";
}
});
const regex = RegExp(/(.*) ([0-9]+)$/);
const matches = filename.match(regex);
const file = matches[1];
const lineNumber = parseInt(matches[2]);
hunks.push({
file,
lineNumber,
previousText,
afterText,
});
previousHunk = index;
}
});
return hunks;
};
const getLocation = (reposConfig, branchName, repoName) => {
const config = reposConfig.repos[repoName];
if (config._type === "darcs") {
return config.branches[branchName].location;
}
else if (config._type === "git") {
return config.location;
}
};
export { getDarcsDiffsFromPatchText, getGitDiffsFromPatchText, getLocation, };