string-list: add string_list_sort_u() that mimics "sort -u"

Many callsites of string_list_remove_duplicates() call it
immdediately after calling string_list_sort(), understandably
as the former requires string-list to be sorted, it is clear
that these places are sorting only to remove duplicates and
for no other reason.

Introduce a helper function string_list_sort_u that combines
these two calls that often appear together, to simplify
these callsites. Replace the current calls of those methods with
string_list_sort_u().

Signed-off-by: Amisha Chhajed <amishhhaaaa@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Amisha Chhajed 2026-01-29 17:42:20 +05:30 committed by Junio C Hamano
parent 208642cfbb
commit 2e711acfbd
9 changed files with 54 additions and 16 deletions

View File

@ -1136,8 +1136,7 @@ int cmd_clone(int argc,
int val;

/* remove duplicates */
string_list_sort(&option_recurse_submodules);
string_list_remove_duplicates(&option_recurse_submodules, 0);
string_list_sort_u(&option_recurse_submodules, 0);

/*
* NEEDSWORK: In a multi-working-tree world, this needs to be

View File

@ -1118,8 +1118,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
free(full_name);
}

string_list_sort(&extra_refs);
string_list_remove_duplicates(&extra_refs, 0);
string_list_sort_u(&extra_refs, 0);
}

static void handle_tags_and_duplicates(struct string_list *extras)

View File

@ -3855,10 +3855,8 @@ static void read_packs_list_from_stdin(struct rev_info *revs)
strbuf_reset(&buf);
}

string_list_sort(&include_packs);
string_list_remove_duplicates(&include_packs, 0);
string_list_sort(&exclude_packs);
string_list_remove_duplicates(&exclude_packs, 0);
string_list_sort_u(&include_packs, 0);
string_list_sort_u(&exclude_packs, 0);

repo_for_each_pack(the_repository, p) {
const char *pack_name = pack_basename(p);

View File

@ -292,8 +292,7 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl)
string_list_insert(&sl, pe->pattern);
}

string_list_sort(&sl);
string_list_remove_duplicates(&sl, 0);
string_list_sort_u(&sl, 0);

fprintf(fp, "/*\n!/*/\n");

@ -316,8 +315,7 @@ static void write_cone_to_file(FILE *fp, struct pattern_list *pl)

strbuf_release(&parent_pattern);

string_list_sort(&sl);
string_list_remove_duplicates(&sl, 0);
string_list_sort_u(&sl, 0);

for (i = 0; i < sl.nr; i++) {
char *pattern = escaped_pattern(sl.items[i].string);

3
help.c
View File

@ -420,8 +420,7 @@ void list_cmds_by_config(struct string_list *list)
if (repo_config_get_string_tmp(the_repository, "completion.commands", &cmd_list))
return;

string_list_sort(list);
string_list_remove_duplicates(list, 0);
string_list_sort_u(list, 0);

while (*cmd_list) {
struct strbuf sb = STRBUF_INIT;

View File

@ -921,8 +921,7 @@ int combine_notes_cat_sort_uniq(struct object_id *cur_oid,
if (string_list_add_note_lines(&sort_uniq_list, new_oid))
goto out;
string_list_remove_empty_items(&sort_uniq_list, 0);
string_list_sort(&sort_uniq_list);
string_list_remove_duplicates(&sort_uniq_list, 0);
string_list_sort_u(&sort_uniq_list, 0);

/* create a new blob object from sort_uniq_list */
if (for_each_string_list(&sort_uniq_list,

View File

@ -247,6 +247,12 @@ void string_list_sort(struct string_list *list)
QSORT_S(list->items, list->nr, cmp_items, &sort_ctx);
}

void string_list_sort_u(struct string_list *list, int free_util)
{
string_list_sort(list);
string_list_remove_duplicates(list, free_util);
}

struct string_list_item *unsorted_string_list_lookup(struct string_list *list,
const char *string)
{

View File

@ -239,6 +239,12 @@ struct string_list_item *string_list_append_nodup(struct string_list *list, char
*/
void string_list_sort(struct string_list *list);

/**
* Sort the list and then remove duplicate entries. If free_util is true,
* call free() on the util members of any items that have to be deleted.
*/
void string_list_sort_u(struct string_list *list, int free_util);

/**
* Like `string_list_has_string()` but for unsorted lists. Linear in
* size of the list.

View File

@ -437,6 +437,40 @@ void test_string_list__remove_duplicates(void)
t_string_list_clear(&list, 0);
}

static void t_string_list_sort_u(struct string_list *list, ...)
{
struct string_list expected_strings = STRING_LIST_INIT_DUP;
va_list ap;

va_start(ap, list);
t_vcreate_string_list_dup(&expected_strings, 0, ap);
va_end(ap);

string_list_sort_u(list, 0);
t_string_list_equal(list, &expected_strings);

string_list_clear(&expected_strings, 0);
}

void test_string_list__sort_u(void)
{
struct string_list list = STRING_LIST_INIT_DUP;

t_create_string_list_dup(&list, 0, NULL);
t_string_list_sort_u(&list, NULL);

t_create_string_list_dup(&list, 0, "", "", "", "", NULL);
t_string_list_sort_u(&list, "", NULL);

t_create_string_list_dup(&list, 0, "b", "a", "a", "", NULL);
t_string_list_sort_u(&list, "", "a", "b", NULL);

t_create_string_list_dup(&list, 0, "b", "a", "a", "d", "c", "c", NULL);
t_string_list_sort_u(&list, "a", "b", "c", "d", NULL);

t_string_list_clear(&list, 0);
}

static void t_string_list_remove_empty_items(
struct string_list *expected_strings,
struct string_list *list)