summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2016-09-01 15:14:25 +0200
committerPatrick Steinhardt <ps@pks.im>2016-09-01 15:14:25 +0200
commit4b34f687bd3382fc94012fa221885028f4cfded5 (patch)
treefc689195fb3374a87084982fdf3e0613671af1e7
parenta08e88259fe7ef3d7514a4774acd6eec5a6a2ca7 (diff)
downloadlibgit2-4b34f687bd3382fc94012fa221885028f4cfded5.tar.gz
patch_generate: only calculate binary diffs if requested
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.
-rw-r--r--src/patch_generate.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/src/patch_generate.c b/src/patch_generate.c
index 927786a43..67a13b706 100644
--- a/src/patch_generate.c
+++ b/src/patch_generate.c
@@ -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),