X-Git-Url: https://git.cameronkatri.com/cgit.git/blobdiff_plain/a342ac6b4d7830f82230b0f6a29bc9378d66747e..e6c960c7c0f0d2e54b51cc43ef190df3ce52755e:/ui-diff.c diff --git a/ui-diff.c b/ui-diff.c index 7ec5701..0dcabe9 100644 --- a/ui-diff.c +++ b/ui-diff.c @@ -7,6 +7,188 @@ */ #include "cgit.h" +#include "html.h" +#include "ui-shared.h" +#include "ui-ssdiff.h" + +unsigned char old_rev_sha1[20]; +unsigned char new_rev_sha1[20]; + +static int files, slots; +static int total_adds, total_rems, max_changes; +static int lines_added, lines_removed; + +static struct fileinfo { + char status; + unsigned char old_sha1[20]; + unsigned char new_sha1[20]; + unsigned short old_mode; + unsigned short new_mode; + char *old_path; + char *new_path; + unsigned int added; + unsigned int removed; + unsigned long old_size; + unsigned long new_size; + int binary:1; +} *items; + +static int use_ssdiff = 0; + +static void print_fileinfo(struct fileinfo *info) +{ + char *class; + + switch (info->status) { + case DIFF_STATUS_ADDED: + class = "add"; + break; + case DIFF_STATUS_COPIED: + class = "cpy"; + break; + case DIFF_STATUS_DELETED: + class = "del"; + break; + case DIFF_STATUS_MODIFIED: + class = "upd"; + break; + case DIFF_STATUS_RENAMED: + class = "mov"; + break; + case DIFF_STATUS_TYPE_CHANGED: + class = "typ"; + break; + case DIFF_STATUS_UNKNOWN: + class = "unk"; + break; + case DIFF_STATUS_UNMERGED: + class = "stg"; + break; + default: + die("bug: unhandled diff status %c", info->status); + } + + html("
", + info->added * 100.0 / max_changes); + htmlf(" | ", + info->removed * 100.0 / max_changes); + htmlf(" | ", + (max_changes - info->removed - info->added) * 100.0 / max_changes); + html(" |
");
+ subproject = (S_ISGITLINK(mode1) || S_ISGITLINK(mode2));
html(" ");
html("diff --git a/");
html_txt(path1);
html(" b/");
html_txt(path2);
- abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
- abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV));
- htmlf("\nindex %s..%s", abbrev1, abbrev2);
- free(abbrev1);
- free(abbrev2);
- html("\n--- a/");
- html_txt(path1);
- html("\n+++ b/");
- html_txt(path2);
+
+ if (is_null_sha1(sha1))
+ path1 = "dev/null";
+ if (is_null_sha1(sha2))
+ path2 = "dev/null";
+
+ if (mode1 == 0)
+ htmlf(" ");
}
+static void print_ssdiff_link()
+{
+ if (!strcmp(ctx.qry.page, "diff")) {
+ if (use_ssdiff)
+ cgit_diff_link("Unidiff", NULL, NULL, ctx.qry.head,
+ ctx.qry.sha1, ctx.qry.sha2, ctx.qry.path, 1);
+ else
+ cgit_diff_link("Side-by-side diff", NULL, NULL,
+ ctx.qry.head, ctx.qry.sha1,
+ ctx.qry.sha2, ctx.qry.path, 1);
+ }
+}
+
static void filepair_cb(struct diff_filepair *pair)
{
- header(pair->one->sha1, pair->one->path,
- pair->two->sha1, pair->two->path);
- if (cgit_diff_files(pair->one->sha1, pair->two->sha1, print_line))
+ unsigned long old_size = 0;
+ unsigned long new_size = 0;
+ int binary = 0;
+ linediff_fn print_line_fn = print_line;
+
+ if (use_ssdiff) {
+ cgit_ssdiff_header_begin();
+ print_line_fn = cgit_ssdiff_line_cb;
+ }
+ header(pair->one->sha1, pair->one->path, pair->one->mode,
+ pair->two->sha1, pair->two->path, pair->two->mode);
+ if (use_ssdiff)
+ cgit_ssdiff_header_end();
+ if (S_ISGITLINK(pair->one->mode) || S_ISGITLINK(pair->two->mode)) {
+ if (S_ISGITLINK(pair->one->mode))
+ print_line_fn(fmt("-Subproject %s", sha1_to_hex(pair->one->sha1)), 52);
+ if (S_ISGITLINK(pair->two->mode))
+ print_line_fn(fmt("+Subproject %s", sha1_to_hex(pair->two->sha1)), 52);
+ if (use_ssdiff)
+ cgit_ssdiff_footer();
+ return;
+ }
+ if (cgit_diff_files(pair->one->sha1, pair->two->sha1, &old_size,
+ &new_size, &binary, ctx.qry.context,
+ ctx.qry.ignorews, print_line_fn))
cgit_print_error("Error running diff");
- html("new file mode %.6o", mode2); + + if (mode2 == 0) + htmlf(" deleted file mode %.6o", mode1); + + if (!subproject) { + abbrev1 = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV)); + abbrev2 = xstrdup(find_unique_abbrev(sha2, DEFAULT_ABBREV)); + htmlf(" index %s..%s", abbrev1, abbrev2); + free(abbrev1); + free(abbrev2); + if (mode1 != 0 && mode2 != 0) { + htmlf(" %.6o", mode1); + if (mode2 != mode1) + htmlf("..%.6o", mode2); + } + html(" --- a/"); + if (mode1 != 0) + cgit_tree_link(path1, NULL, NULL, ctx.qry.head, + sha1_to_hex(old_rev_sha1), path1); + else + html_txt(path1); + html(" +++ b/"); + if (mode2 != 0) + cgit_tree_link(path2, NULL, NULL, ctx.qry.head, + sha1_to_hex(new_rev_sha1), path2); + else + html_txt(path2); + } html(" | |||
Binary files differ |
"); - header(sha1, path, sha2, path); - if (cgit_diff_files(sha1, sha2, print_line)) - cgit_print_error("Error running diff"); - html(" |