commit: convert mergetag before computing the signature of a commit
It so happens that commit mergetag lines embed a tag object. So to compute the compatible signature of a commit object that has mergetag lines the compatible embedded tag must be computed first. Implement this by duplicating and converting the commit extra headers into the compatible version of the commit extra headers, that need to be passed to commit_tree_extended. To handle merge tags only the compatible extra headers need to be computed. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Eric W. Biederman committed
Oct 1, 2023 at 21:40 UTC
a3e8ae5473942c0d2621c5936685b6d98e63f006
1 file changed
+41
-1
commit.c
+41
-1
@@ -1355,6 +1355,39 @@ void append_merge_tag_headers(struct commit_list *parents,
1355
}
1356
}
1357
1358
+static int convert_commit_extra_headers(struct commit_extra_header *orig,
1359
+ struct commit_extra_header **result)
1360
+{
1361
+ const struct git_hash_algo *compat = the_repository->compat_hash_algo;
1362
+ const struct git_hash_algo *algo = the_repository->hash_algo;
1363
+ struct commit_extra_header *extra = NULL, **tail = &extra;
1364
+ struct strbuf out = STRBUF_INIT;
1365
+ while (orig) {
1366
+ struct commit_extra_header *new;
1367
+ CALLOC_ARRAY(new, 1);
1368
+ if (!strcmp(orig->key, "mergetag")) {
1369
+ if (convert_object_file(&out, algo, compat,
1370
+ orig->value, orig->len,
1371
+ OBJ_TAG, 1)) {
1372
+ free(new);
1373
+ free_commit_extra_headers(extra);
1374
+ return -1;
1375
+ }
1376
+ new->key = xstrdup("mergetag");
1377
+ new->value = strbuf_detach(&out, &new->len);
1378
+ } else {
1379
+ new->key = xstrdup(orig->key);
1380
+ new->len = orig->len;
1381
+ new->value = xmemdupz(orig->value, orig->len);
1382
+ }
1383
+ *tail = new;
1384
+ tail = &new->next;
1385
+ orig = orig->next;
1386
+ }
1387
+ *result = extra;
1388
+ return 0;
1389
+}
1390
+
1391
static void add_extra_header(struct strbuf *buffer,
1392
struct commit_extra_header *extra)
1393
{
@@ -1679,6 +1712,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
1712
goto out;
1713
}
1714
if (r->compat_hash_algo) {
1715
+ struct commit_extra_header *compat_extra = NULL;
1716
struct object_id mapped_tree;
1717
struct object_id *mapped_parents;
1718
@@ -1695,8 +1729,14 @@ int commit_tree_extended(const char *msg, size_t msg_len,
1729
free(mapped_parents);
1730
goto out;
1731
}
1732
+ if (convert_commit_extra_headers(extra, &compat_extra)) {
1733
+ result = -1;
1734
+ free(mapped_parents);
1735
+ goto out;
1736
+ }
1737
write_commit_tree(&compat_buffer, msg, msg_len, &mapped_tree,
1699
- mapped_parents, nparents, author, committer, extra);
1738
+ mapped_parents, nparents, author, committer, compat_extra);
1739
+ free_commit_extra_headers(compat_extra);
1740
free(mapped_parents);
1741
1742
if (sign_commit && sign_commit_to_strbuf(&compat_sig, &compat_buffer, sign_commit)) {