summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--cgit.css66
-rw-r--r--ui-diff.c21
-rw-r--r--ui-ssdiff.c20
-rw-r--r--ui-ssdiff.h3
4 files changed, 88 insertions, 22 deletions
diff --git a/cgit.css b/cgit.css
index bf58b8a..3f37165 100644
--- a/cgit.css
+++ b/cgit.css
@@ -581,58 +581,112 @@ table.vgraph div.bar {
581} 581}
582 582
583table.hgraph { 583table.hgraph {
584 border: solid 1px black; 584 border: solid 1px black;
585 width: 800px; 585 width: 800px;
586} 586}
587 587
588table.hgraph th { 588table.hgraph th {
589 background-color: #eee; 589 background-color: #eee;
590 font-weight: bold; 590 font-weight: bold;
591 border: solid 1px black; 591 border: solid 1px black;
592 padding: 1px 0.5em; 592 padding: 1px 0.5em;
593} 593}
594 594
595table.hgraph td { 595table.hgraph td {
596 vertical-align: center; 596 vertical-align: center;
597 padding: 2px 2px; 597 padding: 2px 2px;
598} 598}
599 599
600table.hgraph div.bar { 600table.hgraph div.bar {
601 background-color: #eee; 601 background-color: #eee;
602 height: 1em; 602 height: 1em;
603} 603}
604 604
605table.ssdiff {
606 width: 100%;
607}
608
609table.ssdiff td {
610 font-size: 75%;
611 font-family: monospace;
612 white-space: pre;
613 padding: 1px 4px 1px 4px;
614 border-left: solid 1px #aaa;
615 border-right: solid 1px #aaa;
616}
617
605table.ssdiff td.add { 618table.ssdiff td.add {
606 color: black; 619 color: black;
607 background: #afa; 620 background: #cfc;
621 min-width: 50%;
608} 622}
609 623
610table.ssdiff td.add_dark { 624table.ssdiff td.add_dark {
611 color: black; 625 color: black;
612 background: #9c9; 626 background: #aca;
627 min-width: 50%;
613} 628}
614 629
615table.ssdiff td.del { 630table.ssdiff td.del {
616 color: black; 631 color: black;
617 background: #faa; 632 background: #fcc;
633 min-width: 50%;
618} 634}
619 635
620table.ssdiff td.del_dark { 636table.ssdiff td.del_dark {
621 color: black; 637 color: black;
622 background: #c99; 638 background: #caa;
639 min-width: 50%;
623} 640}
624 641
625table.ssdiff td.changed { 642table.ssdiff td.changed {
626 color: black; 643 color: black;
627 background: #ffa; 644 background: #ffc;
645 min-width: 50%;
628} 646}
629 647
630table.ssdiff td.changed_dark { 648table.ssdiff td.changed_dark {
631 color: black; 649 color: black;
632 background: #cc9; 650 background: #cca;
651 min-width: 50%;
652}
653
654table.ssdiff td.lineno {
655 color: black;
656 background: #eee;
657 text-align: right;
658 width: 3em;
659 min-width: 3em;
633} 660}
634 661
635table.ssdiff td.hunk { 662table.ssdiff td.hunk {
636 color: #black; 663 color: #black;
637 background: #ccf; 664 background: #ccf;
665 border-top: solid 1px #aaa;
666 border-bottom: solid 1px #aaa;
667}
668
669table.ssdiff td.head {
670 border-top: solid 1px #aaa;
671 border-bottom: solid 1px #aaa;
672}
673
674table.ssdiff td.head div.head {
675 font-weight: bold;
676 color: black;
677}
678
679table.ssdiff td.foot {
680 border-top: solid 1px #aaa;
681 border-left: none;
682 border-right: none;
683 border-bottom: none;
684}
685
686table.ssdiff td.space {
687 border: none;
688}
689
690table.ssdiff td.space div {
691 min-height: 3em;
638} 692}
diff --git a/ui-diff.c b/ui-diff.c
index 42e81ac..b21c2c1 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -225,118 +225,123 @@ static void header(unsigned char *sha1, char *path1, int mode1,
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 if (use_ssdiff) {
338 html("<table summary='ssdiff' class='ssdiff'>");
339 } else {
337 html("<table summary='diff' class='diff'>"); 340 html("<table summary='diff' class='diff'>");
338 html("<tr><td>"); 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);
344 if (!use_ssdiff)
340 html("</td></tr>"); 345 html("</td></tr>");
341 html("</table>"); 346 html("</table>");
342} 347}
diff --git a/ui-ssdiff.c b/ui-ssdiff.c
index 3591ab4..8215051 100644
--- a/ui-ssdiff.c
+++ b/ui-ssdiff.c
@@ -85,66 +85,66 @@ static void deferred_old_add(char *line, int line_no)
85 } else { 85 } else {
86 deferred_old = deferred_old_last = item; 86 deferred_old = deferred_old_last = item;
87 } 87 }
88} 88}
89 89
90static void deferred_new_add(char *line, int line_no) 90static void deferred_new_add(char *line, int line_no)
91{ 91{
92 struct deferred_lines *item = xmalloc(sizeof(struct deferred_lines)); 92 struct deferred_lines *item = xmalloc(sizeof(struct deferred_lines));
93 item->line = xstrdup(line); 93 item->line = xstrdup(line);
94 item->line_no = line_no; 94 item->line_no = line_no;
95 item->next = NULL; 95 item->next = NULL;
96 if (deferred_new) { 96 if (deferred_new) {
97 deferred_new_last->next = item; 97 deferred_new_last->next = item;
98 deferred_new_last = item; 98 deferred_new_last = item;
99 } else { 99 } else {
100 deferred_new = deferred_new_last = item; 100 deferred_new = deferred_new_last = item;
101 } 101 }
102} 102}
103 103
104static void print_ssdiff_line(char *class, int old_line_no, char *old_line, 104static void print_ssdiff_line(char *class, int old_line_no, char *old_line,
105 int new_line_no, char *new_line) 105 int new_line_no, char *new_line)
106{ 106{
107 html("<tr>"); 107 html("<tr>");
108 if (old_line_no > 0) 108 if (old_line_no > 0)
109 htmlf("<td class='%s'>%d </td><td class='%s'>", class, 109 htmlf("<td class='lineno'>%d</td><td class='%s'>",
110 old_line_no, class); 110 old_line_no, class);
111 else 111 else
112 htmlf("<td class='%s_dark'> </td><td class='%s_dark'>", class, class); 112 htmlf("<td class='lineno'></td><td class='%s_dark'>", class);
113 113
114 if (old_line) { 114 if (old_line) {
115 old_line = replace_tabs(old_line + 1); 115 old_line = replace_tabs(old_line + 1);
116 html_txt(old_line); 116 html_txt(old_line);
117 free(old_line); 117 free(old_line);
118 } 118 }
119 119
120 html(" </td>"); 120 html(" </td>");
121 121
122 if (new_line_no > 0) 122 if (new_line_no > 0)
123 htmlf("<td class='%s'> %d </td><td class='%s'>", class, 123 htmlf("<td class='lineno'>%d</td><td class='%s'>",
124 new_line_no, class); 124 new_line_no, class);
125 else 125 else
126 htmlf("<td class='%s_dark'> </td><td class='%s_dark'>", class, class); 126 htmlf("<td class='lineno'></td><td class='%s_dark'>", class);
127 127
128 if (new_line) { 128 if (new_line) {
129 new_line = replace_tabs(new_line + 1); 129 new_line = replace_tabs(new_line + 1);
130 html_txt(new_line); 130 html_txt(new_line);
131 free(new_line); 131 free(new_line);
132 } 132 }
133 133
134 html("</td></tr>"); 134 html("</td></tr>");
135} 135}
136 136
137static void print_deferred_old_lines() 137static void print_deferred_old_lines()
138{ 138{
139 struct deferred_lines *iter_old, *tmp; 139 struct deferred_lines *iter_old, *tmp;
140 140
141 iter_old = deferred_old; 141 iter_old = deferred_old;
142 while (iter_old) { 142 while (iter_old) {
143 print_ssdiff_line("del", iter_old->line_no, 143 print_ssdiff_line("del", iter_old->line_no,
144 iter_old->line, -1, NULL); 144 iter_old->line, -1, NULL);
145 tmp = iter_old->next; 145 tmp = iter_old->next;
146 free(iter_old); 146 free(iter_old);
147 iter_old = tmp; 147 iter_old = tmp;
148 } 148 }
149} 149}
150 150
@@ -228,37 +228,43 @@ void cgit_ssdiff_line_cb(char *line, int len)
228 if (deferred_old || deferred_new) 228 if (deferred_old || deferred_new)
229 cgit_ssdiff_print_deferred_lines(); 229 cgit_ssdiff_print_deferred_lines();
230 print_ssdiff_line("ctx", current_old_line, line, 230 print_ssdiff_line("ctx", current_old_line, line,
231 current_new_line, line); 231 current_new_line, line);
232 current_old_line += 1; 232 current_old_line += 1;
233 current_new_line += 1; 233 current_new_line += 1;
234 } else if (line[0] == '+') { 234 } else if (line[0] == '+') {
235 deferred_new_add(line, current_new_line); 235 deferred_new_add(line, current_new_line);
236 current_new_line += 1; 236 current_new_line += 1;
237 } else if (line[0] == '-') { 237 } else if (line[0] == '-') {
238 deferred_old_add(line, current_old_line); 238 deferred_old_add(line, current_old_line);
239 current_old_line += 1; 239 current_old_line += 1;
240 } else if (line[0] == '@') { 240 } else if (line[0] == '@') {
241 html("<tr><td colspan='4' class='hunk'>"); 241 html("<tr><td colspan='4' class='hunk'>");
242 html_txt(line); 242 html_txt(line);
243 html("</td></tr>"); 243 html("</td></tr>");
244 } else { 244 } else {
245 html("<tr><td colspan='4' class='ctx'>"); 245 html("<tr><td colspan='4' class='ctx'>");
246 html_txt(line); 246 html_txt(line);
247 html("</td></tr>"); 247 html("</td></tr>");
248 } 248 }
249 line[len - 1] = c; 249 line[len - 1] = c;
250} 250}
251 251
252void cgit_ssdiff_header() 252void cgit_ssdiff_header_begin()
253{ 253{
254 current_old_line = 0; 254 current_old_line = 0;
255 current_new_line = 0; 255 current_new_line = 0;
256 html("<table class='ssdiff'>"); 256 html("<tr><td class='space' colspan='4'><div></div></td></tr>");
257 html("<tr><td class='head' colspan='4'>");
258}
259
260void cgit_ssdiff_header_end()
261{
262 html("</td><tr>");
257} 263}
258 264
259void cgit_ssdiff_footer() 265void cgit_ssdiff_footer()
260{ 266{
261 if (deferred_old || deferred_new) 267 if (deferred_old || deferred_new)
262 cgit_ssdiff_print_deferred_lines(); 268 cgit_ssdiff_print_deferred_lines();
263 html("</table>"); 269 html("<tr><td class='foot' colspan='4'></td></tr>");
264} 270}
diff --git a/ui-ssdiff.h b/ui-ssdiff.h
index a0b1efe..64b4b12 100644
--- a/ui-ssdiff.h
+++ b/ui-ssdiff.h
@@ -1,12 +1,13 @@
1#ifndef UI_SSDIFF_H 1#ifndef UI_SSDIFF_H
2#define UI_SSDIFF_H 2#define UI_SSDIFF_H
3 3
4extern void cgit_ssdiff_print_deferred_lines(); 4extern void cgit_ssdiff_print_deferred_lines();
5 5
6extern void cgit_ssdiff_line_cb(char *line, int len); 6extern void cgit_ssdiff_line_cb(char *line, int len);
7 7
8extern void cgit_ssdiff_header(); 8extern void cgit_ssdiff_header_begin();
9extern void cgit_ssdiff_header_end();
9 10
10extern void cgit_ssdiff_footer(); 11extern void cgit_ssdiff_footer();
11 12
12#endif /* UI_SSDIFF_H */ 13#endif /* UI_SSDIFF_H */