Skip to content

Commit 4b34f68

Browse files
committed
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.
1 parent a08e882 commit 4b34f68

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

src/patch_generate.c

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -349,20 +349,24 @@ static int diff_binary(git_patch_generated_output *output, git_patch_generated *
349349
new_len = patch->nfile.map.len;
350350
int error;
351351

352-
/* Create the old->new delta (as the "new" side of the patch),
353-
* and the new->old delta (as the "old" side)
354-
*/
355-
if ((error = create_binary(&binary.old_file.type,
356-
(char **)&binary.old_file.data,
357-
&binary.old_file.datalen,
358-
&binary.old_file.inflatedlen,
359-
new_data, new_len, old_data, old_len)) < 0 ||
360-
(error = create_binary(&binary.new_file.type,
361-
(char **)&binary.new_file.data,
362-
&binary.new_file.datalen,
363-
&binary.new_file.inflatedlen,
364-
old_data, old_len, new_data, new_len)) < 0)
365-
return error;
352+
/* Only load contents if the user actually wants to diff
353+
* binary files. */
354+
if (patch->base.diff_opts.flags & GIT_DIFF_SHOW_BINARY) {
355+
/* Create the old->new delta (as the "new" side of the patch),
356+
* and the new->old delta (as the "old" side)
357+
*/
358+
if ((error = create_binary(&binary.old_file.type,
359+
(char **)&binary.old_file.data,
360+
&binary.old_file.datalen,
361+
&binary.old_file.inflatedlen,
362+
new_data, new_len, old_data, old_len)) < 0 ||
363+
(error = create_binary(&binary.new_file.type,
364+
(char **)&binary.new_file.data,
365+
&binary.new_file.datalen,
366+
&binary.new_file.inflatedlen,
367+
old_data, old_len, new_data, new_len)) < 0)
368+
return error;
369+
}
366370

367371
error = giterr_set_after_callback_function(
368372
output->binary_cb(patch->base.delta, &binary, output->payload),

0 commit comments

Comments
 (0)