Changes
2 changed files (+665/-3)
-
-
@@ -0,0 +1,657 @@From a42071e287f3fbf24c1010170f1aaff4781567b6 Mon Sep 17 00:00:00 2001 From: Christian Hesse <mail@eworm.de> Date: Fri, 16 Dec 2022 18:37:10 +0100 Subject: [PATCH 01/10] ui-log: show ellipsis if detailed commit message is available The existence of a detailed commit message may be of interst even if only the subject is shown by default. Signed-off-by: Christian Hesse <mail@eworm.de> --- cgit.css | 9 +++++++++ ui-log.c | 2 ++ 2 files changed, 11 insertions(+) diff --git a/cgit.css b/cgit.css index d10a24d..1d4634c 100644 --- a/cgit.css +++ b/cgit.css @@ -678,6 +678,15 @@ div#cgit div.footer a:hover { text-decoration: underline; } +div#cgit span.msg-avail { + color: #000; + margin: 0px 0.5em; + padding: 0px 0.25em; + background-color: #f0f0f0; + border: solid 1px #777777; + border-radius: 5px; +} + div#cgit a.branch-deco { color: #000; margin: 0px 0.5em; diff --git a/ui-log.c b/ui-log.c index 9906bbc..ee51bde 100644 --- a/ui-log.c +++ b/ui-log.c @@ -244,6 +244,8 @@ static void print_commit(struct commit *commit, struct rev_info *revs) } cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, oid_to_hex(&commit->object.oid), ctx.qry.vpath); + if (!ctx.qry.showmsg && info->msg && *(info->msg)) + html("<span class='msg-avail'>...</span>"); show_commit_decorations(commit); html("</td><td>"); cgit_open_filter(ctx.repo->email_filter, info->author_email, "log"); -- 2.54.0 From c829e631ded662d70fc843b8b83eb7b5d9872cd3 Mon Sep 17 00:00:00 2001 From: Christian Hesse <mail@eworm.de> Date: Mon, 5 Aug 2024 00:25:49 +0200 Subject: [PATCH 02/10] ui-log: show commit message in tooltip ... now that we have the ellipsis to indicate it is available. Signed-off-by: Christian Hesse <mail@eworm.de> --- cgit.css | 18 ++++++++++++++++++ ui-log.c | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/cgit.css b/cgit.css index 1d4634c..092883f 100644 --- a/cgit.css +++ b/cgit.css @@ -687,6 +687,24 @@ div#cgit span.msg-avail { border-radius: 5px; } +div#cgit span.msg-avail span.msg-tooltip { + color: #000; + margin: 0px 0.5em; + padding: 0px 0.25em; + background-color: #f0f0f0; + border: solid 1px #777777; + border-radius: 5px; + box-shadow: 2px 2px 7px rgba(100,100,100,0.75); + visibility: hidden; + position: absolute; + white-space: pre; + z-index: 1; +} + +div#cgit span.msg-avail:hover span.msg-tooltip { + visibility: visible; +} + div#cgit a.branch-deco { color: #000; margin: 0px 0.5em; diff --git a/ui-log.c b/ui-log.c index ee51bde..4ec5817 100644 --- a/ui-log.c +++ b/ui-log.c @@ -244,8 +244,11 @@ static void print_commit(struct commit *commit, struct rev_info *revs) } cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, oid_to_hex(&commit->object.oid), ctx.qry.vpath); - if (!ctx.qry.showmsg && info->msg && *(info->msg)) - html("<span class='msg-avail'>...</span>"); + if (!ctx.qry.showmsg && info->msg && *(info->msg)) { + html("<span class='msg-avail'>...<span class='msg-tooltip'>"); + html_txt(info->msg); + html("</span></span>"); + } show_commit_decorations(commit); html("</td><td>"); cgit_open_filter(ctx.repo->email_filter, info->author_email, "log"); -- 2.54.0 From 8c1d1cd5dee361084e28e7561e903eb5fbf5a544 Mon Sep 17 00:00:00 2001 From: Christian Hesse <mail@eworm.de> Date: Wed, 16 Oct 2024 11:59:42 +0200 Subject: [PATCH 03/10] ui-log: build ellipsis from bullets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These look cleaner... IMHO. 😜 Signed-off-by: Christian Hesse <mail@eworm.de> --- ui-log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-log.c b/ui-log.c index 4ec5817..434ff8d 100644 --- a/ui-log.c +++ b/ui-log.c @@ -245,7 +245,7 @@ static void print_commit(struct commit *commit, struct rev_info *revs) cgit_commit_link(info->subject, NULL, NULL, ctx.qry.head, oid_to_hex(&commit->object.oid), ctx.qry.vpath); if (!ctx.qry.showmsg && info->msg && *(info->msg)) { - html("<span class='msg-avail'>...<span class='msg-tooltip'>"); + html("<span class='msg-avail'>•••<span class='msg-tooltip'>"); html_txt(info->msg); html("</span></span>"); } -- 2.54.0 From f1861553f3bfd48f4fc1559b23a5cc1b0cc7bda2 Mon Sep 17 00:00:00 2001 From: Christian Hesse <mail@eworm.de> Date: Sat, 29 Dec 2018 00:13:54 +0100 Subject: [PATCH 04/10] ui-tree: provide link to about page for pretty formatting We have an ongoing discussion about display filters and pretty formatting in tree view. How about providing a link to about page for pretty formatting? Signed-off-by: Christian Hesse <mail@eworm.de> --- ui-shared.c | 6 ++++++ ui-shared.h | 3 +++ ui-tree.c | 3 +++ 3 files changed, 12 insertions(+) diff --git a/ui-shared.c b/ui-shared.c index df52a9b..0734711 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -348,6 +348,12 @@ void cgit_tree_link(const char *name, const char *title, const char *class, reporevlink("tree", name, title, class, head, rev, path); } +void cgit_about_link(const char *name, const char *title, const char *class, + const char *head, const char *rev, const char *path) +{ + reporevlink("about", name, title, class, head, rev, path); +} + void cgit_plain_link(const char *name, const char *title, const char *class, const char *head, const char *rev, const char *path) { diff --git a/ui-shared.h b/ui-shared.h index 2a3a7f5..6a2c6e2 100644 --- a/ui-shared.h +++ b/ui-shared.h @@ -24,6 +24,9 @@ extern void cgit_tag_link(const char *name, const char *title, extern void cgit_tree_link(const char *name, const char *title, const char *class, const char *head, const char *rev, const char *path); +extern void cgit_about_link(const char *name, const char *title, + const char *class, const char *head, + const char *rev, const char *path); extern void cgit_plain_link(const char *name, const char *title, const char *class, const char *head, const char *rev, const char *path); diff --git a/ui-tree.c b/ui-tree.c index 5ac8c9a..851074e 100644 --- a/ui-tree.c +++ b/ui-tree.c @@ -112,6 +112,9 @@ static void print_object(const struct object_id *oid, const char *path, const ch cgit_print_layout_start(); htmlf("blob: %s (", oid_to_hex(oid)); + cgit_about_link("about", NULL, NULL, ctx.qry.head, + rev, path); + html(") ("); cgit_plain_link("plain", NULL, NULL, ctx.qry.head, rev, path); if (ctx.repo->enable_blame && !is_binary) { -- 2.54.0 From 4c037918a2aab30e47cacfe1b296a7927137ace4 Mon Sep 17 00:00:00 2001 From: Christian Hesse <mail@eworm.de> Date: Wed, 2 Jan 2019 09:20:40 +0100 Subject: [PATCH 05/10] ui-tree: add about link in tree view list Signed-off-by: Christian Hesse <mail@eworm.de> --- ui-tree.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui-tree.c b/ui-tree.c index 851074e..542c523 100644 --- a/ui-tree.c +++ b/ui-tree.c @@ -272,6 +272,9 @@ static int ls_item(const struct object_id *oid, struct strbuf *base, if (!S_ISGITLINK(mode)) cgit_plain_link("plain", NULL, "button", ctx.qry.head, walk_tree_ctx->curr_rev, fullpath.buf); + if (!S_ISDIR(mode)) + cgit_about_link("about", NULL, "button", ctx.qry.head, + walk_tree_ctx->curr_rev, fullpath.buf); if (!S_ISDIR(mode) && ctx.repo->enable_blame) cgit_blame_link("blame", NULL, "button", ctx.qry.head, walk_tree_ctx->curr_rev, fullpath.buf); -- 2.54.0 From 1854c18658707741c5bf0b5eaca554e083a3729b Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" <Jason@zx2c4.com> Date: Wed, 19 Mar 2014 02:58:41 -0600 Subject: [PATCH 06/10] steal kernel.org's libravatar lua Signed-off-by: Christian Hesse <mail@eworm.de> --- cgit.css | 28 ++++++++++++++++++++++++++++ filters/email-libravatar-hover.lua | 25 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 filters/email-libravatar-hover.lua diff --git a/cgit.css b/cgit.css index 092883f..dab5977 100644 --- a/cgit.css +++ b/cgit.css @@ -934,3 +934,31 @@ div#cgit table.ssdiff td.space { div#cgit table.ssdiff td.space div { min-height: 3em; } +div#cgit span.libravatar img.onhover { + display: none; + border: 1px solid gray; + padding: 0px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + width: 128px; + height: 128px; +} + +div#cgit span.libravatar img.inline { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + width: 13px; + height: 13px; + margin-right: 0.2em; + opacity: 0.6; +} + +div#cgit span.libravatar:hover > img.onhover { + display: block; + position: absolute; + margin-left: 1.5em; + background-color: #eeeeee; + box-shadow: 2px 2px 7px rgba(100,100,100,0.75); +} diff --git a/filters/email-libravatar-hover.lua b/filters/email-libravatar-hover.lua new file mode 100644 index 0000000..c14b618 --- /dev/null +++ b/filters/email-libravatar-hover.lua @@ -0,0 +1,25 @@ +local digest = require("openssl.digest") + +function md5_hex(input) + local b = digest.new("md5"):final(input) + local x = "" + for i = 1, #b do + x = x .. string.format("%.2x", string.byte(b, i)) + end + return x +end + +function filter_open(email, page) + buffer = "" + hexdigest = md5_hex(email:sub(2, -2):lower()) +end + +function filter_close() + baseurl = os.getenv("HTTPS") and "https://seccdn.libravatar.org/" or "http://cdn.libravatar.org/" + html("<span class='libravatar'><img class='inline' src='" .. baseurl .. "avatar/" .. hexdigest .. "?s=13&d=retro' /><img class='onhover' src='" .. baseurl .. "avatar/" .. hexdigest .. "?s=128&d=retro' /></span>" .. buffer) + return 0 +end + +function filter_write(str) + buffer = buffer .. str +end -- 2.54.0 From 0f782947ed10ba7341d95fcf3de5095c3dc2ef8c Mon Sep 17 00:00:00 2001 From: Eric Wong <e@80x24.org> Date: Thu, 21 May 2026 15:04:30 +0200 Subject: [PATCH 07/10] ui-log: improve decoration display for browsers without CSS Text-based browsers without CSS support show all the decorations bunched together without spacing. Rely on a whitespace instead of CSS support. --- cgit.css | 1 - ui-log.c | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cgit.css b/cgit.css index dab5977..d669e47 100644 --- a/cgit.css +++ b/cgit.css @@ -755,7 +755,6 @@ div#cgit div.commit-subject a.tag-deco, div#cgit div.commit-subject a.tag-annotated-deco, div#cgit div.commit-subject a.remote-deco, div#cgit div.commit-subject a.deco { - margin-left: 1em; font-size: 75%; } diff --git a/ui-log.c b/ui-log.c index 434ff8d..b4c895c 100644 --- a/ui-log.c +++ b/ui-log.c @@ -77,11 +77,13 @@ void show_commit_decorations(struct commit *commit) * don't display anything. */ break; case DECORATION_REF_LOCAL: + html(" "); cgit_log_link(buf, NULL, "branch-deco", buf, NULL, ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg, 0); break; case DECORATION_REF_TAG: + html(" "); if (!refs_read_ref(get_main_ref_store(the_repository), deco->name, &oid_tag) && !peel_object(the_repository, &oid_tag, &peeled, PEEL_OBJECT_VERIFY_TAGGED_OBJECT_TYPE)) is_annotated = !oideq(&oid_tag, &peeled); @@ -90,12 +92,14 @@ void show_commit_decorations(struct commit *commit) case DECORATION_REF_REMOTE: if (!ctx.repo->enable_remote_branches) break; + html(" "); cgit_log_link(buf, NULL, "remote-deco", NULL, oid_to_hex(&commit->object.oid), ctx.qry.vpath, 0, NULL, NULL, ctx.qry.showmsg, 0); break; default: + html(" "); cgit_commit_link(buf, NULL, "deco", ctx.qry.head, oid_to_hex(&commit->object.oid), ctx.qry.vpath); -- 2.54.0 From 1cd637cd1f637aa8aa1c2d416ae01ee31b3a691c Mon Sep 17 00:00:00 2001 From: Eric Wong <e@80x24.org> Date: Thu, 21 May 2026 15:11:10 +0200 Subject: [PATCH 08/10] use buffered stdio Our generation of HTML triggers many small write(2) syscalls which is inefficient. Time output on a horrible query against my git.git mirror shows significant performance improvement: QUERY_STRING='id=2b93bfac0f5bcabbf60f174f4e7bfa9e318e64d5&id2=d6da71a9d16b8cf27f9d8f90692d3625c849cbc8' PATH_INFO=/mirrors/git.git/diff export QUERY_STRING PATH_INFO time ./cgit >/dev/null Before: real 0m1.585s user 0m0.904s sys 0m0.658s After: real 0m0.750s user 0m0.666s sys 0m0.076s Signed-off-by: Eric Wong <e@80x24.org> Signed-off-by: Alyssa Ross <hi@alyssa.is> --- cache.c | 7 +++++++ cgit.c | 2 +- filter.c | 22 +++++++++++++++++++++- html.c | 2 +- ui-snapshot.c | 3 +++ 5 files changed, 33 insertions(+), 3 deletions(-) diff --git a/cache.c b/cache.c index e70af13..13cceac 100644 --- a/cache.c +++ b/cache.c @@ -272,6 +272,13 @@ static int process_slot(struct cache_slot *slot) { int err; + /* + * Make sure any buffered data is flushed before we redirect, + * do sendfile(2) or write(2) + */ + if (fflush(stdout)) + return errno; + err = open_slot(slot); if (!err && slot->match) { if (is_expired(slot)) { diff --git a/cgit.c b/cgit.c index ca318e8..3dc55c3 100644 --- a/cgit.c +++ b/cgit.c @@ -684,7 +684,7 @@ static inline void authenticate_post(void) len = MAX_AUTHENTICATION_POST_BYTES; if ((len = read(STDIN_FILENO, buffer, len)) < 0) die_errno("Could not read POST from stdin"); - if (write(STDOUT_FILENO, buffer, len) < 0) + if (fwrite(buffer, 1, len, stdout) < len) die_errno("Could not write POST to stdout"); cgit_close_filter(ctx.cfg.auth_filter); exit(0); diff --git a/filter.c b/filter.c index c778d05..781f8e3 100644 --- a/filter.c +++ b/filter.c @@ -48,6 +48,7 @@ static int open_exec_filter(struct cgit_filter *base, va_list ap) for (i = 0; i < filter->base.argument_count; i++) filter->argv[i + 1] = va_arg(ap, char *); + chk_zero(fflush(stdout), "unable to flush STDOUT"); filter->old_stdout = chk_positive(dup(STDOUT_FILENO), "Unable to duplicate STDOUT"); chk_zero(pipe(pipe_fh), "Unable to create pipe to subprocess"); @@ -71,6 +72,7 @@ static int close_exec_filter(struct cgit_filter *base) struct cgit_exec_filter *filter = (struct cgit_exec_filter *)base; int i, exit_status = 0; + chk_zero(fflush(stdout), "unable to flush STDOUT"); chk_non_negative(dup2(filter->old_stdout, STDOUT_FILENO), "Unable to restore STDOUT"); close(filter->old_stdout); @@ -143,17 +145,32 @@ void cgit_init_filters(void) #endif #ifndef NO_LUA -static ssize_t (*libc_write)(int fd, const void *buf, size_t count); +static size_t (*libc_fwrite)(const void *buf, size_t size, size_t n, FILE *); +static ssize_t (*libc_write)(int fd, const void *buf, size_t size); static ssize_t (*filter_write)(struct cgit_filter *base, const void *buf, size_t count) = NULL; static struct cgit_filter *current_write_filter = NULL; void cgit_init_filters(void) { + /* + * we need to wrap both functions since the Lua filter may + * have code which calls write(2) directly, bypassing fwrite(3) + */ + libc_fwrite = dlsym(RTLD_NEXT, "fwrite"); + if (!libc_fwrite) + die("Could not locate libc's write function"); libc_write = dlsym(RTLD_NEXT, "write"); if (!libc_write) die("Could not locate libc's write function"); } +size_t fwrite(const void *buf, size_t size, size_t n, FILE *f) +{ + if (f != stdout || !filter_write) + return libc_fwrite(buf, size, n, f); + return filter_write(current_write_filter, buf, size * n); +} + ssize_t write(int fd, const void *buf, size_t count) { if (fd != STDOUT_FILENO || !filter_write) @@ -305,6 +322,9 @@ static int open_lua_filter(struct cgit_filter *base, va_list ap) struct lua_filter *filter = (struct lua_filter *)base; int i; + if (fflush(stdout)) + return 1; + if (init_lua_filter(filter)) return 1; diff --git a/html.c b/html.c index 0bac34b..ced781a 100644 --- a/html.c +++ b/html.c @@ -80,7 +80,7 @@ char *fmtalloc(const char *format, ...) void html_raw(const char *data, size_t size) { - if (write(STDOUT_FILENO, data, size) != size) + if (fwrite(data, 1, size, stdout) != size) die_errno("write error on html output"); } diff --git a/ui-snapshot.c b/ui-snapshot.c index d157222..b3039d9 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c @@ -39,6 +39,9 @@ static int write_archive_type(const char *format, const char *hex, const char *p /* strvec guarantees a trailing NULL entry. */ memcpy(nargv, argv.v, sizeof(char *) * (argv.nr + 1)); + if (fflush(stdout)) + return errno; + result = write_archive(argv.nr, nargv, NULL, the_repository, NULL, 0); strvec_clear(&argv); free(nargv); -- 2.54.0 From 55f8359c0b18e6f2c182fd14132d1d58fb39b6d1 Mon Sep 17 00:00:00 2001 From: Alyssa Ross <hi@alyssa.is> Date: Thu, 21 May 2026 14:17:50 +0200 Subject: [PATCH 09/10] ui-shared: add "this commit" option to switch form Branches are grouped into their own section to make the "this commit" option visually distinct. Adding this option will result in two options being marked as selected if a branch has the same name as a commit oid. But that would cause all sorts of other problems anyway (attempting to switch to the branch would actually give you the commit, etc.), so let's not worry about that. A "permalink" link on the blob view next to the "plain" link would probably be more discoverable, but that would only work for the blob view. The switch UI is visible everywhere. Signed-off-by: Alyssa Ross <hi@alyssa.is> --- ui-shared.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ui-shared.c b/ui-shared.c index 0734711..9b602cc 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -947,6 +947,15 @@ void cgit_add_clone_urls(void (*fn)(const char *)) add_clone_urls(fn, ctx.cfg.clone_prefix, ctx.repo->url); } +static int print_this_commit_option(void) +{ + struct object_id oid; + if (repo_get_oid(the_repository, ctx.qry.head, &oid)) + return 1; + html_option(oid_to_hex(&oid), "this commit", ctx.qry.head); + return 0; +} + static int print_branch_option(const struct reference *ref, void *cb_data) { char *name = (char *)ref->name; @@ -1053,11 +1062,14 @@ static void print_header(void) html("<form method='get'>\n"); cgit_add_hidden_formfields(0, 1, ctx.qry.page); html("<select name='h' onchange='this.form.submit();'>\n"); + print_this_commit_option(); + html("<optgroup label='branches'>"); refs_for_each_branch_ref(get_main_ref_store(the_repository), print_branch_option, ctx.qry.head); if (ctx.repo->enable_remote_branches) refs_for_each_remote_ref(get_main_ref_store(the_repository), print_branch_option, ctx.qry.head); + html("</optgroup>"); html("</select> "); html("<input type='submit' value='switch'/>"); html("</form>"); -- 2.54.0 From c9f91124f9462d8eeb0a9d2ddeff586807413fc0 Mon Sep 17 00:00:00 2001 From: Baptiste Jonglez <git@bitsofnetworks.org> Date: Fri, 27 Feb 2026 16:51:11 +0100 Subject: [PATCH 10/10] cgit: Fix guessing default branch Even when HEAD is set to "main" in a repository, cgit still uses the "master" branch to detect the age of the last commit. Example: $ cat repositories/openwrt/openwrt.git/HEAD ref: refs/heads/main $ stat repositories/openwrt/openwrt.git/refs/heads/master Modify: 2024-02-22 23:00:01.285731731 +0000 $ stat repositories/openwrt/openwrt.git/refs/heads/main Modify: 2026-02-27 15:33:49.506017172 +0000 In this situation, cgit displays "25 months" for this repository on the index page. I guess the internal format for HEAD has changed at some point, so it needs to be taken into account when parsing it in cgit. Signed-off-by: Baptiste Jonglez <git@bitsofnetworks.org> --- cgit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cgit.c b/cgit.c index 3dc55c3..2efbb2c 100644 --- a/cgit.c +++ b/cgit.c @@ -496,7 +496,7 @@ static char *guess_defbranch(void) ref = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), "HEAD", 0, &oid, NULL); - if (!ref || !skip_prefix(ref, "refs/heads/", &refname)) + if (!ref || !skip_prefix(ref, "ref: refs/heads/", &refname)) return "master"; return xstrdup(refname); } -- 2.54.0
-
-
-
@@ -1,7 +1,12 @@final: prev: { cgit = prev.cgit.overrideAttrs (old: { # Make default pages configurable # Vendor the patch here since the original no longer applies cleanly patches = [ ./default-pages.patch ]; patches = [ # Make default pages configurable # Vendor the patch here since the original no longer applies cleanly ./default-pages.patch # This has some performance improvements and doesn't assume the default branch is master # Actually that default branch bug might not be fixed but whatever ./for-jason.patch ]; }); }
-