Re: [PATCH v3 8/8] fetch: introduce machine-parseable "porcelain" output format
- From
Patrick Steinhardt <ps@pks.im>
- Date
- May 9, 2023, 12:41 UTC
- Message-ID
- <ZFo_hHiwRU_7yDsg@ncase>
- In-Reply-To
- <kl6lild21jbd.fsf@chooglen-macbookpro.roam.corp.google.com>
On Mon, May 08, 2023 at 04:42:46PM -0700, Glen Choo wrote:
Show 26 quoted lines
> This version looks great! I only have minor comments. > > Patrick Steinhardt <ps@pks.im> writes: > > > A notable ommission here is that the output format does not include the > > remote from which a reference was fetched, which might be important > > information especially in the context of multi-remote fetches. But as > > such a format would require us to print the remote for every single > > reference update due to parallelizable fetches it feels wasteful for the > > most likely usecase, which is when fetching from a single remote. > > > > In a similar spirit, a second restriction is that this cannot be used > > with `--recurse-submodules`. This is because any reference updates would > > be ambiguous without also printing the repository in which the update > > happens. > > > > Considering that both multi-remote and submodule fetches are rather > > niche and likely not going to be useful for the majority of usecases > > these omissions feel acceptable. If usecases for either of these come up > > in the future though it is easy enough to add a new "porcelain-v2" > > format that adds this information. > > As a point of clarification, I think these options aren't niche in > themselves, but they are more user-facing, so using them _in conjunction > with_ --porcelain is probably pretty niche, so I think this is okay for > now.
Yeah, that's what I indeed intended to say. Will clarify.
[snip]
Show 22 quoted lines
> > @@ -1830,6 +1857,7 @@ struct parallel_fetch_state {
> > const char **argv;
> > struct string_list *remotes;
> > int next, result;
> > + enum display_format format;
> > };
> >
> > static int fetch_next_remote(struct child_process *cp,
> > @@ -1849,7 +1877,7 @@ static int fetch_next_remote(struct child_process *cp,
> > strvec_push(&cp->args, remote);
> > cp->git_cmd = 1;
> >
> > - if (verbosity >= 0)
> > + if (verbosity >= 0 && state->format != DISPLAY_FORMAT_PORCELAIN)
> > printf(_("Fetching %s\n"), remote);
> >
> > return 1;
>
> Here and elsewhere, I wonder if it's clearer to name the variable
> "porcelain" and separate it from "enum display_format". Then we can
> check "porcelain" directly instead of using "format ==
> DISPLAY_FORMAT_PORCELAIN" as a proxy...For now I'd like to keep this as-is: it's easier to keep track of this when there is only a single variable that keeps track of the output format. But if we were to add additional porcelain formats in the future I agree that it would be nice to refactor the code as you propose.
I'd rather keep the simpler version for now though where we only have a single state to worry about.
Show 25 quoted lines
> > +static int opt_parse_porcelain(const struct option *opt, const char *arg, int unset)
> > +{
> > + enum display_format *format = opt->value;
> > + *format = DISPLAY_FORMAT_PORCELAIN;
> > + return 0;
> > +}
> > +
> > int cmd_fetch(int argc, const char **argv, const char *prefix)
> > {
> > const char *bundle_uri;
> > @@ -2104,6 +2140,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
> > PARSE_OPT_OPTARG, option_fetch_parse_recurse_submodules),
> > OPT_BOOL(0, "dry-run", &dry_run,
> > N_("dry run")),
> > + OPT_CALLBACK_F(0, "porcelain", &display_format, NULL, N_("machine-readable output"),
> > + PARSE_OPT_NOARG|PARSE_OPT_NONEG, opt_parse_porcelain),
> > OPT_BOOL(0, "write-fetch-head", &write_fetch_head,
> > N_("write fetched references to the FETCH_HEAD file")),
> > OPT_BOOL('k', "keep", &keep, N_("keep downloaded pack")),
>
> e.g. since we are reusing the "display_format" variable, we need to make
> sure we parse "--porcelain" after we read "fetch.output". I
> double-checked to make sure we were doing the right thing, though it
> would be nice to not have to worry about those sorts of things. This
> shouldn't hold up the series though.In fact it is the other way round: we parse `--porcelain` first and then only read "fetch.output" in the case where the `display_format` variable is still set to `DISPLAY_FORMAT_UNKNOWN`.
So in the end there is no fragile order dependence here -- it would work just the same regardless of whether we first parse command line options or the configuration.
Show 20 quoted lines
> > +test_expect_success 'fetch porcelain with multiple remotes' ' > > + test_when_finished "rm -rf porcelain" && > > + > > + git clone . porcelain && > > + git -C porcelain remote add second-remote "$PWD" && > > + git -C porcelain fetch second-remote && > > + > > + test_commit --no-tag multi-commit && > > + old_commit=$(git rev-parse HEAD~) && > > + new_commit=$(git rev-parse HEAD) && > > + > > + cat >expect <<-EOF && > > + $old_commit $new_commit refs/remotes/origin/force-updated > > + $old_commit $new_commit refs/remotes/second-remote/force-updated > > + EOF > > The only thing in this test that relies on the previous test is that > HEAD is pointing to "force-updated", and it's hard to tell where HEAD is > since the previous test is so long. Could we create a new branch > instead?
Makes sense, done.
Patrick