{"thread":{"id":"4060","subject":"[PATCH] Teach fmt-patch to write individual files.","startedAt":"2006-05-04T23:07:22Z","lastAt":"2006-05-04T23:15:31Z","messageCount":2,"participants":["Johannes Schindelin"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"19529","messageId":"Pine.LNX.4.63.0605050106180.12713@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4060","inReplyTo":null,"subject":"[PATCH] Teach fmt-patch to write individual files.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-05-04T23:07:22Z","receivedAt":"2006-05-04T23:07:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nWhen called with \"--stdout\", it still writes to standard output.\n\nNotable differences to git-format-patch:\n\n\t- since fmt-patch uses the standardized logging machinery, it is\n\t  no longer \"From nobody\", but \"From <commit_sha1>\",\n\n\t- the empty lines before and after the \"---\" just before the\n\t  diffstat are no longer there,\n\n\t- git-format-patch outputs the commit_sha1 just before the first\n\t  diff, which fmt-patch does not,\n\n\t- the file names are no longer output to stdout, but to stderr\n\t  (since stdout is freopen()ed all the time), and\n\n\t- \"git fmt-patch HEAD^\" does not work as expected: it outputs\n\t  *all* commits reachable from HEAD^!\n\nThe last one is possibly a showstopper. At least I used to call that\ncommand quite often...\n\nSigned-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\n---\n builtin-log.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 60 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-log.c b/builtin-log.c\nindex a39aed6..a75a37f 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -69,12 +69,54 @@ int cmd_log(int argc, const char **argv,\n \treturn cmd_log_wc(argc, argv, envp, &rev);\n }\n \n+static int istitlechar(char c)\n+{\n+\treturn (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||\n+\t\t(c >= '0' && c <= '9') || c == '.' || c == '_';\n+}\n+\n+static void reopen_stdout(struct commit *commit, int nr)\n+{\n+\tchar filename[1024];\n+\tchar *sol;\n+\tint len;\n+\n+\n+\tsprintf(filename, \"%04d\", nr);\n+\tlen = strlen(filename);\n+\n+\tsol = strstr(commit->buffer, \"\\n\\n\");\n+\tif (sol) {\n+\t\tint j, space = 1;\n+\n+\t\tsol += 2;\n+\t\tfor (j = 0; len < 1024 - 6 && sol[j] && sol[j] != '\\n'; j++) {\n+\t\t\tif (istitlechar(sol[j])) {\n+\t\t\t\tif (space) {\n+\t\t\t\t\tfilename[len++] = '-';\n+\t\t\t\t\tspace = 0;\n+\t\t\t\t}\n+\t\t\t\tfilename[len++] = sol[j];\n+\t\t\t\tif (sol[j] == '.')\n+\t\t\t\t\twhile (sol[++j] == '.');\n+\t\t\t} else\n+\t\t\t\tspace = 1;\n+\t\t}\n+\t\twhile (filename[len - 1] == '.')\n+\t\t\tlen--;\n+\t}\n+\tstrcpy(filename + len, \".txt\");\n+\tfprintf(stderr, \"%s\\n\", filename);\n+\tfreopen(filename, \"w\", stdout);\n+}\n+\n int cmd_format_patch(int argc, const char **argv, char **envp)\n {\n \tstruct commit *commit;\n \tstruct commit **list = NULL;\n \tstruct rev_info rev;\n-\tint nr = 0;\n+\tint nr = 0, total;\n+\tint use_stdout = 0;\n \n \tinit_revisions(&rev);\n \trev.commit_format = CMIT_FMT_EMAIL;\n@@ -87,20 +129,37 @@ int cmd_format_patch(int argc, const cha\n \trev.diffopt.output_format = DIFF_FORMAT_PATCH;\n \targc = setup_revisions(argc, argv, &rev, \"HEAD\");\n \n+\twhile (argc > 1) {\n+\t\tif (!strcmp(argv[1], \"--stdout\"))\n+\t\t\tuse_stdout = 1;\n+\t\telse\n+\t\t\tdie (\"unrecognized argument: %s\", argv[1]);\n+\t\targc--;\n+\t\targv++;\n+\t}\n+\n \tprepare_revision_walk(&rev);\n \twhile ((commit = get_revision(&rev)) != NULL) {\n+\t\t/* ignore merges */\n+\t\tif (commit->parents && commit->parents->next)\n+\t\t\tcontinue;\n \t\tnr++;\n \t\tlist = realloc(list, nr * sizeof(list[0]));\n \t\tlist[nr - 1] = commit;\n \t}\n+\ttotal = nr;\n \twhile (0 <= --nr) {\n \t\tint shown;\n \t\tcommit = list[nr];\n+\t\tif (!use_stdout)\n+\t\t\treopen_stdout(commit, total - nr);\n \t\tshown = log_tree_commit(&rev, commit);\n \t\tfree(commit->buffer);\n \t\tcommit->buffer = NULL;\n \t\tif (shown)\n \t\t\tprintf(\"-- \\n%s\\n\\n\", git_version_string);\n+\t\tif (!use_stdout)\n+\t\t\tfclose(stdout);\n \t}\n \tfree(list);\n \treturn 0;\n-- \n1.3.1.g42859-dirty\n"},{"id":"19530","messageId":"Pine.LNX.4.63.0605050114590.12795@wbgn013.biozentrum.uni-wuerzburg.de","threadId":"4060","inReplyTo":"Pine.LNX.4.63.0605050106180.12713@wbgn013.biozentrum.uni-wuerzburg.de","subject":"Re: [PATCH] Teach fmt-patch to write individual files.","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2006-05-04T23:15:31Z","receivedAt":"2006-05-04T23:15:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nthis patch is faulty. I'll send a fixed patch in one minute.\n\nSorry,\nDscho\n"}]}