]> git.proxmox.com Git - libgit2.git/commitdiff
patch_generate: only calculate binary diffs if requested
authorPatrick Steinhardt <ps@pks.im>
Thu, 1 Sep 2016 13:14:25 +0000 (15:14 +0200)
committerPatrick Steinhardt <ps@pks.im>
Thu, 1 Sep 2016 13:14:25 +0000 (15:14 +0200)
When generating diffs for binary files, we load and decompress
the blobs in order to generate the actual diff, which can be very
costly. While we cannot avoid this for the case when we are
called with the `GIT_DIFF_SHOW_BINARY` flag, we do not have to
load the blobs in the case where this flag is not set, as the
caller is expected to have no interest in the actual content of
binary files.

Fix the issue by only generating a binary diff when the caller is
actually interested in the diff. As libgit2 uses heuristics to
determine that a blob contains binary data by inspecting its size
without loading from the ODB, this saves us quite some time when
diffing in a repository with binary files.

src/patch_generate.c

index 927786a437b1876900742aa787722b6b780e9dc0..67a13b706e0f64ddda96ff5a4fc4f88876f23e3a 100644 (file)
@@ -349,20 +349,24 @@ static int diff_binary(git_patch_generated_output *output, git_patch_generated *
                new_len = patch->nfile.map.len;
        int error;
 
-       /* Create the old->new delta (as the "new" side of the patch),
-        * and the new->old delta (as the "old" side)
-        */
-       if ((error = create_binary(&binary.old_file.type,
-                       (char **)&binary.old_file.data,
-                       &binary.old_file.datalen,
-                       &binary.old_file.inflatedlen,
-                       new_data, new_len, old_data, old_len)) < 0 ||
-               (error = create_binary(&binary.new_file.type,
-                       (char **)&binary.new_file.data,
-                       &binary.new_file.datalen,
-                       &binary.new_file.inflatedlen,
-                       old_data, old_len, new_data, new_len)) < 0)
-               return error;
+       /* Only load contents if the user actually wants to diff
+        * binary files. */
+       if (patch->base.diff_opts.flags & GIT_DIFF_SHOW_BINARY) {
+               /* Create the old->new delta (as the "new" side of the patch),
+                * and the new->old delta (as the "old" side)
+                */
+               if ((error = create_binary(&binary.old_file.type,
+                               (char **)&binary.old_file.data,
+                               &binary.old_file.datalen,
+                               &binary.old_file.inflatedlen,
+                               new_data, new_len, old_data, old_len)) < 0 ||
+                       (error = create_binary(&binary.new_file.type,
+                               (char **)&binary.new_file.data,
+                               &binary.new_file.datalen,
+                               &binary.new_file.inflatedlen,
+                               old_data, old_len, new_data, new_len)) < 0)
+                       return error;
+       }
 
        error = giterr_set_after_callback_function(
                output->binary_cb(patch->base.delta, &binary, output->payload),