Diff options
Diffstat (limited to '')
| -rw-r--r-- | source/ui-log.c | 138 |
1 file changed, 53 insertions, 85 deletions
diff --git a/source/ui-log.c b/source/ui-log.c index 870ff06..5b3a88a 100644 --- a/source/ui-log.c +++ b/source/ui-log.c @@ -11,7 +11,6 @@ #define USE_THE_REPOSITORY_VARIABLE #include "cgit.h" -#include "filter.h" #include "html.h" #include "parsing.h" #include "shared.h" @@ -212,28 +211,26 @@ static void print_graph_padding(struct rev_info *revs, struct strbuf *graph, int html("</td>\n"); } -// Ends a row in a table wider than the log with an empty cell for each column -// the log has no use for. +/* + * Ends a row in a table wider than the log with an empty cell for each column + * the log has no use for. + */ static void print_filler(int columns) { while (columns-- > 0) html("<td></td>"); } -static void print_commit(struct commit *commit, struct rev_info *revs, int filler) +/* + * columns counts the filler too, because the rows that span the table reach + * across it as well. + */ +static void print_commit(struct commit *commit, struct rev_info *revs, int columns, int filler) { struct commitinfo *info; - int columns = revs->graph ? 4 : 3; struct strbuf graphbuf = STRBUF_INIT; struct strbuf msgbuf = STRBUF_INIT; - if (ctx.repo->enable_log_filecount) - columns++; - if (ctx.repo->enable_log_linecount) - columns++; - // The rows that span the table reach across the filler as well. - columns += filler; - if (revs->graph) print_graph_above(revs, &graphbuf, columns); @@ -258,9 +255,7 @@ static void print_commit(struct commit *commit, struct rev_info *revs, int fille oid_to_hex(&commit->object.oid), ctx.qry.vpath); cgit_print_commit_decorations(commit); html("</td><td class='col-author'>"); - cgit_open_filter(ctx.repo->email_filter, info->author_email ? info->author_email : "", "log"); - html_txt(info->author); - cgit_close_filter(ctx.repo->email_filter); + cgit_print_person(info->author, info->author_email, "log", 0); if (revs->graph) { html("</td><td>"); @@ -355,28 +350,6 @@ static int valid_range_token(const char *arg) return ok; } -static char *next_token(char **src) -{ - char *token; - - if (!*src) - return NULL; - while (isspace((unsigned char)**src)) - (*src)++; - if (!**src) - return NULL; - token = *src; - while (**src) { - if (isspace((unsigned char)**src)) { - **src = '\0'; - (*src)++; - break; - } - (*src)++; - } - return token; -} - /* * Whether there is a page after this one is answered by pulling one more * commit off the walk. The links carry the path as it was asked for, since a @@ -466,13 +439,25 @@ void cgit_print_commit_decorations(struct commit *commit) html("</span>"); } -void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, +int cgit_log_columns(int graph) +{ + int columns = graph ? 4 : 3; + + if (ctx.repo->enable_log_filecount) + columns++; + if (ctx.repo->enable_log_linecount) + columns++; + return columns; +} + +void cgit_print_log(const char *tip, int ofs, int cnt, const char *grep, const char *pattern, const char *path, int pager, int commit_graph, int commit_sort, int table_columns) { - struct rev_info rev; + struct rev_info rev = REV_INFO_INIT; struct commit *commit; struct strvec rev_argv = STRVEC_INIT; - int i, columns = commit_graph ? 4 : 3, filler = 0; + struct string_list tokens = STRING_LIST_INIT_DUP; + int i, columns, filler = 0; int must_free_tip = 0; // setup_revisions skips the first entry the way a command skips its @@ -487,25 +472,14 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern // option. if (tip && !cgit_valid_rev(tip)) { cgit_print_error_page(400, "Bad Request", "Invalid revision"); - if (must_free_tip) - free((char *)tip); - strvec_clear(&rev_argv); - return; + goto out; } strvec_push(&rev_argv, tip); - // A leading colon makes git read the path as a pathspec with magic, - // which can end the request inside git. - if (path && path[0] == ':') { - cgit_print_error_page(400, "Bad Request", "Invalid path"); - if (must_free_tip) - free((char *)tip); - strvec_clear(&rev_argv); - return; - } + if (cgit_refuse_pathspec_magic(path)) + goto out; if (grep && pattern && *pattern) { - pattern = xstrdup(pattern); if (!strcmp(grep, "grep") || !strcmp(grep, "author") || !strcmp(grep, "committer")) { // The search is literal and ignores case. setup_revisions // compiles the pattern, so the flags go in with it. @@ -513,21 +487,19 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern strvec_push(&rev_argv, "--regexp-ignore-case"); strvec_pushf(&rev_argv, "--%s=%s", grep, pattern); } else if (!strcmp(grep, "range")) { - char *arg; + struct string_list_item *token; // Each whitespace separated token has to pass the same // check as any other revision. The tip pushed above goes // away, since the range supersedes it. strvec_pop(&rev_argv); - while ((arg = next_token(&pattern))) { - if (!valid_range_token(arg)) { + string_list_split_f(&tokens, pattern, " \t\n\r", -1, STRING_LIST_SPLIT_NONEMPTY); + for_each_string_list_item(token, &tokens) { + if (!valid_range_token(token->string)) { cgit_print_error_page(400, "Bad Request", "Invalid revision"); - if (must_free_tip) - free((char *)tip); - strvec_clear(&rev_argv); - return; + goto out; } - strvec_push(&rev_argv, arg); + strvec_push(&rev_argv, token->string); } } } @@ -555,28 +527,24 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern repo_init_revisions(the_repository, &rev, NULL); // The author and committer searches then match the mapped idents. rev.mailmap = cgit_mailmap(); - rev.abbrev = DEFAULT_ABBREV; - rev.commit_format = CMIT_FMT_DEFAULT; - rev.verbose_header = 1; - rev.show_root_diff = 0; rev.ignore_missing = 1; - rev.simplify_history = 1; - setup_revisions(rev_argv.nr, rev_argv.v, &rev, NULL); + setup_revisions_from_strvec(&rev_argv, &rev, NULL); load_ref_decorations(NULL, DECORATE_FULL_REFS); rev.show_decorations = 1; + // A followed log is walked without the graph even when commit_graph + // asks for one, so the walk decides the columns. + columns = cgit_log_columns(rev.graph != NULL); + if (table_columns > columns) + filler = table_columns - columns; + rev.diffopt.detect_rename = 1; rev.diffopt.rename_limit = ctx.cfg.renamelimit; if (ctx.qry.ignorews) DIFF_XDL_SET(&rev.diffopt, IGNORE_WHITESPACE); - // A failed setup leaves the walk holding freed commits, so it must - // not be read from. - if (prepare_revision_walk(&rev)) { - cgit_print_error_page(500, "Internal Server Error", "Unable to read the history"); - strvec_clear(&rev_argv); - return; - } + if (cgit_prepare_walk(&rev)) + goto out; if (pager) { cgit_print_layout_start(); @@ -584,7 +552,7 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern } html("<tbody class='log'>\n<tr class='nohover'>"); - if (commit_graph) + if (rev.graph) html("<th scope='col' aria-label='Graph'></th>"); else html("<th class='left' scope='col'>Age</th>"); @@ -601,16 +569,10 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern html("</th><th class='left col-author' scope='col'>Author</th>"); if (rev.graph) html("<th class='left' scope='col'>Age</th>"); - if (ctx.repo->enable_log_filecount) { + if (ctx.repo->enable_log_filecount) html("<th class='left col-count' scope='col'>Files</th>"); - columns++; - } - if (ctx.repo->enable_log_linecount) { + if (ctx.repo->enable_log_linecount) html("<th class='left col-count' scope='col'>Lines</th>"); - columns++; - } - if (table_columns > columns) - filler = table_columns - columns; print_filler(filler); html("</tr>\n"); @@ -630,7 +592,7 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern counts_ready = 0; if (should_show(commit, &rev)) { i++; - print_commit(commit, &rev, filler); + print_commit(commit, &rev, columns + filler, filler); } release_commit_memory(the_repository->parsed_objects, commit); commit->parents = NULL; @@ -650,6 +612,12 @@ void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern html("</tbody>\n"); } + // The mailmap is cgit's own and outlives the walk. + rev.mailmap = NULL; + release_revisions(&rev); +out: if (must_free_tip) free((char *)tip); + strvec_clear(&rev_argv); + string_list_clear(&tokens, 0); } |
