git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH 1/2] Add fetch.updateHead option

From
Patrick Steinhardt <ps@pks.im>
Date
Apr 5, 2023, 10:15 UTC
Message-ID
<ZC1KW3oN1JgrvTfn@ncase>
In-Reply-To
<230405.86fs9evfte.gmgdl@evledraar.gmail.com>
On Wed, Apr 05, 2023 at 11:16:12AM +0200, Ævar Arnfjörð Bjarmason wrote:
> On Tue, Apr 04 2023, Felipe Contreras wrote:
[snip]
Show 29 quoted lines
> > @@ -1579,6 +1584,47 @@ static int backfill_tags(struct transport *transport,
> >  	return retcode;
> >  }
> >  
> > +static void update_head(int config, const struct ref *head, const struct remote *remote)
> 
> Here you pass a "const struct remote".
> 
> > +{
> > +	char *ref, *target;
> > +	const char *r;
> > +	int flags;
> > +
> > +	if (!head || !head->symref || !remote)
> > +		return;
> > +
> > +	ref = apply_refspecs((struct refspec *)&remote->fetch, "refs/heads/HEAD");
> > +	target = apply_refspecs((struct refspec *)&remote->fetch, head->symref);
> 
> But here we end up with this cast, as it's not const after all, we're
> modifying it.
> 
> I think this sort of thing makes the code harder to read & reason about,
> and adds cast verbosity.
> 
> If you want to clearly communicate that the "remote->name" and
> "remote->mirror" you're using are "const" I think a better way to do
> this is to pass those as explicit parameters to this new static helper
> function, and then just pass a "struct refspec *fetch_rs" directly.

I think the underlying problem is that `apply_refspecs()` and transitively called functions expect the argument to be non-const even though they never modify it.

So maybe the proper way to handle this would be to add a preparatory patch that constifies the parameter. Something like what I've attached to the end of this mail.

Patrick
-- >8 --
diff --git a/remote.c b/remote.c
index b04e5da338..1752c391c3 100644
--- a/remote.c
+++ b/remote.c
@@ -851,7 +851,7 @@ static int refspec_match(const struct refspec_item *refspec,
 	return !strcmp(refspec->src, name);
 }
 
-int omit_name_by_refspec(const char *name, struct refspec *rs)
+int omit_name_by_refspec(const char *name, const struct refspec *rs)
 {
 	int i;
 
@@ -880,7 +880,7 @@ struct ref *apply_negative_refspecs(struct ref *ref_map, struct refspec *rs)
 	return ref_map;
 }
 
-static int query_matches_negative_refspec(struct refspec *rs, struct refspec_item *query)
+static int query_matches_negative_refspec(const struct refspec *rs, struct refspec_item *query)
 {
 	int i, matched_negative = 0;
 	int find_src = !query->src;
@@ -968,7 +968,7 @@ static void query_refspecs_multiple(struct refspec *rs,
 	}
 }
 
-int query_refspecs(struct refspec *rs, struct refspec_item *query)
+int query_refspecs(const struct refspec *rs, struct refspec_item *query)
 {
 	int i;
 	int find_src = !query->src;
@@ -1002,7 +1002,7 @@ int query_refspecs(struct refspec *rs, struct refspec_item *query)
 	return -1;
 }
 
-char *apply_refspecs(struct refspec *rs, const char *name)
+char *apply_refspecs(const struct refspec *rs, const char *name)
 {
 	struct refspec_item query;
 
diff --git a/remote.h b/remote.h
index 5b38ee20b8..cd3c1439ab 100644
--- a/remote.h
+++ b/remote.h
@@ -253,7 +253,7 @@ struct ref *ref_remove_duplicates(struct ref *ref_map);
  * Check whether a name matches any negative refspec in rs. Returns 1 if the
  * name matches at least one negative refspec, and 0 otherwise.
  */
-int omit_name_by_refspec(const char *name, struct refspec *rs);
+int omit_name_by_refspec(const char *name, const struct refspec *rs);
 
 /*
  * Remove all entries in the input list which match any negative refspec in
@@ -261,8 +261,8 @@ int omit_name_by_refspec(const char *name, struct refspec *rs);
  */
 struct ref *apply_negative_refspecs(struct ref *ref_map, struct refspec *rs);
 
-int query_refspecs(struct refspec *rs, struct refspec_item *query);
-char *apply_refspecs(struct refspec *rs, const char *name);
+int query_refspecs(const struct refspec *rs, struct refspec_item *query);
+char *apply_refspecs(const struct refspec *rs, const char *name);
 
 int check_push_refs(struct ref *src, struct refspec *rs);
 int match_push_refs(struct ref *src, struct ref **dst,
Previous: Ævar Arnfjörð BjarmasonNext: Felipe Contreras
Message 4 of 9 in “Add fetch.updateHead option”
  1. 0/2 Add fetch.updateHead optionFelipe Contreras, Apr 5, 2023
  2. 1/2 Add fetch.updateHead optionFelipe Contreras, Apr 5, 2023
  3. Ævar Arnfjörð BjarmasonApr 5, 2023
  4. Patrick SteinhardtApr 5, 2023
  5. Felipe ContrerasApr 5, 2023
  6. Ævar Arnfjörð BjarmasonApr 6, 2023
  7. Felipe ContrerasApr 7, 2023
  8. Ævar Arnfjörð BjarmasonApr 5, 2023
  9. 2/2 fetch: add support for HEAD update on mirrorsFelipe Contreras, Apr 5, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.