From: Jacob Keller <jacob.e.keller@intel.com>
To: Junio C Hamano <gitster@pobox.com>
Cc: <git@vger.kernel.org>, Jacob Keller <jacob.keller@gmail.com>,
Lidong Yan <yldhome2d2@gmail.com>, Patrick Steinhardt <ps@pks.im>
Subject: Re: [PATCH v2 1/6] remote: fix tear down of struct branch and struct remote
Date: Tue, 17 Jun 2025 16:45:59 -0700 [thread overview]
Message-ID: <c61c0c6f-6d54-466b-9592-e4f3071ff7f0@intel.com> (raw)
In-Reply-To: <xmqqcyb2uhth.fsf@gitster.g>
On 6/17/2025 3:25 PM, Junio C Hamano wrote:
> Jacob Keller <jacob.e.keller@intel.com> writes:
>
>> From: Jacob Keller <jacob.keller@gmail.com>
>
> where we iterate over branch->merge[] and branch->merge_name[]
> for branch->nr times and each time we check the NULL-ness of these
> two pointers.
>
> merge_nr is only incremented inside add_merge() when merge_name[]
> array is grown by the same amount. Do we need to check for the
> NULL-ness of branch->merge_name?
>
> Near the beginning of set_merge() we allocate branch->merge[]
> only when branch->merge_nr is non-zero (the assumption seems to be
> that we accumulate in the merge_names[] while reading the config,
> so as long as branch->merge is initialized properly to NULL, it will
> never be NULL if merge_nr is not 0, no?
>
> Thanks.
Perhaps something like this might be a better solution so that we don't
need to worry about merge being NULL and tracking the difference between
merge_name and merge. Its a bit ugly still with a partially initialized
refspec_item so I am not 100% sure but I think this is overall a bit
better than the current situation:
> diff --git i/remote.h w/remote.h
> index 59033d5d82dd..0ca399e1835b 100644
> --- i/remote.h
> +++ w/remote.h
> @@ -316,8 +316,8 @@ struct branch {
>
> char *pushremote_name;
>
> - /* An array of the "merge" lines in the configuration. */
> - char **merge_name;
> + /* True if set_merge() has been called to finalize the merge array */
> + int set_merge;
>
> /**
> * An array of the struct refspecs used for the merge lines. That is,
> diff --git i/branch.c w/branch.c
> index 6d01d7d6bdb2..93f5b4e8dd9f 100644
> --- i/branch.c
> +++ w/branch.c
> @@ -230,7 +230,7 @@ static int inherit_tracking(struct tracking *tracking, const char *orig_ref)
> return -1;
> }
>
> - if (branch->merge_nr < 1 || !branch->merge_name || !branch->merge_name[0]) {
> + if (branch->merge_nr < 1 || !branch->merge || !branch->merge[0] || !branch->merge[0]->src) {
> warning(_("asked to inherit tracking from '%s', but no merge configuration is set"),
> bare_ref);
> return -1;
> @@ -238,7 +238,7 @@ static int inherit_tracking(struct tracking *tracking, const char *orig_ref)
>
> tracking->remote = branch->remote_name;
> for (i = 0; i < branch->merge_nr; i++)
> - string_list_append(tracking->srcs, branch->merge_name[i]);
> + string_list_append(tracking->srcs, branch->merge[i]->src);
> return 0;
> }
>
> diff --git i/builtin/pull.c w/builtin/pull.c
> index a1ebc6ad3328..f4556ae155ce 100644
> --- i/builtin/pull.c
> +++ w/builtin/pull.c
> @@ -487,7 +487,7 @@ static void NORETURN die_no_merge_candidates(const char *repo, const char **refs
> } else
> fprintf_ln(stderr, _("Your configuration specifies to merge with the ref '%s'\n"
> "from the remote, but no such ref was fetched."),
> - *curr_branch->merge_name);
> + curr_branch->merge[0]->src);
> exit(1);
> }
>
> diff --git i/remote.c w/remote.c
> index 706c25af0c27..1850e8fa4e42 100644
> --- i/remote.c
> +++ w/remote.c
> @@ -177,9 +177,15 @@ static void remote_clear(struct remote *remote)
>
> static void add_merge(struct branch *branch, const char *name)
> {
> - ALLOC_GROW(branch->merge_name, branch->merge_nr + 1,
> + struct refspec_item *merge;
> +
> + ALLOC_GROW(branch->merge, branch->merge_nr + 1,
> branch->merge_alloc);
> - branch->merge_name[branch->merge_nr++] = xstrdup(name);
> +
> + merge = xcalloc(1, sizeof(*merge));
> + merge->src = xstrdup(name);
> +
> + branch->merge[branch->merge_nr++] = merge;
> }
>
> struct branches_hash_key {
> @@ -250,22 +256,23 @@ static struct branch *make_branch(struct remote_state *remote_state,
> return ret;
> }
>
> +static void merge_clear(struct branch *branch)
> +{
> + for (int i = 0; i < branch->merge_nr; i++) {
> + refspec_item_clear(branch->merge[i]);
> + free(branch->merge[i]);
> + }
> + free(branch->merge);
> + branch->merge_nr = 0;
> +}
> +
> static void branch_release(struct branch *branch)
> {
> free((char *)branch->name);
> free((char *)branch->refname);
> free(branch->remote_name);
> free(branch->pushremote_name);
> - for (int i = 0; i < branch->merge_nr; i++) {
> - if (branch->merge) {
> - refspec_item_clear(branch->merge[i]);
> - free(branch->merge[i]);
> - }
> - if (branch->merge_name)
> - free(branch->merge_name[i]);
> - }
> - free(branch->merge);
> - free(branch->merge_name);
> + merge_clear(branch);
> }
>
> static struct rewrite *make_rewrite(struct rewrites *r,
> @@ -700,7 +707,7 @@ char *remote_ref_for_branch(struct branch *branch, int for_push)
> if (branch) {
> if (!for_push) {
> if (branch->merge_nr) {
> - return xstrdup(branch->merge_name[0]);
> + return xstrdup(branch->merge[0]->src);
> }
> } else {
> char *dst;
> @@ -1738,32 +1745,30 @@ static void set_merge(struct repository *repo, struct branch *ret)
>
> if (!ret)
> return; /* no branch */
> - if (ret->merge)
> + if (ret->set_merge)
> return; /* already run */
> if (!ret->remote_name || !ret->merge_nr) {
> /*
> * no merge config; let's make sure we don't confuse callers
> * with a non-zero merge_nr but a NULL merge
> */
> - ret->merge_nr = 0;
> + merge_clear(ret);
> return;
> }
> + ret->set_merge = 1;
>
> remote = remotes_remote_get(repo, ret->remote_name);
>
> - CALLOC_ARRAY(ret->merge, ret->merge_nr);
> for (i = 0; i < ret->merge_nr; i++) {
> - ret->merge[i] = xcalloc(1, sizeof(**ret->merge));
> - ret->merge[i]->src = xstrdup(ret->merge_name[i]);
> if (!remote_find_tracking(remote, ret->merge[i]) ||
> strcmp(ret->remote_name, "."))
> continue;
> - if (repo_dwim_ref(repo, ret->merge_name[i],
> - strlen(ret->merge_name[i]), &oid, &ref,
> + if (repo_dwim_ref(repo, ret->merge[i]->src,
> + strlen(ret->merge[i]->src), &oid, &ref,
> 0) == 1)
> ret->merge[i]->dst = ref;
> else
> - ret->merge[i]->dst = xstrdup(ret->merge_name[i]);
> + ret->merge[i]->dst = xstrdup(ret->merge[i]->src);
> }
> }
>
next prev parent reply other threads:[~2025-06-17 23:46 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-17 21:30 [PATCH v2 0/6] submodule: improve remote lookup logic Jacob Keller
2025-06-17 21:30 ` [PATCH v2 1/6] remote: fix tear down of struct branch and struct remote Jacob Keller
2025-06-17 22:25 ` Junio C Hamano
2025-06-17 23:25 ` Jacob Keller
2025-06-18 1:30 ` Junio C Hamano
2025-06-18 11:20 ` Junio C Hamano
2025-06-18 17:41 ` Jacob Keller
2025-06-18 2:44 ` Lidong Yan
2025-06-17 23:45 ` Jacob Keller [this message]
2025-06-17 21:30 ` [PATCH v2 2/6] dir: move starts_with_dot(_dot)_slash to dir.h Jacob Keller
2025-06-17 21:30 ` [PATCH v2 3/6] remote: remove the_repository from some functions Jacob Keller
2025-06-17 22:46 ` Junio C Hamano
2025-06-17 23:19 ` Jacob Keller
2025-06-17 21:30 ` [PATCH v2 4/6] submodule--helper: improve logic for fallback remote name Jacob Keller
2025-06-17 23:12 ` Junio C Hamano
2025-06-17 23:21 ` Jacob Keller
2025-06-17 21:30 ` [PATCH v2 5/6] submodule: move get_default_remote_submodule() Jacob Keller
2025-06-17 21:30 ` [PATCH v2 6/6] submodule: look up remotes by URL first Jacob Keller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c61c0c6f-6d54-466b-9592-e4f3071ff7f0@intel.com \
--to=jacob.e.keller@intel.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jacob.keller@gmail.com \
--cc=ps@pks.im \
--cc=yldhome2d2@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).