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

Re: [RFC/PATCH] patch-ids: check modified paths before calculating diff

From
Jeff King <peff@peff.net>
Date
May 29, 2013, 06:20 UTC
Message-ID
<20130529062007.GA11955@sigill.intra.peff.net>
In-Reply-To
<a7088a74742b71a01423f3ddc1a6c7fd89474ed8.1368969438.git.john@keeping.me.uk>
On Sun, May 19, 2013 at 02:17:35PM +0100, John Keeping wrote:
Show 9 quoted lines
> When using "git cherry" or "git log --cherry-pick" we often have a small
> number of commits on one side and a large number on the other.  In
> revision.c::cherry_pick_list we store the patch IDs for the small side
> before comparing the large side to this.
> 
> In this case, it is likely that only a small number of paths are touched
> by the commits on the smaller side of the range and by storing these we
> can ignore many commits on the other side before unpacking blobs and
> diffing them.
There are two observations that make your scheme work:
  1. For something like --cherry-pick, we do not even care about the
     actual patch-ids, only whether there are matches from the left and
     right sides.
  2. Comparing the sets of paths touched by two commits is often
     sufficient to realize they do not have the same patch-ids.

But I think those observations mean we can do even better than calculating the real patch-id for the small side at all.

Imagine we have both "loose" and "strict" patch-ids, where the loose one is much faster to compute, and has that property that a match _might_ mean we have the same strict patch-id, but a non-match means we definitely do not have the same strict patch-id.

I think such a loose patch-id could just be a hash of the filenames that were changed by the patch (e.g., the first 32-bits of the sha1 of the concatenated filenames). Computing that should be about as expensive as a tree-diff. Per observation 2 above, if two commits do not have the same loose id, we know that they cannot possibly have the same strict id.

Then we can forget about the smaller-side and bigger-side entirely, and just do something like:

  1. Make a sorted list (or hash table) of loose ids for one side.
  2. For each commit on the other side, calculate its loose id and look
     that up in the sorted list. If no hits, we know that there is no
     match. For any hits, lazily calculate (and cache) the strict patch
     id for both sides and compare as usual.

In the best case, we compute no patch-ids at all. And even for the average case, I'd expect our lazy calculation to only have to compute a handful of ids.

-Peff
Previous: Junio C HamanoNext: Jeff King
Message 7 of 13 in “patch-ids: check modified paths before calculating diff”
  1. patch-ids: check modified paths before calculating diffJohn Keeping, May 19, 2013
  2. Jonathan NiederMay 19, 2013
  3. John KeepingMay 19, 2013
  4. Jonathan NiederMay 20, 2013
  5. John KeepingMay 20, 2013
  6. Junio C HamanoMay 20, 2013
  7. Jeff KingMay 29, 2013
  8. Jeff KingMay 29, 2013
  9. Jeff KingMay 29, 2013
  10. Junio C HamanoMay 29, 2013
  11. Jeff KingMay 29, 2013
  12. Junio C HamanoMay 29, 2013
  13. John KeepingMay 29, 2013

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.