diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Keep a detached head in the branch switcher
Diffstat (limited to '')
-rw-r--r--source/ui-shared.c41
1 file changed, 41 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);