diff options
Diffstat (limited to 'builtin-log.c')
-rw-r--r-- | builtin-log.c | 98 |
1 files changed, 33 insertions, 65 deletions
diff --git a/builtin-log.c b/builtin-log.c index c7a5772594..193de3ff2e 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -419,12 +419,6 @@ int cmd_log(int argc, const char **argv, const char *prefix) /* format-patch */ #define FORMAT_PATCH_NAME_MAX 64 -static int istitlechar(char c) -{ - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || c == '.' || c == '_'; -} - static const char *fmt_patch_suffix = ".patch"; static int numbered = 0; static int auto_number = 1; @@ -519,61 +513,33 @@ static int git_format_config(const char *var, const char *value, void *cb) } -static const char *get_oneline_for_filename(struct commit *commit, - int keep_subject) +static void get_patch_filename(struct commit *commit, int nr, + const char *suffix, struct strbuf *buf) { - static char filename[PATH_MAX]; - char *sol; - int len = 0; - int suffix_len = strlen(fmt_patch_suffix) + 1; - - sol = strstr(commit->buffer, "\n\n"); - if (!sol) - filename[0] = '\0'; - else { - int j, space = 0; - - sol += 2; - /* strip [PATCH] or [PATCH blabla] */ - if (!keep_subject && !prefixcmp(sol, "[PATCH")) { - char *eos = strchr(sol + 6, ']'); - if (eos) { - while (isspace(*eos)) - eos++; - sol = eos; - } - } + int suffix_len = strlen(suffix) + 1; + int start_len = buf->len; - for (j = 0; - j < FORMAT_PATCH_NAME_MAX - suffix_len - 5 && - len < sizeof(filename) - suffix_len && - 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 + 1] == '.') - j++; - } else - space = 1; - } - while (filename[len - 1] == '.' - || filename[len - 1] == '-') - len--; - filename[len] = '\0'; + strbuf_addf(buf, commit ? "%04d-" : "%d", nr); + if (commit) { + format_commit_message(commit, "%f", buf, DATE_NORMAL); + /* + * Replace characters at the end with the suffix if the + * filename is too long + */ + if (buf->len + suffix_len > FORMAT_PATCH_NAME_MAX + start_len) + strbuf_splice(buf, + start_len + FORMAT_PATCH_NAME_MAX - suffix_len, + suffix_len, suffix, suffix_len); + else + strbuf_addstr(buf, suffix); } - return filename; } static FILE *realstdout = NULL; static const char *output_directory = NULL; static int outdir_offset; -static int reopen_stdout(const char *oneline, int nr, struct rev_info *rev) +static int reopen_stdout(const char *oneline, struct rev_info *rev) { char filename[PATH_MAX]; int len = 0; @@ -589,14 +555,7 @@ static int reopen_stdout(const char *oneline, int nr, struct rev_info *rev) filename[len++] = '/'; } - if (!oneline) - len += sprintf(filename + len, "%d", nr); - else { - len += sprintf(filename + len, "%04d-", nr); - len += snprintf(filename + len, sizeof(filename) - len - 1 - - suffix_len, "%s", oneline); - strcpy(filename + len, fmt_patch_suffix); - } + strncpy(filename + len, oneline, PATH_MAX - len); if (!DIFF_OPT_TST(&rev->diffopt, QUIET)) fprintf(realstdout, "%s\n", filename + outdir_offset); @@ -684,12 +643,17 @@ 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]; if (rev->commit_format != CMIT_FMT_EMAIL) die("Cover letter needs email format"); - if (!use_stdout && reopen_stdout(numbered_files ? - NULL : "cover-letter", 0, rev)) + if (numbered_files) + sprintf(filename, "0"); + else + sprintf(filename, "%04d-cover-letter%s", 0, fmt_patch_suffix); + + if (!use_stdout && reopen_stdout(filename, rev)) return; head_sha1 = sha1_to_hex(head->object.sha1); @@ -802,6 +766,7 @@ 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); @@ -1104,10 +1069,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) } gen_message_id(&rev, sha1_to_hex(commit->object.sha1)); } - if (!use_stdout && reopen_stdout(numbered_files ? NULL : - get_oneline_for_filename(commit, keep_subject), - rev.nr, &rev)) + + get_patch_filename(numbered_files ? NULL : commit, rev.nr, + fmt_patch_suffix, &patch_filename); + if (!use_stdout && reopen_stdout(patch_filename.buf, &rev)) die("Failed to create output files"); + strbuf_setlen(&patch_filename, 0); shown = log_tree_commit(&rev, commit); free(commit->buffer); commit->buffer = NULL; @@ -1131,6 +1098,7 @@ 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); |