{"thread":{"id":"56591","subject":"[PATCH 0/6] Non-trivial designated initializer conversion","startedAt":"2021-09-27T00:53:25Z","lastAt":"2021-10-02T20:16:40Z","messageCount":33,"participants":["Ævar Arnfjörð Bjarmason","Phillip Wood","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":6},"messages":[{"id":"437106","messageId":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","threadId":"56591","inReplyTo":null,"subject":"[PATCH 0/6] Non-trivial designated initializer conversion","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T00:53:14Z","receivedAt":"2021-09-27T00:53:25Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"A sister series to the just-submitted series of trivial designated\ninitalizer cleanups:\nhttps://lore.kernel.org/git/cover-0.5-00000000000-20210927T003330Z-avarab@gmail.com/\n\nThis doesn't conflict semantically or textually with that series, but\nis migrating to easier to manage initialization patterns for the same\nreasons.\n\nThe code changes are all rather small, the diff in 6/6 looks scary,\nbut as --word-diff will show most of it schanging x->y to an &x->y and\nthe like, as two struct members were changed from being pointers.\n\nÆvar Arnfjörð Bjarmason (6):\n  daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro\n  builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro\n  shortlog: use designated initializer for \"struct shortlog\"\n  urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n  builtin/remote.c: add and use a REF_STATES_INIT\n  builtin/remote.c: add and use SHOW_INFO_INIT\n\n builtin/blame.c    |  30 ++++++------\n builtin/config.c   |   3 +-\n builtin/remote.c   | 111 ++++++++++++++++++++++-----------------------\n builtin/shortlog.c |   2 +-\n credential.c       |   4 +-\n daemon.c           |  19 +++-----\n http.c             |   4 +-\n shortlog.h         |   4 ++\n urlmatch.h         |   4 ++\n 9 files changed, 87 insertions(+), 94 deletions(-)\n\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437107","messageId":"patch-1.6-3130693b416-20210927T004920Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","subject":"[PATCH 1/6] daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T00:53:15Z","receivedAt":"2021-09-27T00:53:26Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the hostinfo_init() function added in 01cec54e135 (daemon:\ndeglobalize hostname information, 2015-03-07) and instead initialize\nthe \"struct hostinfo\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n daemon.c | 19 +++++++------------\n 1 file changed, 7 insertions(+), 12 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex 5c4cbad62d0..d80d009d1a1 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -63,6 +63,12 @@ struct hostinfo {\n \tunsigned int hostname_lookup_done:1;\n \tunsigned int saw_extended_args:1;\n };\n+#define HOSTINFO_INIT { \\\n+\t.hostname = STRBUF_INIT, \\\n+\t.canon_hostname = STRBUF_INIT, \\\n+\t.ip_address = STRBUF_INIT, \\\n+\t.tcp_port = STRBUF_INIT, \\\n+}\n \n static void lookup_hostname(struct hostinfo *hi);\n \n@@ -727,15 +733,6 @@ static void lookup_hostname(struct hostinfo *hi)\n \t}\n }\n \n-static void hostinfo_init(struct hostinfo *hi)\n-{\n-\tmemset(hi, 0, sizeof(*hi));\n-\tstrbuf_init(&hi->hostname, 0);\n-\tstrbuf_init(&hi->canon_hostname, 0);\n-\tstrbuf_init(&hi->ip_address, 0);\n-\tstrbuf_init(&hi->tcp_port, 0);\n-}\n-\n static void hostinfo_clear(struct hostinfo *hi)\n {\n \tstrbuf_release(&hi->hostname);\n@@ -760,11 +757,9 @@ static int execute(void)\n \tchar *line = packet_buffer;\n \tint pktlen, len, i;\n \tchar *addr = getenv(\"REMOTE_ADDR\"), *port = getenv(\"REMOTE_PORT\");\n-\tstruct hostinfo hi;\n+\tstruct hostinfo hi = HOSTINFO_INIT;\n \tstruct strvec env = STRVEC_INIT;\n \n-\thostinfo_init(&hi);\n-\n \tif (addr)\n \t\tloginfo(\"Connection from %s:%s\", addr, port);\n \n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437108","messageId":"patch-2.6-65c5295c1ac-20210927T004920Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","subject":"[PATCH 2/6] builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T00:53:16Z","receivedAt":"2021-09-27T00:53:28Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the commit_info_init() function addded in ea02ffa3857 (mailmap:\nsimplify map_user() interface, 2013-01-05) and instead initialize the\n\"struct commit_info\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nThe get_commit_info() function is only called by the three callers\nbeing changed here immediately after initializing the struct with the\nmacros, so by moving the initialization to the callers we don't need\nto do it in get_commit_info() anymore.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/blame.c | 30 +++++++++++++-----------------\n 1 file changed, 13 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex 641523ff9af..1c31a996403 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -101,6 +101,16 @@ struct commit_info {\n \tstruct strbuf summary;\n };\n \n+#define COMMIT_INFO_INIT { \\\n+\t.author = STRBUF_INIT, \\\n+\t.author_mail = STRBUF_INIT, \\\n+\t.author_tz = STRBUF_INIT, \\\n+\t.committer = STRBUF_INIT, \\\n+\t.committer_mail = STRBUF_INIT, \\\n+\t.committer_tz = STRBUF_INIT, \\\n+\t.summary = STRBUF_INIT, \\\n+}\n+\n /*\n  * Parse author/committer line in the commit object buffer\n  */\n@@ -160,18 +170,6 @@ static void get_ac_line(const char *inbuf, const char *what,\n \tstrbuf_add(name, namebuf, namelen);\n }\n \n-static void commit_info_init(struct commit_info *ci)\n-{\n-\n-\tstrbuf_init(&ci->author, 0);\n-\tstrbuf_init(&ci->author_mail, 0);\n-\tstrbuf_init(&ci->author_tz, 0);\n-\tstrbuf_init(&ci->committer, 0);\n-\tstrbuf_init(&ci->committer_mail, 0);\n-\tstrbuf_init(&ci->committer_tz, 0);\n-\tstrbuf_init(&ci->summary, 0);\n-}\n-\n static void commit_info_destroy(struct commit_info *ci)\n {\n \n@@ -192,8 +190,6 @@ static void get_commit_info(struct commit *commit,\n \tconst char *subject, *encoding;\n \tconst char *message;\n \n-\tcommit_info_init(ret);\n-\n \tencoding = get_log_output_encoding();\n \tmessage = logmsg_reencode(commit, NULL, encoding);\n \tget_ac_line(message, \"\\nauthor \",\n@@ -246,7 +242,7 @@ static void write_filename_info(struct blame_origin *suspect)\n  */\n static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat)\n {\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \n \tif (!repeat && (suspect->commit->object.flags & METAINFO_SHOWN))\n \t\treturn 0;\n@@ -440,7 +436,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int\n \tint cnt;\n \tconst char *cp;\n \tstruct blame_origin *suspect = ent->suspect;\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \tchar hex[GIT_MAX_HEXSZ + 1];\n \tint show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);\n \tconst char *default_color = NULL, *color = NULL, *reset = NULL;\n@@ -630,7 +626,7 @@ static void find_alignment(struct blame_scoreboard *sb, int *option)\n \t\tif (longest_file < num)\n \t\t\tlongest_file = num;\n \t\tif (!(suspect->commit->object.flags & METAINFO_SHOWN)) {\n-\t\t\tstruct commit_info ci;\n+\t\t\tstruct commit_info ci = COMMIT_INFO_INIT;\n \t\t\tsuspect->commit->object.flags |= METAINFO_SHOWN;\n \t\t\tget_commit_info(suspect->commit, &ci, 1);\n \t\t\tif (*option & OUTPUT_SHOW_EMAIL)\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437109","messageId":"patch-3.6-c9db107fcb1-20210927T004920Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","subject":"[PATCH 3/6] shortlog: use designated initializer for \"struct shortlog\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T00:53:17Z","receivedAt":"2021-09-27T00:53:31Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change code added in 64093fc06a (blame,shortlog: don't make local\noption variables static, 2016-06-13) to use a designated initializer\nvia a typical *_INIT macro pattern.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/shortlog.c | 2 +-\n shortlog.h         | 4 ++++\n 2 files changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/shortlog.c b/builtin/shortlog.c\nindex 3e7ab1ca821..fa1f76cc51e 100644\n--- a/builtin/shortlog.c\n+++ b/builtin/shortlog.c\n@@ -342,7 +342,7 @@ void shortlog_init(struct shortlog *log)\n \n int cmd_shortlog(int argc, const char **argv, const char *prefix)\n {\n-\tstruct shortlog log = { STRING_LIST_INIT_NODUP };\n+\tstruct shortlog log = SHORTLOG_INIT;\n \tstruct rev_info rev;\n \tint nongit = !startup_info->have_repository;\n \ndiff --git a/shortlog.h b/shortlog.h\nindex 3f7e9aabcae..47892d6d604 100644\n--- a/shortlog.h\n+++ b/shortlog.h\n@@ -28,6 +28,10 @@ struct shortlog {\n \tFILE *file;\n };\n \n+#define SHORTLOG_INIT { \\\n+\t.list = STRING_LIST_INIT_NODUP, \\\n+}\n+\n void shortlog_init(struct shortlog *log);\n \n void shortlog_add_commit(struct shortlog *log, struct commit *commit);\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437110","messageId":"patch-4.6-cb4c81dcc83-20210927T004920Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","subject":"[PATCH 4/6] urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T00:53:18Z","receivedAt":"2021-09-27T00:53:32Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the initialization pattern of \"struct urlmatch_config\" to use\nan *_INIT macro and designated initializers.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/config.c | 3 +--\n credential.c     | 4 +---\n http.c           | 4 +---\n urlmatch.h       | 4 ++++\n 4 files changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/config.c b/builtin/config.c\nindex 865fddd6ce8..1ea4f68b7de 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -575,11 +575,10 @@ static int get_urlmatch(const char *var, const char *url)\n \tint ret;\n \tchar *section_tail;\n \tstruct string_list_item *item;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct string_list values = STRING_LIST_INIT_DUP;\n \n \tconfig.collect_fn = urlmatch_collect_fn;\n-\tconfig.cascade_fn = NULL;\n \tconfig.cb = &values;\n \n \tif (!url_normalize(url, &config.url))\ndiff --git a/credential.c b/credential.c\nindex 000ac7a8d43..c85db8a75cd 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -105,7 +105,7 @@ static int match_partial_url(const char *url, void *cb)\n static void credential_apply_config(struct credential *c)\n {\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct strbuf url = STRBUF_INIT;\n \n \tif (!c->host)\n@@ -117,9 +117,7 @@ static void credential_apply_config(struct credential *c)\n \t\treturn;\n \n \tconfig.section = \"credential\";\n-\tconfig.key = NULL;\n \tconfig.collect_fn = credential_config_callback;\n-\tconfig.cascade_fn = NULL;\n \tconfig.select_fn = select_all;\n \tconfig.fallback_match_fn = match_partial_url;\n \tconfig.cb = c;\ndiff --git a/http.c b/http.c\nindex d7c20493d7f..3d6ad5c7be8 100644\n--- a/http.c\n+++ b/http.c\n@@ -990,13 +990,11 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n \tchar *low_speed_limit;\n \tchar *low_speed_time;\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \n \tconfig.section = \"http\";\n-\tconfig.key = NULL;\n \tconfig.collect_fn = http_options;\n \tconfig.cascade_fn = git_default_config;\n-\tconfig.cb = NULL;\n \n \thttp_is_verbose = 0;\n \tnormalized_url = url_normalize(url, &config.url);\ndiff --git a/urlmatch.h b/urlmatch.h\nindex 6ff42f81b0c..34a3ba6d197 100644\n--- a/urlmatch.h\n+++ b/urlmatch.h\n@@ -66,6 +66,10 @@ struct urlmatch_config {\n \tint (*fallback_match_fn)(const char *url, void *cb);\n };\n \n+#define URLMATCH_CONFIG_INIT { \\\n+\t.vars = STRING_LIST_INIT_DUP, \\\n+}\n+\n int urlmatch_config_entry(const char *var, const char *value, void *cb);\n \n #endif /* URL_MATCH_H */\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437111","messageId":"patch-5.6-1c34c00feb5-20210927T004920Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","subject":"[PATCH 5/6] builtin/remote.c: add and use a REF_STATES_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T00:53:19Z","receivedAt":"2021-09-27T00:53:33Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Use a new REF_STATES_INIT designated initializer instead of assigning\nto the \"strdup_strings\" member of the previously memzero()'d version\nof this struct.\n\nThe pattern of assigning to \"strdup_strings\" dates back to\n211c89682ee (Make git-remote a builtin, 2008-02-29) (when it was\n\"strdup_paths\"), i.e. long before we used anything like our current\nestablished *_INIT patterns consistently.\n\nThen in e61e0cc6b70 (builtin-remote: teach show to display remote\nHEAD, 2009-02-25) and e5dcbfd9ab7 (builtin-remote: new show output\nstyle for push refspecs, 2009-02-25) we added some more of these.\n\nAs it turns out we only initialized this struct three times, all the\nother uses were of pointers to those initialized structs. So let's\ninitialize it in those three places, skip the memset(), and pass those\nstructs down appropriately.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 23 +++++++++++------------\n 1 file changed, 11 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f88e6ce9de..160dd954f74 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -344,6 +344,14 @@ struct ref_states {\n \tint queried;\n };\n \n+#define REF_STATES_INIT { \\\n+\t.new_refs = STRING_LIST_INIT_DUP, \\\n+\t.stale = STRING_LIST_INIT_DUP, \\\n+\t.tracked = STRING_LIST_INIT_DUP, \\\n+\t.heads = STRING_LIST_INIT_DUP, \\\n+\t.push = STRING_LIST_INIT_DUP, \\\n+}\n+\n static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)\n {\n \tstruct ref *fetch_map = NULL, **tail = &fetch_map;\n@@ -355,9 +363,6 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat\n \t\t\tdie(_(\"Could not get fetch map for refspec %s\"),\n \t\t\t\tstates->remote->fetch.raw[i]);\n \n-\tstates->new_refs.strdup_strings = 1;\n-\tstates->tracked.strdup_strings = 1;\n-\tstates->stale.strdup_strings = 1;\n \tfor (ref = fetch_map; ref; ref = ref->next) {\n \t\tif (!ref->peer_ref || !ref_exists(ref->peer_ref->name))\n \t\t\tstring_list_append(&states->new_refs, abbrev_branch(ref->name));\n@@ -406,7 +411,6 @@ static int get_push_ref_states(const struct ref *remote_refs,\n \n \tmatch_push_refs(local_refs, &push_map, &remote->push, MATCH_REFS_NONE);\n \n-\tstates->push.strdup_strings = 1;\n \tfor (ref = push_map; ref; ref = ref->next) {\n \t\tstruct string_list_item *item;\n \t\tstruct push_info *info;\n@@ -449,7 +453,6 @@ static int get_push_ref_states_noquery(struct ref_states *states)\n \tif (remote->mirror)\n \t\treturn 0;\n \n-\tstates->push.strdup_strings = 1;\n \tif (!remote->push.nr) {\n \t\titem = string_list_append(&states->push, _(\"(matching)\"));\n \t\tinfo = item->util = xcalloc(1, sizeof(struct push_info));\n@@ -483,7 +486,6 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat\n \trefspec.force = 0;\n \trefspec.pattern = 1;\n \trefspec.src = refspec.dst = \"refs/heads/*\";\n-\tstates->heads.strdup_strings = 1;\n \tget_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);\n \tmatches = guess_remote_head(find_ref_by_name(remote_refs, \"HEAD\"),\n \t\t\t\t    fetch_map, 1);\n@@ -1212,7 +1214,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n \tstruct show_info info;\n \n@@ -1225,7 +1227,6 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&states, 0, sizeof(states));\n \tmemset(&info, 0, sizeof(info));\n \tinfo.states = &states;\n \tinfo.list = &info_list;\n@@ -1334,8 +1335,7 @@ static int set_head(int argc, const char **argv)\n \tif (!opt_a && !opt_d && argc == 2) {\n \t\thead_name = xstrdup(argv[1]);\n \t} else if (opt_a && !opt_d && argc == 1) {\n-\t\tstruct ref_states states;\n-\t\tmemset(&states, 0, sizeof(states));\n+\t\tstruct ref_states states = REF_STATES_INIT;\n \t\tget_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);\n \t\tif (!states.heads.nr)\n \t\t\tresult |= error(_(\"Cannot determine remote HEAD\"));\n@@ -1374,14 +1374,13 @@ static int set_head(int argc, const char **argv)\n static int prune_remote(const char *remote, int dry_run)\n {\n \tint result = 0;\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list refs_to_prune = STRING_LIST_INIT_NODUP;\n \tstruct string_list_item *item;\n \tconst char *dangling_msg = dry_run\n \t\t? _(\" %s will become dangling!\")\n \t\t: _(\" %s has become dangling!\");\n \n-\tmemset(&states, 0, sizeof(states));\n \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n \n \tif (!states.stale.nr) {\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437112","messageId":"patch-6.6-76fa070e89c-20210927T004920Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","subject":"[PATCH 6/6] builtin/remote.c: add and use SHOW_INFO_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T00:53:20Z","receivedAt":"2021-09-27T00:53:36Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In the preceding commit we introduced REF_STATES_INIT, but did not\nchange the \"struct show_info\" to have a corresponding\ninitializer. Let's do that, and make it use \"REF_STATES_INIT\" and\n\"STRING_LIST_INIT_DUP\", doing that requires changing \"list\" and\n\"states\" away from being pointers.\n\nThe resulting end-state is simpler since we omit the local \"info_list\"\nand \"states\" variables in show() as well as the memset().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 90 ++++++++++++++++++++++++------------------------\n 1 file changed, 45 insertions(+), 45 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 160dd954f74..deb48772ac5 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -972,26 +972,31 @@ static int get_remote_ref_states(const char *name,\n }\n \n struct show_info {\n-\tstruct string_list *list;\n-\tstruct ref_states *states;\n+\tstruct string_list list;\n+\tstruct ref_states states;\n \tint width, width2;\n \tint any_rebase;\n };\n \n+#define SHOW_INFO_INIT { \\\n+\t.list = STRING_LIST_INIT_DUP, \\\n+\t.states = REF_STATES_INIT, \\\n+}\n+\n static int add_remote_to_show_info(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n \tint n = strlen(item->string);\n \tif (n > info->width)\n \t\tinfo->width = n;\n-\tstring_list_insert(info->list, item->string);\n+\tstring_list_insert(&info->list, item->string);\n \treturn 0;\n }\n \n static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n-\tstruct ref_states *states = info->states;\n+\tstruct ref_states *states = &info->states;\n \tconst char *name = item->string;\n \n \tif (states->queried) {\n@@ -1018,7 +1023,7 @@ static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n static int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)\n {\n \tstruct show_info *show_info = cb_data;\n-\tstruct ref_states *states = show_info->states;\n+\tstruct ref_states *states = &show_info->states;\n \tstruct branch_info *branch_info = branch_item->util;\n \tstruct string_list_item *item;\n \tint n;\n@@ -1031,7 +1036,7 @@ static int add_local_to_show_info(struct string_list_item *branch_item, void *cb\n \tif (branch_info->rebase >= REBASE_TRUE)\n \t\tshow_info->any_rebase = 1;\n \n-\titem = string_list_insert(show_info->list, branch_item->string);\n+\titem = string_list_insert(&show_info->list, branch_item->string);\n \titem->util = branch_info;\n \n \treturn 0;\n@@ -1086,7 +1091,7 @@ static int add_push_to_show_info(struct string_list_item *push_item, void *cb_da\n \t\tshow_info->width = n;\n \tif ((n = strlen(push_info->dest)) > show_info->width2)\n \t\tshow_info->width2 = n;\n-\titem = string_list_append(show_info->list, push_item->string);\n+\titem = string_list_append(&show_info->list, push_item->string);\n \titem->util = push_item->util;\n \treturn 0;\n }\n@@ -1214,9 +1219,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states = REF_STATES_INIT;\n-\tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n-\tstruct show_info info;\n+\tstruct show_info info = SHOW_INFO_INIT;\n \n \targc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,\n \t\t\t     0);\n@@ -1227,25 +1230,22 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&info, 0, sizeof(info));\n-\tinfo.states = &states;\n-\tinfo.list = &info_list;\n \tfor (; argc; argc--, argv++) {\n \t\tint i;\n \t\tconst char **url;\n \t\tint url_nr;\n \n-\t\tget_remote_ref_states(*argv, &states, query_flag);\n+\t\tget_remote_ref_states(*argv, &info.states, query_flag);\n \n \t\tprintf_ln(_(\"* remote %s\"), *argv);\n-\t\tprintf_ln(_(\"  Fetch URL: %s\"), states.remote->url_nr > 0 ?\n-\t\t       states.remote->url[0] : _(\"(no URL)\"));\n-\t\tif (states.remote->pushurl_nr) {\n-\t\t\turl = states.remote->pushurl;\n-\t\t\turl_nr = states.remote->pushurl_nr;\n+\t\tprintf_ln(_(\"  Fetch URL: %s\"), info.states.remote->url_nr > 0 ?\n+\t\t       info.states.remote->url[0] : _(\"(no URL)\"));\n+\t\tif (info.states.remote->pushurl_nr) {\n+\t\t\turl = info.states.remote->pushurl;\n+\t\t\turl_nr = info.states.remote->pushurl_nr;\n \t\t} else {\n-\t\t\turl = states.remote->url;\n-\t\t\turl_nr = states.remote->url_nr;\n+\t\t\turl = info.states.remote->url;\n+\t\t\turl_nr = info.states.remote->url_nr;\n \t\t}\n \t\tfor (i = 0; i < url_nr; i++)\n \t\t\t/*\n@@ -1258,57 +1258,57 @@ static int show(int argc, const char **argv)\n \t\t\tprintf_ln(_(\"  Push  URL: %s\"), _(\"(no URL)\"));\n \t\tif (no_query)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(not queried)\"));\n-\t\telse if (!states.heads.nr)\n+\t\telse if (!info.states.heads.nr)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(unknown)\"));\n-\t\telse if (states.heads.nr == 1)\n-\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), states.heads.items[0].string);\n+\t\telse if (info.states.heads.nr == 1)\n+\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), info.states.heads.items[0].string);\n \t\telse {\n \t\t\tprintf(_(\"  HEAD branch (remote HEAD is ambiguous,\"\n \t\t\t\t \" may be one of the following):\\n\"));\n-\t\t\tfor (i = 0; i < states.heads.nr; i++)\n-\t\t\t\tprintf(\"    %s\\n\", states.heads.items[i].string);\n+\t\t\tfor (i = 0; i < info.states.heads.nr; i++)\n+\t\t\t\tprintf(\"    %s\\n\", info.states.heads.items[i].string);\n \t\t}\n \n \t\t/* remote branch info */\n \t\tinfo.width = 0;\n-\t\tfor_each_string_list(&states.new_refs, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.tracked, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.stale, add_remote_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.new_refs, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.tracked, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.stale, add_remote_to_show_info, &info);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Remote branch:%s\",\n \t\t\t\t     \"  Remote branches:%s\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_remote_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_remote_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git pull info */\n \t\tinfo.width = 0;\n \t\tinfo.any_rebase = 0;\n \t\tfor_each_string_list(&branch_list, add_local_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local branch configured for 'git pull':\",\n \t\t\t\t     \"  Local branches configured for 'git pull':\",\n-\t\t\t\t     info.list->nr));\n-\t\tfor_each_string_list(info.list, show_local_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\t\t\t     info.list.nr));\n+\t\tfor_each_string_list(&info.list, show_local_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git push info */\n-\t\tif (states.remote->mirror)\n+\t\tif (info.states.remote->mirror)\n \t\t\tprintf_ln(_(\"  Local refs will be mirrored by 'git push'\"));\n \n \t\tinfo.width = info.width2 = 0;\n-\t\tfor_each_string_list(&states.push, add_push_to_show_info, &info);\n-\t\tQSORT(info.list->items, info.list->nr, cmp_string_with_push);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.push, add_push_to_show_info, &info);\n+\t\tQSORT(info.list.items, info.list.nr, cmp_string_with_push);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local ref configured for 'git push'%s:\",\n \t\t\t\t     \"  Local refs configured for 'git push'%s:\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_push_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_push_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n-\t\tfree_remote_ref_states(&states);\n+\t\tfree_remote_ref_states(&info.states);\n \t}\n \n \treturn result;\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437119","messageId":"94842a94-d168-2b61-4a44-0059ecbe1b36@gmail.com","threadId":"56591","inReplyTo":"patch-3.6-c9db107fcb1-20210927T004920Z-avarab@gmail.com","subject":"Re: [PATCH 3/6] shortlog: use designated initializer for \"struct shortlog\"","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2021-09-27T09:06:02Z","receivedAt":"2021-09-27T09:06:11Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Ævar\n\nOn 27/09/2021 01:53, Ævar Arnfjörð Bjarmason wrote:\n> Change code added in 64093fc06a (blame,shortlog: don't make local\n> option variables static, 2016-06-13) to use a designated initializer\n> via a typical *_INIT macro pattern.\n> \n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>   builtin/shortlog.c | 2 +-\n>   shortlog.h         | 4 ++++\n>   2 files changed, 5 insertions(+), 1 deletion(-)\n> \n> diff --git a/builtin/shortlog.c b/builtin/shortlog.c\n> index 3e7ab1ca821..fa1f76cc51e 100644\n> --- a/builtin/shortlog.c\n> +++ b/builtin/shortlog.c\n> @@ -342,7 +342,7 @@ void shortlog_init(struct shortlog *log)\n>   \n>   int cmd_shortlog(int argc, const char **argv, const char *prefix)\n>   {\n> -\tstruct shortlog log = { STRING_LIST_INIT_NODUP };\n> +\tstruct shortlog log = SHORTLOG_INIT;\n>   \tstruct rev_info rev;\n>   \tint nongit = !startup_info->have_repository;\n>   \n> diff --git a/shortlog.h b/shortlog.h\n> index 3f7e9aabcae..47892d6d604 100644\n> --- a/shortlog.h\n> +++ b/shortlog.h\n> @@ -28,6 +28,10 @@ struct shortlog {\n>   \tFILE *file;\n>   };\n>   \n> +#define SHORTLOG_INIT { \\\n> +\t.list = STRING_LIST_INIT_NODUP, \\\n> +}\n> +\n>   void shortlog_init(struct shortlog *log);\n\nlooking at this wouldn't it be better follow the pattern in the first \npatch in this series and replace shortlog_init() with a designated \ninitializer?\n\nBest Wishes\n\nPhillip\n\n>   void shortlog_add_commit(struct shortlog *log, struct commit *commit);\n> \n"},{"id":"437129","messageId":"87lf3i1e7k.fsf@evledraar.gmail.com","threadId":"56591","inReplyTo":"94842a94-d168-2b61-4a44-0059ecbe1b36@gmail.com","subject":"Re: [PATCH 3/6] shortlog: use designated initializer for \"struct shortlog\"","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T10:52:33Z","receivedAt":"2021-09-27T10:54:11Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Sep 27 2021, Phillip Wood wrote:\n\n> Hi Ævar\n>\n> On 27/09/2021 01:53, Ævar Arnfjörð Bjarmason wrote:\n>> Change code added in 64093fc06a (blame,shortlog: don't make local\n>> option variables static, 2016-06-13) to use a designated initializer\n>> via a typical *_INIT macro pattern.\n>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> ---\n>>   builtin/shortlog.c | 2 +-\n>>   shortlog.h         | 4 ++++\n>>   2 files changed, 5 insertions(+), 1 deletion(-)\n>> diff --git a/builtin/shortlog.c b/builtin/shortlog.c\n>> index 3e7ab1ca821..fa1f76cc51e 100644\n>> --- a/builtin/shortlog.c\n>> +++ b/builtin/shortlog.c\n>> @@ -342,7 +342,7 @@ void shortlog_init(struct shortlog *log)\n>>     int cmd_shortlog(int argc, const char **argv, const char\n>> *prefix)\n>>   {\n>> -\tstruct shortlog log = { STRING_LIST_INIT_NODUP };\n>> +\tstruct shortlog log = SHORTLOG_INIT;\n>>   \tstruct rev_info rev;\n>>   \tint nongit = !startup_info->have_repository;\n>>   diff --git a/shortlog.h b/shortlog.h\n>> index 3f7e9aabcae..47892d6d604 100644\n>> --- a/shortlog.h\n>> +++ b/shortlog.h\n>> @@ -28,6 +28,10 @@ struct shortlog {\n>>   \tFILE *file;\n>>   };\n>>   +#define SHORTLOG_INIT { \\\n>> +\t.list = STRING_LIST_INIT_NODUP, \\\n>> +}\n>> +\n>>   void shortlog_init(struct shortlog *log);\n>\n> looking at this wouldn't it be better follow the pattern in the first\n> patch in this series and replace shortlog_init() with a designated \n> initializer?\n\nI've ejected this patch from a WIP re-roll, I don't know what I was\nthinking when I included it.\n\nIt's \"correct\", but one of those cases where we can't easily get rid of\nthe not-a-macro init() function, so having a *_INIT macro that doesn't\nactually do the initialization for both users is just confusing.\n\nWorse, that \"nodup\" is actually a like, the shortlog_init() function\nsets it to \"dup\", that issue pre-dated by change here, but I shouldn't\nhave carried it forward.\n\nSorry!\n"},{"id":"437140","messageId":"cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com","subject":"[PATCH v2 0/5] Non-trivial designated initializer conversion","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T12:58:40Z","receivedAt":"2021-09-27T12:58:51Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"See\nhttp://lore.kernel.org/git/cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com\nfor the v1 & goals. As noted in\nhttp://lore.kernel.org/git/87lf3i1e7k.fsf@evledraar.gmail.com I\nejected the previous 3/6. It wasn't incorrect, but partially\nconverting to an *_INIT macro doesn't make any sense in the \"struct\nshortlog\" case.\n\nÆvar Arnfjörð Bjarmason (5):\n  daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro\n  builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro\n  urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n  builtin/remote.c: add and use a REF_STATES_INIT\n  builtin/remote.c: add and use SHOW_INFO_INIT\n\n builtin/blame.c  |  30 ++++++-------\n builtin/config.c |   3 +-\n builtin/remote.c | 111 +++++++++++++++++++++++------------------------\n credential.c     |   4 +-\n daemon.c         |  19 +++-----\n http.c           |   4 +-\n urlmatch.h       |   4 ++\n 7 files changed, 82 insertions(+), 93 deletions(-)\n\nRange-diff against v1:\n1:  3130693b416 = 1:  3130693b416 daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro\n2:  65c5295c1ac = 2:  65c5295c1ac builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro\n3:  c9db107fcb1 < -:  ----------- shortlog: use designated initializer for \"struct shortlog\"\n4:  cb4c81dcc83 = 3:  3783788b553 urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n5:  1c34c00feb5 = 4:  13ef9566903 builtin/remote.c: add and use a REF_STATES_INIT\n6:  76fa070e89c = 5:  b78a9ec0846 builtin/remote.c: add and use SHOW_INFO_INIT\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437141","messageId":"patch-v2-1.5-3130693b416-20210927T125715Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com","subject":"[PATCH v2 1/5] daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T12:58:41Z","receivedAt":"2021-09-27T12:58:53Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the hostinfo_init() function added in 01cec54e135 (daemon:\ndeglobalize hostname information, 2015-03-07) and instead initialize\nthe \"struct hostinfo\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n daemon.c | 19 +++++++------------\n 1 file changed, 7 insertions(+), 12 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex 5c4cbad62d0..d80d009d1a1 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -63,6 +63,12 @@ struct hostinfo {\n \tunsigned int hostname_lookup_done:1;\n \tunsigned int saw_extended_args:1;\n };\n+#define HOSTINFO_INIT { \\\n+\t.hostname = STRBUF_INIT, \\\n+\t.canon_hostname = STRBUF_INIT, \\\n+\t.ip_address = STRBUF_INIT, \\\n+\t.tcp_port = STRBUF_INIT, \\\n+}\n \n static void lookup_hostname(struct hostinfo *hi);\n \n@@ -727,15 +733,6 @@ static void lookup_hostname(struct hostinfo *hi)\n \t}\n }\n \n-static void hostinfo_init(struct hostinfo *hi)\n-{\n-\tmemset(hi, 0, sizeof(*hi));\n-\tstrbuf_init(&hi->hostname, 0);\n-\tstrbuf_init(&hi->canon_hostname, 0);\n-\tstrbuf_init(&hi->ip_address, 0);\n-\tstrbuf_init(&hi->tcp_port, 0);\n-}\n-\n static void hostinfo_clear(struct hostinfo *hi)\n {\n \tstrbuf_release(&hi->hostname);\n@@ -760,11 +757,9 @@ static int execute(void)\n \tchar *line = packet_buffer;\n \tint pktlen, len, i;\n \tchar *addr = getenv(\"REMOTE_ADDR\"), *port = getenv(\"REMOTE_PORT\");\n-\tstruct hostinfo hi;\n+\tstruct hostinfo hi = HOSTINFO_INIT;\n \tstruct strvec env = STRVEC_INIT;\n \n-\thostinfo_init(&hi);\n-\n \tif (addr)\n \t\tloginfo(\"Connection from %s:%s\", addr, port);\n \n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437142","messageId":"patch-v2-2.5-65c5295c1ac-20210927T125715Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com","subject":"[PATCH v2 2/5] builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T12:58:42Z","receivedAt":"2021-09-27T12:58:54Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the commit_info_init() function addded in ea02ffa3857 (mailmap:\nsimplify map_user() interface, 2013-01-05) and instead initialize the\n\"struct commit_info\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nThe get_commit_info() function is only called by the three callers\nbeing changed here immediately after initializing the struct with the\nmacros, so by moving the initialization to the callers we don't need\nto do it in get_commit_info() anymore.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/blame.c | 30 +++++++++++++-----------------\n 1 file changed, 13 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex 641523ff9af..1c31a996403 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -101,6 +101,16 @@ struct commit_info {\n \tstruct strbuf summary;\n };\n \n+#define COMMIT_INFO_INIT { \\\n+\t.author = STRBUF_INIT, \\\n+\t.author_mail = STRBUF_INIT, \\\n+\t.author_tz = STRBUF_INIT, \\\n+\t.committer = STRBUF_INIT, \\\n+\t.committer_mail = STRBUF_INIT, \\\n+\t.committer_tz = STRBUF_INIT, \\\n+\t.summary = STRBUF_INIT, \\\n+}\n+\n /*\n  * Parse author/committer line in the commit object buffer\n  */\n@@ -160,18 +170,6 @@ static void get_ac_line(const char *inbuf, const char *what,\n \tstrbuf_add(name, namebuf, namelen);\n }\n \n-static void commit_info_init(struct commit_info *ci)\n-{\n-\n-\tstrbuf_init(&ci->author, 0);\n-\tstrbuf_init(&ci->author_mail, 0);\n-\tstrbuf_init(&ci->author_tz, 0);\n-\tstrbuf_init(&ci->committer, 0);\n-\tstrbuf_init(&ci->committer_mail, 0);\n-\tstrbuf_init(&ci->committer_tz, 0);\n-\tstrbuf_init(&ci->summary, 0);\n-}\n-\n static void commit_info_destroy(struct commit_info *ci)\n {\n \n@@ -192,8 +190,6 @@ static void get_commit_info(struct commit *commit,\n \tconst char *subject, *encoding;\n \tconst char *message;\n \n-\tcommit_info_init(ret);\n-\n \tencoding = get_log_output_encoding();\n \tmessage = logmsg_reencode(commit, NULL, encoding);\n \tget_ac_line(message, \"\\nauthor \",\n@@ -246,7 +242,7 @@ static void write_filename_info(struct blame_origin *suspect)\n  */\n static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat)\n {\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \n \tif (!repeat && (suspect->commit->object.flags & METAINFO_SHOWN))\n \t\treturn 0;\n@@ -440,7 +436,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int\n \tint cnt;\n \tconst char *cp;\n \tstruct blame_origin *suspect = ent->suspect;\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \tchar hex[GIT_MAX_HEXSZ + 1];\n \tint show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);\n \tconst char *default_color = NULL, *color = NULL, *reset = NULL;\n@@ -630,7 +626,7 @@ static void find_alignment(struct blame_scoreboard *sb, int *option)\n \t\tif (longest_file < num)\n \t\t\tlongest_file = num;\n \t\tif (!(suspect->commit->object.flags & METAINFO_SHOWN)) {\n-\t\t\tstruct commit_info ci;\n+\t\t\tstruct commit_info ci = COMMIT_INFO_INIT;\n \t\t\tsuspect->commit->object.flags |= METAINFO_SHOWN;\n \t\t\tget_commit_info(suspect->commit, &ci, 1);\n \t\t\tif (*option & OUTPUT_SHOW_EMAIL)\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437143","messageId":"patch-v2-3.5-3783788b553-20210927T125715Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com","subject":"[PATCH v2 3/5] urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T12:58:43Z","receivedAt":"2021-09-27T12:58:55Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the initialization pattern of \"struct urlmatch_config\" to use\nan *_INIT macro and designated initializers.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/config.c | 3 +--\n credential.c     | 4 +---\n http.c           | 4 +---\n urlmatch.h       | 4 ++++\n 4 files changed, 7 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/config.c b/builtin/config.c\nindex 865fddd6ce8..1ea4f68b7de 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -575,11 +575,10 @@ static int get_urlmatch(const char *var, const char *url)\n \tint ret;\n \tchar *section_tail;\n \tstruct string_list_item *item;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct string_list values = STRING_LIST_INIT_DUP;\n \n \tconfig.collect_fn = urlmatch_collect_fn;\n-\tconfig.cascade_fn = NULL;\n \tconfig.cb = &values;\n \n \tif (!url_normalize(url, &config.url))\ndiff --git a/credential.c b/credential.c\nindex 000ac7a8d43..c85db8a75cd 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -105,7 +105,7 @@ static int match_partial_url(const char *url, void *cb)\n static void credential_apply_config(struct credential *c)\n {\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct strbuf url = STRBUF_INIT;\n \n \tif (!c->host)\n@@ -117,9 +117,7 @@ static void credential_apply_config(struct credential *c)\n \t\treturn;\n \n \tconfig.section = \"credential\";\n-\tconfig.key = NULL;\n \tconfig.collect_fn = credential_config_callback;\n-\tconfig.cascade_fn = NULL;\n \tconfig.select_fn = select_all;\n \tconfig.fallback_match_fn = match_partial_url;\n \tconfig.cb = c;\ndiff --git a/http.c b/http.c\nindex d7c20493d7f..3d6ad5c7be8 100644\n--- a/http.c\n+++ b/http.c\n@@ -990,13 +990,11 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n \tchar *low_speed_limit;\n \tchar *low_speed_time;\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \n \tconfig.section = \"http\";\n-\tconfig.key = NULL;\n \tconfig.collect_fn = http_options;\n \tconfig.cascade_fn = git_default_config;\n-\tconfig.cb = NULL;\n \n \thttp_is_verbose = 0;\n \tnormalized_url = url_normalize(url, &config.url);\ndiff --git a/urlmatch.h b/urlmatch.h\nindex 6ff42f81b0c..34a3ba6d197 100644\n--- a/urlmatch.h\n+++ b/urlmatch.h\n@@ -66,6 +66,10 @@ struct urlmatch_config {\n \tint (*fallback_match_fn)(const char *url, void *cb);\n };\n \n+#define URLMATCH_CONFIG_INIT { \\\n+\t.vars = STRING_LIST_INIT_DUP, \\\n+}\n+\n int urlmatch_config_entry(const char *var, const char *value, void *cb);\n \n #endif /* URL_MATCH_H */\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437144","messageId":"patch-v2-4.5-13ef9566903-20210927T125715Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com","subject":"[PATCH v2 4/5] builtin/remote.c: add and use a REF_STATES_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T12:58:44Z","receivedAt":"2021-09-27T12:58:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Use a new REF_STATES_INIT designated initializer instead of assigning\nto the \"strdup_strings\" member of the previously memzero()'d version\nof this struct.\n\nThe pattern of assigning to \"strdup_strings\" dates back to\n211c89682ee (Make git-remote a builtin, 2008-02-29) (when it was\n\"strdup_paths\"), i.e. long before we used anything like our current\nestablished *_INIT patterns consistently.\n\nThen in e61e0cc6b70 (builtin-remote: teach show to display remote\nHEAD, 2009-02-25) and e5dcbfd9ab7 (builtin-remote: new show output\nstyle for push refspecs, 2009-02-25) we added some more of these.\n\nAs it turns out we only initialized this struct three times, all the\nother uses were of pointers to those initialized structs. So let's\ninitialize it in those three places, skip the memset(), and pass those\nstructs down appropriately.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 23 +++++++++++------------\n 1 file changed, 11 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f88e6ce9de..160dd954f74 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -344,6 +344,14 @@ struct ref_states {\n \tint queried;\n };\n \n+#define REF_STATES_INIT { \\\n+\t.new_refs = STRING_LIST_INIT_DUP, \\\n+\t.stale = STRING_LIST_INIT_DUP, \\\n+\t.tracked = STRING_LIST_INIT_DUP, \\\n+\t.heads = STRING_LIST_INIT_DUP, \\\n+\t.push = STRING_LIST_INIT_DUP, \\\n+}\n+\n static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)\n {\n \tstruct ref *fetch_map = NULL, **tail = &fetch_map;\n@@ -355,9 +363,6 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat\n \t\t\tdie(_(\"Could not get fetch map for refspec %s\"),\n \t\t\t\tstates->remote->fetch.raw[i]);\n \n-\tstates->new_refs.strdup_strings = 1;\n-\tstates->tracked.strdup_strings = 1;\n-\tstates->stale.strdup_strings = 1;\n \tfor (ref = fetch_map; ref; ref = ref->next) {\n \t\tif (!ref->peer_ref || !ref_exists(ref->peer_ref->name))\n \t\t\tstring_list_append(&states->new_refs, abbrev_branch(ref->name));\n@@ -406,7 +411,6 @@ static int get_push_ref_states(const struct ref *remote_refs,\n \n \tmatch_push_refs(local_refs, &push_map, &remote->push, MATCH_REFS_NONE);\n \n-\tstates->push.strdup_strings = 1;\n \tfor (ref = push_map; ref; ref = ref->next) {\n \t\tstruct string_list_item *item;\n \t\tstruct push_info *info;\n@@ -449,7 +453,6 @@ static int get_push_ref_states_noquery(struct ref_states *states)\n \tif (remote->mirror)\n \t\treturn 0;\n \n-\tstates->push.strdup_strings = 1;\n \tif (!remote->push.nr) {\n \t\titem = string_list_append(&states->push, _(\"(matching)\"));\n \t\tinfo = item->util = xcalloc(1, sizeof(struct push_info));\n@@ -483,7 +486,6 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat\n \trefspec.force = 0;\n \trefspec.pattern = 1;\n \trefspec.src = refspec.dst = \"refs/heads/*\";\n-\tstates->heads.strdup_strings = 1;\n \tget_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);\n \tmatches = guess_remote_head(find_ref_by_name(remote_refs, \"HEAD\"),\n \t\t\t\t    fetch_map, 1);\n@@ -1212,7 +1214,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n \tstruct show_info info;\n \n@@ -1225,7 +1227,6 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&states, 0, sizeof(states));\n \tmemset(&info, 0, sizeof(info));\n \tinfo.states = &states;\n \tinfo.list = &info_list;\n@@ -1334,8 +1335,7 @@ static int set_head(int argc, const char **argv)\n \tif (!opt_a && !opt_d && argc == 2) {\n \t\thead_name = xstrdup(argv[1]);\n \t} else if (opt_a && !opt_d && argc == 1) {\n-\t\tstruct ref_states states;\n-\t\tmemset(&states, 0, sizeof(states));\n+\t\tstruct ref_states states = REF_STATES_INIT;\n \t\tget_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);\n \t\tif (!states.heads.nr)\n \t\t\tresult |= error(_(\"Cannot determine remote HEAD\"));\n@@ -1374,14 +1374,13 @@ static int set_head(int argc, const char **argv)\n static int prune_remote(const char *remote, int dry_run)\n {\n \tint result = 0;\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list refs_to_prune = STRING_LIST_INIT_NODUP;\n \tstruct string_list_item *item;\n \tconst char *dangling_msg = dry_run\n \t\t? _(\" %s will become dangling!\")\n \t\t: _(\" %s has become dangling!\");\n \n-\tmemset(&states, 0, sizeof(states));\n \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n \n \tif (!states.stale.nr) {\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437145","messageId":"patch-v2-5.5-b78a9ec0846-20210927T125715Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com","subject":"[PATCH v2 5/5] builtin/remote.c: add and use SHOW_INFO_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T12:58:45Z","receivedAt":"2021-09-27T12:58:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In the preceding commit we introduced REF_STATES_INIT, but did not\nchange the \"struct show_info\" to have a corresponding\ninitializer. Let's do that, and make it use \"REF_STATES_INIT\" and\n\"STRING_LIST_INIT_DUP\", doing that requires changing \"list\" and\n\"states\" away from being pointers.\n\nThe resulting end-state is simpler since we omit the local \"info_list\"\nand \"states\" variables in show() as well as the memset().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 90 ++++++++++++++++++++++++------------------------\n 1 file changed, 45 insertions(+), 45 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 160dd954f74..deb48772ac5 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -972,26 +972,31 @@ static int get_remote_ref_states(const char *name,\n }\n \n struct show_info {\n-\tstruct string_list *list;\n-\tstruct ref_states *states;\n+\tstruct string_list list;\n+\tstruct ref_states states;\n \tint width, width2;\n \tint any_rebase;\n };\n \n+#define SHOW_INFO_INIT { \\\n+\t.list = STRING_LIST_INIT_DUP, \\\n+\t.states = REF_STATES_INIT, \\\n+}\n+\n static int add_remote_to_show_info(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n \tint n = strlen(item->string);\n \tif (n > info->width)\n \t\tinfo->width = n;\n-\tstring_list_insert(info->list, item->string);\n+\tstring_list_insert(&info->list, item->string);\n \treturn 0;\n }\n \n static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n-\tstruct ref_states *states = info->states;\n+\tstruct ref_states *states = &info->states;\n \tconst char *name = item->string;\n \n \tif (states->queried) {\n@@ -1018,7 +1023,7 @@ static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n static int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)\n {\n \tstruct show_info *show_info = cb_data;\n-\tstruct ref_states *states = show_info->states;\n+\tstruct ref_states *states = &show_info->states;\n \tstruct branch_info *branch_info = branch_item->util;\n \tstruct string_list_item *item;\n \tint n;\n@@ -1031,7 +1036,7 @@ static int add_local_to_show_info(struct string_list_item *branch_item, void *cb\n \tif (branch_info->rebase >= REBASE_TRUE)\n \t\tshow_info->any_rebase = 1;\n \n-\titem = string_list_insert(show_info->list, branch_item->string);\n+\titem = string_list_insert(&show_info->list, branch_item->string);\n \titem->util = branch_info;\n \n \treturn 0;\n@@ -1086,7 +1091,7 @@ static int add_push_to_show_info(struct string_list_item *push_item, void *cb_da\n \t\tshow_info->width = n;\n \tif ((n = strlen(push_info->dest)) > show_info->width2)\n \t\tshow_info->width2 = n;\n-\titem = string_list_append(show_info->list, push_item->string);\n+\titem = string_list_append(&show_info->list, push_item->string);\n \titem->util = push_item->util;\n \treturn 0;\n }\n@@ -1214,9 +1219,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states = REF_STATES_INIT;\n-\tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n-\tstruct show_info info;\n+\tstruct show_info info = SHOW_INFO_INIT;\n \n \targc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,\n \t\t\t     0);\n@@ -1227,25 +1230,22 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&info, 0, sizeof(info));\n-\tinfo.states = &states;\n-\tinfo.list = &info_list;\n \tfor (; argc; argc--, argv++) {\n \t\tint i;\n \t\tconst char **url;\n \t\tint url_nr;\n \n-\t\tget_remote_ref_states(*argv, &states, query_flag);\n+\t\tget_remote_ref_states(*argv, &info.states, query_flag);\n \n \t\tprintf_ln(_(\"* remote %s\"), *argv);\n-\t\tprintf_ln(_(\"  Fetch URL: %s\"), states.remote->url_nr > 0 ?\n-\t\t       states.remote->url[0] : _(\"(no URL)\"));\n-\t\tif (states.remote->pushurl_nr) {\n-\t\t\turl = states.remote->pushurl;\n-\t\t\turl_nr = states.remote->pushurl_nr;\n+\t\tprintf_ln(_(\"  Fetch URL: %s\"), info.states.remote->url_nr > 0 ?\n+\t\t       info.states.remote->url[0] : _(\"(no URL)\"));\n+\t\tif (info.states.remote->pushurl_nr) {\n+\t\t\turl = info.states.remote->pushurl;\n+\t\t\turl_nr = info.states.remote->pushurl_nr;\n \t\t} else {\n-\t\t\turl = states.remote->url;\n-\t\t\turl_nr = states.remote->url_nr;\n+\t\t\turl = info.states.remote->url;\n+\t\t\turl_nr = info.states.remote->url_nr;\n \t\t}\n \t\tfor (i = 0; i < url_nr; i++)\n \t\t\t/*\n@@ -1258,57 +1258,57 @@ static int show(int argc, const char **argv)\n \t\t\tprintf_ln(_(\"  Push  URL: %s\"), _(\"(no URL)\"));\n \t\tif (no_query)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(not queried)\"));\n-\t\telse if (!states.heads.nr)\n+\t\telse if (!info.states.heads.nr)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(unknown)\"));\n-\t\telse if (states.heads.nr == 1)\n-\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), states.heads.items[0].string);\n+\t\telse if (info.states.heads.nr == 1)\n+\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), info.states.heads.items[0].string);\n \t\telse {\n \t\t\tprintf(_(\"  HEAD branch (remote HEAD is ambiguous,\"\n \t\t\t\t \" may be one of the following):\\n\"));\n-\t\t\tfor (i = 0; i < states.heads.nr; i++)\n-\t\t\t\tprintf(\"    %s\\n\", states.heads.items[i].string);\n+\t\t\tfor (i = 0; i < info.states.heads.nr; i++)\n+\t\t\t\tprintf(\"    %s\\n\", info.states.heads.items[i].string);\n \t\t}\n \n \t\t/* remote branch info */\n \t\tinfo.width = 0;\n-\t\tfor_each_string_list(&states.new_refs, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.tracked, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.stale, add_remote_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.new_refs, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.tracked, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.stale, add_remote_to_show_info, &info);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Remote branch:%s\",\n \t\t\t\t     \"  Remote branches:%s\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_remote_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_remote_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git pull info */\n \t\tinfo.width = 0;\n \t\tinfo.any_rebase = 0;\n \t\tfor_each_string_list(&branch_list, add_local_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local branch configured for 'git pull':\",\n \t\t\t\t     \"  Local branches configured for 'git pull':\",\n-\t\t\t\t     info.list->nr));\n-\t\tfor_each_string_list(info.list, show_local_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\t\t\t     info.list.nr));\n+\t\tfor_each_string_list(&info.list, show_local_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git push info */\n-\t\tif (states.remote->mirror)\n+\t\tif (info.states.remote->mirror)\n \t\t\tprintf_ln(_(\"  Local refs will be mirrored by 'git push'\"));\n \n \t\tinfo.width = info.width2 = 0;\n-\t\tfor_each_string_list(&states.push, add_push_to_show_info, &info);\n-\t\tQSORT(info.list->items, info.list->nr, cmp_string_with_push);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.push, add_push_to_show_info, &info);\n+\t\tQSORT(info.list.items, info.list.nr, cmp_string_with_push);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local ref configured for 'git push'%s:\",\n \t\t\t\t     \"  Local refs configured for 'git push'%s:\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_push_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_push_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n-\t\tfree_remote_ref_states(&states);\n+\t\tfree_remote_ref_states(&info.states);\n \t}\n \n \treturn result;\n-- \n2.33.0.1316.gb2e9b3ba3ae\n\n"},{"id":"437201","messageId":"xmqq8rzhoeg9.fsf@gitster.g","threadId":"56591","inReplyTo":"patch-v2-3.5-3783788b553-20210927T125715Z-avarab@gmail.com","subject":"Re: [PATCH v2 3/5] urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-27T22:12:38Z","receivedAt":"2021-09-27T22:12:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> @@ -575,11 +575,10 @@ static int get_urlmatch(const char *var, const char *url)\n>  \tint ret;\n>  \tchar *section_tail;\n>  \tstruct string_list_item *item;\n> -\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n> +\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n\nWhile I think this is much easier to follow than the original, I am\nnot quite sure about the removal of these explicit _assignments_ in\ncode, like this ...\n\n>  \tconfig.collect_fn = urlmatch_collect_fn;\n> -\tconfig.cascade_fn = NULL;\n>  \tconfig.cb = &values;\n\nand this ...\n\n>  \tconfig.section = \"credential\";\n> -\tconfig.key = NULL;\n>  \tconfig.collect_fn = credential_config_callback;\n> -\tconfig.cascade_fn = NULL;\n>  \tconfig.select_fn = select_all;\n\nand this ...\n\n>  \tconfig.section = \"http\";\n> -\tconfig.key = NULL;\n>  \tconfig.collect_fn = http_options;\n>  \tconfig.cascade_fn = git_default_config;\n> -\tconfig.cb = NULL;\n\nas they have documentation value (e.g. \"for this invocation I do\nwant to use no cascade_fn\" is a statement worth making, by having\nit next to the assignment to .collect_fn member).\n\n"},{"id":"437203","messageId":"xmqq4ka5oc1k.fsf@gitster.g","threadId":"56591","inReplyTo":"patch-v2-4.5-13ef9566903-20210927T125715Z-avarab@gmail.com","subject":"Re: [PATCH v2 4/5] builtin/remote.c: add and use a REF_STATES_INIT","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-27T23:04:39Z","receivedAt":"2021-09-27T23:04:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> Use a new REF_STATES_INIT designated initializer instead of assigning\n> to the \"strdup_strings\" member of the previously memzero()'d version\n> of this struct.\n>\n> The pattern of assigning to \"strdup_strings\" dates back to\n> 211c89682ee (Make git-remote a builtin, 2008-02-29) (when it was\n> \"strdup_paths\"), i.e. long before we used anything like our current\n> established *_INIT patterns consistently.\n>\n> Then in e61e0cc6b70 (builtin-remote: teach show to display remote\n> HEAD, 2009-02-25) and e5dcbfd9ab7 (builtin-remote: new show output\n> style for push refspecs, 2009-02-25) we added some more of these.\n>\n> As it turns out we only initialized this struct three times, all the\n> other uses were of pointers to those initialized structs. So let's\n> initialize it in those three places, skip the memset(), and pass those\n> structs down appropriately.\n>\n> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n> ---\n>  builtin/remote.c | 23 +++++++++++------------\n>  1 file changed, 11 insertions(+), 12 deletions(-)\n>\n> diff --git a/builtin/remote.c b/builtin/remote.c\n> index 7f88e6ce9de..160dd954f74 100644\n> --- a/builtin/remote.c\n> +++ b/builtin/remote.c\n> @@ -344,6 +344,14 @@ struct ref_states {\n>  \tint queried;\n>  };\n>  \n> +#define REF_STATES_INIT { \\\n> +\t.new_refs = STRING_LIST_INIT_DUP, \\\n> +\t.stale = STRING_LIST_INIT_DUP, \\\n> +\t.tracked = STRING_LIST_INIT_DUP, \\\n> +\t.heads = STRING_LIST_INIT_DUP, \\\n> +\t.push = STRING_LIST_INIT_DUP, \\\n> +}\n\nSo, now everybody owns the string, but ...\n\n>  static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)\n>  {\n>  \tstruct ref *fetch_map = NULL, **tail = &fetch_map;\n> @@ -355,9 +363,6 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat\n>  \t\t\tdie(_(\"Could not get fetch map for refspec %s\"),\n>  \t\t\t\tstates->remote->fetch.raw[i]);\n>  \n> -\tstates->new_refs.strdup_strings = 1;\n> -\tstates->tracked.strdup_strings = 1;\n> -\tstates->stale.strdup_strings = 1;\n\n... we used to set up selectively to own.\n\nHow would we make sure after this change we are not adding leaks?\nIs there a way to do so mechanically?\n\n> -\tstruct ref_states states;\n> +\tstruct ref_states states = REF_STATES_INIT;\n>  \tstruct string_list refs_to_prune = STRING_LIST_INIT_NODUP;\n>  \tstruct string_list_item *item;\n>  \tconst char *dangling_msg = dry_run\n>  \t\t? _(\" %s will become dangling!\")\n>  \t\t: _(\" %s has become dangling!\");\n>  \n> -\tmemset(&states, 0, sizeof(states));\n>  \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n\nLike this one, get_remote_ref_states() used to receive states that\nare set to borrow strings, but now we get duplicated strings, right?\nAre we leaking whatever strings we push to these string lists now?\n\n\n"},{"id":"437206","messageId":"87v92lzihd.fsf@evledraar.gmail.com","threadId":"56591","inReplyTo":"xmqq4ka5oc1k.fsf@gitster.g","subject":"Re: [PATCH v2 4/5] builtin/remote.c: add and use a REF_STATES_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-09-27T23:38:16Z","receivedAt":"2021-09-27T23:50:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"\nOn Mon, Sep 27 2021, Junio C Hamano wrote:\n\n> Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n>\n>> Use a new REF_STATES_INIT designated initializer instead of assigning\n>> to the \"strdup_strings\" member of the previously memzero()'d version\n>> of this struct.\n>>\n>> The pattern of assigning to \"strdup_strings\" dates back to\n>> 211c89682ee (Make git-remote a builtin, 2008-02-29) (when it was\n>> \"strdup_paths\"), i.e. long before we used anything like our current\n>> established *_INIT patterns consistently.\n>>\n>> Then in e61e0cc6b70 (builtin-remote: teach show to display remote\n>> HEAD, 2009-02-25) and e5dcbfd9ab7 (builtin-remote: new show output\n>> style for push refspecs, 2009-02-25) we added some more of these.\n>>\n>> As it turns out we only initialized this struct three times, all the\n>> other uses were of pointers to those initialized structs. So let's\n>> initialize it in those three places, skip the memset(), and pass those\n>> structs down appropriately.\n>>\n>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n>> ---\n>>  builtin/remote.c | 23 +++++++++++------------\n>>  1 file changed, 11 insertions(+), 12 deletions(-)\n>>\n>> diff --git a/builtin/remote.c b/builtin/remote.c\n>> index 7f88e6ce9de..160dd954f74 100644\n>> --- a/builtin/remote.c\n>> +++ b/builtin/remote.c\n>> @@ -344,6 +344,14 @@ struct ref_states {\n>>  \tint queried;\n>>  };\n>>  \n>> +#define REF_STATES_INIT { \\\n>> +\t.new_refs = STRING_LIST_INIT_DUP, \\\n>> +\t.stale = STRING_LIST_INIT_DUP, \\\n>> +\t.tracked = STRING_LIST_INIT_DUP, \\\n>> +\t.heads = STRING_LIST_INIT_DUP, \\\n>> +\t.push = STRING_LIST_INIT_DUP, \\\n>> +}\n>\n> So, now everybody owns the string, but ...\n>\n>>  static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)\n>>  {\n>>  \tstruct ref *fetch_map = NULL, **tail = &fetch_map;\n>> @@ -355,9 +363,6 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat\n>>  \t\t\tdie(_(\"Could not get fetch map for refspec %s\"),\n>>  \t\t\t\tstates->remote->fetch.raw[i]);\n>>  \n>> -\tstates->new_refs.strdup_strings = 1;\n>> -\tstates->tracked.strdup_strings = 1;\n>> -\tstates->stale.strdup_strings = 1;\n>\n> ... we used to set up selectively to own.\n>\n> How would we make sure after this change we are not adding leaks?\n> Is there a way to do so mechanically?\n\nI manual run with SANITIZE=leak shows the same amount of memory leakage\nbefore & after this change for me.\n\nWe should fix those leaks, but until my \"tests: add a test mode for\nSANITIZE=leak, run it in CI\" lands on master I'm still waiting on fixing\nthose, and this series will help make it easier.\n\nThe ownership of the \"states\" struct or its lifetime isn't different\nafter this change. It's only that we're doing:\n\n    struct foo = FOO_INIT;\n    /* use &foo */\n\nInstead of:\n\n    struct foo;\n    memset(&foo, 0, sizeof(foo));\n    foo->some_list.strdup_strings = 1;\n\nWhat is different is that that \"strdup_strings\" member in the contained\n\"some_list\" will be set to \"1\" earlier. E.g. in the case of this in the\npre-image:\n\n    states->new_refs.strdup_strings = 1;\n\nWe'd do that in get_ref_states(), which was called by\nget_remote_ref_states(), which was e.g. called by show(). So before we\nwouldn't flip that particular value until we got all the way down into\nget_remote_ref_states(), now we initialize the struct like that on the\nstack right away.\n\nBut it doesn't result in any new allocations, string_list like strbuf\netc. won't allocate until something is pushed onto the list, using the\ncommon \"nr/alloc\" & malloc on demand pattern.\n\n>> -\tstruct ref_states states;\n>> +\tstruct ref_states states = REF_STATES_INIT;\n>>  \tstruct string_list refs_to_prune = STRING_LIST_INIT_NODUP;\n>>  \tstruct string_list_item *item;\n>>  \tconst char *dangling_msg = dry_run\n>>  \t\t? _(\" %s will become dangling!\")\n>>  \t\t: _(\" %s has become dangling!\");\n>>  \n>> -\tmemset(&states, 0, sizeof(states));\n>>  \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n>\n> Like this one, get_remote_ref_states() used to receive states that\n> are set to borrow strings, but now we get duplicated strings, right?\n> Are we leaking whatever strings we push to these string lists now?\n\nAh, yes it *could* happen as a side-effect of this sotr of change that\nthat memset() was implicitly flipping some string_list structs to the\nequivalent of strdup_strings=0.\n\nBut that's not the case here, it was just memset() boilerplate, then in\nget_remote_ref_states() we'd set all the string lists we'd use to \"dup\".\n"},{"id":"437209","messageId":"xmqqv92lmv2b.fsf@gitster.g","threadId":"56591","inReplyTo":"87v92lzihd.fsf@evledraar.gmail.com","subject":"Re: [PATCH v2 4/5] builtin/remote.c: add and use a REF_STATES_INIT","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-09-27T23:56:44Z","receivedAt":"2021-09-27T23:56:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason <avarab@gmail.com> writes:\n\n> The ownership of the \"states\" struct or its lifetime isn't different\n> after this change. It's only that we're doing:\n>\n>     struct foo = FOO_INIT;\n>     /* use &foo */\n>\n> Instead of:\n>\n>     struct foo;\n>     memset(&foo, 0, sizeof(foo));\n>     foo->some_list.strdup_strings = 1;\n\nNo, I am not talking about ownership of \"foo\" itself.  What changes\nis ownership of some of the string_list embedded in \"foo\" that used\nNOT to have strdup_strings member set now have the bit set, so the\nstring list owns the string.\n\n>>> +\tstruct ref_states states = REF_STATES_INIT;\n>>>  \tstruct string_list refs_to_prune = STRING_LIST_INIT_NODUP;\n>>>  \tstruct string_list_item *item;\n>>>  \tconst char *dangling_msg = dry_run\n>>>  \t\t? _(\" %s will become dangling!\")\n>>>  \t\t: _(\" %s has become dangling!\");\n>>>  \n>>> -\tmemset(&states, 0, sizeof(states));\n>>>  \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n>>\n>> Like this one, get_remote_ref_states() used to receive states that\n>> are set to borrow strings, but now we get duplicated strings, right?\n>> Are we leaking whatever strings we push to these string lists now?\n>\n> Ah, yes it *could* happen as a side-effect of this sotr of change that\n> that memset() was implicitly flipping some string_list structs to the\n> equivalent of strdup_strings=0.\n>\n> But that's not the case here, it was just memset() boilerplate, then in\n> get_remote_ref_states() we'd set all the string lists we'd use to \"dup\".\n\nOK, get_remotes_ref_states() marked all string list to the dup\nvariant, then we won't have a problem.  I was trying to make sure\nthat was something you looked at when preparing these patches.\n\nThanks.\n"},{"id":"437668","messageId":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com","subject":"[PATCH v3 0/6] Non-trivial designated initializer conversion","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-01T10:27:30Z","receivedAt":"2021-10-01T10:27:47Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"See\nhttp://lore.kernel.org/git/cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com\nfor the v1 & goals, and\nhttps://lore.kernel.org/git/cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com/\nfor the v2.\n\nThis v3:\n\n * Addresses Junio's comments about URLMATCH_CONFIG_INIT use, I'm no\n   longer removing explicit assignments to NULL related to it.\n\n * Updates the commit message of 5/6 for the discussion ending at\n   https://lore.kernel.org/git/xmqqv92lmv2b.fsf@gitster.g/\n\n * I've added a new 6/6 with an UNPACK_TREES_OPTIONS_INIT. It's\n   related to the discussion about how unpack-trees.[ch] memory\n   management happens at [1], but is really orthagonal to the points\n   Elijah and I were discussing there.\n\n   I think whatever approach we'd decide to go with (his in\n   en/removing-untracked-fixes, or my WIP suggestion) the move to an\n   UNPACK_TREES_OPTIONS_INIT makes sense, and would be the same either\n   way.\n\n   It does make the WIP patches I've got at[1] to solve memory leaks &\n   simplify the setup in unpack-trees.[ch] much smaller, and is like\n   the other *_INIT changes here, so I've included it.\n\n1. https://lore.kernel.org/git/87fstlrumj.fsf@evledraar.gmail.com/\n2. https://github.com/avar/git/compare/avar/post-sanitize-leak-test-mode-add-and-use-revisions-release...avar/post-sanitize-leak-test-mode-unpack-trees-and-dir\n\nÆvar Arnfjörð Bjarmason (6):\n  daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro\n  builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro\n  urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n  builtin/remote.c: add and use a REF_STATES_INIT\n  builtin/remote.c: add and use SHOW_INFO_INIT\n  unpack-trees.[ch]: define and use a UNPACK_TREES_OPTIONS_INIT\n\n archive.c                 |   3 +-\n builtin/am.c              |   6 +--\n builtin/blame.c           |  30 +++++------\n builtin/checkout.c        |   6 +--\n builtin/clone.c           |   3 +-\n builtin/commit.c          |   3 +-\n builtin/config.c          |   2 +-\n builtin/merge.c           |   3 +-\n builtin/read-tree.c       |   3 +-\n builtin/remote.c          | 111 +++++++++++++++++++-------------------\n builtin/reset.c           |   3 +-\n builtin/sparse-checkout.c |   3 +-\n builtin/stash.c           |   6 +--\n credential.c              |   2 +-\n daemon.c                  |  19 +++----\n diff-lib.c                |   3 +-\n http.c                    |   2 +-\n merge-ort.c               |   3 +-\n merge-recursive.c         |   4 +-\n reset.c                   |   2 +-\n sequencer.c               |   3 +-\n unpack-trees.h            |   1 +\n urlmatch.h                |   4 ++\n 23 files changed, 103 insertions(+), 122 deletions(-)\n\nRange-diff against v2:\n1:  3130693b416 = 1:  8f3f3f97fcb daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro\n2:  65c5295c1ac = 2:  ced1d581f15 builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro\n3:  3783788b553 ! 3:  266948e604c urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n    @@ Commit message\n         urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n     \n         Change the initialization pattern of \"struct urlmatch_config\" to use\n    -    an *_INIT macro and designated initializers.\n    +    an *_INIT macro and designated initializers. Right now there's no\n    +    other \"struct\" member of \"struct urlmatch_config\" which would require\n    +    its own *_INIT, but it's good practice not to assume that. Let's also\n    +    change this to a designated initializer while we're at it.\n     \n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n    @@ builtin/config.c: static int get_urlmatch(const char *var, const char *url)\n      \tstruct string_list values = STRING_LIST_INIT_DUP;\n      \n      \tconfig.collect_fn = urlmatch_collect_fn;\n    --\tconfig.cascade_fn = NULL;\n    - \tconfig.cb = &values;\n    - \n    - \tif (!url_normalize(url, &config.url))\n     \n      ## credential.c ##\n     @@ credential.c: static int match_partial_url(const char *url, void *cb)\n    @@ credential.c: static int match_partial_url(const char *url, void *cb)\n      \tstruct strbuf url = STRBUF_INIT;\n      \n      \tif (!c->host)\n    -@@ credential.c: static void credential_apply_config(struct credential *c)\n    - \t\treturn;\n    - \n    - \tconfig.section = \"credential\";\n    --\tconfig.key = NULL;\n    - \tconfig.collect_fn = credential_config_callback;\n    --\tconfig.cascade_fn = NULL;\n    - \tconfig.select_fn = select_all;\n    - \tconfig.fallback_match_fn = match_partial_url;\n    - \tconfig.cb = c;\n     \n      ## http.c ##\n     @@ http.c: void http_init(struct remote *remote, const char *url, int proactive_auth)\n    @@ http.c: void http_init(struct remote *remote, const char *url, int proactive_aut\n     +\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n      \n      \tconfig.section = \"http\";\n    --\tconfig.key = NULL;\n    - \tconfig.collect_fn = http_options;\n    - \tconfig.cascade_fn = git_default_config;\n    --\tconfig.cb = NULL;\n    - \n    - \thttp_is_verbose = 0;\n    - \tnormalized_url = url_normalize(url, &config.url);\n    + \tconfig.key = NULL;\n     \n      ## urlmatch.h ##\n     @@ urlmatch.h: struct urlmatch_config {\n4:  13ef9566903 ! 4:  41fcb0a45e5 builtin/remote.c: add and use a REF_STATES_INIT\n    @@ Commit message\n         initialize it in those three places, skip the memset(), and pass those\n         structs down appropriately.\n     \n    +    This would be a behavior change if we had codepaths that relied say on\n    +    implicitly having had \"new_refs\" initialized to STRING_LIST_INIT_NODUP\n    +    with the memset(), but only set the \"strdup_strings\" on some other\n    +    struct, but then called string_list_append() on \"new_refs\". There\n    +    isn't any such codepath, all of the late assignments to\n    +    \"strdup_strings\" assigned to those structs that we'd use for those\n    +    codepaths.\n    +\n    +    So just initializing them all up-front makes for easier to understand\n    +    code, i.e. in the pre-image it looked as though we had that tricky\n    +    edge case, but we didn't.\n    +\n         Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n     \n      ## builtin/remote.c ##\n5:  b78a9ec0846 = 5:  25fec54877b builtin/remote.c: add and use SHOW_INFO_INIT\n-:  ----------- > 6:  18358f5d57a unpack-trees.[ch]: define and use a UNPACK_TREES_OPTIONS_INIT\n-- \n2.33.0.1375.gbbd823cc90f\n\n"},{"id":"437669","messageId":"patch-v3-1.6-8f3f3f97fcb-20211001T102056Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","subject":"[PATCH v3 1/6] daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-01T10:27:31Z","receivedAt":"2021-10-01T10:27:48Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the hostinfo_init() function added in 01cec54e135 (daemon:\ndeglobalize hostname information, 2015-03-07) and instead initialize\nthe \"struct hostinfo\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n daemon.c | 19 +++++++------------\n 1 file changed, 7 insertions(+), 12 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex 5c4cbad62d0..d80d009d1a1 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -63,6 +63,12 @@ struct hostinfo {\n \tunsigned int hostname_lookup_done:1;\n \tunsigned int saw_extended_args:1;\n };\n+#define HOSTINFO_INIT { \\\n+\t.hostname = STRBUF_INIT, \\\n+\t.canon_hostname = STRBUF_INIT, \\\n+\t.ip_address = STRBUF_INIT, \\\n+\t.tcp_port = STRBUF_INIT, \\\n+}\n \n static void lookup_hostname(struct hostinfo *hi);\n \n@@ -727,15 +733,6 @@ static void lookup_hostname(struct hostinfo *hi)\n \t}\n }\n \n-static void hostinfo_init(struct hostinfo *hi)\n-{\n-\tmemset(hi, 0, sizeof(*hi));\n-\tstrbuf_init(&hi->hostname, 0);\n-\tstrbuf_init(&hi->canon_hostname, 0);\n-\tstrbuf_init(&hi->ip_address, 0);\n-\tstrbuf_init(&hi->tcp_port, 0);\n-}\n-\n static void hostinfo_clear(struct hostinfo *hi)\n {\n \tstrbuf_release(&hi->hostname);\n@@ -760,11 +757,9 @@ static int execute(void)\n \tchar *line = packet_buffer;\n \tint pktlen, len, i;\n \tchar *addr = getenv(\"REMOTE_ADDR\"), *port = getenv(\"REMOTE_PORT\");\n-\tstruct hostinfo hi;\n+\tstruct hostinfo hi = HOSTINFO_INIT;\n \tstruct strvec env = STRVEC_INIT;\n \n-\thostinfo_init(&hi);\n-\n \tif (addr)\n \t\tloginfo(\"Connection from %s:%s\", addr, port);\n \n-- \n2.33.0.1375.gbbd823cc90f\n\n"},{"id":"437670","messageId":"patch-v3-2.6-ced1d581f15-20211001T102056Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","subject":"[PATCH v3 2/6] builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-01T10:27:32Z","receivedAt":"2021-10-01T10:27:51Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the commit_info_init() function addded in ea02ffa3857 (mailmap:\nsimplify map_user() interface, 2013-01-05) and instead initialize the\n\"struct commit_info\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nThe get_commit_info() function is only called by the three callers\nbeing changed here immediately after initializing the struct with the\nmacros, so by moving the initialization to the callers we don't need\nto do it in get_commit_info() anymore.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/blame.c | 30 +++++++++++++-----------------\n 1 file changed, 13 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex 641523ff9af..1c31a996403 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -101,6 +101,16 @@ struct commit_info {\n \tstruct strbuf summary;\n };\n \n+#define COMMIT_INFO_INIT { \\\n+\t.author = STRBUF_INIT, \\\n+\t.author_mail = STRBUF_INIT, \\\n+\t.author_tz = STRBUF_INIT, \\\n+\t.committer = STRBUF_INIT, \\\n+\t.committer_mail = STRBUF_INIT, \\\n+\t.committer_tz = STRBUF_INIT, \\\n+\t.summary = STRBUF_INIT, \\\n+}\n+\n /*\n  * Parse author/committer line in the commit object buffer\n  */\n@@ -160,18 +170,6 @@ static void get_ac_line(const char *inbuf, const char *what,\n \tstrbuf_add(name, namebuf, namelen);\n }\n \n-static void commit_info_init(struct commit_info *ci)\n-{\n-\n-\tstrbuf_init(&ci->author, 0);\n-\tstrbuf_init(&ci->author_mail, 0);\n-\tstrbuf_init(&ci->author_tz, 0);\n-\tstrbuf_init(&ci->committer, 0);\n-\tstrbuf_init(&ci->committer_mail, 0);\n-\tstrbuf_init(&ci->committer_tz, 0);\n-\tstrbuf_init(&ci->summary, 0);\n-}\n-\n static void commit_info_destroy(struct commit_info *ci)\n {\n \n@@ -192,8 +190,6 @@ static void get_commit_info(struct commit *commit,\n \tconst char *subject, *encoding;\n \tconst char *message;\n \n-\tcommit_info_init(ret);\n-\n \tencoding = get_log_output_encoding();\n \tmessage = logmsg_reencode(commit, NULL, encoding);\n \tget_ac_line(message, \"\\nauthor \",\n@@ -246,7 +242,7 @@ static void write_filename_info(struct blame_origin *suspect)\n  */\n static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat)\n {\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \n \tif (!repeat && (suspect->commit->object.flags & METAINFO_SHOWN))\n \t\treturn 0;\n@@ -440,7 +436,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int\n \tint cnt;\n \tconst char *cp;\n \tstruct blame_origin *suspect = ent->suspect;\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \tchar hex[GIT_MAX_HEXSZ + 1];\n \tint show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);\n \tconst char *default_color = NULL, *color = NULL, *reset = NULL;\n@@ -630,7 +626,7 @@ static void find_alignment(struct blame_scoreboard *sb, int *option)\n \t\tif (longest_file < num)\n \t\t\tlongest_file = num;\n \t\tif (!(suspect->commit->object.flags & METAINFO_SHOWN)) {\n-\t\t\tstruct commit_info ci;\n+\t\t\tstruct commit_info ci = COMMIT_INFO_INIT;\n \t\t\tsuspect->commit->object.flags |= METAINFO_SHOWN;\n \t\t\tget_commit_info(suspect->commit, &ci, 1);\n \t\t\tif (*option & OUTPUT_SHOW_EMAIL)\n-- \n2.33.0.1375.gbbd823cc90f\n\n"},{"id":"437671","messageId":"patch-v3-3.6-266948e604c-20211001T102056Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","subject":"[PATCH v3 3/6] urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-01T10:27:33Z","receivedAt":"2021-10-01T10:27:53Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the initialization pattern of \"struct urlmatch_config\" to use\nan *_INIT macro and designated initializers. Right now there's no\nother \"struct\" member of \"struct urlmatch_config\" which would require\nits own *_INIT, but it's good practice not to assume that. Let's also\nchange this to a designated initializer while we're at it.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/config.c | 2 +-\n credential.c     | 2 +-\n http.c           | 2 +-\n urlmatch.h       | 4 ++++\n 4 files changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/config.c b/builtin/config.c\nindex 865fddd6ce8..542d8d02b2b 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -575,7 +575,7 @@ static int get_urlmatch(const char *var, const char *url)\n \tint ret;\n \tchar *section_tail;\n \tstruct string_list_item *item;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct string_list values = STRING_LIST_INIT_DUP;\n \n \tconfig.collect_fn = urlmatch_collect_fn;\ndiff --git a/credential.c b/credential.c\nindex 000ac7a8d43..e7240f3f636 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -105,7 +105,7 @@ static int match_partial_url(const char *url, void *cb)\n static void credential_apply_config(struct credential *c)\n {\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct strbuf url = STRBUF_INIT;\n \n \tif (!c->host)\ndiff --git a/http.c b/http.c\nindex d7c20493d7f..da12471c242 100644\n--- a/http.c\n+++ b/http.c\n@@ -990,7 +990,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n \tchar *low_speed_limit;\n \tchar *low_speed_time;\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \n \tconfig.section = \"http\";\n \tconfig.key = NULL;\ndiff --git a/urlmatch.h b/urlmatch.h\nindex 6ff42f81b0c..34a3ba6d197 100644\n--- a/urlmatch.h\n+++ b/urlmatch.h\n@@ -66,6 +66,10 @@ struct urlmatch_config {\n \tint (*fallback_match_fn)(const char *url, void *cb);\n };\n \n+#define URLMATCH_CONFIG_INIT { \\\n+\t.vars = STRING_LIST_INIT_DUP, \\\n+}\n+\n int urlmatch_config_entry(const char *var, const char *value, void *cb);\n \n #endif /* URL_MATCH_H */\n-- \n2.33.0.1375.gbbd823cc90f\n\n"},{"id":"437672","messageId":"patch-v3-4.6-41fcb0a45e5-20211001T102056Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","subject":"[PATCH v3 4/6] builtin/remote.c: add and use a REF_STATES_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-01T10:27:34Z","receivedAt":"2021-10-01T10:27:55Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Use a new REF_STATES_INIT designated initializer instead of assigning\nto the \"strdup_strings\" member of the previously memzero()'d version\nof this struct.\n\nThe pattern of assigning to \"strdup_strings\" dates back to\n211c89682ee (Make git-remote a builtin, 2008-02-29) (when it was\n\"strdup_paths\"), i.e. long before we used anything like our current\nestablished *_INIT patterns consistently.\n\nThen in e61e0cc6b70 (builtin-remote: teach show to display remote\nHEAD, 2009-02-25) and e5dcbfd9ab7 (builtin-remote: new show output\nstyle for push refspecs, 2009-02-25) we added some more of these.\n\nAs it turns out we only initialized this struct three times, all the\nother uses were of pointers to those initialized structs. So let's\ninitialize it in those three places, skip the memset(), and pass those\nstructs down appropriately.\n\nThis would be a behavior change if we had codepaths that relied say on\nimplicitly having had \"new_refs\" initialized to STRING_LIST_INIT_NODUP\nwith the memset(), but only set the \"strdup_strings\" on some other\nstruct, but then called string_list_append() on \"new_refs\". There\nisn't any such codepath, all of the late assignments to\n\"strdup_strings\" assigned to those structs that we'd use for those\ncodepaths.\n\nSo just initializing them all up-front makes for easier to understand\ncode, i.e. in the pre-image it looked as though we had that tricky\nedge case, but we didn't.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 23 +++++++++++------------\n 1 file changed, 11 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f88e6ce9de..160dd954f74 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -344,6 +344,14 @@ struct ref_states {\n \tint queried;\n };\n \n+#define REF_STATES_INIT { \\\n+\t.new_refs = STRING_LIST_INIT_DUP, \\\n+\t.stale = STRING_LIST_INIT_DUP, \\\n+\t.tracked = STRING_LIST_INIT_DUP, \\\n+\t.heads = STRING_LIST_INIT_DUP, \\\n+\t.push = STRING_LIST_INIT_DUP, \\\n+}\n+\n static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)\n {\n \tstruct ref *fetch_map = NULL, **tail = &fetch_map;\n@@ -355,9 +363,6 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat\n \t\t\tdie(_(\"Could not get fetch map for refspec %s\"),\n \t\t\t\tstates->remote->fetch.raw[i]);\n \n-\tstates->new_refs.strdup_strings = 1;\n-\tstates->tracked.strdup_strings = 1;\n-\tstates->stale.strdup_strings = 1;\n \tfor (ref = fetch_map; ref; ref = ref->next) {\n \t\tif (!ref->peer_ref || !ref_exists(ref->peer_ref->name))\n \t\t\tstring_list_append(&states->new_refs, abbrev_branch(ref->name));\n@@ -406,7 +411,6 @@ static int get_push_ref_states(const struct ref *remote_refs,\n \n \tmatch_push_refs(local_refs, &push_map, &remote->push, MATCH_REFS_NONE);\n \n-\tstates->push.strdup_strings = 1;\n \tfor (ref = push_map; ref; ref = ref->next) {\n \t\tstruct string_list_item *item;\n \t\tstruct push_info *info;\n@@ -449,7 +453,6 @@ static int get_push_ref_states_noquery(struct ref_states *states)\n \tif (remote->mirror)\n \t\treturn 0;\n \n-\tstates->push.strdup_strings = 1;\n \tif (!remote->push.nr) {\n \t\titem = string_list_append(&states->push, _(\"(matching)\"));\n \t\tinfo = item->util = xcalloc(1, sizeof(struct push_info));\n@@ -483,7 +486,6 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat\n \trefspec.force = 0;\n \trefspec.pattern = 1;\n \trefspec.src = refspec.dst = \"refs/heads/*\";\n-\tstates->heads.strdup_strings = 1;\n \tget_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);\n \tmatches = guess_remote_head(find_ref_by_name(remote_refs, \"HEAD\"),\n \t\t\t\t    fetch_map, 1);\n@@ -1212,7 +1214,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n \tstruct show_info info;\n \n@@ -1225,7 +1227,6 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&states, 0, sizeof(states));\n \tmemset(&info, 0, sizeof(info));\n \tinfo.states = &states;\n \tinfo.list = &info_list;\n@@ -1334,8 +1335,7 @@ static int set_head(int argc, const char **argv)\n \tif (!opt_a && !opt_d && argc == 2) {\n \t\thead_name = xstrdup(argv[1]);\n \t} else if (opt_a && !opt_d && argc == 1) {\n-\t\tstruct ref_states states;\n-\t\tmemset(&states, 0, sizeof(states));\n+\t\tstruct ref_states states = REF_STATES_INIT;\n \t\tget_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);\n \t\tif (!states.heads.nr)\n \t\t\tresult |= error(_(\"Cannot determine remote HEAD\"));\n@@ -1374,14 +1374,13 @@ static int set_head(int argc, const char **argv)\n static int prune_remote(const char *remote, int dry_run)\n {\n \tint result = 0;\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list refs_to_prune = STRING_LIST_INIT_NODUP;\n \tstruct string_list_item *item;\n \tconst char *dangling_msg = dry_run\n \t\t? _(\" %s will become dangling!\")\n \t\t: _(\" %s has become dangling!\");\n \n-\tmemset(&states, 0, sizeof(states));\n \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n \n \tif (!states.stale.nr) {\n-- \n2.33.0.1375.gbbd823cc90f\n\n"},{"id":"437673","messageId":"patch-v3-5.6-25fec54877b-20211001T102056Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","subject":"[PATCH v3 5/6] builtin/remote.c: add and use SHOW_INFO_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-01T10:27:35Z","receivedAt":"2021-10-01T10:27:56Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In the preceding commit we introduced REF_STATES_INIT, but did not\nchange the \"struct show_info\" to have a corresponding\ninitializer. Let's do that, and make it use \"REF_STATES_INIT\" and\n\"STRING_LIST_INIT_DUP\", doing that requires changing \"list\" and\n\"states\" away from being pointers.\n\nThe resulting end-state is simpler since we omit the local \"info_list\"\nand \"states\" variables in show() as well as the memset().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 90 ++++++++++++++++++++++++------------------------\n 1 file changed, 45 insertions(+), 45 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 160dd954f74..deb48772ac5 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -972,26 +972,31 @@ static int get_remote_ref_states(const char *name,\n }\n \n struct show_info {\n-\tstruct string_list *list;\n-\tstruct ref_states *states;\n+\tstruct string_list list;\n+\tstruct ref_states states;\n \tint width, width2;\n \tint any_rebase;\n };\n \n+#define SHOW_INFO_INIT { \\\n+\t.list = STRING_LIST_INIT_DUP, \\\n+\t.states = REF_STATES_INIT, \\\n+}\n+\n static int add_remote_to_show_info(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n \tint n = strlen(item->string);\n \tif (n > info->width)\n \t\tinfo->width = n;\n-\tstring_list_insert(info->list, item->string);\n+\tstring_list_insert(&info->list, item->string);\n \treturn 0;\n }\n \n static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n-\tstruct ref_states *states = info->states;\n+\tstruct ref_states *states = &info->states;\n \tconst char *name = item->string;\n \n \tif (states->queried) {\n@@ -1018,7 +1023,7 @@ static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n static int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)\n {\n \tstruct show_info *show_info = cb_data;\n-\tstruct ref_states *states = show_info->states;\n+\tstruct ref_states *states = &show_info->states;\n \tstruct branch_info *branch_info = branch_item->util;\n \tstruct string_list_item *item;\n \tint n;\n@@ -1031,7 +1036,7 @@ static int add_local_to_show_info(struct string_list_item *branch_item, void *cb\n \tif (branch_info->rebase >= REBASE_TRUE)\n \t\tshow_info->any_rebase = 1;\n \n-\titem = string_list_insert(show_info->list, branch_item->string);\n+\titem = string_list_insert(&show_info->list, branch_item->string);\n \titem->util = branch_info;\n \n \treturn 0;\n@@ -1086,7 +1091,7 @@ static int add_push_to_show_info(struct string_list_item *push_item, void *cb_da\n \t\tshow_info->width = n;\n \tif ((n = strlen(push_info->dest)) > show_info->width2)\n \t\tshow_info->width2 = n;\n-\titem = string_list_append(show_info->list, push_item->string);\n+\titem = string_list_append(&show_info->list, push_item->string);\n \titem->util = push_item->util;\n \treturn 0;\n }\n@@ -1214,9 +1219,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states = REF_STATES_INIT;\n-\tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n-\tstruct show_info info;\n+\tstruct show_info info = SHOW_INFO_INIT;\n \n \targc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,\n \t\t\t     0);\n@@ -1227,25 +1230,22 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&info, 0, sizeof(info));\n-\tinfo.states = &states;\n-\tinfo.list = &info_list;\n \tfor (; argc; argc--, argv++) {\n \t\tint i;\n \t\tconst char **url;\n \t\tint url_nr;\n \n-\t\tget_remote_ref_states(*argv, &states, query_flag);\n+\t\tget_remote_ref_states(*argv, &info.states, query_flag);\n \n \t\tprintf_ln(_(\"* remote %s\"), *argv);\n-\t\tprintf_ln(_(\"  Fetch URL: %s\"), states.remote->url_nr > 0 ?\n-\t\t       states.remote->url[0] : _(\"(no URL)\"));\n-\t\tif (states.remote->pushurl_nr) {\n-\t\t\turl = states.remote->pushurl;\n-\t\t\turl_nr = states.remote->pushurl_nr;\n+\t\tprintf_ln(_(\"  Fetch URL: %s\"), info.states.remote->url_nr > 0 ?\n+\t\t       info.states.remote->url[0] : _(\"(no URL)\"));\n+\t\tif (info.states.remote->pushurl_nr) {\n+\t\t\turl = info.states.remote->pushurl;\n+\t\t\turl_nr = info.states.remote->pushurl_nr;\n \t\t} else {\n-\t\t\turl = states.remote->url;\n-\t\t\turl_nr = states.remote->url_nr;\n+\t\t\turl = info.states.remote->url;\n+\t\t\turl_nr = info.states.remote->url_nr;\n \t\t}\n \t\tfor (i = 0; i < url_nr; i++)\n \t\t\t/*\n@@ -1258,57 +1258,57 @@ static int show(int argc, const char **argv)\n \t\t\tprintf_ln(_(\"  Push  URL: %s\"), _(\"(no URL)\"));\n \t\tif (no_query)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(not queried)\"));\n-\t\telse if (!states.heads.nr)\n+\t\telse if (!info.states.heads.nr)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(unknown)\"));\n-\t\telse if (states.heads.nr == 1)\n-\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), states.heads.items[0].string);\n+\t\telse if (info.states.heads.nr == 1)\n+\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), info.states.heads.items[0].string);\n \t\telse {\n \t\t\tprintf(_(\"  HEAD branch (remote HEAD is ambiguous,\"\n \t\t\t\t \" may be one of the following):\\n\"));\n-\t\t\tfor (i = 0; i < states.heads.nr; i++)\n-\t\t\t\tprintf(\"    %s\\n\", states.heads.items[i].string);\n+\t\t\tfor (i = 0; i < info.states.heads.nr; i++)\n+\t\t\t\tprintf(\"    %s\\n\", info.states.heads.items[i].string);\n \t\t}\n \n \t\t/* remote branch info */\n \t\tinfo.width = 0;\n-\t\tfor_each_string_list(&states.new_refs, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.tracked, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.stale, add_remote_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.new_refs, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.tracked, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.stale, add_remote_to_show_info, &info);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Remote branch:%s\",\n \t\t\t\t     \"  Remote branches:%s\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_remote_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_remote_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git pull info */\n \t\tinfo.width = 0;\n \t\tinfo.any_rebase = 0;\n \t\tfor_each_string_list(&branch_list, add_local_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local branch configured for 'git pull':\",\n \t\t\t\t     \"  Local branches configured for 'git pull':\",\n-\t\t\t\t     info.list->nr));\n-\t\tfor_each_string_list(info.list, show_local_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\t\t\t     info.list.nr));\n+\t\tfor_each_string_list(&info.list, show_local_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git push info */\n-\t\tif (states.remote->mirror)\n+\t\tif (info.states.remote->mirror)\n \t\t\tprintf_ln(_(\"  Local refs will be mirrored by 'git push'\"));\n \n \t\tinfo.width = info.width2 = 0;\n-\t\tfor_each_string_list(&states.push, add_push_to_show_info, &info);\n-\t\tQSORT(info.list->items, info.list->nr, cmp_string_with_push);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.push, add_push_to_show_info, &info);\n+\t\tQSORT(info.list.items, info.list.nr, cmp_string_with_push);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local ref configured for 'git push'%s:\",\n \t\t\t\t     \"  Local refs configured for 'git push'%s:\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_push_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_push_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n-\t\tfree_remote_ref_states(&states);\n+\t\tfree_remote_ref_states(&info.states);\n \t}\n \n \treturn result;\n-- \n2.33.0.1375.gbbd823cc90f\n\n"},{"id":"437674","messageId":"patch-v3-6.6-18358f5d57a-20211001T102056Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","subject":"[PATCH v3 6/6] unpack-trees.[ch]: define and use a UNPACK_TREES_OPTIONS_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-01T10:27:36Z","receivedAt":"2021-10-01T10:27:57Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Almost all users of \"struct unpack_trees_options\" allocate it on the\nstack already, let's provide an *_INIT macro for them to use. This\nwill make later changes that would like to initialize other members of\nthe struct easier[1][2], but for now we're keeping it compatible with\na memset() to \"0\" with an \"{ 0 }\" initialization.\n\nThis leaves a caller in \"checkout_fast_forward()\" in \"merge.c\" still\ndoing the memset(). I've left it to avoid a conflict with the\nin-flight en/removing-untracked-fixes. As noted above conflict is just\ntextual, not semantic, so we can clean it up some other time. I've\nmanually validated[3] with some WIP changes on top of this that the\nremaining \"checkout_fast_forward()\" caller is the only one that.s\nleft.\n\n1. https://lore.kernel.org/git/87k0ixrv23.fsf@evledraar.gmail.com/\n2. https://lore.kernel.org/git/87fstlrumj.fsf@evledraar.gmail.com/\n3. https://lore.kernel.org/git/877dexrqvg.fsf@evledraar.gmail.com/\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n archive.c                 | 3 +--\n builtin/am.c              | 6 ++----\n builtin/checkout.c        | 6 ++----\n builtin/clone.c           | 3 +--\n builtin/commit.c          | 3 +--\n builtin/merge.c           | 3 +--\n builtin/read-tree.c       | 3 +--\n builtin/reset.c           | 3 +--\n builtin/sparse-checkout.c | 3 +--\n builtin/stash.c           | 6 ++----\n diff-lib.c                | 3 +--\n merge-ort.c               | 3 +--\n merge-recursive.c         | 4 +++-\n reset.c                   | 2 +-\n sequencer.c               | 3 +--\n unpack-trees.h            | 1 +\n 16 files changed, 21 insertions(+), 34 deletions(-)\n\ndiff --git a/archive.c b/archive.c\nindex a3bbb091256..210d7235c5a 100644\n--- a/archive.c\n+++ b/archive.c\n@@ -269,7 +269,7 @@ int write_archive_entries(struct archiver_args *args,\n \t\twrite_archive_entry_fn_t write_entry)\n {\n \tstruct archiver_context context;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree_desc t;\n \tint err;\n \tstruct strbuf path_in_archive = STRBUF_INIT;\n@@ -300,7 +300,6 @@ int write_archive_entries(struct archiver_args *args,\n \t * Setup index and instruct attr to read index only\n \t */\n \tif (!args->worktree_attributes) {\n-\t\tmemset(&opts, 0, sizeof(opts));\n \t\topts.index_only = 1;\n \t\topts.head_idx = -1;\n \t\topts.src_index = args->repo->index;\ndiff --git a/builtin/am.c b/builtin/am.c\nindex e4a0ff9cd7c..82641ce68ec 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1901,7 +1901,7 @@ static void am_resolve(struct am_state *state)\n static int fast_forward_to(struct tree *head, struct tree *remote, int reset)\n {\n \tstruct lock_file lock_file = LOCK_INIT;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree_desc t[2];\n \n \tif (parse_tree(head) || parse_tree(remote))\n@@ -1911,7 +1911,6 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)\n \n \trefresh_cache(REFRESH_QUIET);\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = 1;\n \topts.src_index = &the_index;\n \topts.dst_index = &the_index;\n@@ -1940,7 +1939,7 @@ static int fast_forward_to(struct tree *head, struct tree *remote, int reset)\n static int merge_tree(struct tree *tree)\n {\n \tstruct lock_file lock_file = LOCK_INIT;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree_desc t[1];\n \n \tif (parse_tree(tree))\n@@ -1948,7 +1947,6 @@ static int merge_tree(struct tree *tree)\n \n \thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = 1;\n \topts.src_index = &the_index;\n \topts.dst_index = &the_index;\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex 8c69dcdf72a..fea4533dbec 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -639,10 +639,9 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,\n \t\t      int worktree, int *writeout_error,\n \t\t      struct branch_info *info)\n {\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree_desc tree_desc;\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = -1;\n \topts.update = worktree;\n \topts.skip_unmerged = !worktree;\n@@ -719,9 +718,8 @@ static int merge_working_tree(const struct checkout_opts *opts,\n \t} else {\n \t\tstruct tree_desc trees[2];\n \t\tstruct tree *tree;\n-\t\tstruct unpack_trees_options topts;\n+\t\tstruct unpack_trees_options topts = UNPACK_TREES_OPTIONS_INIT;\n \n-\t\tmemset(&topts, 0, sizeof(topts));\n \t\ttopts.head_idx = -1;\n \t\ttopts.src_index = &the_index;\n \t\ttopts.dst_index = &the_index;\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex ff1d3d447a3..0df820c5970 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -655,7 +655,7 @@ static int checkout(int submodule_progress)\n \tstruct object_id oid;\n \tchar *head;\n \tstruct lock_file lock_file = LOCK_INIT;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree *tree;\n \tstruct tree_desc t;\n \tint err = 0;\n@@ -683,7 +683,6 @@ static int checkout(int submodule_progress)\n \n \thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n \n-\tmemset(&opts, 0, sizeof opts);\n \topts.update = 1;\n \topts.merge = 1;\n \topts.clone = 1;\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex e7320f66f95..6cc7313bad8 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -303,7 +303,7 @@ static void add_remove_files(struct string_list *list)\n static void create_base_index(const struct commit *current_head)\n {\n \tstruct tree *tree;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree_desc t;\n \n \tif (!current_head) {\n@@ -311,7 +311,6 @@ static void create_base_index(const struct commit *current_head)\n \t\treturn;\n \t}\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = 1;\n \topts.index_only = 1;\n \topts.merge = 1;\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex 3fbdacc7db4..73290a07fcc 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -670,9 +670,8 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,\n \tint i, nr_trees = 0;\n \tstruct tree *trees[MAX_UNPACK_TREES];\n \tstruct tree_desc t[MAX_UNPACK_TREES];\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = 2;\n \topts.src_index = &the_index;\n \topts.dst_index = &the_index;\ndiff --git a/builtin/read-tree.c b/builtin/read-tree.c\nindex 485e7b04794..847182fdad6 100644\n--- a/builtin/read-tree.c\n+++ b/builtin/read-tree.c\n@@ -116,7 +116,7 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)\n \tint i, stage = 0;\n \tstruct object_id oid;\n \tstruct tree_desc t[MAX_UNPACK_TREES];\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tint prefix_set = 0;\n \tstruct lock_file lock_file = LOCK_INIT;\n \tconst struct option read_tree_options[] = {\n@@ -158,7 +158,6 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)\n \t\tOPT_END()\n \t};\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = -1;\n \topts.src_index = &the_index;\n \topts.dst_index = &the_index;\ndiff --git a/builtin/reset.c b/builtin/reset.c\nindex 51c9e2f43ff..86c604b21e9 100644\n--- a/builtin/reset.c\n+++ b/builtin/reset.c\n@@ -51,10 +51,9 @@ static int reset_index(const char *ref, const struct object_id *oid, int reset_t\n \tint i, nr = 0;\n \tstruct tree_desc desc[2];\n \tstruct tree *tree;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tint ret = -1;\n \n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = 1;\n \topts.src_index = &the_index;\n \topts.dst_index = &the_index;\ndiff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c\nindex d0f5c4702be..4c3c29fb580 100644\n--- a/builtin/sparse-checkout.c\n+++ b/builtin/sparse-checkout.c\n@@ -195,7 +195,7 @@ static void clean_tracked_sparse_directories(struct repository *r)\n static int update_working_directory(struct pattern_list *pl)\n {\n \tenum update_sparsity_result result;\n-\tstruct unpack_trees_options o;\n+\tstruct unpack_trees_options o = UNPACK_TREES_OPTIONS_INIT;\n \tstruct lock_file lock_file = LOCK_INIT;\n \tstruct repository *r = the_repository;\n \n@@ -205,7 +205,6 @@ static int update_working_directory(struct pattern_list *pl)\n \n \tr->index->sparse_checkout_patterns = pl;\n \n-\tmemset(&o, 0, sizeof(o));\n \to.verbose_update = isatty(2);\n \to.update = 1;\n \to.head_idx = -1;\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 8f42360ca91..1137e5fcbe8 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -233,7 +233,7 @@ static int clear_stash(int argc, const char **argv, const char *prefix)\n static int reset_tree(struct object_id *i_tree, int update, int reset)\n {\n \tint nr_trees = 1;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree_desc t[MAX_UNPACK_TREES];\n \tstruct tree *tree;\n \tstruct lock_file lock_file = LOCK_INIT;\n@@ -244,8 +244,6 @@ static int reset_tree(struct object_id *i_tree, int update, int reset)\n \n \thold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);\n \n-\tmemset(&opts, 0, sizeof(opts));\n-\n \ttree = parse_tree_indirect(i_tree);\n \tif (parse_tree(tree))\n \t\treturn -1;\n@@ -799,7 +797,7 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op\n \tconst struct object_id *oid[] = { &info->w_commit, &info->u_tree };\n \tstruct tree *tree[ARRAY_SIZE(oid)];\n \tstruct tree_desc tree_desc[ARRAY_SIZE(oid)];\n-\tstruct unpack_trees_options unpack_tree_opt = { 0 };\n+\tstruct unpack_trees_options unpack_tree_opt = UNPACK_TREES_OPTIONS_INIT;\n \tint i;\n \n \tfor (i = 0; i < ARRAY_SIZE(oid); i++) {\ndiff --git a/diff-lib.c b/diff-lib.c\nindex ca085a03efc..8a08d9af4eb 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -526,13 +526,12 @@ static int diff_cache(struct rev_info *revs,\n {\n \tstruct tree *tree;\n \tstruct tree_desc t;\n-\tstruct unpack_trees_options opts;\n+\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n \n \ttree = parse_tree_indirect(tree_oid);\n \tif (!tree)\n \t\treturn error(\"bad tree object %s\",\n \t\t\t     tree_name ? tree_name : oid_to_hex(tree_oid));\n-\tmemset(&opts, 0, sizeof(opts));\n \topts.head_idx = 1;\n \topts.index_only = cached;\n \topts.diff_index_cached = (cached &&\ndiff --git a/merge-ort.c b/merge-ort.c\nindex 35aa979c3a4..75d2b8e4b99 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -4021,9 +4021,8 @@ static int checkout(struct merge_options *opt,\n \t/* Switch the index/working copy from old to new */\n \tint ret;\n \tstruct tree_desc trees[2];\n-\tstruct unpack_trees_options unpack_opts;\n+\tstruct unpack_trees_options unpack_opts = UNPACK_TREES_OPTIONS_INIT;\n \n-\tmemset(&unpack_opts, 0, sizeof(unpack_opts));\n \tunpack_opts.head_idx = -1;\n \tunpack_opts.src_index = opt->repo->index;\n \tunpack_opts.dst_index = opt->repo->index;\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex e594d4c3fa1..40254ec0b3d 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -404,8 +404,10 @@ static int unpack_trees_start(struct merge_options *opt,\n \tint rc;\n \tstruct tree_desc t[3];\n \tstruct index_state tmp_index = { NULL };\n+\tstruct unpack_trees_options blank = UNPACK_TREES_OPTIONS_INIT;\n \n-\tmemset(&opt->priv->unpack_opts, 0, sizeof(opt->priv->unpack_opts));\n+\tassert(sizeof(blank) == sizeof(opt->priv->unpack_opts));\n+\tmemcpy(&opt->priv->unpack_opts, &blank, sizeof(opt->priv->unpack_opts));\n \tif (opt->priv->call_depth)\n \t\topt->priv->unpack_opts.index_only = 1;\n \telse\ndiff --git a/reset.c b/reset.c\nindex 79310ae071b..d13984ab781 100644\n--- a/reset.c\n+++ b/reset.c\n@@ -21,7 +21,7 @@ int reset_head(struct repository *r, struct object_id *oid, const char *action,\n \tstruct object_id head_oid;\n \tstruct tree_desc desc[2] = { { NULL }, { NULL } };\n \tstruct lock_file lock = LOCK_INIT;\n-\tstruct unpack_trees_options unpack_tree_opts = { 0 };\n+\tstruct unpack_trees_options unpack_tree_opts = UNPACK_TREES_OPTIONS_INIT;\n \tstruct tree *tree;\n \tconst char *reflog_action;\n \tstruct strbuf msg = STRBUF_INIT;\ndiff --git a/sequencer.c b/sequencer.c\nindex 614d56f5e21..abd85b6c562 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -3652,7 +3652,7 @@ static int do_reset(struct repository *r,\n \tstruct lock_file lock = LOCK_INIT;\n \tstruct tree_desc desc;\n \tstruct tree *tree;\n-\tstruct unpack_trees_options unpack_tree_opts;\n+\tstruct unpack_trees_options unpack_tree_opts = UNPACK_TREES_OPTIONS_INIT;\n \tint ret = 0;\n \n \tif (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0)\n@@ -3691,7 +3691,6 @@ static int do_reset(struct repository *r,\n \t\t}\n \t}\n \n-\tmemset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));\n \tsetup_unpack_trees_porcelain(&unpack_tree_opts, \"reset\");\n \tunpack_tree_opts.head_idx = 1;\n \tunpack_tree_opts.src_index = r->index;\ndiff --git a/unpack-trees.h b/unpack-trees.h\nindex 2d88b19dca7..caa7ada59ab 100644\n--- a/unpack-trees.h\n+++ b/unpack-trees.h\n@@ -90,6 +90,7 @@ struct unpack_trees_options {\n \tstruct pattern_list *pl; /* for internal use */\n \tstruct checkout_metadata meta;\n };\n+#define UNPACK_TREES_OPTIONS_INIT { 0 }\n \n int unpack_trees(unsigned n, struct tree_desc *t,\n \t\t struct unpack_trees_options *options);\n-- \n2.33.0.1375.gbbd823cc90f\n\n"},{"id":"437733","messageId":"xmqqk0iw4e7v.fsf@gitster.g","threadId":"56591","inReplyTo":"patch-v3-6.6-18358f5d57a-20211001T102056Z-avarab@gmail.com","subject":"Re: [PATCH v3 6/6] unpack-trees.[ch]: define and use a UNPACK_TREES_OPTIONS_INIT","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-10-01T21:39:16Z","receivedAt":"2021-10-01T21:39:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ævar Arnfjörð Bjarmason  <avarab@gmail.com> writes:\n\n> diff --git a/archive.c b/archive.c\n> index a3bbb091256..210d7235c5a 100644\n> --- a/archive.c\n> +++ b/archive.c\n> @@ -269,7 +269,7 @@ int write_archive_entries(struct archiver_args *args,\n>  \t\twrite_archive_entry_fn_t write_entry)\n>  {\n>  \tstruct archiver_context context;\n> -\tstruct unpack_trees_options opts;\n> +\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n>  \tstruct tree_desc t;\n>  \tint err;\n>  \tstruct strbuf path_in_archive = STRBUF_INIT;\n> @@ -300,7 +300,6 @@ int write_archive_entries(struct archiver_args *args,\n>  \t * Setup index and instruct attr to read index only\n>  \t */\n>  \tif (!args->worktree_attributes) {\n> -\t\tmemset(&opts, 0, sizeof(opts));\n>  \t\topts.index_only = 1;\n>  \t\topts.head_idx = -1;\n>  \t\topts.src_index = args->repo->index;\n\nThese two hunks almost makes me say \"Meh\" (I am adding this\nparenthetical comment after reading the patch thru and I am not yet\nconvinced otherwise).\n\nThe reason why we had memset(0), getting rid of which I have no\nproblem about, is because we didn't prepare the members of the\nstructure using initializer in the first place, no?  The \"opts\" is\nused only in this block, so instead of these lines, we could have\n\n\tif (!args->worktree_attributes) {\n\t\tstruct unpack_trees_options opts = {\n\t\t\t.index_only = 1,\n                        .head_idx = -1,\n\t\t        ...\n\t\t\t.fn = oneway_merge;\n\t\t};\n\t\tinit_tree_desc(...);\n\t\tif (unpack_trees(1, &t, &opts))\n\t\t\t...\n\nwhich would be much easier to understand.  We can get rid of\nmemset(0), having UNPACK_TREES_OPTIONS_INIT did not help us much.\n\nSome hunks show that we have code between the location where \"opts\"\nis declared and where we know for certain that \"opts\" needs to be\nactually used and with what values in its members, like ...\n\n> diff --git a/builtin/am.c b/builtin/am.c\n> index e4a0ff9cd7c..82641ce68ec 100644\n> --- a/builtin/am.c\n> +++ b/builtin/am.c\n> @@ -1901,7 +1901,7 @@ static void am_resolve(struct am_state *state)\n>  static int fast_forward_to(struct tree *head, struct tree *remote, int reset)\n>  {\n>  \tstruct lock_file lock_file = LOCK_INIT;\n> -\tstruct unpack_trees_options opts;\n> +\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n>  \tstruct tree_desc t[2];\n>  \n>  \tif (parse_tree(head) || parse_tree(remote))\n> ...\n>  \n>  \trefresh_cache(REFRESH_QUIET);\n>  \n> -\tmemset(&opts, 0, sizeof(opts));\n>  \topts.head_idx = 1;\n>  \topts.src_index = &the_index;\n>  \topts.dst_index = &the_index;\n\n... this one.  And it is not necessarily a good idea to initialize\n\"opts\" with the actual values we'd use, and _INIT does help us\ngetting rid of memset(0);\n\nBut many in this patch are much simpler like this one:\n\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index 8c69dcdf72a..fea4533dbec 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -639,10 +639,9 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,\n>  \t\t      int worktree, int *writeout_error,\n>  \t\t      struct branch_info *info)\n>  {\n> -\tstruct unpack_trees_options opts;\n> +\tstruct unpack_trees_options opts = UNPACK_TREES_OPTIONS_INIT;\n>  \tstruct tree_desc tree_desc;\n>  \n> -\tmemset(&opts, 0, sizeof(opts));\n>  \topts.head_idx = -1;\n>  \topts.update = worktree;\n>  \topts.skip_unmerged = !worktree;\n\nwhich can be initialized with designated initializers in place, and\nhaving an _INIT macro would not help us very much.\n\n> @@ -719,9 +718,8 @@ static int merge_working_tree(const struct checkout_opts *opts,\n>  \t} else {\n>  \t\tstruct tree_desc trees[2];\n>  \t\tstruct tree *tree;\n> -\t\tstruct unpack_trees_options topts;\n> +\t\tstruct unpack_trees_options topts = UNPACK_TREES_OPTIONS_INIT;\n>  \n> -\t\tmemset(&topts, 0, sizeof(topts));\n>  \t\ttopts.head_idx = -1;\n>  \t\ttopts.src_index = &the_index;\n>  \t\ttopts.dst_index = &the_index;\n\nLikewise here.\n\nSo...\n"},{"id":"437781","messageId":"cover-v4-0.5-00000000000-20211002T201434Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com","subject":"[PATCH v4 0/5] Non-trivial designated initializer conversion","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-02T20:16:12Z","receivedAt":"2021-10-02T20:16:24Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"See\nhttp://lore.kernel.org/git/cover-0.6-00000000000-20210927T004920Z-avarab@gmail.com\nfor the v1 & goals, and\nhttps://lore.kernel.org/git/cover-v2-0.5-00000000000-20210927T125715Z-avarab@gmail.com/\nfor the v2 and\nhttps://lore.kernel.org/git/cover-v3-0.6-00000000000-20211001T102056Z-avarab@gmail.com\nfor the v3.\n\nI ejected teh \"UNPACK_TREES_OPTIONS_INIT\" patch. I'll just propose\nthat as some alternate/fixup for en/removing-untracked-fixes\ninstead. It makes more sense as a lead-in to wider unpack-trees.c\nfixes.\n\nÆvar Arnfjörð Bjarmason (5):\n  daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro\n  builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro\n  urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n  builtin/remote.c: add and use a REF_STATES_INIT\n  builtin/remote.c: add and use SHOW_INFO_INIT\n\n builtin/blame.c  |  30 ++++++-------\n builtin/config.c |   2 +-\n builtin/remote.c | 111 +++++++++++++++++++++++------------------------\n credential.c     |   2 +-\n daemon.c         |  19 +++-----\n http.c           |   2 +-\n urlmatch.h       |   4 ++\n 7 files changed, 82 insertions(+), 88 deletions(-)\n\nRange-diff against v3:\n1:  8f3f3f97fcb = 1:  8f3f3f97fcb daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro\n2:  ced1d581f15 = 2:  ced1d581f15 builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro\n3:  266948e604c = 3:  266948e604c urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT\n4:  41fcb0a45e5 = 4:  41fcb0a45e5 builtin/remote.c: add and use a REF_STATES_INIT\n5:  25fec54877b = 5:  25fec54877b builtin/remote.c: add and use SHOW_INFO_INIT\n6:  18358f5d57a < -:  ----------- unpack-trees.[ch]: define and use a UNPACK_TREES_OPTIONS_INIT\n-- \n2.33.0.1380.g193143c62ce\n\n"},{"id":"437783","messageId":"patch-v4-2.5-ced1d581f15-20211002T201434Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v4-0.5-00000000000-20211002T201434Z-avarab@gmail.com","subject":"[PATCH v4 2/5] builtin/blame.c: refactor commit_info_init() to COMMIT_INFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-02T20:16:14Z","receivedAt":"2021-10-02T20:16:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the commit_info_init() function addded in ea02ffa3857 (mailmap:\nsimplify map_user() interface, 2013-01-05) and instead initialize the\n\"struct commit_info\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nThe get_commit_info() function is only called by the three callers\nbeing changed here immediately after initializing the struct with the\nmacros, so by moving the initialization to the callers we don't need\nto do it in get_commit_info() anymore.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/blame.c | 30 +++++++++++++-----------------\n 1 file changed, 13 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin/blame.c b/builtin/blame.c\nindex 641523ff9af..1c31a996403 100644\n--- a/builtin/blame.c\n+++ b/builtin/blame.c\n@@ -101,6 +101,16 @@ struct commit_info {\n \tstruct strbuf summary;\n };\n \n+#define COMMIT_INFO_INIT { \\\n+\t.author = STRBUF_INIT, \\\n+\t.author_mail = STRBUF_INIT, \\\n+\t.author_tz = STRBUF_INIT, \\\n+\t.committer = STRBUF_INIT, \\\n+\t.committer_mail = STRBUF_INIT, \\\n+\t.committer_tz = STRBUF_INIT, \\\n+\t.summary = STRBUF_INIT, \\\n+}\n+\n /*\n  * Parse author/committer line in the commit object buffer\n  */\n@@ -160,18 +170,6 @@ static void get_ac_line(const char *inbuf, const char *what,\n \tstrbuf_add(name, namebuf, namelen);\n }\n \n-static void commit_info_init(struct commit_info *ci)\n-{\n-\n-\tstrbuf_init(&ci->author, 0);\n-\tstrbuf_init(&ci->author_mail, 0);\n-\tstrbuf_init(&ci->author_tz, 0);\n-\tstrbuf_init(&ci->committer, 0);\n-\tstrbuf_init(&ci->committer_mail, 0);\n-\tstrbuf_init(&ci->committer_tz, 0);\n-\tstrbuf_init(&ci->summary, 0);\n-}\n-\n static void commit_info_destroy(struct commit_info *ci)\n {\n \n@@ -192,8 +190,6 @@ static void get_commit_info(struct commit *commit,\n \tconst char *subject, *encoding;\n \tconst char *message;\n \n-\tcommit_info_init(ret);\n-\n \tencoding = get_log_output_encoding();\n \tmessage = logmsg_reencode(commit, NULL, encoding);\n \tget_ac_line(message, \"\\nauthor \",\n@@ -246,7 +242,7 @@ static void write_filename_info(struct blame_origin *suspect)\n  */\n static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat)\n {\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \n \tif (!repeat && (suspect->commit->object.flags & METAINFO_SHOWN))\n \t\treturn 0;\n@@ -440,7 +436,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int\n \tint cnt;\n \tconst char *cp;\n \tstruct blame_origin *suspect = ent->suspect;\n-\tstruct commit_info ci;\n+\tstruct commit_info ci = COMMIT_INFO_INIT;\n \tchar hex[GIT_MAX_HEXSZ + 1];\n \tint show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);\n \tconst char *default_color = NULL, *color = NULL, *reset = NULL;\n@@ -630,7 +626,7 @@ static void find_alignment(struct blame_scoreboard *sb, int *option)\n \t\tif (longest_file < num)\n \t\t\tlongest_file = num;\n \t\tif (!(suspect->commit->object.flags & METAINFO_SHOWN)) {\n-\t\t\tstruct commit_info ci;\n+\t\t\tstruct commit_info ci = COMMIT_INFO_INIT;\n \t\t\tsuspect->commit->object.flags |= METAINFO_SHOWN;\n \t\t\tget_commit_info(suspect->commit, &ci, 1);\n \t\t\tif (*option & OUTPUT_SHOW_EMAIL)\n-- \n2.33.0.1380.g193143c62ce\n\n"},{"id":"437784","messageId":"patch-v4-1.5-8f3f3f97fcb-20211002T201434Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v4-0.5-00000000000-20211002T201434Z-avarab@gmail.com","subject":"[PATCH v4 1/5] daemon.c: refactor hostinfo_init() to HOSTINFO_INIT macro","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-02T20:16:13Z","receivedAt":"2021-10-02T20:16:30Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Remove the hostinfo_init() function added in 01cec54e135 (daemon:\ndeglobalize hostname information, 2015-03-07) and instead initialize\nthe \"struct hostinfo\" with a macro.\n\nThis is the more idiomatic pattern in the codebase, and doesn't leave\nus wondering when we see the *_init() function if this struct needs\nmore complex initialization than a macro can provide.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n daemon.c | 19 +++++++------------\n 1 file changed, 7 insertions(+), 12 deletions(-)\n\ndiff --git a/daemon.c b/daemon.c\nindex 5c4cbad62d0..d80d009d1a1 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -63,6 +63,12 @@ struct hostinfo {\n \tunsigned int hostname_lookup_done:1;\n \tunsigned int saw_extended_args:1;\n };\n+#define HOSTINFO_INIT { \\\n+\t.hostname = STRBUF_INIT, \\\n+\t.canon_hostname = STRBUF_INIT, \\\n+\t.ip_address = STRBUF_INIT, \\\n+\t.tcp_port = STRBUF_INIT, \\\n+}\n \n static void lookup_hostname(struct hostinfo *hi);\n \n@@ -727,15 +733,6 @@ static void lookup_hostname(struct hostinfo *hi)\n \t}\n }\n \n-static void hostinfo_init(struct hostinfo *hi)\n-{\n-\tmemset(hi, 0, sizeof(*hi));\n-\tstrbuf_init(&hi->hostname, 0);\n-\tstrbuf_init(&hi->canon_hostname, 0);\n-\tstrbuf_init(&hi->ip_address, 0);\n-\tstrbuf_init(&hi->tcp_port, 0);\n-}\n-\n static void hostinfo_clear(struct hostinfo *hi)\n {\n \tstrbuf_release(&hi->hostname);\n@@ -760,11 +757,9 @@ static int execute(void)\n \tchar *line = packet_buffer;\n \tint pktlen, len, i;\n \tchar *addr = getenv(\"REMOTE_ADDR\"), *port = getenv(\"REMOTE_PORT\");\n-\tstruct hostinfo hi;\n+\tstruct hostinfo hi = HOSTINFO_INIT;\n \tstruct strvec env = STRVEC_INIT;\n \n-\thostinfo_init(&hi);\n-\n \tif (addr)\n \t\tloginfo(\"Connection from %s:%s\", addr, port);\n \n-- \n2.33.0.1380.g193143c62ce\n\n"},{"id":"437785","messageId":"patch-v4-4.5-41fcb0a45e5-20211002T201434Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v4-0.5-00000000000-20211002T201434Z-avarab@gmail.com","subject":"[PATCH v4 4/5] builtin/remote.c: add and use a REF_STATES_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-02T20:16:16Z","receivedAt":"2021-10-02T20:16:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Use a new REF_STATES_INIT designated initializer instead of assigning\nto the \"strdup_strings\" member of the previously memzero()'d version\nof this struct.\n\nThe pattern of assigning to \"strdup_strings\" dates back to\n211c89682ee (Make git-remote a builtin, 2008-02-29) (when it was\n\"strdup_paths\"), i.e. long before we used anything like our current\nestablished *_INIT patterns consistently.\n\nThen in e61e0cc6b70 (builtin-remote: teach show to display remote\nHEAD, 2009-02-25) and e5dcbfd9ab7 (builtin-remote: new show output\nstyle for push refspecs, 2009-02-25) we added some more of these.\n\nAs it turns out we only initialized this struct three times, all the\nother uses were of pointers to those initialized structs. So let's\ninitialize it in those three places, skip the memset(), and pass those\nstructs down appropriately.\n\nThis would be a behavior change if we had codepaths that relied say on\nimplicitly having had \"new_refs\" initialized to STRING_LIST_INIT_NODUP\nwith the memset(), but only set the \"strdup_strings\" on some other\nstruct, but then called string_list_append() on \"new_refs\". There\nisn't any such codepath, all of the late assignments to\n\"strdup_strings\" assigned to those structs that we'd use for those\ncodepaths.\n\nSo just initializing them all up-front makes for easier to understand\ncode, i.e. in the pre-image it looked as though we had that tricky\nedge case, but we didn't.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 23 +++++++++++------------\n 1 file changed, 11 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 7f88e6ce9de..160dd954f74 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -344,6 +344,14 @@ struct ref_states {\n \tint queried;\n };\n \n+#define REF_STATES_INIT { \\\n+\t.new_refs = STRING_LIST_INIT_DUP, \\\n+\t.stale = STRING_LIST_INIT_DUP, \\\n+\t.tracked = STRING_LIST_INIT_DUP, \\\n+\t.heads = STRING_LIST_INIT_DUP, \\\n+\t.push = STRING_LIST_INIT_DUP, \\\n+}\n+\n static int get_ref_states(const struct ref *remote_refs, struct ref_states *states)\n {\n \tstruct ref *fetch_map = NULL, **tail = &fetch_map;\n@@ -355,9 +363,6 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat\n \t\t\tdie(_(\"Could not get fetch map for refspec %s\"),\n \t\t\t\tstates->remote->fetch.raw[i]);\n \n-\tstates->new_refs.strdup_strings = 1;\n-\tstates->tracked.strdup_strings = 1;\n-\tstates->stale.strdup_strings = 1;\n \tfor (ref = fetch_map; ref; ref = ref->next) {\n \t\tif (!ref->peer_ref || !ref_exists(ref->peer_ref->name))\n \t\t\tstring_list_append(&states->new_refs, abbrev_branch(ref->name));\n@@ -406,7 +411,6 @@ static int get_push_ref_states(const struct ref *remote_refs,\n \n \tmatch_push_refs(local_refs, &push_map, &remote->push, MATCH_REFS_NONE);\n \n-\tstates->push.strdup_strings = 1;\n \tfor (ref = push_map; ref; ref = ref->next) {\n \t\tstruct string_list_item *item;\n \t\tstruct push_info *info;\n@@ -449,7 +453,6 @@ static int get_push_ref_states_noquery(struct ref_states *states)\n \tif (remote->mirror)\n \t\treturn 0;\n \n-\tstates->push.strdup_strings = 1;\n \tif (!remote->push.nr) {\n \t\titem = string_list_append(&states->push, _(\"(matching)\"));\n \t\tinfo = item->util = xcalloc(1, sizeof(struct push_info));\n@@ -483,7 +486,6 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat\n \trefspec.force = 0;\n \trefspec.pattern = 1;\n \trefspec.src = refspec.dst = \"refs/heads/*\";\n-\tstates->heads.strdup_strings = 1;\n \tget_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);\n \tmatches = guess_remote_head(find_ref_by_name(remote_refs, \"HEAD\"),\n \t\t\t\t    fetch_map, 1);\n@@ -1212,7 +1214,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n \tstruct show_info info;\n \n@@ -1225,7 +1227,6 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&states, 0, sizeof(states));\n \tmemset(&info, 0, sizeof(info));\n \tinfo.states = &states;\n \tinfo.list = &info_list;\n@@ -1334,8 +1335,7 @@ static int set_head(int argc, const char **argv)\n \tif (!opt_a && !opt_d && argc == 2) {\n \t\thead_name = xstrdup(argv[1]);\n \t} else if (opt_a && !opt_d && argc == 1) {\n-\t\tstruct ref_states states;\n-\t\tmemset(&states, 0, sizeof(states));\n+\t\tstruct ref_states states = REF_STATES_INIT;\n \t\tget_remote_ref_states(argv[0], &states, GET_HEAD_NAMES);\n \t\tif (!states.heads.nr)\n \t\t\tresult |= error(_(\"Cannot determine remote HEAD\"));\n@@ -1374,14 +1374,13 @@ static int set_head(int argc, const char **argv)\n static int prune_remote(const char *remote, int dry_run)\n {\n \tint result = 0;\n-\tstruct ref_states states;\n+\tstruct ref_states states = REF_STATES_INIT;\n \tstruct string_list refs_to_prune = STRING_LIST_INIT_NODUP;\n \tstruct string_list_item *item;\n \tconst char *dangling_msg = dry_run\n \t\t? _(\" %s will become dangling!\")\n \t\t: _(\" %s has become dangling!\");\n \n-\tmemset(&states, 0, sizeof(states));\n \tget_remote_ref_states(remote, &states, GET_REF_STATES);\n \n \tif (!states.stale.nr) {\n-- \n2.33.0.1380.g193143c62ce\n\n"},{"id":"437786","messageId":"patch-v4-5.5-25fec54877b-20211002T201434Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v4-0.5-00000000000-20211002T201434Z-avarab@gmail.com","subject":"[PATCH v4 5/5] builtin/remote.c: add and use SHOW_INFO_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-02T20:16:17Z","receivedAt":"2021-10-02T20:16:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"In the preceding commit we introduced REF_STATES_INIT, but did not\nchange the \"struct show_info\" to have a corresponding\ninitializer. Let's do that, and make it use \"REF_STATES_INIT\" and\n\"STRING_LIST_INIT_DUP\", doing that requires changing \"list\" and\n\"states\" away from being pointers.\n\nThe resulting end-state is simpler since we omit the local \"info_list\"\nand \"states\" variables in show() as well as the memset().\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/remote.c | 90 ++++++++++++++++++++++++------------------------\n 1 file changed, 45 insertions(+), 45 deletions(-)\n\ndiff --git a/builtin/remote.c b/builtin/remote.c\nindex 160dd954f74..deb48772ac5 100644\n--- a/builtin/remote.c\n+++ b/builtin/remote.c\n@@ -972,26 +972,31 @@ static int get_remote_ref_states(const char *name,\n }\n \n struct show_info {\n-\tstruct string_list *list;\n-\tstruct ref_states *states;\n+\tstruct string_list list;\n+\tstruct ref_states states;\n \tint width, width2;\n \tint any_rebase;\n };\n \n+#define SHOW_INFO_INIT { \\\n+\t.list = STRING_LIST_INIT_DUP, \\\n+\t.states = REF_STATES_INIT, \\\n+}\n+\n static int add_remote_to_show_info(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n \tint n = strlen(item->string);\n \tif (n > info->width)\n \t\tinfo->width = n;\n-\tstring_list_insert(info->list, item->string);\n+\tstring_list_insert(&info->list, item->string);\n \treturn 0;\n }\n \n static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n {\n \tstruct show_info *info = cb_data;\n-\tstruct ref_states *states = info->states;\n+\tstruct ref_states *states = &info->states;\n \tconst char *name = item->string;\n \n \tif (states->queried) {\n@@ -1018,7 +1023,7 @@ static int show_remote_info_item(struct string_list_item *item, void *cb_data)\n static int add_local_to_show_info(struct string_list_item *branch_item, void *cb_data)\n {\n \tstruct show_info *show_info = cb_data;\n-\tstruct ref_states *states = show_info->states;\n+\tstruct ref_states *states = &show_info->states;\n \tstruct branch_info *branch_info = branch_item->util;\n \tstruct string_list_item *item;\n \tint n;\n@@ -1031,7 +1036,7 @@ static int add_local_to_show_info(struct string_list_item *branch_item, void *cb\n \tif (branch_info->rebase >= REBASE_TRUE)\n \t\tshow_info->any_rebase = 1;\n \n-\titem = string_list_insert(show_info->list, branch_item->string);\n+\titem = string_list_insert(&show_info->list, branch_item->string);\n \titem->util = branch_info;\n \n \treturn 0;\n@@ -1086,7 +1091,7 @@ static int add_push_to_show_info(struct string_list_item *push_item, void *cb_da\n \t\tshow_info->width = n;\n \tif ((n = strlen(push_info->dest)) > show_info->width2)\n \t\tshow_info->width2 = n;\n-\titem = string_list_append(show_info->list, push_item->string);\n+\titem = string_list_append(&show_info->list, push_item->string);\n \titem->util = push_item->util;\n \treturn 0;\n }\n@@ -1214,9 +1219,7 @@ static int show(int argc, const char **argv)\n \t\tOPT_BOOL('n', NULL, &no_query, N_(\"do not query remotes\")),\n \t\tOPT_END()\n \t};\n-\tstruct ref_states states = REF_STATES_INIT;\n-\tstruct string_list info_list = STRING_LIST_INIT_NODUP;\n-\tstruct show_info info;\n+\tstruct show_info info = SHOW_INFO_INIT;\n \n \targc = parse_options(argc, argv, NULL, options, builtin_remote_show_usage,\n \t\t\t     0);\n@@ -1227,25 +1230,22 @@ static int show(int argc, const char **argv)\n \tif (!no_query)\n \t\tquery_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES);\n \n-\tmemset(&info, 0, sizeof(info));\n-\tinfo.states = &states;\n-\tinfo.list = &info_list;\n \tfor (; argc; argc--, argv++) {\n \t\tint i;\n \t\tconst char **url;\n \t\tint url_nr;\n \n-\t\tget_remote_ref_states(*argv, &states, query_flag);\n+\t\tget_remote_ref_states(*argv, &info.states, query_flag);\n \n \t\tprintf_ln(_(\"* remote %s\"), *argv);\n-\t\tprintf_ln(_(\"  Fetch URL: %s\"), states.remote->url_nr > 0 ?\n-\t\t       states.remote->url[0] : _(\"(no URL)\"));\n-\t\tif (states.remote->pushurl_nr) {\n-\t\t\turl = states.remote->pushurl;\n-\t\t\turl_nr = states.remote->pushurl_nr;\n+\t\tprintf_ln(_(\"  Fetch URL: %s\"), info.states.remote->url_nr > 0 ?\n+\t\t       info.states.remote->url[0] : _(\"(no URL)\"));\n+\t\tif (info.states.remote->pushurl_nr) {\n+\t\t\turl = info.states.remote->pushurl;\n+\t\t\turl_nr = info.states.remote->pushurl_nr;\n \t\t} else {\n-\t\t\turl = states.remote->url;\n-\t\t\turl_nr = states.remote->url_nr;\n+\t\t\turl = info.states.remote->url;\n+\t\t\turl_nr = info.states.remote->url_nr;\n \t\t}\n \t\tfor (i = 0; i < url_nr; i++)\n \t\t\t/*\n@@ -1258,57 +1258,57 @@ static int show(int argc, const char **argv)\n \t\t\tprintf_ln(_(\"  Push  URL: %s\"), _(\"(no URL)\"));\n \t\tif (no_query)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(not queried)\"));\n-\t\telse if (!states.heads.nr)\n+\t\telse if (!info.states.heads.nr)\n \t\t\tprintf_ln(_(\"  HEAD branch: %s\"), _(\"(unknown)\"));\n-\t\telse if (states.heads.nr == 1)\n-\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), states.heads.items[0].string);\n+\t\telse if (info.states.heads.nr == 1)\n+\t\t\tprintf_ln(_(\"  HEAD branch: %s\"), info.states.heads.items[0].string);\n \t\telse {\n \t\t\tprintf(_(\"  HEAD branch (remote HEAD is ambiguous,\"\n \t\t\t\t \" may be one of the following):\\n\"));\n-\t\t\tfor (i = 0; i < states.heads.nr; i++)\n-\t\t\t\tprintf(\"    %s\\n\", states.heads.items[i].string);\n+\t\t\tfor (i = 0; i < info.states.heads.nr; i++)\n+\t\t\t\tprintf(\"    %s\\n\", info.states.heads.items[i].string);\n \t\t}\n \n \t\t/* remote branch info */\n \t\tinfo.width = 0;\n-\t\tfor_each_string_list(&states.new_refs, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.tracked, add_remote_to_show_info, &info);\n-\t\tfor_each_string_list(&states.stale, add_remote_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.new_refs, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.tracked, add_remote_to_show_info, &info);\n+\t\tfor_each_string_list(&info.states.stale, add_remote_to_show_info, &info);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Remote branch:%s\",\n \t\t\t\t     \"  Remote branches:%s\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_remote_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_remote_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git pull info */\n \t\tinfo.width = 0;\n \t\tinfo.any_rebase = 0;\n \t\tfor_each_string_list(&branch_list, add_local_to_show_info, &info);\n-\t\tif (info.list->nr)\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local branch configured for 'git pull':\",\n \t\t\t\t     \"  Local branches configured for 'git pull':\",\n-\t\t\t\t     info.list->nr));\n-\t\tfor_each_string_list(info.list, show_local_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\t\t\t     info.list.nr));\n+\t\tfor_each_string_list(&info.list, show_local_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n \t\t/* git push info */\n-\t\tif (states.remote->mirror)\n+\t\tif (info.states.remote->mirror)\n \t\t\tprintf_ln(_(\"  Local refs will be mirrored by 'git push'\"));\n \n \t\tinfo.width = info.width2 = 0;\n-\t\tfor_each_string_list(&states.push, add_push_to_show_info, &info);\n-\t\tQSORT(info.list->items, info.list->nr, cmp_string_with_push);\n-\t\tif (info.list->nr)\n+\t\tfor_each_string_list(&info.states.push, add_push_to_show_info, &info);\n+\t\tQSORT(info.list.items, info.list.nr, cmp_string_with_push);\n+\t\tif (info.list.nr)\n \t\t\tprintf_ln(Q_(\"  Local ref configured for 'git push'%s:\",\n \t\t\t\t     \"  Local refs configured for 'git push'%s:\",\n-\t\t\t\t     info.list->nr),\n+\t\t\t\t     info.list.nr),\n \t\t\t\t  no_query ? _(\" (status not queried)\") : \"\");\n-\t\tfor_each_string_list(info.list, show_push_info_item, &info);\n-\t\tstring_list_clear(info.list, 0);\n+\t\tfor_each_string_list(&info.list, show_push_info_item, &info);\n+\t\tstring_list_clear(&info.list, 0);\n \n-\t\tfree_remote_ref_states(&states);\n+\t\tfree_remote_ref_states(&info.states);\n \t}\n \n \treturn result;\n-- \n2.33.0.1380.g193143c62ce\n\n"},{"id":"437787","messageId":"patch-v4-3.5-266948e604c-20211002T201434Z-avarab@gmail.com","threadId":"56591","inReplyTo":"cover-v4-0.5-00000000000-20211002T201434Z-avarab@gmail.com","subject":"[PATCH v4 3/5] urlmatch.[ch]: add and use URLMATCH_CONFIG_INIT","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2021-10-02T20:16:15Z","receivedAt":"2021-10-02T20:16:40Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Change the initialization pattern of \"struct urlmatch_config\" to use\nan *_INIT macro and designated initializers. Right now there's no\nother \"struct\" member of \"struct urlmatch_config\" which would require\nits own *_INIT, but it's good practice not to assume that. Let's also\nchange this to a designated initializer while we're at it.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n builtin/config.c | 2 +-\n credential.c     | 2 +-\n http.c           | 2 +-\n urlmatch.h       | 4 ++++\n 4 files changed, 7 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/config.c b/builtin/config.c\nindex 865fddd6ce8..542d8d02b2b 100644\n--- a/builtin/config.c\n+++ b/builtin/config.c\n@@ -575,7 +575,7 @@ static int get_urlmatch(const char *var, const char *url)\n \tint ret;\n \tchar *section_tail;\n \tstruct string_list_item *item;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct string_list values = STRING_LIST_INIT_DUP;\n \n \tconfig.collect_fn = urlmatch_collect_fn;\ndiff --git a/credential.c b/credential.c\nindex 000ac7a8d43..e7240f3f636 100644\n--- a/credential.c\n+++ b/credential.c\n@@ -105,7 +105,7 @@ static int match_partial_url(const char *url, void *cb)\n static void credential_apply_config(struct credential *c)\n {\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \tstruct strbuf url = STRBUF_INIT;\n \n \tif (!c->host)\ndiff --git a/http.c b/http.c\nindex d7c20493d7f..da12471c242 100644\n--- a/http.c\n+++ b/http.c\n@@ -990,7 +990,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)\n \tchar *low_speed_limit;\n \tchar *low_speed_time;\n \tchar *normalized_url;\n-\tstruct urlmatch_config config = { STRING_LIST_INIT_DUP };\n+\tstruct urlmatch_config config = URLMATCH_CONFIG_INIT;\n \n \tconfig.section = \"http\";\n \tconfig.key = NULL;\ndiff --git a/urlmatch.h b/urlmatch.h\nindex 6ff42f81b0c..34a3ba6d197 100644\n--- a/urlmatch.h\n+++ b/urlmatch.h\n@@ -66,6 +66,10 @@ struct urlmatch_config {\n \tint (*fallback_match_fn)(const char *url, void *cb);\n };\n \n+#define URLMATCH_CONFIG_INIT { \\\n+\t.vars = STRING_LIST_INIT_DUP, \\\n+}\n+\n int urlmatch_config_entry(const char *var, const char *value, void *cb);\n \n #endif /* URL_MATCH_H */\n-- \n2.33.0.1380.g193143c62ce\n\n"}]}