git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 11/12] commit: copy merged signed tags to headers of merge commit

From
Junio C Hamano <gitster@pobox.com>
Date
Nov 8, 2011, 03:00 UTC
Message-ID
<1320721245-13223-12-git-send-email-gitster@pobox.com>
In-Reply-To
<1320721245-13223-1-git-send-email-gitster@pobox.com>

Now MERGE_HEAD records the tag objects without peeling, we could record the result of manual conflict resolution via "git commit" without losing the tag information.

In hindsight, it would have been better to make "merge --continue" as the way to continue from such an interrupted merge, not "commit", but this is a backward compatibility baggage we would need to carry around for now.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/commit.c |   10 +++++-----
 commit.c         |   46 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/builtin/commit.c b/builtin/commit.c
index c46f2d1..4688a73 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1425,7 +1425,6 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 			pptr = &commit_list_insert(c->item, pptr)->next;
 	} else if (whence == FROM_MERGE) {
 		struct strbuf m = STRBUF_INIT;
-		struct commit *commit;
 		FILE *fp;
 
 		if (!reflog_msg)
@@ -1436,11 +1435,12 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 			die_errno(_("could not open '%s' for reading"),
 				  git_path("MERGE_HEAD"));
 		while (strbuf_getline(&m, fp, '\n') != EOF) {
-			unsigned char sha1[20];
-			if (get_sha1_hex(m.buf, sha1) < 0)
+			struct commit *parent;
+
+			parent = get_merge_parent(m.buf);
+			if (!parent)
 				die(_("Corrupt MERGE_HEAD file (%s)"), m.buf);
-			commit = lookup_commit_or_die(sha1, "MERGE_HEAD");
-			pptr = &commit_list_insert(commit, pptr)->next;
+			pptr = &commit_list_insert(parent, pptr)->next;
 		}
 		fclose(fp);
 		strbuf_release(&m);
diff --git a/commit.c b/commit.c
index 83ff503..7d471a3 100644
--- a/commit.c
+++ b/commit.c
@@ -840,6 +840,41 @@ struct commit_list *reduce_heads(struct commit_list *heads)
 	return result;
 }
 
+static void handle_signed_tag(struct strbuf *signed_tags, struct commit *parent)
+{
+	struct merge_remote_desc *desc;
+	struct strbuf sig = STRBUF_INIT;
+	char *buf;
+	unsigned long size, len;
+	enum object_type type;
+
+	desc = merge_remote_util(parent);
+	if (!desc || !desc->obj)
+		return;
+	buf = read_sha1_file(desc->obj->sha1, &type, &size);
+	if (!buf || type != OBJ_TAG)
+		goto free_return;
+	len = parse_signature(buf, size);
+	if (size == len)
+		goto free_return;
+	/*
+	 * We could verify this signature again and either omit writing
+	 * the contents of the tag when it does not validate, but the
+	 * integrator may not have the public key of the signer of the
+	 * tag he is merging, while a later auditor may acquire the public
+	 * key while auditing, so let's not run verify-signed-buffer here
+	 * for now...
+	 *
+	 * if (verify_signed_buffer(buf, len, buf + len, size - len, &sig))
+	 *	warn("warning: signed tag unverified.");
+	 */
+	strbuf_add_lines(signed_tags, "mergetag ", buf, size);
+
+free_return:
+	strbuf_release(&sig);
+	free(buf);
+}
+
 static const char commit_utf8_warn[] =
 "Warning: commit message does not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -852,6 +887,7 @@ int commit_tree(const char *msg, unsigned char *tree,
 	int result;
 	int encoding_is_utf8;
 	struct strbuf buffer;
+	struct strbuf signed_tags = STRBUF_INIT;
 
 	assert_sha1_type(tree, OBJ_TREE);
 
@@ -868,8 +904,11 @@ int commit_tree(const char *msg, unsigned char *tree,
 	 */
 	while (parents) {
 		struct commit_list *next = parents->next;
+		struct commit *parent = parents->item;
+
 		strbuf_addf(&buffer, "parent %s\n",
-			sha1_to_hex(parents->item->object.sha1));
+			    sha1_to_hex(parent->object.sha1));
+		handle_signed_tag(&signed_tags, parent);
 		free(parents);
 		parents = next;
 	}
@@ -881,6 +920,11 @@ int commit_tree(const char *msg, unsigned char *tree,
 	strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME));
 	if (!encoding_is_utf8)
 		strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
+
+	if (signed_tags.len) {
+		strbuf_addbuf(&buffer, &signed_tags);
+		strbuf_release(&signed_tags);
+	}
 	strbuf_addch(&buffer, '\n');
 
 	/* And add the comment */
-- 
1.7.8.rc0.128.g31aa4
Previous: Junio C HamanoNext: Junio C Hamano
Message 26 of 32 in “Pulling signed tag”
  1. 00/10 Pulling signed tagJunio C Hamano, Nov 5, 2011
  2. 01/10 Split GPG interface into its own helper libraryJunio C Hamano, Nov 5, 2011
  3. 02/10 fetch: do not store peeled tag object names in FETCH_HEADJunio C Hamano, Nov 5, 2011
  4. 03/10 merge: notice local merging of tags and keep it unwrappedJunio C Hamano, Nov 5, 2011
  5. 04/10 fetch: allow "git fetch $there v1.0" to fetch a tagJunio C Hamano, Nov 5, 2011
  6. 05/10 tests: distinguish merges of tags and commitsJunio C Hamano, Nov 5, 2011
  7. 06/10 refs DWIMmery: use the same rule for both "git fetch" and othersJunio C Hamano, Nov 5, 2011
  8. 07/10 fmt-merge-msg: avoid early returnsJunio C Hamano, Nov 5, 2011
  9. 08/10 fmt-merge-msg: package options into a structureJunio C Hamano, Nov 5, 2011
  10. 09/10 fmt-merge-msg: Add contents of merged tag in the merge messageJunio C Hamano, Nov 5, 2011
  11. Johannes SixtNov 5, 2011
  12. Junio C HamanoNov 6, 2011
  13. 10/10 merge: force edit mode when merging a tag objectJunio C Hamano, Nov 5, 2011
  14. Nguyen Thai Ngoc DuyNov 5, 2011
  15. 00/12 Pulling signed/annotated tagsJunio C Hamano, Nov 8, 2011
  16. 01/12 Split GPG interface into its own helper libraryJunio C Hamano, Nov 8, 2011
  17. 02/12 fetch: do not store peeled tag object names in FETCH_HEADJunio C Hamano, Nov 8, 2011
  18. 03/12 merge: notice local merging of tags and keep it unwrappedJunio C Hamano, Nov 8, 2011
  19. 04/12 fetch: allow "git fetch $there v1.0" to fetch a tagJunio C Hamano, Nov 8, 2011
  20. 05/12 refs DWIMmery: use the same rule for both "git fetch" and othersJunio C Hamano, Nov 8, 2011
  21. 06/12 fmt-merge-msg: avoid early returnsJunio C Hamano, Nov 8, 2011
  22. 07/12 fmt-merge-msg: package options into a structureJunio C Hamano, Nov 8, 2011
  23. 08/12 fmt-merge-msg: Add contents of merged tag in the merge messageJunio C Hamano, Nov 8, 2011
  24. 09/12 merge: make usage of commit->util more extensibleJunio C Hamano, Nov 8, 2011
  25. 10/12 merge: record tag objects without peeling in MERGE_HEADJunio C Hamano, Nov 8, 2011
  26. 11/12 commit: copy merged signed tags to headers of merge commitJunio C Hamano, Nov 8, 2011
  27. 12/12 merge: force edit mode when merging a tag objectJunio C Hamano, Nov 8, 2011
  28. Linus TorvaldsNov 8, 2011
  29. Junio C HamanoNov 8, 2011
  30. Linus TorvaldsNov 8, 2011
  31. Junio C HamanoNov 8, 2011
  32. Junio C HamanoNov 8, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.