@@ -61,6 +61,8 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
{
int patchlen = 0, found_next = 0;
int before = -1, after = -1;
+ int diff_is_binary = 0;
+ char pre_oid_str[GIT_MAX_HEXSZ + 1], post_oid_str[GIT_MAX_HEXSZ + 1];
git_hash_ctx ctx;
the_hash_algo->init_fn(&ctx);
@@ -88,14 +90,44 @@ static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
/* Parsing diff header? */
if (before == -1) {
- if (starts_with(line, "index "))
+ if (starts_with(line, "GIT binary patch") ||
+ starts_with(line, "Binary files")) {
+ diff_is_binary = 1;
+ before = 0;
+ the_hash_algo->update_fn(&ctx, pre_oid_str,
+ strlen(pre_oid_str));
+ the_hash_algo->update_fn(&ctx, post_oid_str,
+ strlen(post_oid_str));
+ if (stable)
+ flush_one_hunk(result, &ctx);
continue;
- else if (starts_with(line, "--- "))
+ } else if (skip_prefix(line, "index ", &p)) {
+ char *oid1_end = strstr(line, "..");
+ char *oid2_end = NULL;
+ if (oid1_end)
+ oid2_end = strstr(oid1_end, " ");
+ if (!oid2_end)
+ oid2_end = line + strlen(line) - 1;
+ if (oid1_end != NULL && oid2_end != NULL) {
+ *oid1_end = *oid2_end = '\0';
+ strlcpy(pre_oid_str, p, GIT_MAX_HEXSZ + 1);
+ strlcpy(post_oid_str, oid1_end + 2, GIT_MAX_HEXSZ + 1);
+ }
+ continue;
+ } else if (starts_with(line, "--- "))
before = after = 1;
else if (!isalpha(line[0]))
break;
}
+ if (diff_is_binary) {
+ if (starts_with(line, "diff ")) {
+ diff_is_binary = 0;
+ before = -1;
+ }
+ continue;
+ }
+
/* Looking for a valid hunk header? */
if (before == 0 && after == 0) {
if (starts_with(line, "@@ -")) {
@@ -42,7 +42,7 @@ calc_patch_id () {
}
get_top_diff () {
- git log -p -1 "$@" -O bar-then-foo --
+ git log -p -1 "$@" -O bar-then-foo --full-index --
}
get_patch_id () {
@@ -61,6 +61,33 @@ test_expect_success 'patch-id detects inequality' '
get_patch_id notsame &&
! test_cmp patch-id_main patch-id_notsame
'
+test_expect_success 'patch-id detects equality binary' '
+ cat >.gitattributes <<-\EOF &&
+ foo binary
+ bar binary
+ EOF
+ get_patch_id main &&
+ get_patch_id same &&
+ git log -p -1 --binary main >top-diff.output &&
+ calc_patch_id <top-diff.output main_binpatch &&
+ git log -p -1 --binary same >top-diff.output &&
+ calc_patch_id <top-diff.output same_binpatch &&
+ test_cmp patch-id_main patch-id_main_binpatch &&
+ test_cmp patch-id_same patch-id_same_binpatch &&
+ test_cmp patch-id_main patch-id_same &&
+ test_when_finished "rm .gitattributes"
+'
+
+test_expect_success 'patch-id detects inequality binary' '
+ cat >.gitattributes <<-\EOF &&
+ foo binary
+ bar binary
+ EOF
+ get_patch_id main &&
+ get_patch_id notsame &&
+ ! test_cmp patch-id_main patch-id_notsame &&
+ test_when_finished "rm .gitattributes"
+'
test_expect_success 'patch-id supports git-format-patch output' '
get_patch_id main &&