Diff options
Diffstat (limited to '')
-rw-r--r--source/ui-log.c138
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);
}