| author | 2026-09-08 10:07:45 +0700 | |
|---|---|---|
| committer | 2026-09-08 10:07:45 +0700 | |
| commit | 60a59f650da76dd95f6c6221287b2745b7e44291 (patch) | |
| tree | f73b532b4433be931e78df15197384d60b0c4670 | |
| parent | 3e40b846456e4efc06ece7180ef152e053114385 (diff) | |
| download | cgitext-60a59f650da76dd95f6c6221287b2745b7e44291.tar.gz cgitext-60a59f650da76dd95f6c6221287b2745b7e44291.zip | |
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-x | tests/t0106-diff.sh | 29 | ||||
| -rw-r--r-- | ui-diff.c | 78 |
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&idoff=2&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 @@ -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>"); |