summaryrefslogtreecommitdiffabout
path: root/ui-diff.c
Unidiff
Diffstat (limited to 'ui-diff.c') (more/less context) (ignore whitespace changes)
-rw-r--r--ui-diff.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/ui-diff.c b/ui-diff.c
index 42e81ac..b21c2c1 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -217,126 +217,131 @@ static void header(unsigned char *sha1, char *path1, int mode1,
217 217
218 if (mode1 == 0) 218 if (mode1 == 0)
219 htmlf("<br/>new file mode %.6o", mode2); 219 htmlf("<br/>new file mode %.6o", mode2);
220 220
221 if (mode2 == 0) 221 if (mode2 == 0)
222 htmlf("<br/>deleted file mode %.6o", mode1); 222 htmlf("<br/>deleted file mode %.6o", mode1);
223 223
224 if (!subproject) { 224 if (!subproject) {
225 abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV)); 225 abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
226 abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV)); 226 abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV));
227 htmlf("<br/>index %s..%s", abbrev1, abbrev2); 227 htmlf("<br/>index %s..%s", abbrev1, abbrev2);
228 free(abbrev1); 228 free(abbrev1);
229 free(abbrev2); 229 free(abbrev2);
230 if (mode1 != 0 && mode2 != 0) { 230 if (mode1 != 0 && mode2 != 0) {
231 htmlf(" %.6o", mode1); 231 htmlf(" %.6o", mode1);
232 if (mode2 != mode1) 232 if (mode2 != mode1)
233 htmlf("..%.6o", mode2); 233 htmlf("..%.6o", mode2);
234 } 234 }
235 html("<br/>--- a/"); 235 html("<br/>--- a/");
236 if (mode1 != 0) 236 if (mode1 != 0)
237 cgit_tree_link(path1, NULL, NULL, ctx.qry.head, 237 cgit_tree_link(path1, NULL, NULL, ctx.qry.head,
238 sha1_to_hex(old_rev_sha1), path1); 238 sha1_to_hex(old_rev_sha1), path1);
239 else 239 else
240 html_txt(path1); 240 html_txt(path1);
241 html("<br/>+++ b/"); 241 html("<br/>+++ b/");
242 if (mode2 != 0) 242 if (mode2 != 0)
243 cgit_tree_link(path2, NULL, NULL, ctx.qry.head, 243 cgit_tree_link(path2, NULL, NULL, ctx.qry.head,
244 sha1_to_hex(new_rev_sha1), path2); 244 sha1_to_hex(new_rev_sha1), path2);
245 else 245 else
246 html_txt(path2); 246 html_txt(path2);
247 } 247 }
248 html("</div>"); 248 html("</div>");
249 if (use_ssdiff)
250 cgit_ssdiff_header();
251} 249}
252 250
253static void print_ssdiff_link() 251static void print_ssdiff_link()
254{ 252{
255 if (!strcmp(ctx.qry.page, "diff")) { 253 if (!strcmp(ctx.qry.page, "diff")) {
256 if (use_ssdiff) 254 if (use_ssdiff)
257 cgit_diff_link("Unidiff", NULL, NULL, ctx.qry.head, 255 cgit_diff_link("Unidiff", NULL, NULL, ctx.qry.head,
258 ctx.qry.sha1, ctx.qry.sha2, NULL, 1); 256 ctx.qry.sha1, ctx.qry.sha2, NULL, 1);
259 else 257 else
260 cgit_diff_link("Side-by-side diff", NULL, NULL, 258 cgit_diff_link("Side-by-side diff", NULL, NULL,
261 ctx.qry.head, ctx.qry.sha1, 259 ctx.qry.head, ctx.qry.sha1,
262 ctx.qry.sha2, NULL, 1); 260 ctx.qry.sha2, NULL, 1);
263 } 261 }
264} 262}
265 263
266static void filepair_cb(struct diff_filepair *pair) 264static void filepair_cb(struct diff_filepair *pair)
267{ 265{
268 unsigned long old_size = 0; 266 unsigned long old_size = 0;
269 unsigned long new_size = 0; 267 unsigned long new_size = 0;
270 int binary = 0; 268 int binary = 0;
271 linediff_fn print_line_fn = print_line; 269 linediff_fn print_line_fn = print_line;
272 270
273 header(pair->one->sha1, pair->one->path, pair->one->mode,
274 pair->two->sha1, pair->two->path, pair->two->mode);
275 if (use_ssdiff) { 271 if (use_ssdiff) {
276 cgit_ssdiff_header(); 272 cgit_ssdiff_header_begin();
277 print_line_fn = cgit_ssdiff_line_cb; 273 print_line_fn = cgit_ssdiff_line_cb;
278 } 274 }
275 header(pair->one->sha1, pair->one->path, pair->one->mode,
276 pair->two->sha1, pair->two->path, pair->two->mode);
277 if (use_ssdiff)
278 cgit_ssdiff_header_end();
279 if (S_ISGITLINK(pair->one->mode) || S_ISGITLINK(pair->two->mode)) { 279 if (S_ISGITLINK(pair->one->mode) || S_ISGITLINK(pair->two->mode)) {
280 if (S_ISGITLINK(pair->one->mode)) 280 if (S_ISGITLINK(pair->one->mode))
281 print_line(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52); 281 print_line_fn(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52);
282 if (S_ISGITLINK(pair->two->mode)) 282 if (S_ISGITLINK(pair->two->mode))
283 print_line(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52); 283 print_line_fn(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52);
284 return; 284 return;
285 } 285 }
286 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size, 286 if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
287 &new_size, &binary, print_line_fn)) 287 &new_size, &binary, print_line_fn))
288 cgit_print_error("Error running diff"); 288 cgit_print_error("Error running diff");
289 if (binary) 289 if (binary)
290 html("Binary files differ"); 290 print_line_fn(" Binary files differ", 20);
291 if (use_ssdiff) 291 if (use_ssdiff)
292 cgit_ssdiff_footer(); 292 cgit_ssdiff_footer();
293} 293}
294 294
295void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefix) 295void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefix)
296{ 296{
297 enum object_type type; 297 enum object_type type;
298 unsigned long size; 298 unsigned long size;
299 struct commit *commit, *commit2; 299 struct commit *commit, *commit2;
300 300
301 if (!new_rev) 301 if (!new_rev)
302 new_rev = ctx.qry.head; 302 new_rev = ctx.qry.head;
303 get_sha1(new_rev, new_rev_sha1); 303 get_sha1(new_rev, new_rev_sha1);
304 type = sha1_object_info(new_rev_sha1, &size); 304 type = sha1_object_info(new_rev_sha1, &size);
305 if (type == OBJ_BAD) { 305 if (type == OBJ_BAD) {
306 cgit_print_error(fmt("Bad object name: %s", new_rev)); 306 cgit_print_error(fmt("Bad object name: %s", new_rev));
307 return; 307 return;
308 } 308 }
309 commit = lookup_commit_reference(new_rev_sha1); 309 commit = lookup_commit_reference(new_rev_sha1);
310 if (!commit || parse_commit(commit)) 310 if (!commit || parse_commit(commit))
311 cgit_print_error(fmt("Bad commit: %s", sha1_to_hex(new_rev_sha1))); 311 cgit_print_error(fmt("Bad commit: %s", sha1_to_hex(new_rev_sha1)));
312 312
313 if (old_rev) 313 if (old_rev)
314 get_sha1(old_rev, old_rev_sha1); 314 get_sha1(old_rev, old_rev_sha1);
315 else if (commit->parents && commit->parents->item) 315 else if (commit->parents && commit->parents->item)
316 hashcpy(old_rev_sha1, commit->parents->item->object.sha1); 316 hashcpy(old_rev_sha1, commit->parents->item->object.sha1);
317 else 317 else
318 hashclr(old_rev_sha1); 318 hashclr(old_rev_sha1);
319 319
320 if (!is_null_sha1(old_rev_sha1)) { 320 if (!is_null_sha1(old_rev_sha1)) {
321 type = sha1_object_info(old_rev_sha1, &size); 321 type = sha1_object_info(old_rev_sha1, &size);
322 if (type == OBJ_BAD) { 322 if (type == OBJ_BAD) {
323 cgit_print_error(fmt("Bad object name: %s", sha1_to_hex(old_rev_sha1))); 323 cgit_print_error(fmt("Bad object name: %s", sha1_to_hex(old_rev_sha1)));
324 return; 324 return;
325 } 325 }
326 commit2 = lookup_commit_reference(old_rev_sha1); 326 commit2 = lookup_commit_reference(old_rev_sha1);
327 if (!commit2 || parse_commit(commit2)) 327 if (!commit2 || parse_commit(commit2))
328 cgit_print_error(fmt("Bad commit: %s", sha1_to_hex(old_rev_sha1))); 328 cgit_print_error(fmt("Bad commit: %s", sha1_to_hex(old_rev_sha1)));
329 } 329 }
330 330
331 if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff)) 331 if ((ctx.qry.ssdiff && !ctx.cfg.ssdiff) || (!ctx.qry.ssdiff && ctx.cfg.ssdiff))
332 use_ssdiff = 1; 332 use_ssdiff = 1;
333 333
334 print_ssdiff_link(); 334 print_ssdiff_link();
335 cgit_print_diffstat(old_rev_sha1, new_rev_sha1); 335 cgit_print_diffstat(old_rev_sha1, new_rev_sha1);
336 336
337 html("<table summary='diff' class='diff'>"); 337 if (use_ssdiff) {
338 html("<tr><td>"); 338 html("<table summary='ssdiff' class='ssdiff'>");
339 } else {
340 html("<table summary='diff' class='diff'>");
341 html("<tr><td>");
342 }
339 cgit_diff_tree(old_rev_sha1, new_rev_sha1, filepair_cb, prefix); 343 cgit_diff_tree(old_rev_sha1, new_rev_sha1, filepair_cb, prefix);
340 html("</td></tr>"); 344 if (!use_ssdiff)
345 html("</td></tr>");
341 html("</table>"); 346 html("</table>");
342} 347}