diff options
| author | 2026-08-15 22:17:12 +0700 | |
|---|---|---|
| committer | 2026-08-15 22:17:12 +0700 | |
| commit | 61aa4378441859ed2851db01d5d1b01ed1aa2458 (patch) | |
| tree | 9769811b616bcf8a5741cd89b3d46c361ba43f4d | |
| parent | 3beb4785562b158fc4c4e67185ac488d5bfa5c60 (diff) | |
| download | cgitext-61aa4378441859ed2851db01d5d1b01ed1aa2458.tar.gz cgitext-61aa4378441859ed2851db01d5d1b01ed1aa2458.zip | |
Beforehand the choice between two refs in diff could not be changed from
web ui (only via url query), and by default it was current and previous
commit. Now it is doable with dropdown menus.
| -rw-r--r-- | README.md | 2 | ||||
| -rwxr-xr-x | tests/t0106-diff.sh | 56 | ||||
| -rw-r--r-- | ui-diff.c | 66 |
3 files changed, 123 insertions, 1 deletions
@@ -12,6 +12,8 @@ This is a custom expansion to cgit. Its most prominent changes by now are: * Include optional solarized.css addon theme. +* Allow user to pick variable refs for diff in web ui. + The original cgit project is hosted at [git.zx2c4.com](https://git.zx2c4.com/cgit/about/) ## cgit – CGI for Git diff --git a/tests/t0106-diff.sh b/tests/t0106-diff.sh index 82b645e..0c167d4 100755 --- a/tests/t0106-diff.sh +++ b/tests/t0106-diff.sh @@ -16,4 +16,60 @@ test_expect_success 'find added line' ' grep "<div class=.add.>+5</div>" tmp ' +test_expect_success 'ref picker: from: select present' ' + grep "<select name=.id2." tmp +' + +test_expect_success 'ref picker: to: select present' ' + grep "<select name=.id." tmp +' + +test_expect_success 'ref picker: from: label present' ' + grep "from:" tmp +' + +test_expect_success 'ref picker: to: label present' ' + grep "to:" tmp +' + +test_expect_success 'ref picker: master branch listed' ' + grep "master" tmp +' + +test_expect_success 'ref picker: auto-submit on change' ' + grep "onchange=.this.form.submit()." tmp +' + +test_expect_success 'compare two refs: foo/diff?id=master&id2=HEAD' ' + cgit_query "url=foo/diff&id=master&id2=HEAD" >tmp +' + +test_expect_success 'diff with explicit refs shows diffstat' ' + grep "diffstat" tmp +' + +test_expect_success 'diff with oid2 parameter uses it for old ref' ' + cgit_query "url=foo/diff&id=master&id2=HEAD" >tmp && + grep "from:" tmp +' + +test_expect_success 'ref picker: to: shows master when id=master' ' + cgit_query "url=foo/diff&id=master" >tmp && + grep "master" tmp +' + +test_expect_success 'ref picker: from: empty when no id2' ' + cgit_query "url=foo/diff" >tmp && + grep "<select name=.id2." tmp +' + +test_expect_success 'compare initial commit with HEAD' ' + root=$(git --git-dir="$PWD/repos/foo/.git" rev-list --max-parents=0 HEAD) && + cgit_query "url=foo/diff&id=HEAD&id2=$root" >tmp +' + +test_expect_success 'diff with HEAD and root shows content' ' + grep "diffstat" tmp +' + test_done @@ -1,6 +1,10 @@ /* ui-diff.c: show diff between two blobs * * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com> + * Copyright (C) 2026 Saya Andy <saya.andy@posteo.com> + * + * Modified 2026 by Saya Andy: + * Select variable refs from web ui for diff * * Licensed under GNU General Public License v2 * (see COPYING for full license text) @@ -336,6 +340,32 @@ static void filepair_cb(struct diff_filepair *pair) cgit_ssdiff_footer(); } +static int print_ref_option(const struct reference *ref, void *cb_data) +{ + const char **sel = (const char **)cb_data; + + html_option(ref->name, ref->name, sel[0]); + return 0; +} + +static void cgit_print_ref_select(const char *name, const char *selected) +{ + /* + * Offer every branch and tag so that any two refs can be compared. + */ + html("<select name='"); + html_attr(name); + html("' onchange='this.form.submit();'>"); + refs_for_each_branch_ref(get_main_ref_store(the_repository), + print_ref_option, (void *)&selected); + if (ctx.repo->enable_remote_branches) + refs_for_each_remote_ref(get_main_ref_store(the_repository), + print_ref_option, (void *)&selected); + refs_for_each_tag_ref(get_main_ref_store(the_repository), + print_ref_option, (void *)&selected); + html("</select>"); +} + void cgit_print_diff_ctrls(void) { int i, curr; @@ -343,9 +373,43 @@ void cgit_print_diff_ctrls(void) html("<div class='cgit-panel'>"); html("<b>diff options</b>"); html("<form method='get'>"); - cgit_add_hidden_formfields(1, 0, ctx.qry.page); + /* + * Emit the same hidden fields as cgit_add_hidden_formfields(), except + * id/id2, which are carried by the ref-picker selects below. + */ + if (!ctx.cfg.virtual_root) { + struct strbuf url = STRBUF_INIT; + strbuf_addf(&url, "%s/%s", ctx.qry.repo, ctx.qry.page); + if (ctx.qry.vpath) + strbuf_addf(&url, "/%s", ctx.qry.vpath); + html_hidden("url", url.buf); + strbuf_release(&url); + } + if (ctx.qry.head && ctx.repo->defbranch && + strcmp(ctx.qry.head, ctx.repo->defbranch)) + html_hidden("h", ctx.qry.head); + if (ctx.qry.showmsg) + html_hidden("showmsg", "1"); + html("<table>"); html("<tr><td colspan='2'/></tr>"); + + /* ref pickers: compare any two refs (branches/tags) */ + { + const char *new_ref = ctx.qry.oid ? ctx.qry.oid : ctx.qry.head; + const char *old_ref = ctx.qry.oid2; + + html("<tr>"); + html("<td class='label'>from:</td>"); + html("<td class='ctrl'>"); + cgit_print_ref_select("id2", old_ref); + html("</td></tr><tr>"); + html("<td class='label'>to:</td>"); + html("<td class='ctrl'>"); + cgit_print_ref_select("id", new_ref); + html("</td></tr>"); + } + html("<tr>"); html("<td class='label'>context:</td>"); html("<td class='ctrl'>"); |