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

Re: [PATCH v2] diff: Fix modified lines stats with --stat and --numstat

From
Junio C Hamano <gitster@pobox.com>
Date
Sep 21, 2020, 21:51 UTC
Message-ID
<xmqqft7aer3a.fsf@gitster.c.googlers.com>
In-Reply-To
<20200921192630.GA2399334@coredump.intra.peff.net>
Jeff King <peff@peff.net> writes:
Show 23 quoted lines
> For diffstat, though, it seems like a waste of time; we don't care what
> the object hash is. I.e., if we were to do this:
>
> diff --git a/diff.c b/diff.c
> index 16eeaf6645..1934af29a5 100644
> --- a/diff.c
> +++ b/diff.c
> @@ -4564,9 +4564,6 @@ static void run_diffstat(struct diff_filepair *p, struct diff_options *o,
>  	if (o->prefix_length)
>  		strip_prefix(o->prefix_length, &name, &other);
>  
> -	diff_fill_oid_info(p->one, o->repo->index);
> -	diff_fill_oid_info(p->two, o->repo->index);
> -
>  	builtin_diffstat(name, other, p->one, p->two,
>  			 diffstat, o, p);
>  }
>
> then everything seems to work fine _except_ a "git diff --stat
> --no-index", exactly because it hits this "same_contents" check we've
> been discussing. And once that is fixed properly (to handle any case
> where we have no oid, not just when the stdin flag is set), then perhaps
> it is worth doing.
Show 16 quoted lines
> Or perhaps not. Even if we have to memcmp sometimes in
> builtin_diffstat(), it would be faster than computing the individual
> hashes. But it may not be measurably so, and it would be no difference
> for the common case of filespecs for which we do know the oid for free.
> I also suspect we'd need to be a little smarter about combined formats
> (e.g., "--stat --patch" might as well compute the oid as early as
> possible, since we'll need it eventually for the patch; but we'd hit the
> call in builtin_diffstat() before the one in run_diff()).
>
>> But there are paths for which oid cannot be computed without
>> destroying their contents.  Such paths are marked by the function
>> with null_oid.
>
> I'm not clear how computing the oid destroys the contents. We have them
> in an in-memory buffer at this point, don't we? So we _could_ generate
> an oid even for stdin, like this:

Yes, yes yes. That is the "best" (which later retracted) approach I suggested in the same message, but it would end up filling a real-looking object name for working tree side of diff-files, which has a far larger consequence we need to think about and consumes more brain cycles than warranted here, I would think.

Show 22 quoted lines
>> Summarizing the above, I think the second best fix is this (which
>> means that the posted patch is the third best):
>> 
>> 	/*
>> 	 * diff_fill_oid_info() marked one/two->oid with null_oid
>> 	 * for a path whose oid is not available.  Disable early
>> 	 * return optimization for them.
>> 	 */
>> 	if (oideq(&one->oid, &null_oid) || oideq(&two->oid, &null_oid))
>> 		same_contents = 0; /* could be different */
>> 	else if (oideq(&one->oid, &two->oid))
>> 		same_contents = 1; /* definitely the same */
>> 	else
>> 		same_contents = 0; /* definitely different */
>
> This is the direction I was getting at in my earlier emails, except that
> I imagined that first conditional could be checking:
>
>   if (!one->oid_valid || !two->oid_valid)
>
> but I was surprised to see that diff_fill_oid_info() does not set
> oid_valid. Is that a bug?

I do not think so. oid_valid refers to the state during the collection phase (those who called diff_addremove() etc.) and updating it in diff_fill_oid_info() would lose information. Maybe nobody looks at the bit at this late in the processing chain these days, in which case we can start flipping the bit there, but I offhand do not know what consequences such a change would trigger.

Show 6 quoted lines
> I also imagined that we'd have to determine right then whether the
> contents are actually different or not with a memcmp(), to avoid
> emitting a "0 changes" line, but we do handle that case within the
> "!same_contents" conditional. See the comment starting with "Omit
> diffstats..." added recently by 1cf3d5db9b (diff: teach --stat to ignore
> uninteresting modifications, 2020-08-20).

Yes, we are essentially on the same page---same_contents bit is merely an optimization to decide cheaply when we do not have to do xdl, but the codepath that does the xdl must be prepared to deal with the "we thought they are different, but after all they turn out to be equivalent" case. Therefore false positive to declare two different things as same cannot be tolerated, but false negative to declare two things that are the same as !same_contents is fine.

Previous: Jeff KingNext: Jeff King
Message 46 of 50 in “Allow passing pipes to diff --no-index + bugfix”
  1. Thomas Guyot-SionnestSep 18, 2020
  2. 2/2 Allow passing pipes for input pipes to diff --no-indexThomas Guyot-Sionnest, Sep 18, 2020
  3. Taylor BlauSep 18, 2020
  4. Thomas Guyot-SionnestSep 18, 2020
  5. Jeff KingSep 18, 2020
  6. Jeff KingSep 18, 2020
  7. Thomas Guyot-SionnestSep 18, 2020
  8. Junio C HamanoSep 18, 2020
  9. Jeff KingSep 18, 2020
  10. Thomas GuyotSep 20, 2020
  11. Jeff KingSep 21, 2020
  12. Junio C HamanoSep 21, 2020
  13. Taylor BlauSep 18, 2020
  14. Jeff KingSep 18, 2020
  15. Jeff KingSep 18, 2020
  16. Taylor BlauSep 18, 2020
  17. brian m. carlsonSep 18, 2020
  18. 1/2 diff: Fix modified lines stats with --stat and --numstatThomas Guyot-Sionnest, Sep 18, 2020
  19. Taylor BlauSep 18, 2020
  20. Thomas Guyot-SionnestSep 18, 2020
  21. Jeff KingSep 18, 2020
  22. Thomas Guyot-SionnestSep 18, 2020
  23. Thomas GuyotSep 20, 2020
  24. Jeff KingSep 18, 2020
  25. Thomas Guyot-SionnestSep 18, 2020
  26. Junio C HamanoSep 18, 2020
  27. Johannes SchindelinSep 23, 2020
  28. Junio C HamanoSep 23, 2020
  29. Johannes SchindelinSep 23, 2020
  30. Thomas GuyotSep 24, 2020
  31. diff: Fix modified lines stats with --stat and --numstatThomas Guyot-Sionnest, Sep 24, 2020
  32. diff: Fix modified lines stats with --stat and --numstatThomas Guyot-Sionnest, Sep 24, 2020
  33. Junio C HamanoSep 24, 2020
  34. Thomas GuyotSep 24, 2020
  35. Junio C HamanoSep 24, 2020
  36. Junio C HamanoSep 24, 2020
  37. Johannes SchindelinSep 23, 2020
  38. diff: Fix modified lines stats with --stat and --numstatThomas Guyot-Sionnest, Sep 20, 2020
  39. Taylor BlauSep 20, 2020
  40. Thomas GuyotSep 20, 2020
  41. Junio C HamanoSep 20, 2020
  42. Junio C HamanoSep 20, 2020
  43. Junio C HamanoSep 20, 2020
  44. Junio C HamanoSep 20, 2020
  45. Jeff KingSep 21, 2020
  46. Junio C HamanoSep 21, 2020
  47. Jeff KingSep 21, 2020
  48. Junio C HamanoSep 21, 2020
  49. Junio C HamanoSep 18, 2020
  50. Thomas Guyot-SionnestSep 18, 2020

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.