aboutsummaryrefslogtreecommitdiff
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
authorGravatar Saya Andy <saya.andy@posteo.com> 2026-09-08 10:07:45 +0700
committerGravatar Saya Andy <saya.andy@posteo.com> 2026-09-08 10:07:45 +0700
commit60a59f650da76dd95f6c6221287b2745b7e44291 (patch)
treef73b532b4433be931e78df15197384d60b0c4670
parent3e40b846456e4efc06ece7180ef152e053114385 (diff)
downloadcgitext-1.3.1+17.tar.gz
cgitext-1.3.1+17.zip
diff: show the default from ref in the refs panelHEADv1.3.1+17masterdevelop
By default a diff against a ref is shown as that ref against its parent, but the refs panel left the from picker empty, so the controls described a different diff than the page showed. When no from ref is given, preselect the to ref with one extra commit back, which is the parent of the (stepped) to rev, and reuse the same values in the flip link.
-rwxr-xr-xtests/t0106-diff.sh29
-rw-r--r--ui-diff.c78
2 files changed, 65 insertions, 42 deletions
diff --git a/tests/t0106-diff.sh b/tests/t0106-diff.sh
index 0e45087..4490ecc 100755
--- a/tests/t0106-diff.sh
+++ b/tests/t0106-diff.sh
@@ -71,9 +71,17 @@ test_expect_success 'ref picker: to: shows master when id=master' '
grep "master" tmp
'
-test_expect_success 'ref picker: from: empty when no id2' '
+test_expect_success 'ref picker: from: preselects the to ref when no id2' '
cgit_query "url=foo/diff" >tmp &&
- grep "<select name=.id2." tmp
+ grep "<select name=.id2. onchange=.this.form.submit();.><option value=.master. selected=.selected.>master</option>" tmp
+'
+
+test_expect_success 'from offset: one back when no id2' '
+ grep "name=.id2off. title=.N commits back from the selected ref. value=.1.>" tmp
+'
+
+test_expect_success 'to offset: empty when idoff unset' '
+ grep "name=.idoff. title=.N commits back from the selected ref.>" tmp
'
test_expect_success 'compare initial commit with HEAD' '
@@ -145,4 +153,21 @@ test_expect_success 'flip link carries the offsets' '
grep "/foo/diff/?id2=master&amp;idoff=2&amp;id2off=1" tmp
'
+test_expect_success 'from ref: follows the stepped to ref' '
+ cgit_query "url=foo/diff&id=master&idoff=2" >tmp &&
+ grep "name=.id2off. title=.N commits back from the selected ref. value=.3.>" tmp &&
+ grep "name=.idoff. title=.N commits back from the selected ref. value=.2.>" tmp
+'
+
+test_expect_success 'from ref: shows the given offset' '
+ cgit_query "url=foo/diff&id=master&id2=master&id2off=2" >tmp &&
+ grep "name=.id2off. title=.N commits back from the selected ref. value=.2.>" tmp
+'
+
+test_expect_success 'from ref: empty when the to ref is the root' '
+ root=$(git --git-dir="$PWD/repos/foo/.git" rev-list --max-parents=0 HEAD) &&
+ cgit_query "url=foo/diff&id=$root" >tmp &&
+ grep "name=.id2off. title=.N commits back from the selected ref.>" tmp
+'
+
test_done
diff --git a/ui-diff.c b/ui-diff.c
index c77ca2f..a542eb0 100644
--- a/ui-diff.c
+++ b/ui-diff.c
@@ -415,12 +415,34 @@ void cgit_print_diff_ctrls(void)
const char *new_ref = ctx.qry.oid && *ctx.qry.oid ?
ctx.qry.oid : ctx.qry.head;
const char *old_ref = ctx.qry.oid2;
+ const char *disp_old_ref;
+ int idoff = ctx.qry.idoff;
+ int id2off = ctx.qry.id2off;
+ int disp_id2off;
+
+ if (old_ref && *old_ref) {
+ disp_old_ref = old_ref;
+ disp_id2off = id2off;
+ } else if (!is_null_oid(old_rev_oid)) {
+ /*
+ * No from ref given: the diff compares the (stepped)
+ * to rev against its parent, i.e. new_ref~(idoff+1);
+ * show that instead of leaving the picker empty. Keep
+ * the ref name rather than a materialized parent sha.
+ */
+ disp_old_ref = new_ref;
+ disp_id2off = idoff + 1;
+ } else {
+ /* to rev is the root: diff against the empty tree */
+ disp_old_ref = NULL;
+ disp_id2off = 0;
+ }
html("<tr>");
html("<td class='label'>from:</td>");
html("<td class='ctrl'>");
- cgit_print_ref_select("id2", old_ref);
- cgit_print_ref_offset("id2off", ctx.qry.id2off);
+ cgit_print_ref_select("id2", disp_old_ref);
+ cgit_print_ref_offset("id2off", disp_id2off);
html("</td></tr><tr>");
html("<td class='label'>to:</td>");
html("<td class='ctrl'>");
@@ -431,44 +453,20 @@ void cgit_print_diff_ctrls(void)
html("<tr><td/><td class='ctrl'>");
html("<input type='submit' value='apply'>");
html(" | ");
- {
- const char *flip_new_ref;
- int flip_idoff;
- int idoff = ctx.qry.idoff;
- int id2off = ctx.qry.id2off;
-
- if (old_ref && *old_ref) {
- /* explicit from ref */
- flip_new_ref = old_ref;
- flip_idoff = id2off;
- } else if (!is_null_oid(old_rev_oid)) {
- /*
- * The from rev is the parent of the (stepped)
- * to rev, i.e. new_ref~(idoff+1); keep the
- * ref name in the url instead of a materialized
- * parent sha.
- */
- flip_new_ref = new_ref;
- flip_idoff = idoff + 1;
- } else {
- /* root: no from rev to flip to */
- flip_new_ref = NULL;
- flip_idoff = 0;
- }
-
- /*
- * cgit_diff_link() emits the offsets from ctx.qry;
- * swap them around the call so they follow the refs.
- */
- ctx.qry.idoff = flip_idoff;
- ctx.qry.id2off = idoff;
- cgit_diff_link("flip", "swap from and to", "button",
- ctx.qry.head,
- flip_new_ref, new_ref,
- ctx.qry.path);
- ctx.qry.idoff = idoff;
- ctx.qry.id2off = id2off;
- }
+ /*
+ * The flip link swaps the displayed refs, so the displayed
+ * from ref becomes the to ref. cgit_diff_link() emits the
+ * offsets from ctx.qry; swap them around the call so they
+ * follow the refs.
+ */
+ ctx.qry.idoff = disp_id2off;
+ ctx.qry.id2off = idoff;
+ cgit_diff_link("flip", "swap from and to", "button",
+ ctx.qry.head,
+ disp_old_ref, new_ref,
+ ctx.qry.path);
+ ctx.qry.idoff = idoff;
+ ctx.qry.id2off = id2off;
html("</td></tr>");
}
html("</table>");