[PATCH] Teach fmt-patch to write individual files.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When called with "--stdout", it still writes to standard output.

Notable differences to git-format-patch:

	- since fmt-patch uses the standardized logging machinery, it is
	  no longer "From nobody", but "From <commit_sha1>",

	- the empty lines before and after the "---" just before the
	  diffstat are no longer there,

	- git-format-patch outputs the commit_sha1 just before the first
	  diff, which fmt-patch does not,

	- the file names are no longer output to stdout, but to stderr
	  (since stdout is freopen()ed all the time), and

	- "git fmt-patch HEAD^" does not work as expected: it outputs
	  *all* commits reachable from HEAD^!

The last one is possibly a showstopper. At least I used to call that
command quite often...

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx>
---
 builtin-log.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 60 insertions(+), 1 deletions(-)

diff --git a/builtin-log.c b/builtin-log.c
index a39aed6..a75a37f 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -69,12 +69,54 @@ int cmd_log(int argc, const char **argv,
 	return cmd_log_wc(argc, argv, envp, &rev);
 }
 
+static int istitlechar(char c)
+{
+	return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
+		(c >= '0' && c <= '9') || c == '.' || c == '_';
+}
+
+static void reopen_stdout(struct commit *commit, int nr)
+{
+	char filename[1024];
+	char *sol;
+	int len;
+
+
+	sprintf(filename, "%04d", nr);
+	len = strlen(filename);
+
+	sol = strstr(commit->buffer, "\n\n");
+	if (sol) {
+		int j, space = 1;
+
+		sol += 2;
+		for (j = 0; len < 1024 - 6 && sol[j] && sol[j] != '\n'; j++) {
+			if (istitlechar(sol[j])) {
+				if (space) {
+					filename[len++] = '-';
+					space = 0;
+				}
+				filename[len++] = sol[j];
+				if (sol[j] == '.')
+					while (sol[++j] == '.');
+			} else
+				space = 1;
+		}
+		while (filename[len - 1] == '.')
+			len--;
+	}
+	strcpy(filename + len, ".txt");
+	fprintf(stderr, "%s\n", filename);
+	freopen(filename, "w", stdout);
+}
+
 int cmd_format_patch(int argc, const char **argv, char **envp)
 {
 	struct commit *commit;
 	struct commit **list = NULL;
 	struct rev_info rev;
-	int nr = 0;
+	int nr = 0, total;
+	int use_stdout = 0;
 
 	init_revisions(&rev);
 	rev.commit_format = CMIT_FMT_EMAIL;
@@ -87,20 +129,37 @@ int cmd_format_patch(int argc, const cha
 	rev.diffopt.output_format = DIFF_FORMAT_PATCH;
 	argc = setup_revisions(argc, argv, &rev, "HEAD");
 
+	while (argc > 1) {
+		if (!strcmp(argv[1], "--stdout"))
+			use_stdout = 1;
+		else
+			die ("unrecognized argument: %s", argv[1]);
+		argc--;
+		argv++;
+	}
+
 	prepare_revision_walk(&rev);
 	while ((commit = get_revision(&rev)) != NULL) {
+		/* ignore merges */
+		if (commit->parents && commit->parents->next)
+			continue;
 		nr++;
 		list = realloc(list, nr * sizeof(list[0]));
 		list[nr - 1] = commit;
 	}
+	total = nr;
 	while (0 <= --nr) {
 		int shown;
 		commit = list[nr];
+		if (!use_stdout)
+			reopen_stdout(commit, total - nr);
 		shown = log_tree_commit(&rev, commit);
 		free(commit->buffer);
 		commit->buffer = NULL;
 		if (shown)
 			printf("-- \n%s\n\n", git_version_string);
+		if (!use_stdout)
+			fclose(stdout);
 	}
 	free(list);
 	return 0;
-- 
1.3.1.g42859-dirty

-
: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]