(mine, theirs, base)
| 1128 | } |
| 1129 | } |
| 1130 | function merge(mine, theirs, base) { |
| 1131 | mine = loadPatch(mine, base); |
| 1132 | theirs = loadPatch(theirs, base); |
| 1133 | var ret = {}; // For index we just let it pass through as it doesn't have any necessary meaning. |
| 1134 | // Leaving sanity checks on this to the API consumer that may know more about the |
| 1135 | // meaning in their own context. |
| 1136 | |
| 1137 | if (mine.index || theirs.index) { |
| 1138 | ret.index = mine.index || theirs.index; |
| 1139 | } |
| 1140 | |
| 1141 | if (mine.newFileName || theirs.newFileName) { |
| 1142 | if (!fileNameChanged(mine)) { |
| 1143 | // No header or no change in ours, use theirs (and ours if theirs does not exist) |
| 1144 | ret.oldFileName = theirs.oldFileName || mine.oldFileName; |
| 1145 | ret.newFileName = theirs.newFileName || mine.newFileName; |
| 1146 | ret.oldHeader = theirs.oldHeader || mine.oldHeader; |
| 1147 | ret.newHeader = theirs.newHeader || mine.newHeader; |
| 1148 | } else if (!fileNameChanged(theirs)) { |
| 1149 | // No header or no change in theirs, use ours |
| 1150 | ret.oldFileName = mine.oldFileName; |
| 1151 | ret.newFileName = mine.newFileName; |
| 1152 | ret.oldHeader = mine.oldHeader; |
| 1153 | ret.newHeader = mine.newHeader; |
| 1154 | } else { |
| 1155 | // Both changed... figure it out |
| 1156 | ret.oldFileName = selectField(ret, mine.oldFileName, theirs.oldFileName); |
| 1157 | ret.newFileName = selectField(ret, mine.newFileName, theirs.newFileName); |
| 1158 | ret.oldHeader = selectField(ret, mine.oldHeader, theirs.oldHeader); |
| 1159 | ret.newHeader = selectField(ret, mine.newHeader, theirs.newHeader); |
| 1160 | } |
| 1161 | } |
| 1162 | |
| 1163 | ret.hunks = []; |
| 1164 | var mineIndex = 0, |
| 1165 | theirsIndex = 0, |
| 1166 | mineOffset = 0, |
| 1167 | theirsOffset = 0; |
| 1168 | |
| 1169 | while (mineIndex < mine.hunks.length || theirsIndex < theirs.hunks.length) { |
| 1170 | var mineCurrent = mine.hunks[mineIndex] || { |
| 1171 | oldStart: Infinity |
| 1172 | }, |
| 1173 | theirsCurrent = theirs.hunks[theirsIndex] || { |
| 1174 | oldStart: Infinity |
| 1175 | }; |
| 1176 | |
| 1177 | if (hunkBefore(mineCurrent, theirsCurrent)) { |
| 1178 | // This patch does not overlap with any of the others, yay. |
| 1179 | ret.hunks.push(cloneHunk(mineCurrent, mineOffset)); |
| 1180 | mineIndex++; |
| 1181 | theirsOffset += mineCurrent.newLines - mineCurrent.oldLines; |
| 1182 | } else if (hunkBefore(theirsCurrent, mineCurrent)) { |
| 1183 | // This patch does not overlap with any of the others, yay. |
| 1184 | ret.hunks.push(cloneHunk(theirsCurrent, theirsOffset)); |
| 1185 | theirsIndex++; |
| 1186 | mineOffset += theirsCurrent.newLines - theirsCurrent.oldLines; |
| 1187 | } else { |
nothing calls this directly
no test coverage detected