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

[PATCHv3 3/6] format-patch: pass a commit to reopen_stdout()

From
Stephen Boyd <bebarino@gmail.com>
Date
Mar 23, 2009, 02:14 UTC
Message-ID
<00c4e51c2ff7786be6aedb4a451b8d1ff269d7b3.1237773604.git.bebarino@gmail.com>
In-Reply-To
<616420f398701fafc45b5d5cebb1371534f88caa.1237773604.git.bebarino@gmail.com>

We use the commit to generate the patch filename in reopen_stdout() before we redirect stdout. The cover letter codepath creates a dummy commit with the desired subject line 'cover letter'.

Signed-off-by: Stephen Boyd <bebarino@gmail.com>
---
 builtin-log.c |   68 +++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 40 insertions(+), 28 deletions(-)
diff --git a/builtin-log.c b/builtin-log.c
index 54ef248..392b16a 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -540,30 +540,29 @@ static FILE *realstdout = NULL;
 static const char *output_directory = NULL;
 static int outdir_offset;
 
-static int reopen_stdout(const char *oneline, struct rev_info *rev)
+static int reopen_stdout(struct commit *commit, struct rev_info *rev)
 {
-	char filename[PATH_MAX];
-	int len = 0;
+	struct strbuf filename = STRBUF_INIT;
 	int suffix_len = strlen(fmt_patch_suffix) + 1;
 
 	if (output_directory) {
-		len = snprintf(filename, sizeof(filename), "%s",
-				output_directory);
-		if (len >=
-		    sizeof(filename) - FORMAT_PATCH_NAME_MAX - suffix_len)
+		strbuf_addstr(&filename, output_directory);
+		if (filename.len >=
+		    PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len)
 			return error("name of output directory is too long");
-		if (filename[len - 1] != '/')
-			filename[len++] = '/';
+		if (filename.buf[filename.len - 1] != '/')
+			strbuf_addch(&filename, '/');
 	}
 
-	strncpy(filename + len, oneline, PATH_MAX - len);
+	get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename);
 
 	if (!DIFF_OPT_TST(&rev->diffopt, QUIET))
-		fprintf(realstdout, "%s\n", filename + outdir_offset);
+		fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
 
-	if (freopen(filename, "w", stdout) == NULL)
-		return error("Cannot open patch file %s",filename);
+	if (freopen(filename.buf, "w", stdout) == NULL)
+		return error("Cannot open patch file %s", filename.buf);
 
+	strbuf_release(&filename);
 	return 0;
 }
 
@@ -644,26 +643,43 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
 	const char *encoding = "utf-8";
 	struct diff_options opts;
 	int need_8bit_cte = 0;
-	char filename[PATH_MAX];
+	struct commit *commit = NULL;
 
 	if (rev->commit_format != CMIT_FMT_EMAIL)
 		die("Cover letter needs email format");
 
-	if (numbered_files)
-	    sprintf(filename, "0");
-	else
-	    sprintf(filename, "%04d-cover-letter%s", 0, fmt_patch_suffix);
+	committer = git_committer_info(0);
+	head_sha1 = sha1_to_hex(head->object.sha1);
+
+	if (!numbered_files)
+	{
+		/*
+		 * We fake a commit for the cover letter so we get the filename
+		 * desired.
+		 */
+		commit = xcalloc(1, sizeof(*commit));
+		commit->buffer = xmalloc(400);
+		snprintf(commit->buffer, 400,
+			"tree 0000000000000000000000000000000000000000\n"
+			"parent %s\n"
+			"author %s\n"
+			"committer %s\n\n"
+			"cover letter\n",
+			head_sha1, committer, committer);
+	}
 
-	if (!use_stdout && reopen_stdout(filename, rev))
+	if (!use_stdout && reopen_stdout(commit, rev))
 		return;
 
-	head_sha1 = sha1_to_hex(head->object.sha1);
+	if (commit)
+	{
+		free(commit->buffer);
+		free(commit);
+	}
 
 	log_write_email_headers(rev, head_sha1, &subject_start, &extra_headers,
 				&need_8bit_cte);
 
-	committer = git_committer_info(0);
-
 	msg = body;
 	pp_user_info(NULL, CMIT_FMT_EMAIL, &sb, committer, DATE_RFC2822,
 		     encoding);
@@ -767,7 +783,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 	struct patch_ids ids;
 	char *add_signoff = NULL;
 	struct strbuf buf = STRBUF_INIT;
-	struct strbuf patch_filename = STRBUF_INIT;
 
 	git_config(git_format_config, NULL);
 	init_revisions(&rev, prefix);
@@ -1071,11 +1086,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 			gen_message_id(&rev, sha1_to_hex(commit->object.sha1));
 		}
 
-		get_patch_filename(numbered_files ? NULL : commit, rev.nr,
-				    fmt_patch_suffix, &patch_filename);
-		if (!use_stdout && reopen_stdout(patch_filename.buf, &rev))
+		if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit,
+						 &rev))
 			die("Failed to create output files");
-		strbuf_setlen(&patch_filename, 0);
 		shown = log_tree_commit(&rev, commit);
 		free(commit->buffer);
 		commit->buffer = NULL;
@@ -1099,7 +1112,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 		if (!use_stdout)
 			fclose(stdout);
 	}
-	strbuf_release(&patch_filename);
 	free(list);
 	if (ignore_if_in_upstream)
 		free_patch_ids(&ids);
-- 
1.6.2
Previous: Stephen BoydNext: Stephen Boyd
Message 15 of 20 in “[PATCHv2 0/3] format-patch --attach/--inline use filename instead of SHA1”
  1. Stephen BoydMar 22, 2009
  2. 1/3 format-patch: create patch filename in one functionStephen Boyd, Mar 22, 2009
  3. 2/3 format-patch: --attach/inline uses filename instead of SHA1Stephen Boyd, Mar 22, 2009
  4. 3/3 format-patch: --numbered-files and --stdout aren't mutually exclusiveStephen Boyd, Mar 22, 2009
  5. Junio C HamanoMar 22, 2009
  6. Junio C HamanoMar 22, 2009
  7. Junio C HamanoMar 22, 2009
  8. Stephen BoydMar 22, 2009
  9. Junio C HamanoMar 22, 2009
  10. Stephen BoydMar 22, 2009
  11. Junio C HamanoMar 22, 2009
  12. 0/6 format-patch --attach/--inline uses filename not SHA1Stephen Boyd, Mar 23, 2009
  13. 1/6 pretty.c: add %f format specifier to format_commit_message()Stephen Boyd, Mar 23, 2009
  14. 2/6 format-patch: construct patch filename in one functionStephen Boyd, Mar 23, 2009
  15. 3/6 format-patch: pass a commit to reopen_stdout()Stephen Boyd, Mar 23, 2009
  16. 4/6 format-patch: move get_patch_filename() into log-treeStephen Boyd, Mar 23, 2009
  17. 5/6 format-patch: --attach/inline uses filename instead of SHA1Stephen Boyd, Mar 23, 2009
  18. 6/6 format-patch: --numbered-files and --stdout aren't mutually exclusiveStephen Boyd, Mar 23, 2009
  19. René ScharfeMar 31, 2009
  20. format_sanitized_subject: Don't trim past initial length of strbufStephen Boyd, Mar 31, 2009

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.