From 07acda1ec4e46a36b9873fe6bbe470d57b135f45 Mon Sep 17 00:00:00 2001 From: Amisha Chhajed <136238836+amishhaa@users.noreply.github.com> Date: Sat, 21 Feb 2026 21:53:59 +0530 Subject: [PATCH 1/2] help: cleanup the contruction of keys_uniq uniqueness property of keys_uniq depends on the sort operation executed for keys, sorted property of keys does not gurantee sorted property of keys_uniq due to processing keys, this might also introduce regressions in future when the logic of forming keys_uniq from keys is changed. add string_list_sort_u operation for keys_uniq and refactor the processing code to simplify it. Signed-off-by: Amisha Chhajed <136238836+amishhaa@users.noreply.github.com> Signed-off-by: Junio C Hamano --- builtin/help.c | 134 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 90 insertions(+), 44 deletions(-) diff --git a/builtin/help.c b/builtin/help.c index c09cbc8912..b70de09864 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -111,6 +111,84 @@ struct slot_expansion { int found; }; +static void show_config_human(struct string_list *keys) +{ + string_list_sort(keys); + for (size_t i = 0; i < keys->nr; i++) { + const char *var = keys->items[i].string; + puts(var); + } +} + +static void show_config_sections(struct string_list *keys) +{ + struct string_list keys_uniq = STRING_LIST_INIT_DUP; + struct strbuf sb = STRBUF_INIT; + struct string_list_item *item; + + for (size_t i = 0; i < keys->nr; i++) { + const char *var = keys->items[i].string; + const char *dot = strchr(var, '.'); + const char *wildcard = strchr(var, '*'); + const char *tag = strchr(var, '<'); + const char *cut; + + if (dot) + cut = dot; + else if (wildcard && tag) + cut = wildcard < tag ? wildcard : tag; + else if (wildcard) + cut = wildcard; + else if (tag) + cut = tag; + else { + string_list_append(&keys_uniq, var); + continue; + } + + strbuf_add(&sb, var, cut - var); + string_list_append(&keys_uniq, sb.buf); + strbuf_release(&sb); + } + string_list_sort_u(&keys_uniq, 0); + for_each_string_list_item(item, &keys_uniq) + puts(item->string); + string_list_clear(&keys_uniq, 0); +} + +static void show_config_vars(struct string_list *keys) +{ + struct string_list keys_uniq = STRING_LIST_INIT_DUP; + struct strbuf sb = STRBUF_INIT; + struct string_list_item *item; + + for (size_t i = 0; i < keys->nr; i++) { + const char *var = keys->items[i].string; + const char *wildcard = strchr(var, '*'); + const char *tag = strchr(var, '<'); + const char *cut; + + if (wildcard && tag) + cut = wildcard < tag ? wildcard : tag; + else if (wildcard) + cut = wildcard; + else if (tag) + cut = tag; + else { + string_list_append(&keys_uniq, var); + continue; + } + + strbuf_add(&sb, var, cut - var); + string_list_append(&keys_uniq, sb.buf); + strbuf_release(&sb); + } + string_list_sort_u(&keys_uniq, 0); + for_each_string_list_item(item, &keys_uniq) + puts(item->string); + string_list_clear(&keys_uniq, 0); +} + static void list_config_help(enum show_config_type type) { struct slot_expansion slot_expansions[] = { @@ -129,8 +207,6 @@ static void list_config_help(enum show_config_type type) const char **p; struct slot_expansion *e; struct string_list keys = STRING_LIST_INIT_DUP; - struct string_list keys_uniq = STRING_LIST_INIT_DUP; - struct string_list_item *item; for (p = config_name_list; *p; p++) { const char *var = *p; @@ -156,50 +232,20 @@ static void list_config_help(enum show_config_type type) BUG("slot_expansion %s.%s is not used", e->prefix, e->placeholder); - string_list_sort(&keys); - for (size_t i = 0; i < keys.nr; i++) { - const char *var = keys.items[i].string; - const char *wildcard, *tag, *cut; - const char *dot = NULL; - struct strbuf sb = STRBUF_INIT; - - switch (type) { - case SHOW_CONFIG_HUMAN: - puts(var); - continue; - case SHOW_CONFIG_SECTIONS: - dot = strchr(var, '.'); - break; - case SHOW_CONFIG_VARS: - break; - } - wildcard = strchr(var, '*'); - tag = strchr(var, '<'); - - if (!dot && !wildcard && !tag) { - string_list_append(&keys_uniq, var); - continue; - } - - if (dot) - cut = dot; - else if (wildcard && !tag) - cut = wildcard; - else if (!wildcard && tag) - cut = tag; - else - cut = wildcard < tag ? wildcard : tag; - - strbuf_add(&sb, var, cut - var); - string_list_append(&keys_uniq, sb.buf); - strbuf_release(&sb); - + switch (type) { + case SHOW_CONFIG_HUMAN: + show_config_human(&keys); + break; + case SHOW_CONFIG_SECTIONS: + show_config_sections(&keys); + break; + case SHOW_CONFIG_VARS: + show_config_vars(&keys); + break; + default: + BUG("%d: unexpected type", type); } string_list_clear(&keys, 0); - string_list_remove_duplicates(&keys_uniq, 0); - for_each_string_list_item(item, &keys_uniq) - puts(item->string); - string_list_clear(&keys_uniq, 0); } static enum help_format parse_help_format(const char *format) From 6d577915a30c107765cfb939d78d2ac7f4a5a071 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 21 Feb 2026 21:03:45 -0800 Subject: [PATCH 2/2] SQUASH??? simplify --- builtin/help.c | 72 +++++++++++++++++++------------------------------- 1 file changed, 27 insertions(+), 45 deletions(-) diff --git a/builtin/help.c b/builtin/help.c index b70de09864..bc5c5a556c 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -120,36 +120,37 @@ static void show_config_human(struct string_list *keys) } } +static void grab_leading_part(struct string_list *keys, const char *var, int use_dot) +{ + const char *cut = NULL; + + if (use_dot) + cut = strchr(var, use_dot); + + if (!cut) { + size_t prefix_len = strcspn(var, "*<"); + if (var[prefix_len]) + cut = var + prefix_len; + } + + if (!cut) + string_list_append(keys, var); + else { + struct strbuf sb = STRBUF_INIT; + strbuf_add(&sb, var, cut - var); + string_list_append(keys, sb.buf); + strbuf_release(&sb); + } +} + static void show_config_sections(struct string_list *keys) { struct string_list keys_uniq = STRING_LIST_INIT_DUP; - struct strbuf sb = STRBUF_INIT; struct string_list_item *item; - for (size_t i = 0; i < keys->nr; i++) { - const char *var = keys->items[i].string; - const char *dot = strchr(var, '.'); - const char *wildcard = strchr(var, '*'); - const char *tag = strchr(var, '<'); - const char *cut; + for (size_t i = 0; i < keys->nr; i++) + grab_leading_part(&keys_uniq, keys->items[i].string, '.'); - if (dot) - cut = dot; - else if (wildcard && tag) - cut = wildcard < tag ? wildcard : tag; - else if (wildcard) - cut = wildcard; - else if (tag) - cut = tag; - else { - string_list_append(&keys_uniq, var); - continue; - } - - strbuf_add(&sb, var, cut - var); - string_list_append(&keys_uniq, sb.buf); - strbuf_release(&sb); - } string_list_sort_u(&keys_uniq, 0); for_each_string_list_item(item, &keys_uniq) puts(item->string); @@ -159,30 +160,11 @@ static void show_config_sections(struct string_list *keys) static void show_config_vars(struct string_list *keys) { struct string_list keys_uniq = STRING_LIST_INIT_DUP; - struct strbuf sb = STRBUF_INIT; struct string_list_item *item; - for (size_t i = 0; i < keys->nr; i++) { - const char *var = keys->items[i].string; - const char *wildcard = strchr(var, '*'); - const char *tag = strchr(var, '<'); - const char *cut; + for (size_t i = 0; i < keys->nr; i++) + grab_leading_part(&keys_uniq, keys->items[i].string, '\0'); - if (wildcard && tag) - cut = wildcard < tag ? wildcard : tag; - else if (wildcard) - cut = wildcard; - else if (tag) - cut = tag; - else { - string_list_append(&keys_uniq, var); - continue; - } - - strbuf_add(&sb, var, cut - var); - string_list_append(&keys_uniq, sb.buf); - strbuf_release(&sb); - } string_list_sort_u(&keys_uniq, 0); for_each_string_list_item(item, &keys_uniq) puts(item->string);