On Wed, Jun 14, 2017 at 2:48 AM, Jonathan Nieder <jrnieder@xxxxxxxxx> wrote: >> diff --git a/remote.h b/remote.h >> index 924881169..9ad8c1085 100644 >> --- a/remote.h >> +++ b/remote.h >> @@ -164,6 +164,7 @@ struct ref *ref_remove_duplicates(struct ref *ref_map); >> >> int valid_fetch_refspec(const char *refspec); >> struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec); >> +void add_and_parse_fetch_refspec(struct remote *remote, const char *refspec); > I'm tempted to say that this one should be named add_fetch_refspec (or > something like remote_add_refspec) --- this is the only way to add a > fetch refspec in the public remote API, and the fact that it parses is > an implementation detail. The private add_fetch_refpsec that builds > the fetch_refspec as preparation for parsing them in a batch is not > part of the exported API. I kind of agree, but ... First, there is an add_push_refspec() function as well, which, just like its fetch counterpart, doesn't parse the given refspec, only appends it to remote->push_refspec. Changing add_fetch_refspec() to parse, too, would break this symmetry. Furthermore, at the moment we have both remote->fetch_refspec (for strings) and remote->fetch (for parsed refspecs), and parsing a refspec die()s if it's bogus, therefore I think that parsing is not an implementation detail that should be hidden. > The caller adds one refspec right after calling remote_get. I'm > starting to wonder if this could be done more simply by having a > variant of remote_get that allows naming an additional refspec, so > that remote->fetch could be immutable after construction like it was > before. What do you think? That's such a very specific and narrow use case that I don't think it justifies a dedicated function. I don't think remote->fetch should be immutable; I think remote->{fetch,push}_refspec and the lazy parsing of refspecs should go away. Cleaning up this corner of the remote API is beyond the scope of this patch series. > [...] >> + /* Not free_refspecs(), as we copied its pointers above */ >> + free(rs); > > Allocating an array to put the parsed refspec in and then freeing it > seems wasteful. Should parse_refspec_internal be changed to take an > output parameter so it can put the refspec into remote->fetch > directly? No, I found that extracting the huge body of its loop into a helper function that fills an output parameter is much more useful. > [...] >> +++ b/builtin/clone.c > [...] >> @@ -848,16 +853,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix) >> const struct ref *our_head_points_at; >> struct ref *mapped_refs; >> const struct ref *ref; >> - struct strbuf key = STRBUF_INIT, value = STRBUF_INIT; >> + struct strbuf key = STRBUF_INIT, default_refspec = STRBUF_INIT; > > nit: since it's not part of a key, value pair like value, > default_refspec should probably go on its own line. Fun fact: they were never part of a key-value pair. While 'key' is indeed the name of a configuration variable, 'value' is not the value of that configuration variable, or any other configuration variable for that matter. Best, Gábor