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

Re: [RFC/PATCH 1/1] format-patch: add an option to record base tree info

From
Junio C Hamano <gitster@pobox.com>
Date
Feb 24, 2016, 18:34 UTC
Message-ID
<xmqqtwkyt0tj.fsf@gitster.mtv.corp.google.com>
In-Reply-To
<20160224070727.GA23808@wfg-t540p.sh.intel.com>
Fengguang Wu <fengguang.wu@intel.com> writes:
Show 14 quoted lines
>> This starts to sound more like something you would want to write in
>> the cover letter, or the trailer block next to Signed-off-by: at the
>> end of the first patch in the series.
>
> Yes, that's roughly what the current patch does, except in the latter
> case we add new info after diffstat.
>
>> Or even after the mail
>> signature at the very end of the message (incidentally that would
>> probably minimize the damage to the Git codebase needed for this
>> addition--you should be able to do this without touching anything
>> other than builtin/log.c).
>
> That's an interesting place. It looks worth trying. 

Here is an outline of such a structure. The idea is for a history of this shape, where "P" is the well-known public commit (e.g. one in Linus's tree), "X", "Y", "Z" are prerequisite patches in flight, and "A", "B", "C" are the work being sent out for testing,

	 ---P---X---Y---Z---A---B---C

the submitter would say "format-patch --base=P -3 C" (or variants thereof, e.g. with "--cover" or using "Z..C" instead of "-3 C" to specify the range), and the identifiers for P, X, Y, Z are appended at the end of the _first_ message (either the cover letter or the first patch in the series).

You are welcome to steal this as a skeleton and take authorship, as I do not plan to spend too much more time on actually implementing prepare_bases() function myself unless I run out of things to do and get bored, but I think there are already sufficient helper functions to do this (you may want to make commit_patch_id() in patch-ids.c a public helper function).

 builtin/log.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
diff --git a/builtin/log.c b/builtin/log.c
index 069bd3a..8f6cc17 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -1182,6 +1182,59 @@ static int from_callback(const struct option *opt, const char *arg, int unset)
 	return 0;
 }
 
+struct base_tree_info {
+	struct object_id base_commit;
+	int nr_patch_id, alloc_patch_id;
+	struct object_id *patch_id;
+};
+
+static void prepare_bases(struct base_tree_info *bases,
+			  const char *base_commit,
+			  struct commit **list)
+{
+	/*
+	 * If you are given --base=$commit command line argument, that
+	 * names commit 'P' when you are formatting A, B and C in this
+	 * history (i.e. "format-patch --base=P Z..C"):
+	 *
+	 * ---P---X---Y---Z---A---B---C
+	 *
+	 * where "P" is the well-known public commit (e.g. one in
+	 * Linus's tree), "X", "Y", "Z" are prerequisite patches in
+	 * flight whose patch-ids are well-known, and "A", "B", "C"
+	 * are the work being sent out for testing, you would compute
+	 * base_commit=P, patch_ids[] = map(commit_patch_id, [X, Y,
+	 * Z]) here and stuff them in bases structure.
+	 *
+	 * Be sure to check error (e.g. invalid base_commit) and die()
+	 * here as necessary.
+	 */
+	
+}
+
+static void print_bases(struct base_tree_info *bases)
+{
+	int i;
+
+	/* Only do this once, either for the cover or for the first one */
+	if (is_null_oid(&bases->base_commit))
+		return;
+
+	printf("** base-commit-info **\n");
+
+	/* Show the base commit */
+	printf("base-commit: %s\n", oid_to_hex(&bases->base_commit));
+
+	/* Show the prerequisite patches */
+	for (i = 0; i < bases->nr_patch_id; i++)
+		printf("base-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
+
+	free(&bases->patch_id);
+	bases->nr_patch_id = 0;
+	bases->alloc_patch_id = 0;
+	oidclr(&bases->base_commit);
+}
+
 int cmd_format_patch(int argc, const char **argv, const char *prefix)
 {
 	struct commit *commit;
@@ -1205,6 +1258,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 	int reroll_count = -1;
 	char *branch_name = NULL;
 	char *from = NULL;
+	char *base_commit = NULL;
+	struct base_tree_info bases;
+
 	const struct option builtin_format_patch_options[] = {
 		{ OPTION_CALLBACK, 'n', "numbered", &numbered, NULL,
 			    N_("use [PATCH n/m] even with a single patch"),
@@ -1265,6 +1321,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 			    PARSE_OPT_OPTARG, thread_callback },
 		OPT_STRING(0, "signature", &signature, N_("signature"),
 			    N_("add a signature")),
+		OPT_STRING(0, "base", &base_commit, N_("base-commit"),
+			   N_("add prerequisite tree info to the patch series")),
 		OPT_FILENAME(0, "signature-file", &signature_file,
 				N_("add a signature from a file")),
 		OPT__QUIET(&quiet, N_("don't print the patch filenames")),
@@ -1496,6 +1554,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 		signature = strbuf_detach(&buf, NULL);
 	}
 
+	if (base_commit) {
+		memset(&bases, 0, sizeof(bases));
+		prepare_bases(&bases, base_commit, list);
+	}
+
 	if (in_reply_to || thread || cover_letter)
 		rev.ref_message_ids = xcalloc(1, sizeof(struct string_list));
 	if (in_reply_to) {
@@ -1509,6 +1572,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 			gen_message_id(&rev, "cover");
 		make_cover_letter(&rev, use_stdout,
 				  origin, nr, list, branch_name, quiet);
+		print_bases(&bases);
 		total++;
 		start_number--;
 	}
@@ -1574,6 +1638,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 				       rev.mime_boundary);
 			else
 				print_signature();
+			print_bases(&bases);
 		}
 		if (!use_stdout)
 			fclose(stdout);
Previous: Fengguang WuNext: Junio C Hamano
Message 16 of 29 in “Add an option to git-format-patch to record base tree info”
  1. 0/1 Add an option to git-format-patch to record base tree infoXiaolong Ye, Feb 22, 2016
  2. 1/1 format-patch: add an option to record base tree infoXiaolong Ye, Feb 22, 2016
  3. Junio C HamanoFeb 22, 2016
  4. Jacob KellerFeb 22, 2016
  5. Fengguang WuFeb 23, 2016
  6. Junio C HamanoFeb 23, 2016
  7. Fengguang WuFeb 23, 2016
  8. H. Peter AnvinFeb 23, 2016
  9. Fengguang WuFeb 23, 2016
  10. Dan CarpenterFeb 23, 2016
  11. Fengguang WuFeb 23, 2016
  12. Dan CarpenterFeb 23, 2016
  13. Fengguang WuFeb 24, 2016
  14. Junio C HamanoFeb 24, 2016
  15. Fengguang WuFeb 24, 2016
  16. Junio C HamanoFeb 24, 2016
  17. Junio C HamanoFeb 23, 2016
  18. Eric W. BiedermanFeb 23, 2016
  19. Junio C HamanoFeb 23, 2016
  20. H. Peter AnvinFeb 23, 2016
  21. Eric W. BiedermanFeb 23, 2016
  22. H. Peter AnvinFeb 24, 2016
  23. Stefan BellerFeb 23, 2016
  24. Michael J GruberFeb 24, 2016
  25. Junio C HamanoFeb 24, 2016
  26. Fengguang WuFeb 24, 2016
  27. Fengguang WuFeb 24, 2016
  28. Eric W. BiedermanFeb 23, 2016
  29. Fengguang WuFeb 24, 2016

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.