From Jason at zx2c4.com Mon May 4 21:18:44 2026 From: Jason at zx2c4.com (Jason A. Donenfeld) Date: Mon, 4 May 2026 23:18:44 +0200 Subject: [ANNOUNCE] CGIT v1.3.1 Released In-Reply-To: References: <20200314000336.GA997354@zx2c4.com> Message-ID: Hi folks, CGit 1.3.1 is now available. == CGit on the Web == * homepage: https://git.zx2c4.com/cgit/about/ * git repository: https://git.zx2c4.com/cgit * mailing list: cgit at lists.zx2c4.com * mailing list subscribe: https://lists.zx2c4.com/mailman/listinfo/cgit == ChangeLog v1.3.1 == 19 files changed, 147 insertions(+), 120 deletions(-) - Allow link following to be disabled per-repo, so that this CPU intensive operation can be disabled on specific repos. - More gracefully error out if a bad grep pattern is passed. - Truncate cache slots before writing them, so that old cache contents aren't mixed with new cache contents improperly. - Do not accept newlines in config items. This fixes an issue with `git-config` based configuration settings being able to inject cached global settings or per-repo settings for different repos, which might be crossing a privilege barrier. - Various const-correctness issues have been fixed. This release contains commits from: Jason A. Donenfeld and Christian Hesse. == Downloading == This release is available in compressed tarball form here: https://git.zx2c4.com/cgit/snapshot/cgit-1.3.1.tar.xz SHA2-256: c40fd71e120783d5e57d822208f3e17333cde2cd4baf3e7c8c75630b68afe12a A PGP signature of that file decompressed is available here: https://git.zx2c4.com/cgit/snapshot/cgit-1.3.1.tar.asc Signing key: AB9942E6D4A4CFC3412620A749FC7012A5DE03AE Enjoy, Jason From actionmystique at gmail.com Sat May 9 08:41:21 2026 From: actionmystique at gmail.com (jean-christophe manciot) Date: Sat, 9 May 2026 10:41:21 +0200 Subject: 'Make default pages configurable' patch fails when being applied to 1.3.1+ Message-ID: Hi guys, The 'Make default pages configurable' patch cannot be applied anymore as of 1.3.1: git apply --verbose ../Make-default-pages-configurable.patch (attached) Checking patch cgit.c... error: while searching for: repo->homepage = xstrdup(value); else if (!strcmp(name, "defbranch")) repo->defbranch = xstrdup(value); else if (!strcmp(name, "extra-head-content")) repo->extra_head_content = xstrdup(value); else if (!strcmp(name, "snapshots")) error: patch failed: cgit.c:56 error: cgit.c: patch does not apply Checking patch cgit.h... Hunk #1 succeeded at 91 (offset 4 lines). Hunk #2 succeeded at 199 (offset 2 lines). Hunk #3 succeeded at 215 (offset 2 lines). Checking patch cgitrc.5.txt... Checking patch cmd.c... Checking patch ui-repolist.c... Checking patch ui-shared.c... Hunk #1 succeeded at 330 (offset 2 lines). Hunk #2 succeeded at 1047 (offset 6 lines). Hunk #3 succeeded at 1144 (offset 8 lines). Checking patch ui-shared.h... -- Jean-Christophe -------------- next part -------------- A non-text attachment was scrubbed... Name: Make-default-pages-configurable.patch Type: text/x-patch Size: 8777 bytes Desc: not available URL: From dakkar at thenautilus.net Mon May 18 13:26:10 2026 From: dakkar at thenautilus.net (Gianni Ceccarelli) Date: Mon, 18 May 2026 14:26:10 +0100 Subject: output of some filters not included verbatim Message-ID: <20260518142610.2270d36c@exelion> Today I added a `commit-filter=/usr/lib64/cgit/filters/html-converters/md2html` line to my `/etc/cgitrc`, and was a bit surprised when I saw `<` and `>` in the web ui (example: https://www.thenautilus.net/cgit/media-control/commit/?id=6fda0abed78af7be43ca554c07244bce0f0115a7 ) The cgitrc manpage says of `commit-filter`: > the STDOUT from the command will be included verbatim as the commit > message but `md2html` prints `<` and `>`, not `&lt;` and `&gt;` Then I looked through the cgit source, and I saw that different places handle the output of filters differently: * the output of `source_filter` is always printed via `html_raw` * `about_filter` via `html_include` (which calls `html_raw`) or `cgit_print_file` * `email_filter`, `owner_filter`, and `commit_filter`, via `html_txt` So the output of `email_filter`, `owner_filter`, and `commit_filter` is *not* "included verbatim", it undergoes HTML escaping. I think this difference should be documented, or maybe the output of all filters should really be included verbatim (while still using `html_txt` when there's no filter involved, to prevent injection from untrusted input) Opinions? -- Dakkar - GPG public key fingerprint = A071 E618 DD2C 5901 9574 6FE2 40EA 9883 7519 3F88 key id = 0x75193F88 From hi at alyssa.is Thu May 21 12:17:50 2026 From: hi at alyssa.is (Alyssa Ross) Date: Thu, 21 May 2026 14:17:50 +0200 Subject: [PATCH v3] ui-shared: add "this commit" option to switch form Message-ID: <20260521121749.4195-2-hi@alyssa.is> 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 --- v3: rebase v2: https://lists.zx2c4.com/pipermail/cgit/2020-July/004502.html ui-shared.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ui-shared.c b/ui-shared.c index df52a9b..bf8eeea 100644 --- a/ui-shared.c +++ b/ui-shared.c @@ -941,6 +941,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; @@ -1047,11 +1056,14 @@ static void print_header(void) html("
\n"); cgit_add_hidden_formfields(0, 1, ctx.qry.page); html(" "); html(""); html("
"); base-commit: 044821677c774cd24f25f1818ea51d09cc64b006 -- 2.53.0 From hi at alyssa.is Thu May 21 13:04:30 2026 From: hi at alyssa.is (Alyssa Ross) Date: Thu, 21 May 2026 15:04:30 +0200 Subject: [PATCH v2] ui-log: improve decoration display for browsers without CSS Message-ID: <20260521130429.8357-2-hi@alyssa.is> From: Eric Wong Text-based browsers without CSS support show all the decorations bunched together without spacing. Rely on a whitespace instead of CSS support. --- v2: rebase v1: https://lists.zx2c4.com/pipermail/cgit/2019-January/004288.html I've been running cgit with this patch for years. Why I wasn't using Eric's whole original 4-part patch series is lost to time, so I'm just rebasing the ones I have been using individually. cgit.css | 1 - ui-log.c | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/cgit.css b/cgit.css index d10a24d..6963b84 100644 --- a/cgit.css +++ b/cgit.css @@ -728,7 +728,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 9906bbc..12caeed 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); base-commit: 044821677c774cd24f25f1818ea51d09cc64b006 -- 2.53.0 From hi at alyssa.is Thu May 21 13:11:10 2026 From: hi at alyssa.is (Alyssa Ross) Date: Thu, 21 May 2026 15:11:10 +0200 Subject: [PATCH v2] use buffered stdio Message-ID: <20260521131109.9704-2-hi@alyssa.is> From: Eric Wong 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 Signed-off-by: Alyssa Ross --- v2: rebase v1: https://lists.zx2c4.com/pipermail/cgit/2021-March/004630.html 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); base-commit: 044821677c774cd24f25f1818ea51d09cc64b006 -- 2.53.0 From aiden at aidenw.net Sat May 23 21:55:50 2026 From: aiden at aidenw.net (Aiden Woodruff) Date: Sat, 23 May 2026 17:55:50 -0400 Subject: [PATCH v2] ui-log: improve decoration display for browsers without CSS In-Reply-To: <20260521130429.8357-2-hi@alyssa.is> References: <20260521130429.8357-2-hi@alyssa.is> Message-ID: On 5/21/26 9:04 AM, Alyssa Ross wrote: > From: Eric Wong > > Text-based browsers without CSS support show all the decorations > bunched together without spacing. Rely on a whitespace instead > of CSS support. Please consider also adding spaces around about/summary/refs/log/tree/commit/diff/stats tabs or log/stats/plain/blame buttons in the tree view. I think that would also be a readability improvement for text browsers. -- Aiden Woodruff -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 2792 bytes Desc: S/MIME Cryptographic Signature URL: