diff options
| author | Bryce Kwon <bryce@brycekwon.com> | |
|---|---|---|
| committer | Bryce Kwon <bryce@brycekwon.com> | |
| commit | ||
| parent | ||
| tree | ||
| download | ||
Keep a detached head in the branch switcher
| -rw-r--r-- | source/ui-shared.c | 41 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -rwxr-xr-x | tests/t0103-log.sh | 20 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 files changed, 61 insertions, 0 deletions
diff --git a/source/ui-shared.c b/source/ui-shared.c index cd822a0..85712bf 100644 --- a/source/ui-shared.c +++ b/source/ui-shared.c @@ -408,6 +408,45 @@ struct branch_option_data { const char *selected; }; +/* + * Whether the head the request follows is one of the branches the switcher + * lists, remote ones included when those are shown. A head that is not, a + * raw commit id or a tag, would otherwise leave the select resting on the + * first branch, and submitting the form would quietly move the visitor there. + */ +static int head_is_listed_branch(void) +{ + struct ref_store *refs = get_main_ref_store(the_repository); + struct strbuf ref = STRBUF_INIT; + int found; + + strbuf_addf(&ref, "refs/heads/%s", ctx.qry.head); + found = refs_ref_exists(refs, ref.buf); + if (!found && ctx.repo->enable_remote_branches) { + strbuf_reset(&ref); + strbuf_addf(&ref, "refs/remotes/%s", ctx.qry.head); + found = refs_ref_exists(refs, ref.buf); + } + strbuf_release(&ref); + return found; +} + +static void print_detached_head_option(void) +{ + const char *head = ctx.qry.head; + struct object_id oid; + struct strbuf label = STRBUF_INIT; + + // A head that is a full id reads better cut to the length the pinned + // entry uses. + if (strlen(head) == the_hash_algo->hexsz && !get_oid_hex(head, &oid)) + strbuf_addf(&label, "%.*s (detached)", SHORT_HASH_LEN, head); + else + strbuf_addf(&label, "%s (detached)", head); + html_option(head, label.buf, head); + strbuf_release(&label); +} + static int print_branch_option(const struct reference *ref, void *data) { struct branch_option_data *opt = data; @@ -478,6 +517,8 @@ static void print_header(void) html_option(hex, cgit_fmt("%.*s (detached)", SHORT_HASH_LEN, hex), hex); + } else if (!head_is_listed_branch()) { + print_detached_head_option(); } refs_for_each_branch_ref(get_main_ref_store(the_repository), print_branch_option, &opt); diff --git a/tests/t0103-log.sh b/tests/t0103-log.sh index 41b9769..dfb5176 100755 --- a/tests/t0103-log.sh +++ b/tests/t0103-log.sh @@ -17,6 +17,26 @@ test_expect_success 'generate bar/log' 'cgit_url "bar/log" >tmp' test_expect_success 'find commit 1' 'grep "commit 1" tmp' test_expect_success 'find commit 50' 'grep "commit 50" tmp' +# The switch button submits the select as h, so whatever head the request +# follows has to sit in the list selected, or submitting would quietly move +# the visitor to the first branch. +test_expect_success 'a detached head stays selected in the switcher' ' + sha=$(git -C repos/foo rev-parse master~1) && + cgit_url "foo/log&h=$sha" >tmp && + grep "option value=.$sha. selected" tmp +' +test_expect_success 'a tag head stays selected in the switcher' ' + git -C repos/foo tag t-switch master~1 && + cgit_url "foo/log&h=t-switch" >tmp && + grep "option value=.t-switch. selected>t-switch (detached)" tmp && + git -C repos/foo tag -d t-switch +' +test_expect_success 'a branch head keeps its plain option' ' + cgit_url "foo/log&h=master" >tmp && + grep "option value=.master. selected>master<" tmp && + ! grep "detached" tmp +' + test_expect_success 'generate "with%20space/log?qt=grep&q=commit+1"' ' cgit_url "with+space/log&qt=grep&q=commit+1" >tmp ' |
