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

[PATCH 2/2] diff: don't retrieve binary blobs for diffstat

From
Jeff King <peff@peff.net>
Date
Feb 19, 2011, 08:16 UTC
Message-ID
<20110219081631.GB18056@sigill.intra.peff.net>
In-Reply-To
<20110219080307.GA18039@sigill.intra.peff.net>

We only need the size, which is much cheaper to get, especially if it is a big binary file.

Signed-off-by: Jeff King <peff@peff.net>
---
This of course is only really helpful if you have marked the files as
binary via gitattributes, since otherwise we have to pull in the blob to
find out that it's binary. :)

But in my real-world photo/video repo, which has media files marked via gitattributes as binary (but to textconv exif tags, of course). The commit in question has 26 files totalling 88 megabytes.

  $ time git show --stat >old
  real    0m0.428s
  user    0m0.392s
  sys     0m0.032s
  $ time git.jk.diffstat-binary show --stat >new
  real    0m0.005s
  user    0m0.004s
  sys     0m0.000s
  $ cmp old new && echo ok
  ok
8500% speedup isn't too bad. :)
 diff.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/diff.c b/diff.c
index 2ac0fe9..6640857 100644
--- a/diff.c
+++ b/diff.c
@@ -245,6 +245,15 @@ static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one)
 	return 0;
 }
 
+/* like fill_mmfile, but only for size, so we can avoid retrieving blob */
+static unsigned long diff_filespec_size(struct diff_filespec *one)
+{
+	if (!DIFF_FILE_VALID(one))
+		return 0;
+	diff_populate_filespec(one, 1);
+	return one->size;
+}
+
 static int count_trailing_blank(mmfile_t *mf, unsigned ws_rule)
 {
 	char *ptr = mf->ptr;
@@ -2081,11 +2090,9 @@ static void builtin_diffstat(const char *name_a, const char *name_b,
 	}
 
 	if (diff_filespec_is_binary(one) || diff_filespec_is_binary(two)) {
-		if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
-			die("unable to read files to diff");
 		data->is_binary = 1;
-		data->added = mf2.size;
-		data->deleted = mf1.size;
+		data->added = diff_filespec_size(two);
+		data->deleted = diff_filespec_size(one);
 	}
 
 	else if (complete_rewrite) {
-- 
1.7.4.1.26.g3372c
Previous: Jeff KingNext: Junio C Hamano
Message 9 of 12 in “Commit/merge messages for binary files”
  1. Piotr KrukowieckiFeb 17, 2011
  2. Matthieu MoyFeb 18, 2011
  3. Piotr KrukowieckiFeb 18, 2011
  4. Matthieu MoyFeb 18, 2011
  5. Piotr KrukowieckiFeb 18, 2011
  6. Jeff KingFeb 19, 2011
  7. Jeff KingFeb 19, 2011
  8. 1/2 diff: handle diffstat of rewritten binary filesJeff King, Feb 19, 2011
  9. 2/2 diff: don't retrieve binary blobs for diffstatJeff King, Feb 19, 2011
  10. Junio C HamanoFeb 21, 2011
  11. Jeff KingFeb 22, 2011
  12. Junio C HamanoFeb 22, 2011

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.