Diff options
Diffstat (limited to '')
| -rw-r--r-- | source/ui-diff.c | 126 |
1 file changed, 34 insertions, 92 deletions
diff --git a/source/ui-diff.c b/source/ui-diff.c index 91ad860..315a8f0 100644 --- a/source/ui-diff.c +++ b/source/ui-diff.c @@ -54,7 +54,6 @@ static int bodies_usable; static linediff_fn render_line_fn; static int render_suppressed; -static struct diff_filepair *current_filepair; static const char *current_prefix; static int use_ssdiff; @@ -187,15 +186,9 @@ static int show_filepair(struct diff_filepair *pair) starts_with(pair->two->path, current_prefix); } -/* - * The line xdiff produces ends in its newline, which is swapped for a - * terminator while the text is escaped and then put back, because the line - * points into a buffer xdiff still owns. - */ static void print_line(char *line, int len) { const char *class = "ctx"; - char c = line[len - 1]; if (line[0] == '+') class = "add"; @@ -205,31 +198,26 @@ static void print_line(char *line, int len) class = "hunk"; htmlf("<div class='%s'>", class); - line[len - 1] = '\0'; - html_txt(line); + html_ntxt(line, len - 1); html("</div>"); - line[len - 1] = c; } /* - * The buffer repo_find_unique_abbrev returns is reused, so a caller printing - * two abbreviated names together keeps a copy of each. + * Opens the group end_file closes, in whichever view the page uses, and writes + * the header of the pair's diff into it. */ -static char *abbrev_oid(const struct object_id *oid) -{ - return xstrdup(repo_find_unique_abbrev(the_repository, oid, DEFAULT_ABBREV)); -} - -static void print_file_header(const struct object_id *old_oid, const char *old_path, unsigned old_mode, - const struct object_id *new_oid, const char *new_path, unsigned new_mode) +static void print_file_header(struct diff_filepair *pair) { - char *old_abbrev, *new_abbrev; + const struct object_id *old_oid = &pair->one->oid, *new_oid = &pair->two->oid; + const char *old_path = pair->one->path, *new_path = pair->two->path; + unsigned old_mode = pair->one->mode, new_mode = pair->two->mode; + char old_abbrev[GIT_MAX_HEXSZ + 1], new_abbrev[GIT_MAX_HEXSZ + 1]; int subproject; subproject = (S_ISGITLINK(old_mode) || S_ISGITLINK(new_mode)); - // The side by side view opens its file group before the header row, - // so only the unified view opens one here. - if (!use_ssdiff) { + if (use_ssdiff) { + cgit_ssdiff_header_begin(pair); + } else { html("<div class='file' data-path='"); html_attr(new_path); html("'>"); @@ -247,11 +235,9 @@ static void print_file_header(const struct object_id *old_oid, const char *old_p htmlf("<br>deleted file mode %.6o", old_mode); if (!subproject) { - old_abbrev = abbrev_oid(old_oid); - new_abbrev = abbrev_oid(new_oid); + repo_find_unique_abbrev_r(the_repository, old_abbrev, old_oid, DEFAULT_ABBREV); + repo_find_unique_abbrev_r(the_repository, new_abbrev, new_oid, DEFAULT_ABBREV); htmlf("<br>index %s..%s", old_abbrev, new_abbrev); - free(old_abbrev); - free(new_abbrev); if (old_mode != 0 && new_mode != 0) { htmlf(" %.6o", old_mode); if (new_mode != old_mode) @@ -279,12 +265,13 @@ static void print_file_header(const struct object_id *old_oid, const char *old_p html_txt(new_path); } html("</div>"); + if (use_ssdiff) + cgit_ssdiff_header_end(); } /* - * Closes the group print_file_header or cgit_ssdiff_header_begin opened. The - * side by side footer closes its own, so the unified view is the only one with - * work to do here. + * Closes the group print_file_header opened. The side by side footer closes its + * own, so the unified view is the only one with work to do here. */ static void end_file(void) { @@ -338,17 +325,13 @@ static void print_truncated(const char *path) static struct fileinfo *reserve_item(void) { - files++; - if (files >= slots) { - if (slots == 0) - slots = 4; - else - slots = slots * 2; - items = xrealloc(items, slots * sizeof(struct fileinfo)); - } - memset(&items[files - 1], 0, sizeof(items[files - 1])); - strbuf_init(&items[files - 1].body, 0); - return &items[files - 1]; + struct fileinfo *item; + + ALLOC_GROW(items, files + 1, slots); + item = &items[files++]; + memset(item, 0, sizeof(*item)); + strbuf_init(&item->body, 0); + return item; } /* @@ -362,15 +345,8 @@ static void collect_body(struct diff_filepair *pair, struct fileinfo *item, int linediff_fn line_fn = use_ssdiff ? cgit_ssdiff_line_cb : print_line; size_t header_len; - current_filepair = pair; - html_capture_begin(body); - if (use_ssdiff) - cgit_ssdiff_header_begin(pair->two->path); - print_file_header(&pair->one->oid, pair->one->path, pair->one->mode, - &pair->two->oid, pair->two->path, pair->two->mode); - if (use_ssdiff) - cgit_ssdiff_header_end(); + print_file_header(pair); header_len = body->len; // Cleared for the whole file rather than in the branch below, because @@ -468,7 +444,6 @@ static void print_diffstat(const struct object_id *old_oid, const struct object_ html("')"); } html("</div>\n"); - max_changes = 0; cgit_diff_tree(old_oid, new_oid, inspect_filepair, prefix, ctx.qry.ignorews); // A change to no files would leave the table an empty frame. if (files) { @@ -498,21 +473,13 @@ static void filepair_cb(struct diff_filepair *pair) size_t new_size = 0; int binary = 0; int idx; - linediff_fn line_fn = print_line; + linediff_fn line_fn = use_ssdiff ? cgit_ssdiff_line_cb : print_line; if (!show_filepair(pair)) return; idx = item_idx++; - current_filepair = pair; - if (use_ssdiff) { - cgit_ssdiff_header_begin(pair->two->path); - line_fn = cgit_ssdiff_line_cb; - } - print_file_header(&pair->one->oid, pair->one->path, pair->one->mode, - &pair->two->oid, pair->two->path, pair->two->mode); - if (use_ssdiff) - cgit_ssdiff_header_end(); + print_file_header(pair); if (over_line_cap(idx)) { print_truncated(items[idx].new_path); @@ -557,16 +524,6 @@ static void print_raw_patch(const struct object_id *old_tree_oid, const struct o diff_flush(&diffopt); } -struct diff_filespec *cgit_get_current_old_file(void) -{ - return current_filepair->one; -} - -struct diff_filespec *cgit_get_current_new_file(void) -{ - return current_filepair->two; -} - void cgit_print_diff_ctrls(void) { int i, selected; @@ -574,7 +531,7 @@ void cgit_print_diff_ctrls(void) html("<div class='cgit-panel'>\n"); html("<strong>Diff options</strong>"); html("<form method='get' aria-label='Diff options'>"); - cgit_add_hidden_formfields(1, 0, ctx.qry.page); + cgit_add_hidden_formfields(1, 0); html("<div class='fields'>"); html("<label for='diff-context'>context</label>"); html("<select id='diff-context' name='context'>"); @@ -647,31 +604,17 @@ void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefi if (!new_rev) new_rev = ctx.qry.head; - if (repo_get_oid(the_repository, new_rev, new_rev_oid)) { - cgit_print_error_page(404, "Not Found", "Bad object id: %s", new_rev); - return; - } - new_commit = lookup_commit_reference(the_repository, new_rev_oid); - if (!new_commit || repo_parse_commit(the_repository, new_commit)) { - cgit_print_error_page(404, "Not Found", "Not a commit: %s", oid_to_hex(new_rev_oid)); + new_commit = cgit_get_commit(new_rev, new_rev_oid); + if (!new_commit || cgit_get_old_oid(old_rev, new_commit, old_rev_oid)) return; - } new_tree_oid = get_commit_tree_oid(new_commit); - if (old_rev) { - if (repo_get_oid(the_repository, old_rev, old_rev_oid)) { - cgit_print_error_page(404, "Not Found", "Bad object id: %s", old_rev); - return; - } - } else if (new_commit->parents && new_commit->parents->item) { - oidcpy(old_rev_oid, &new_commit->parents->item->object.oid); - } else { - oidclr(old_rev_oid, the_repository->hash_algo); - } - if (!is_null_oid(old_rev_oid)) { + // A named old side is a commit already, so only a first parent + // missing from the repository fails here, and it has no name + // but its id. old_commit = lookup_commit_reference(the_repository, old_rev_oid); - if (!old_commit || repo_parse_commit(the_repository, old_commit)) { + if (!old_commit) { cgit_print_error_page(404, "Not Found", "Not a commit: %s", oid_to_hex(old_rev_oid)); return; } @@ -742,7 +685,6 @@ void cgit_print_diff(const char *new_rev, const char *old_rev, const char *prefi html_raw(items[i].body.buf, items[i].body.len); release_bodies(); } else { - item_idx = 0; cgit_diff_tree(old_rev_oid, new_rev_oid, filepair_cb, prefix, ctx.qry.ignorews); } if (!use_ssdiff) |
