840
return result;
841
}
842
843
+static void handle_signed_tag(struct commit *parent, struct commit_extra_header ***tail)
844
+{
845
+ struct merge_remote_desc *desc;
846
+ struct commit_extra_header *mergetag;
847
+ char *buf;
848
+ unsigned long size, len;
849
+ enum object_type type;
850
+
851
+ desc = merge_remote_util(parent);
852
+ if (!desc || !desc->obj)
853
+ return;
854
+ buf = read_sha1_file(desc->obj->sha1, &type, &size);
855
+ if (!buf || type != OBJ_TAG)
856
+ goto free_return;
857
+ len = parse_signature(buf, size);
858
+ if (size == len)
859
+ goto free_return;
860
+ /*
861
+ * We could verify this signature and either omit the tag when
862
+ * it does not validate, but the integrator may not have the
863
+ * public key of the signer of the tag he is merging, while a
864
+ * later auditor may have it while auditing, so let's not run
865
+ * verify-signed-buffer here for now...
866
+ *
867
+ * if (verify_signed_buffer(buf, len, buf + len, size - len, ...))
868
+ * warn("warning: signed tag unverified.");
869
+ */
870
+ mergetag = xcalloc(1, sizeof(*mergetag));
871
+ mergetag->key = xstrdup("mergetag");
872
+ mergetag->value = buf;
873
+ mergetag->len = size;
874
+
875
+ **tail = mergetag;
876
+ *tail = &mergetag->next;
877
+ return;
878
+
879
+free_return:
880
+ free(buf);
881
+}
882
+
883
+void append_merge_tag_headers(struct commit_list *parents,
884
+ struct commit_extra_header ***tail)
885
+{
886
+ while (parents) {
887
+ struct commit *parent = parents->item;
888
+ handle_signed_tag(parent, tail);
889
+ parents = parents->next;
890
+ }
891
+}
892
+
893
+static void add_extra_header(struct strbuf *buffer,
894
+ struct commit_extra_header *extra)
895
+{
896
+ strbuf_addstr(buffer, extra->key);
897
+ strbuf_add_lines(buffer, " ", extra->value, extra->len);
898
+}
899
+
900
+void free_commit_extra_headers(struct commit_extra_header *extra)
901
+{
902
+ while (extra) {
903
+ struct commit_extra_header *next = extra->next;
904
+ free(extra->key);
905
+ free(extra->value);
906
+ free(extra);
907
+ extra = next;
908
+ }
909
+}
910
+
911
+int commit_tree(const char *msg, unsigned char *tree,
912
+ struct commit_list *parents, unsigned char *ret,
913
+ const char *author)
914
+{
915
+ struct commit_extra_header *extra = NULL, **tail = &extra;
916
+ int result;
917
+
918
+ append_merge_tag_headers(parents, &tail);
919
+ result = commit_tree_extended(msg, tree, parents, ret, author, extra);
920
+ free_commit_extra_headers(extra);
921
+ return result;
922
+}
923
+
924
static const char commit_utf8_warn[] =
925
"Warning: commit message does not conform to UTF-8.\n"
926
"You may want to amend it after fixing the message, or set the config\n"
927
"variable i18n.commitencoding to the encoding your project uses.\n";
928
848
-int commit_tree(const char *msg, unsigned char *tree,
849
- struct commit_list *parents, unsigned char *ret,
850
- const char *author)
929
+int commit_tree_extended(const char *msg, unsigned char *tree,
930
+ struct commit_list *parents, unsigned char *ret,
931
+ const char *author, struct commit_extra_header *extra)
932
{
933
int result;
934
int encoding_is_utf8;
949
*/
950
while (parents) {
951
struct commit_list *next = parents->next;
952
+ struct commit *parent = parents->item;
953
+
954
strbuf_addf(&buffer, "parent %s\n",
872
- sha1_to_hex(parents->item->object.sha1));
955
+ sha1_to_hex(parent->object.sha1));
956
free(parents);
957
parents = next;
958
}
964
strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME));
965
if (!encoding_is_utf8)
966
strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
967
+
968
+ while (extra) {
969
+ add_extra_header(&buffer, extra);
970
+ extra = extra->next;
971
+ }
972
strbuf_addch(&buffer, '\n');
973
974
/* And add the comment */