author | Lars Hjemli <hjemli@gmail.com> | 2008-11-29 17:39:41 (UTC) |
---|---|---|
committer | Lars Hjemli <hjemli@gmail.com> | 2008-11-29 17:39:41 (UTC) |
commit | 0274b57d55a12ed38259757dbfae96b79cfa2e0b (patch) (side-by-side diff) | |
tree | 34c7204f88168f791ef48f603bb8ab66e9df523c | |
parent | 7b5cee65fd9cf31e4f19ce4ff613778cb95512a9 (diff) | |
download | cgit-0274b57d55a12ed38259757dbfae96b79cfa2e0b.zip cgit-0274b57d55a12ed38259757dbfae96b79cfa2e0b.tar.gz cgit-0274b57d55a12ed38259757dbfae96b79cfa2e0b.tar.bz2 |
ui-log: add support for showing the full commit message
Some users prefer to see the full message, so to make these users happy
the new querystring parameter "showmsg" can be used to print the full
commit message per log entry.
A link is provided in the log heading to make this function accessible,
and all links and forms tries to preserve the users preference.
Note: the new link is not displayed on the summary page since the point
of the summary page is to be a summary, but it is still obeyed if specified
manually.
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
-rw-r--r-- | cgit.c | 2 | ||||
-rw-r--r-- | cgit.h | 1 | ||||
-rw-r--r-- | ui-log.c | 32 | ||||
-rw-r--r-- | ui-refs.c | 3 | ||||
-rw-r--r-- | ui-repolist.c | 2 | ||||
-rw-r--r-- | ui-shared.c | 12 | ||||
-rw-r--r-- | ui-shared.h | 2 | ||||
-rw-r--r-- | ui-tree.c | 2 |
8 files changed, 45 insertions, 11 deletions
@@ -109,96 +109,98 @@ void config_cb(const char *name, const char *value) else if (ctx.repo && !strcmp(name, "repo.snapshots")) ctx.repo->snapshots = ctx.cfg.snapshots & cgit_parse_snapshots_mask(value); /* XXX: &? */ else if (ctx.repo && !strcmp(name, "repo.enable-log-filecount")) ctx.repo->enable_log_filecount = ctx.cfg.enable_log_filecount * atoi(value); else if (ctx.repo && !strcmp(name, "repo.enable-log-linecount")) ctx.repo->enable_log_linecount = ctx.cfg.enable_log_linecount * atoi(value); else if (ctx.repo && !strcmp(name, "repo.module-link")) ctx.repo->module_link= xstrdup(value); else if (ctx.repo && !strcmp(name, "repo.readme") && value != NULL) { if (*value == '/') ctx.repo->readme = xstrdup(value); else ctx.repo->readme = xstrdup(fmt("%s/%s", ctx.repo->path, value)); } else if (!strcmp(name, "include")) parse_configfile(value, config_cb); } static void querystring_cb(const char *name, const char *value) { if (!strcmp(name,"r")) { ctx.qry.repo = xstrdup(value); ctx.repo = cgit_get_repoinfo(value); } else if (!strcmp(name, "p")) { ctx.qry.page = xstrdup(value); } else if (!strcmp(name, "url")) { ctx.qry.url = xstrdup(value); cgit_parse_url(value); } else if (!strcmp(name, "qt")) { ctx.qry.grep = xstrdup(value); } else if (!strcmp(name, "q")) { ctx.qry.search = xstrdup(value); } else if (!strcmp(name, "h")) { ctx.qry.head = xstrdup(value); ctx.qry.has_symref = 1; } else if (!strcmp(name, "id")) { ctx.qry.sha1 = xstrdup(value); ctx.qry.has_sha1 = 1; } else if (!strcmp(name, "id2")) { ctx.qry.sha2 = xstrdup(value); ctx.qry.has_sha1 = 1; } else if (!strcmp(name, "ofs")) { ctx.qry.ofs = atoi(value); } else if (!strcmp(name, "path")) { ctx.qry.path = trim_end(value, '/'); } else if (!strcmp(name, "name")) { ctx.qry.name = xstrdup(value); } else if (!strcmp(name, "mimetype")) { ctx.qry.mimetype = xstrdup(value); + } else if (!strcmp(name, "showmsg")) { + ctx.qry.showmsg = atoi(value); } } static void prepare_context(struct cgit_context *ctx) { memset(ctx, 0, sizeof(ctx)); ctx->cfg.agefile = "info/web/last-modified"; ctx->cfg.nocache = 0; ctx->cfg.cache_size = 0; ctx->cfg.cache_dynamic_ttl = 5; ctx->cfg.cache_max_create_time = 5; ctx->cfg.cache_repo_ttl = 5; ctx->cfg.cache_root = CGIT_CACHE_ROOT; ctx->cfg.cache_root_ttl = 5; ctx->cfg.cache_static_ttl = -1; ctx->cfg.css = "/cgit.css"; ctx->cfg.logo = "/git-logo.png"; ctx->cfg.local_time = 0; ctx->cfg.max_repo_count = 50; ctx->cfg.max_commit_count = 50; ctx->cfg.max_lock_attempts = 5; ctx->cfg.max_msg_len = 80; ctx->cfg.max_repodesc_len = 80; ctx->cfg.module_link = "./?repo=%s&page=commit&id=%s"; ctx->cfg.renamelimit = -1; ctx->cfg.robots = "index, nofollow"; ctx->cfg.root_title = "Git repository browser"; ctx->cfg.root_desc = "a fast webinterface for the git dscm"; ctx->cfg.script_name = CGIT_SCRIPT_NAME; ctx->cfg.summary_branches = 10; ctx->cfg.summary_log = 10; ctx->cfg.summary_tags = 10; ctx->page.mimetype = "text/html"; ctx->page.charset = PAGE_ENCODING; ctx->page.filename = NULL; ctx->page.size = 0; ctx->page.modified = time(NULL); ctx->page.expires = ctx->page.modified; } struct refmatch { char *req_ref; char *first_ref; int match; }; int find_current_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data) @@ -76,96 +76,97 @@ struct commitinfo { unsigned long author_date; char *committer; char *committer_email; unsigned long committer_date; char *subject; char *msg; char *msg_encoding; }; struct taginfo { char *tagger; char *tagger_email; unsigned long tagger_date; char *msg; }; struct refinfo { const char *refname; struct object *object; union { struct taginfo *tag; struct commitinfo *commit; }; }; struct reflist { struct refinfo **refs; int alloc; int count; }; struct cgit_query { int has_symref; int has_sha1; char *raw; char *repo; char *page; char *search; char *grep; char *head; char *sha1; char *sha2; char *path; char *name; char *mimetype; char *url; int ofs; int nohead; + int showmsg; }; struct cgit_config { char *agefile; char *cache_root; char *clone_prefix; char *css; char *favicon; char *footer; char *index_header; char *index_info; char *logo; char *logo_link; char *module_link; char *repo_group; char *robots; char *root_title; char *root_desc; char *root_readme; char *script_name; char *virtual_root; int cache_size; int cache_dynamic_ttl; int cache_max_create_time; int cache_repo_ttl; int cache_root_ttl; int cache_static_ttl; int enable_index_links; int enable_log_filecount; int enable_log_linecount; int local_time; int max_repo_count; int max_commit_count; int max_lock_attempts; int max_msg_len; int max_repodesc_len; int nocache; int renamelimit; int snapshots; int summary_branches; int summary_log; int summary_tags; }; struct cgit_page { time_t modified; time_t expires; size_t size; @@ -1,155 +1,177 @@ /* ui-log.c: functions for log output * * Copyright (C) 2006 Lars Hjemli * * Licensed under GNU General Public License v2 * (see COPYING for full license text) */ #include "cgit.h" #include "html.h" #include "ui-shared.h" int files, add_lines, rem_lines; void count_lines(char *line, int size) { if (size <= 0) return; if (line[0] == '+') add_lines++; else if (line[0] == '-') rem_lines++; } void inspect_files(struct diff_filepair *pair) { files++; if (ctx.repo->enable_log_linecount) cgit_diff_files(pair->one->sha1, pair->two->sha1, count_lines); } void print_commit(struct commit *commit) { struct commitinfo *info; char *tmp; info = cgit_parse_commit(commit); html("<tr><td>"); tmp = fmt("id=%s", sha1_to_hex(commit->object.sha1)); tmp = cgit_pageurl(ctx.repo->url, "commit", tmp); html_link_open(tmp, NULL, NULL); cgit_print_age(commit->date, TM_WEEK * 2, FMT_SHORTDATE); html_link_close(); html("</td><td>"); + if (ctx.qry.showmsg) + html("<u>"); cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, sha1_to_hex(commit->object.sha1)); + if (ctx.qry.showmsg) + html("</u>"); html("</td><td>"); html_txt(info->author); if (ctx.repo->enable_log_filecount) { files = 0; add_lines = 0; rem_lines = 0; cgit_diff_commit(commit, inspect_files); html("</td><td>"); htmlf("%d", files); if (ctx.repo->enable_log_linecount) { html("</td><td>"); htmlf("-%d/+%d", rem_lines, add_lines); } } html("</td></tr>\n"); + if (ctx.qry.showmsg) { + html("<tr class='nohover'><td></td><td><div class='commit-msg'>"); + html_txt(info->msg); + html("</div><br/></td><td></td>"); + if (ctx.repo->enable_log_filecount) { + html("<td></td>"); + if (ctx.repo->enable_log_linecount) + html("<td></td>"); + } + html("</tr>\n"); + } cgit_free_commitinfo(info); } void cgit_print_log(const char *tip, int ofs, int cnt, char *grep, char *pattern, char *path, int pager) { struct rev_info rev; struct commit *commit; const char *argv[] = {NULL, tip, NULL, NULL, NULL}; int argc = 2; int i, columns = 3; if (!tip) argv[1] = ctx.qry.head; if (grep && pattern && (!strcmp(grep, "grep") || !strcmp(grep, "author") || !strcmp(grep, "committer"))) argv[argc++] = fmt("--%s=%s", grep, pattern); if (path) { argv[argc++] = "--"; argv[argc++] = path; } init_revisions(&rev, NULL); rev.abbrev = DEFAULT_ABBREV; rev.commit_format = CMIT_FMT_DEFAULT; rev.verbose_header = 1; rev.show_root_diff = 0; setup_revisions(argc, argv, &rev, NULL); rev.grep_filter.regflags |= REG_ICASE; compile_grep_patterns(&rev.grep_filter); prepare_revision_walk(&rev); if (pager) html("<table class='list nowrap'>"); html("<tr class='nohover'><th class='left'>Age</th>" - "<th class='left'>Commit message</th>" - "<th class='left'>Author</th>"); + "<th class='left'>Commit message"); + if (pager) { + html(" ("); + cgit_log_link("toggle", NULL, NULL, ctx.qry.head, ctx.qry.sha1, + ctx.qry.path, ctx.qry.ofs, ctx.qry.grep, + ctx.qry.search, ctx.qry.showmsg ? 0 : 1); + html(")"); + } + html("</th><th class='left'>Author</th>"); if (ctx.repo->enable_log_filecount) { html("<th class='left'>Files</th>"); columns++; if (ctx.repo->enable_log_linecount) { html("<th class='left'>Lines</th>"); columns++; } } html("</tr>\n"); if (ofs<0) ofs = 0; for (i = 0; i < ofs && (commit = get_revision(&rev)) != NULL; i++) { free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); commit->parents = NULL; } for (i = 0; i < cnt && (commit = get_revision(&rev)) != NULL; i++) { print_commit(commit); free(commit->buffer); commit->buffer = NULL; free_commit_list(commit->parents); commit->parents = NULL; } if (pager) { htmlf("</table><div class='pager'>", columns); if (ofs > 0) { cgit_log_link("[prev]", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.path, ofs - cnt, ctx.qry.grep, - ctx.qry.search); + ctx.qry.search, ctx.qry.showmsg); html(" "); } if ((commit = get_revision(&rev)) != NULL) { cgit_log_link("[next]", NULL, NULL, ctx.qry.head, ctx.qry.sha1, ctx.qry.path, ofs + cnt, ctx.qry.grep, - ctx.qry.search); + ctx.qry.search, ctx.qry.showmsg); } html("</div>"); } else if ((commit = get_revision(&rev)) != NULL) { html("<tr class='nohover'><td colspan='3'>"); cgit_log_link("[...]", NULL, NULL, ctx.qry.head, NULL, NULL, 0, - NULL, NULL); + NULL, NULL, ctx.qry.showmsg); html("</td></tr>\n"); } } @@ -13,97 +13,98 @@ static int header; static int cmp_age(int age1, int age2) { if (age1 != 0 && age2 != 0) return age2 - age1; if (age1 == 0 && age2 == 0) return 0; if (age1 == 0) return +1; return -1; } static int cmp_ref_name(const void *a, const void *b) { struct refinfo *r1 = *(struct refinfo **)a; struct refinfo *r2 = *(struct refinfo **)b; return strcmp(r1->refname, r2->refname); } static int cmp_branch_age(const void *a, const void *b) { struct refinfo *r1 = *(struct refinfo **)a; struct refinfo *r2 = *(struct refinfo **)b; return cmp_age(r1->commit->committer_date, r2->commit->committer_date); } static int cmp_tag_age(const void *a, const void *b) { struct refinfo *r1 = *(struct refinfo **)a; struct refinfo *r2 = *(struct refinfo **)b; return cmp_age(r1->tag->tagger_date, r2->tag->tagger_date); } static int print_branch(struct refinfo *ref) { struct commitinfo *info = ref->commit; char *name = (char *)ref->refname; if (!info) return 1; html("<tr><td>"); - cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL); + cgit_log_link(name, NULL, NULL, name, NULL, NULL, 0, NULL, NULL, + ctx.qry.showmsg); html("</td><td>"); if (ref->object->type == OBJ_COMMIT) { cgit_commit_link(info->subject, NULL, NULL, name, NULL); html("</td><td>"); html_txt(info->author); html("</td><td colspan='2'>"); cgit_print_age(info->commit->date, -1, NULL); } else { html("</td><td></td><td>"); cgit_object_link(ref->object); } html("</td></tr>\n"); return 0; } static void print_tag_header() { html("<tr class='nohover'><th class='left'>Tag</th>" "<th class='left'>Reference</th>" "<th class='left'>Author</th>" "<th class='left' colspan='2'>Age</th></tr>\n"); header = 1; } static int print_tag(struct refinfo *ref) { struct tag *tag; struct taginfo *info; char *name = (char *)ref->refname; if (ref->object->type == OBJ_TAG) { tag = (struct tag *)ref->object; info = ref->tag; if (!tag || !info) return 1; html("<tr><td>"); cgit_tag_link(name, NULL, NULL, ctx.qry.head, name); html("</td><td>"); cgit_object_link(tag->tagged); html("</td><td>"); if (info->tagger) html(info->tagger); html("</td><td colspan='2'>"); if (info->tagger_date > 0) cgit_print_age(info->tagger_date, -1, NULL); html("</td></tr>\n"); } else { diff --git a/ui-repolist.c b/ui-repolist.c index c23232c..5833140 100644 --- a/ui-repolist.c +++ b/ui-repolist.c @@ -101,67 +101,67 @@ void cgit_print_repolist() columns++; ctx.page.title = ctx.cfg.root_title; cgit_print_http_headers(&ctx); cgit_print_docstart(&ctx); cgit_print_pageheader(&ctx); if (ctx.cfg.index_header) html_include(ctx.cfg.index_header); html("<table summary='repository list' class='list nowrap'>"); for (i=0; i<cgit_repolist.count; i++) { ctx.repo = &cgit_repolist.repos[i]; if (!(is_match(ctx.repo) && is_in_url(ctx.repo))) continue; hits++; if (hits <= ctx.qry.ofs) continue; if (hits > ctx.qry.ofs + ctx.cfg.max_repo_count) continue; if (!header++) print_header(columns); if ((last_group == NULL && ctx.repo->group != NULL) || (last_group != NULL && ctx.repo->group == NULL) || (last_group != NULL && ctx.repo->group != NULL && strcmp(ctx.repo->group, last_group))) { htmlf("<tr class='nohover'><td colspan='%d' class='repogroup'>", columns); html_txt(ctx.repo->group); html("</td></tr>"); last_group = ctx.repo->group; } htmlf("<tr><td class='%s'>", ctx.repo->group ? "sublevel-repo" : "toplevel-repo"); cgit_summary_link(ctx.repo->name, ctx.repo->name, NULL, NULL); html("</td><td>"); html_link_open(cgit_repourl(ctx.repo->url), NULL, NULL); html_ntxt(ctx.cfg.max_repodesc_len, ctx.repo->desc); html_link_close(); html("</td><td>"); html_txt(ctx.repo->owner); html("</td><td>"); print_modtime(ctx.repo); html("</td>"); if (ctx.cfg.enable_index_links) { html("<td>"); cgit_summary_link("summary", NULL, "button", NULL); cgit_log_link("log", NULL, "button", NULL, NULL, NULL, - 0, NULL, NULL); + 0, NULL, NULL, ctx.qry.showmsg); cgit_tree_link("tree", NULL, "button", NULL, NULL, NULL); html("</td>"); } html("</tr>\n"); } html("</table>"); if (!hits) cgit_print_error("No repositories found"); else if (hits > ctx.cfg.max_repo_count) print_pager(hits, ctx.cfg.max_repo_count, ctx.qry.search); cgit_print_docend(); } void cgit_print_site_readme() { if (ctx.cfg.root_readme) html_include(ctx.cfg.root_readme); } diff --git a/ui-shared.c b/ui-shared.c index 224e5f3..dc39e64 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -236,120 +236,126 @@ static char *repolink(char *title, char *class, char *page, char *head, html(delim); html("h="); html_url_arg(head); delim = "&"; } return fmt("%s", delim); } static void reporevlink(char *page, char *name, char *title, char *class, char *head, char *rev, char *path) { char *delim; delim = repolink(title, class, page, head, path); if (rev && strcmp(rev, ctx.qry.head)) { html(delim); html("id="); html_url_arg(rev); } html("'>"); html_txt(name); html("</a>"); } void cgit_summary_link(char *name, char *title, char *class, char *head) { reporevlink(NULL, name, title, class, head, NULL, NULL); } void cgit_tag_link(char *name, char *title, char *class, char *head, char *rev) { reporevlink("tag", name, title, class, head, rev, NULL); } void cgit_tree_link(char *name, char *title, char *class, char *head, char *rev, char *path) { reporevlink("tree", name, title, class, head, rev, path); } void cgit_plain_link(char *name, char *title, char *class, char *head, char *rev, char *path) { reporevlink("plain", name, title, class, head, rev, path); } void cgit_log_link(char *name, char *title, char *class, char *head, - char *rev, char *path, int ofs, char *grep, char *pattern) + char *rev, char *path, int ofs, char *grep, char *pattern, + int showmsg) { char *delim; delim = repolink(title, class, "log", head, path); if (rev && strcmp(rev, ctx.qry.head)) { html(delim); html("id="); html_url_arg(rev); delim = "&"; } if (grep && pattern) { html(delim); html("qt="); html_url_arg(grep); delim = "&"; html(delim); html("q="); html_url_arg(pattern); } if (ofs > 0) { html(delim); html("ofs="); htmlf("%d", ofs); + delim = "&"; + } + if (showmsg) { + html(delim); + html("showmsg=1"); } html("'>"); html_txt(name); html("</a>"); } void cgit_commit_link(char *name, char *title, char *class, char *head, char *rev) { if (strlen(name) > ctx.cfg.max_msg_len && ctx.cfg.max_msg_len >= 15) { name[ctx.cfg.max_msg_len] = '\0'; name[ctx.cfg.max_msg_len - 1] = '.'; name[ctx.cfg.max_msg_len - 2] = '.'; name[ctx.cfg.max_msg_len - 3] = '.'; } reporevlink("commit", name, title, class, head, rev, NULL); } void cgit_refs_link(char *name, char *title, char *class, char *head, char *rev, char *path) { reporevlink("refs", name, title, class, head, rev, path); } void cgit_snapshot_link(char *name, char *title, char *class, char *head, char *rev, char *archivename) { reporevlink("snapshot", name, title, class, head, rev, archivename); } void cgit_diff_link(char *name, char *title, char *class, char *head, char *new_rev, char *old_rev, char *path) { char *delim; delim = repolink(title, class, "diff", head, path); if (new_rev && strcmp(new_rev, ctx.qry.head)) { html(delim); html("id="); html_url_arg(new_rev); delim = "&"; } if (old_rev) { html(delim); html("id2="); html_url_arg(old_rev); } html("'>"); @@ -523,163 +529,165 @@ int print_archive_ref(const char *refname, const unsigned char *sha1, if (prefixcmp(refname, "refs/archives")) return 0; strncpy(buf, refname+14, sizeof(buf)); obj = parse_object(sha1); if (!obj) return 1; if (obj->type == OBJ_TAG) { tag = lookup_tag(sha1); if (!tag || parse_tag(tag) || !(info = cgit_parse_tag(tag))) return 0; hashcpy(fileid, tag->tagged->sha1); } else if (obj->type != OBJ_BLOB) { return 0; } else { hashcpy(fileid, sha1); } if (!*header) { html("<h1>download</h1>\n"); *header = 1; } url = cgit_pageurl(ctx.qry.repo, "blob", fmt("id=%s&path=%s", sha1_to_hex(fileid), buf)); html_link_open(url, NULL, "menu"); html_txt(strlpart(buf, 20)); html_link_close(); return 0; } void add_hidden_formfields(int incl_head, int incl_search, char *page) { char *url; if (!ctx.cfg.virtual_root) { url = fmt("%s/%s", ctx.qry.repo, page); if (ctx.qry.path) url = fmt("%s/%s", url, ctx.qry.path); html_hidden("url", url); } if (incl_head && ctx.qry.head && ctx.repo->defbranch && strcmp(ctx.qry.head, ctx.repo->defbranch)) html_hidden("h", ctx.qry.head); if (ctx.qry.sha1) html_hidden("id", ctx.qry.sha1); if (ctx.qry.sha2) html_hidden("id2", ctx.qry.sha2); + if (ctx.qry.showmsg) + html_hidden("showmsg", "1"); if (incl_search) { if (ctx.qry.grep) html_hidden("qt", ctx.qry.grep); if (ctx.qry.search) html_hidden("q", ctx.qry.search); } } char *hc(struct cgit_cmd *cmd, const char *page) { return (strcmp(cmd->name, page) ? NULL : "active"); } void cgit_print_pageheader(struct cgit_context *ctx) { struct cgit_cmd *cmd = cgit_get_cmd(ctx); html("<table id='header'>\n"); html("<tr>\n"); html("<td class='logo' rowspan='2'><a href='"); if (ctx->cfg.logo_link) html_attr(ctx->cfg.logo_link); else html_attr(cgit_rooturl()); html("'><img src='"); html_attr(ctx->cfg.logo); html("' alt='cgit logo'/></a></td>\n"); html("<td class='main'>"); if (ctx->repo) { cgit_index_link("index", NULL, NULL, NULL, 0); html(" : "); cgit_summary_link(ctx->repo->name, ctx->repo->name, NULL, NULL); html("</td><td class='form'>"); html("<form method='get' action=''>\n"); add_hidden_formfields(0, 1, ctx->qry.page); html("<select name='h' onchange='this.form.submit();'>\n"); for_each_branch_ref(print_branch_option, ctx->qry.head); html("</select> "); html("<input type='submit' name='' value='switch'/>"); html("</form>"); } else html_txt(ctx->cfg.root_title); html("</td></tr>\n"); html("<tr><td class='sub'>"); if (ctx->repo) { html_txt(ctx->repo->desc); html("</td><td class='sub right'>"); html_txt(ctx->repo->owner); } else { if (ctx->cfg.root_desc) html_txt(ctx->cfg.root_desc); else if (ctx->cfg.index_info) html_include(ctx->cfg.index_info); } html("</td></tr></table>\n"); html("<table class='tabs'><tr><td>\n"); if (ctx->repo) { cgit_summary_link("summary", NULL, hc(cmd, "summary"), ctx->qry.head); cgit_refs_link("refs", NULL, hc(cmd, "refs"), ctx->qry.head, ctx->qry.sha1, NULL); cgit_log_link("log", NULL, hc(cmd, "log"), ctx->qry.head, - NULL, NULL, 0, NULL, NULL); + NULL, NULL, 0, NULL, NULL, ctx->qry.showmsg); cgit_tree_link("tree", NULL, hc(cmd, "tree"), ctx->qry.head, ctx->qry.sha1, NULL); cgit_commit_link("commit", NULL, hc(cmd, "commit"), ctx->qry.head, ctx->qry.sha1); cgit_diff_link("diff", NULL, hc(cmd, "diff"), ctx->qry.head, ctx->qry.sha1, ctx->qry.sha2, NULL); if (ctx->repo->readme) reporevlink("about", "about", NULL, hc(cmd, "about"), ctx->qry.head, NULL, NULL); html("</td><td class='form'>"); html("<form class='right' method='get' action='"); if (ctx->cfg.virtual_root) html_url_path(cgit_fileurl(ctx->qry.repo, "log", ctx->qry.path, NULL)); html("'>\n"); add_hidden_formfields(1, 0, "log"); html("<select name='qt'>\n"); html_option("grep", "log msg", ctx->qry.grep); html_option("author", "author", ctx->qry.grep); html_option("committer", "committer", ctx->qry.grep); html("</select>\n"); html("<input class='txt' type='text' size='10' name='q' value='"); html_attr(ctx->qry.search); html("'/>\n"); html("<input type='submit' value='search'/>\n"); html("</form>\n"); } else { site_link(NULL, "index", NULL, hc(cmd, "repolist"), NULL, 0); if (ctx->cfg.root_readme) site_link("about", "about", NULL, hc(cmd, "about"), NULL, 0); html("</td><td class='form'>"); html("<form method='get' action='"); html_attr(cgit_rooturl()); html("'>\n"); html("<input type='text' name='q' size='10' value='"); html_attr(ctx->qry.search); html("'/>\n"); html("<input type='submit' value='search'/>\n"); html("</form>"); } html("</td></tr></table>\n"); html("<div class='content'>"); } void cgit_print_filemode(unsigned short mode) { diff --git a/ui-shared.h b/ui-shared.h index 3c8a6d0..2ab53ae 100644 --- a/ui-shared.h +++ b/ui-shared.h @@ -1,46 +1,46 @@ #ifndef UI_SHARED_H #define UI_SHARED_H extern char *cgit_hosturl(); extern char *cgit_repourl(const char *reponame); extern char *cgit_fileurl(const char *reponame, const char *pagename, const char *filename, const char *query); extern char *cgit_pageurl(const char *reponame, const char *pagename, const char *query); extern void cgit_index_link(char *name, char *title, char *class, char *pattern, int ofs); extern void cgit_summary_link(char *name, char *title, char *class, char *head); extern void cgit_tag_link(char *name, char *title, char *class, char *head, char *rev); extern void cgit_tree_link(char *name, char *title, char *class, char *head, char *rev, char *path); extern void cgit_plain_link(char *name, char *title, char *class, char *head, char *rev, char *path); extern void cgit_log_link(char *name, char *title, char *class, char *head, char *rev, char *path, int ofs, char *grep, - char *pattern); + char *pattern, int showmsg); extern void cgit_commit_link(char *name, char *title, char *class, char *head, char *rev); extern void cgit_patch_link(char *name, char *title, char *class, char *head, char *rev); extern void cgit_refs_link(char *name, char *title, char *class, char *head, char *rev, char *path); extern void cgit_snapshot_link(char *name, char *title, char *class, char *head, char *rev, char *archivename); extern void cgit_diff_link(char *name, char *title, char *class, char *head, char *new_rev, char *old_rev, char *path); extern void cgit_object_link(struct object *obj); extern void cgit_print_error(char *msg); extern void cgit_print_date(time_t secs, char *format, int local_time); extern void cgit_print_age(time_t t, time_t max_relative, char *format); extern void cgit_print_http_headers(struct cgit_context *ctx); extern void cgit_print_docstart(struct cgit_context *ctx); extern void cgit_print_docend(); extern void cgit_print_pageheader(struct cgit_context *ctx); extern void cgit_print_filemode(unsigned short mode); extern void cgit_print_snapshot_links(const char *repo, const char *head, const char *hex, int snapshots); #endif /* UI_SHARED_H */ @@ -61,97 +61,97 @@ static void print_object(const unsigned char *sha1, char *path) } static int ls_item(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned int mode, int stage, void *cbdata) { char *name; char *fullpath; enum object_type type; unsigned long size = 0; name = xstrdup(pathname); fullpath = fmt("%s%s%s", ctx.qry.path ? ctx.qry.path : "", ctx.qry.path ? "/" : "", name); if (!S_ISGITLINK(mode)) { type = sha1_object_info(sha1, &size); if (type == OBJ_BAD) { htmlf("<tr><td colspan='3'>Bad object: %s %s</td></tr>", name, sha1_to_hex(sha1)); return 0; } } html("<tr><td class='ls-mode'>"); cgit_print_filemode(mode); html("</td><td>"); if (S_ISGITLINK(mode)) { htmlf("<a class='ls-mod' href='"); html_attr(fmt(ctx.repo->module_link, name, sha1_to_hex(sha1))); html("'>"); html_txt(name); html("</a>"); } else if (S_ISDIR(mode)) { cgit_tree_link(name, NULL, "ls-dir", ctx.qry.head, curr_rev, fullpath); } else { cgit_tree_link(name, NULL, "ls-blob", ctx.qry.head, curr_rev, fullpath); } htmlf("</td><td class='ls-size'>%li</td>", size); html("<td>"); cgit_log_link("log", NULL, "button", ctx.qry.head, curr_rev, - fullpath, 0, NULL, NULL); + fullpath, 0, NULL, NULL, ctx.qry.showmsg); html("</td></tr>\n"); free(name); return 0; } static void ls_head() { html("<table summary='tree listing' class='list'>\n"); html("<tr class='nohover'>"); html("<th class='left'>Mode</th>"); html("<th class='left'>Name</th>"); html("<th class='right'>Size</th>"); html("<th/>"); html("</tr>\n"); header = 1; } static void ls_tail() { if (!header) return; html("</table>\n"); header = 0; } static void ls_tree(const unsigned char *sha1, char *path) { struct tree *tree; tree = parse_tree_indirect(sha1); if (!tree) { cgit_print_error(fmt("Not a tree object: %s", sha1_to_hex(sha1))); return; } ls_head(); read_tree_recursive(tree, "", 0, 1, NULL, ls_item, NULL); ls_tail(); } static int walk_tree(const unsigned char *sha1, const char *base, int baselen, const char *pathname, unsigned mode, int stage, void *cbdata) { static int state; static char buffer[PATH_MAX]; |