Skip to content

Commit 0570be7

Browse files
jerry-skydiogitster
authored andcommitted
patch-id: fix stable patch id for binary / header-only
Patch-ids for binary patches are found by hashing the object ids of the before and after objects in succession. However in the --stable case, there is a bug where hunks are not flushed for binary and header-only patch ids, which would always result in a patch-id of 0000. The --unstable case is currently correct. Reorder the logic to branch into 3 cases for populating the patch body: header-only which populates nothing, binary which populates the object ids, and normal which populates the text diff. All branches will end up flushing the hunk. Don't populate the ---a/ and +++b/ lines for binary diffs, to correspond to those lines not being present in the "git diff" text output. This is necessary because we advertise that the patch-id calculated internally and used in format-patch is the same that what the builtin "git patch-id" would produce when piped from a diff. Update the test to run on both binary and normal files. Signed-off-by: Jerry Zhang <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a0feb86 commit 0570be7

File tree

2 files changed

+53
-39
lines changed

2 files changed

+53
-39
lines changed

diff.c

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6221,46 +6221,46 @@ static int diff_get_patch_id(struct diff_options *options, struct object_id *oid
62216221
if (p->one->mode == 0) {
62226222
patch_id_add_string(&ctx, "newfilemode");
62236223
patch_id_add_mode(&ctx, p->two->mode);
6224-
patch_id_add_string(&ctx, "---/dev/null");
6225-
patch_id_add_string(&ctx, "+++b/");
6226-
the_hash_algo->update_fn(&ctx, p->two->path, len2);
62276224
} else if (p->two->mode == 0) {
62286225
patch_id_add_string(&ctx, "deletedfilemode");
62296226
patch_id_add_mode(&ctx, p->one->mode);
6230-
patch_id_add_string(&ctx, "---a/");
6231-
the_hash_algo->update_fn(&ctx, p->one->path, len1);
6232-
patch_id_add_string(&ctx, "+++/dev/null");
6233-
} else {
6234-
patch_id_add_string(&ctx, "---a/");
6235-
the_hash_algo->update_fn(&ctx, p->one->path, len1);
6236-
patch_id_add_string(&ctx, "+++b/");
6237-
the_hash_algo->update_fn(&ctx, p->two->path, len2);
62386227
}
62396228

6240-
if (diff_header_only)
6241-
continue;
6242-
6243-
if (fill_mmfile(options->repo, &mf1, p->one) < 0 ||
6244-
fill_mmfile(options->repo, &mf2, p->two) < 0)
6245-
return error("unable to read files to diff");
6246-
6247-
if (diff_filespec_is_binary(options->repo, p->one) ||
6229+
if (diff_header_only) {
6230+
/* don't do anything since we're only populating header info */
6231+
} else if (diff_filespec_is_binary(options->repo, p->one) ||
62486232
diff_filespec_is_binary(options->repo, p->two)) {
62496233
the_hash_algo->update_fn(&ctx, oid_to_hex(&p->one->oid),
62506234
the_hash_algo->hexsz);
62516235
the_hash_algo->update_fn(&ctx, oid_to_hex(&p->two->oid),
62526236
the_hash_algo->hexsz);
6253-
continue;
6254-
}
6255-
6256-
xpp.flags = 0;
6257-
xecfg.ctxlen = 3;
6258-
xecfg.flags = XDL_EMIT_NO_HUNK_HDR;
6259-
if (xdi_diff_outf(&mf1, &mf2, NULL,
6260-
patch_id_consume, &data, &xpp, &xecfg))
6261-
return error("unable to generate patch-id diff for %s",
6262-
p->one->path);
6237+
} else {
6238+
if (p->one->mode == 0) {
6239+
patch_id_add_string(&ctx, "---/dev/null");
6240+
patch_id_add_string(&ctx, "+++b/");
6241+
the_hash_algo->update_fn(&ctx, p->two->path, len2);
6242+
} else if (p->two->mode == 0) {
6243+
patch_id_add_string(&ctx, "---a/");
6244+
the_hash_algo->update_fn(&ctx, p->one->path, len1);
6245+
patch_id_add_string(&ctx, "+++/dev/null");
6246+
} else {
6247+
patch_id_add_string(&ctx, "---a/");
6248+
the_hash_algo->update_fn(&ctx, p->one->path, len1);
6249+
patch_id_add_string(&ctx, "+++b/");
6250+
the_hash_algo->update_fn(&ctx, p->two->path, len2);
6251+
}
62636252

6253+
if (fill_mmfile(options->repo, &mf1, p->one) < 0 ||
6254+
fill_mmfile(options->repo, &mf2, p->two) < 0)
6255+
return error("unable to read files to diff");
6256+
xpp.flags = 0;
6257+
xecfg.ctxlen = 3;
6258+
xecfg.flags = XDL_EMIT_NO_HUNK_HDR;
6259+
if (xdi_diff_outf(&mf1, &mf2, NULL,
6260+
patch_id_consume, &data, &xpp, &xecfg))
6261+
return error("unable to generate patch-id diff for %s",
6262+
p->one->path);
6263+
}
62646264
if (stable)
62656265
flush_one_hunk(oid, &ctx);
62666266
}

t/t3419-rebase-patch-id.sh

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,16 @@ test_expect_success 'setup: 500 lines' '
4343
git add newfile &&
4444
git commit -q -m "add small file" &&
4545
46-
git cherry-pick main >/dev/null 2>&1
47-
'
46+
git cherry-pick main >/dev/null 2>&1 &&
4847
49-
test_expect_success 'setup attributes' '
50-
echo "file binary" >.gitattributes
48+
git branch -f squashed main &&
49+
git checkout -q -f squashed &&
50+
git reset -q --soft HEAD~2 &&
51+
git commit -q -m squashed
5152
'
5253

5354
test_expect_success 'detect upstream patch' '
54-
git checkout -q main &&
55+
git checkout -q main^{} &&
5556
scramble file &&
5657
git add file &&
5758
git commit -q -m "change big file again" &&
@@ -61,14 +62,27 @@ test_expect_success 'detect upstream patch' '
6162
test_must_be_empty revs
6263
'
6364

65+
test_expect_success 'detect upstream patch binary' '
66+
echo "file binary" >.gitattributes &&
67+
git checkout -q other^{} &&
68+
git rebase main &&
69+
git rev-list main...HEAD~ >revs &&
70+
test_must_be_empty revs &&
71+
test_when_finished "rm .gitattributes"
72+
'
73+
6474
test_expect_success 'do not drop patch' '
65-
git branch -f squashed main &&
66-
git checkout -q -f squashed &&
67-
git reset -q --soft HEAD~2 &&
68-
git commit -q -m squashed &&
6975
git checkout -q other^{} &&
7076
test_must_fail git rebase squashed &&
71-
git rebase --quit
77+
test_when_finished "git rebase --abort"
78+
'
79+
80+
test_expect_success 'do not drop patch binary' '
81+
echo "file binary" >.gitattributes &&
82+
git checkout -q other^{} &&
83+
test_must_fail git rebase squashed &&
84+
test_when_finished "git rebase --abort" &&
85+
test_when_finished "rm .gitattributes"
7286
'
7387

7488
test_done

0 commit comments

Comments
 (0)