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

Re: git commit file completion recently broke

From
Jeff King <peff@peff.net>
Date
Dec 7, 2017, 00:56 UTC
Message-ID
<20171207005639.GB1975@sigill.intra.peff.net>
In-Reply-To
<CA+P7+xpoaa5zaF13ageKKjpPKTECU6XjaRdSZy6WOP7Q0TX+yA@mail.gmail.com>
On Wed, Dec 06, 2017 at 04:38:29PM -0800, Jacob Keller wrote:
Show 19 quoted lines
> >> But nope, it looks like the culprit is f7923a5ece (diff: use
> >> skip_to_optional_val(), 2017-12-04), which switched over parsing of
> >> "--relative".
> >
> > Oh, actually, I guess I was half-right. It feeds &options->prefix as the
> > "default", meaning that we overwrite it with the empty string. I don't
> > think "--relative" works for the semantics of skip_to_optional_value,
> > since it needs:
> >
> >   --relative=foo: set prefix to "foo"
> >
> >   --relative: leave prefix untouched
> >
> > -Peff
> 
> Yep, and apparently our test suite completely lacked any tests of
> --relative on its own.
> 
> I've sent a patch to add some tests.
Great. I was also saddened by our lack of tests.
Show 6 quoted lines
> I don't know the exact best way to fix this, I guess we could just
> revert it the changes to relative... but maybe we could add or modify
> the semantics of skip_to_optional_val()?? What if it was changed so
> that it left the value alone if no value was provided? This would
> require callers to pre-set the value they want as default, but that
> would solve relative's problem.

I think that would work for this case. But just looking at others from the same series, I think they'd get pretty awkward. For instance we now have:

  else if (!strcmp(arg, "--color))
	options->use_color = 1;
  else if (skip_prefix(arg, "--color=", &arg))
	/* parse "arg" as colorbool */
which became:
  else if (skip_to_optional_val_default(arg, "--color", &arg, "always"))
	/* parse "arg" as colorbool */

How would that look with the "leave it alone instead of assigning a default" semantics? It gets pretty clumsy, because you have to pre-assign "always" to some pointer. But then we can't reuse "arg", so we end up with something more like:

  const char *color_val = "always";
  ...
  else if (skip_to_optional_val(arg, "--color", &color_val))

But we need one such "color_val" for every option we test for, and we have to set all of them up before any matches (because we don't know which one we'll actually match). Yuck.

I think we'd do better to just assign NULL when there's "=", so we can tell the difference between "--relative", "--relative=", and "--relative=foo" (all of which are distinct).

I think that's possible with the current scheme by doing:
  else if (skip_to_optional_val_default(arg, "--relative", &arg, NULL)) {
	options->flags.relative_name = 1;
	if (arg)
		options->prefix = arg;
  }

IOW, the problem isn't in the design of the skip function, but just how it was used in this particular case. I do think it may make sense for the "short" one to use NULL, like:

  skip_to_optional_val(arg, "--relative, &arg)

but maybe some other callers would be more inconvenienced (they may have to current NULL back into the empty string if they want to string "--foo" the same as "--foo=").

-Peff
Previous: Jacob KellerNext: Jacob Keller
Message 7 of 13 in “git commit file completion recently broke”
  1. Jacob KellerDec 6, 2017
  2. Jacob KellerDec 7, 2017
  3. Jacob KellerDec 7, 2017
  4. Jeff KingDec 7, 2017
  5. Jeff KingDec 7, 2017
  6. Jacob KellerDec 7, 2017
  7. Jeff KingDec 7, 2017
  8. Jacob KellerDec 7, 2017
  9. Jeff KingDec 7, 2017
  10. Christian CouderDec 7, 2017
  11. Jeff KingDec 7, 2017
  12. Junio C HamanoDec 7, 2017
  13. Jacob KellerDec 7, 2017

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.