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

Re: [RFC PATCH] diff: only prefetch for certain output formats

From
Jeff King <peff@peff.net>
Date
Jan 29, 2020, 05:09 UTC
Message-ID
<20200129050935.GA601903@coredump.intra.peff.net>
In-Reply-To
<20200128213508.31661-1-jonathantanmy@google.com>
On Tue, Jan 28, 2020 at 01:35:08PM -0800, Jonathan Tan wrote:
Show 12 quoted lines
> Running "git status" on a partial clone that was cloned with
> "--no-checkout", like this:
> 
>   git clone --no-checkout --filter=blob:none <url> foo
>   git -C foo status
> 
> results in an unnecessary lazy fetch. This is because of commit
> 7fbbcb21b1 ("diff: batch fetching of missing blobs", 2019-04-08), which
> optimized "diff" by prefetching, but inadvertently affected at least one
> command ("status") that does not need prefetching. These 2 cases can be
> distinguished by looking at output_format; the former uses
> DIFF_FORMAT_PATCH and the latter uses DIFF_FORMAT_CALLBACK.

Sometimes "status" does need the actual blobs, if it's going to do inexact rename detection. Likewise if break-detection is turned on, though I don't think anything does it by default, and there's (I don't think) any config option to enable it.

So something like "git log --name-status -B -M" would probably regress from this (though only in speed, of course; I do think we can play a little loose with heuristics since we'd generate the correct answer either way).

You could get pretty specific by putting logic inside diffcore_rename(), which would know if anything is left over after exact rename detection, but I suspect just checking:

  (options->break_opt != -1 || options->detect_rename)
in diffcore_std() would be OK in practice.
> (Note that other callers that use DIFF_FORMAT_CALLBACK will also lose
> prefetching. I haven't investigated enough to see if this is a net
> benefit or drawback, but I think this will need to be done on a
> caller-by-caller basis and can be done in the future.)

We can't know what the caller is going to do with a DIFF_FORMAT_CALLBACK, so I think it makes sense to avoid pre-fetching in that case. It might be nice, though, if that pre-fetch loop in diffcore_std() were pulled into a helper function, so they could just call:

  diffcore_prefetch(&options);

or something. I'm OK to wait on that until one of the FORMAT_CALLBACK users needs it, though.

> Points of discussion I can think of:
> 
>  - Is the whitelist of output_format constants the best?

I think it could be pared down a bit. For example, --raw doesn't need the blobs (aside from renames, etc, above). I think the same is true of --summary. You've already omitted --name-status and --name-only, which makes sense.

I think --dirstat, even though it is only showing per-file info, still relies on the line-level stat info. So it should stay.

>  - Should we just have the callers pass a prefetch boolean arg instead
>    of trying to guess it ourselves? I'm leaning towards no since I think
>    we should avoid options unless they are necessary.

If we can avoid it, I think we should. It makes sense to me to try to tweak the heuristics as much as possible in this central code. If there's a case that does the wrong thing, then we can decide whether the heuristics can be improved, or if we need more information from the caller.

-Peff
Previous: Jonathan TanNext: Jonathan Tan
Message 2 of 8 in “diff: only prefetch for certain output formats”
  1. diff: only prefetch for certain output formatsJonathan Tan, Jan 28, 2020
  2. Jeff KingJan 29, 2020
  3. Jonathan TanJan 30, 2020
  4. Jeff KingJan 30, 2020
  5. Jonathan TanJan 30, 2020
  6. Jeff KingJan 31, 2020
  7. Junio C HamanoJan 31, 2020
  8. Jeff KingFeb 1, 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.