This option, when set, causes a fatal error if format-patch would overwrite an existing coverletter to avoid information loss if the letter was already edited before. This changes the return value of get_patch_filename() from void to int and its prototype now contains a new integer parameter 'check'. If 'check' is false, get_patch_filename() behaves as it did before and it will always return zero. If 'check' is true, get_patch_filename() will use access(3) to check whether the filename it created exists, if so get_patch_filename() returns 1; zero otherwise. This access(3) test is only done if the overwritecoverletter option is unset and reopen_stdout()'s new 'check' parameter is true. That is done only by make_cover_letter(). The default for overwritecoverletter is true, which means, that the default behaviour does not change. If overwritecoverletter was unset, there is the new --cover-overwrite option to temporarily force overwriting cover letters. Signed-off-by: Frank Terbeck <ft@xxxxxxxxxxxxxxxxxxx> --- builtin-log.c | 24 ++++++++++++++++++++---- log-tree.c | 9 ++++++--- log-tree.h | 4 ++-- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/builtin-log.c b/builtin-log.c index 82d8724..816b4c9 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -438,6 +438,7 @@ static int extra_cc_alloc; static int cover_letter = 0; static int cover_one_patch = 1; +static int cover_overwrite = 1; static void add_header(const char *value) { @@ -523,6 +524,10 @@ static int git_format_config(const char *var, const char *value, void *cb) cover_one_patch = git_config_bool(var, value); return 0; } + if (!strcmp(var, "format.overwritecoverletter")) { + cover_overwrite = git_config_bool(var, value); + return 0; + } return git_log_config(var, value, cb); } @@ -531,7 +536,7 @@ static FILE *realstdout = NULL; static const char *output_directory = NULL; static int outdir_offset; -static int reopen_stdout(struct commit *commit, struct rev_info *rev) +static int reopen_stdout(struct commit *commit, struct rev_info *rev, int check) { struct strbuf filename = STRBUF_INIT; int suffix_len = strlen(fmt_patch_suffix) + 1; @@ -545,7 +550,16 @@ static int reopen_stdout(struct commit *commit, struct rev_info *rev) strbuf_addch(&filename, '/'); } - get_patch_filename(commit, rev->nr, fmt_patch_suffix, &filename); + if (!cover_overwrite && check) { + int exists; + exists = get_patch_filename(commit, rev->nr, fmt_patch_suffix, + check, &filename); + if (exists) + die("Not overwriting existing coverletter: %s", + filename.buf); + } else + get_patch_filename(commit, rev->nr, fmt_patch_suffix, + 0, &filename); if (!DIFF_OPT_TST(&rev->diffopt, QUIET)) fprintf(realstdout, "%s\n", filename.buf + outdir_offset); @@ -656,7 +670,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, sha1_to_hex(head->object.sha1), committer, committer); } - if (!use_stdout && reopen_stdout(commit, rev)) + if (!use_stdout && reopen_stdout(commit, rev, 1)) return; if (commit) { @@ -880,6 +894,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) cover_letter = 1; else if (!strcmp(argv[i], "--cover-one-patch")) cover_one_patch = 1; + else if (!strcmp(argv[i], "--cover-overwrite")) + cover_overwrite = 1; else if (!strcmp(argv[i], "--no-binary")) no_binary_diff = 1; else if (!prefixcmp(argv[i], "--add-header=")) @@ -1086,7 +1102,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) } if (!use_stdout && reopen_stdout(numbered_files ? NULL : commit, - &rev)) + &rev, 0)) die("Failed to create output files"); shown = log_tree_commit(&rev, commit); free(commit->buffer); diff --git a/log-tree.c b/log-tree.c index 5bd29e6..7163abb 100644 --- a/log-tree.c +++ b/log-tree.c @@ -179,8 +179,8 @@ static int has_non_ascii(const char *s) return 0; } -void get_patch_filename(struct commit *commit, int nr, const char *suffix, - struct strbuf *buf) +int get_patch_filename(struct commit *commit, int nr, const char *suffix, + int check, struct strbuf *buf) { int suffix_len = strlen(suffix) + 1; int start_len = buf->len; @@ -194,6 +194,9 @@ void get_patch_filename(struct commit *commit, int nr, const char *suffix, strbuf_setlen(buf, max_len); strbuf_addstr(buf, suffix); } + if (check && (access(buf->buf, F_OK) == 0)) + return 1; + return 0; } void log_write_email_headers(struct rev_info *opt, struct commit *commit, @@ -262,7 +265,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit, extra_headers = subject_buffer; get_patch_filename(opt->numbered_files ? NULL : commit, opt->nr, - opt->patch_suffix, &filename); + opt->patch_suffix, 0, &filename); snprintf(buffer, sizeof(buffer) - 1, "\n--%s%s\n" "Content-Type: text/x-patch;" diff --git a/log-tree.h b/log-tree.h index 20b5caf..8e91b7a 100644 --- a/log-tree.h +++ b/log-tree.h @@ -20,7 +20,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit, void load_ref_decorations(void); #define FORMAT_PATCH_NAME_MAX 64 -void get_patch_filename(struct commit *commit, int nr, const char *suffix, - struct strbuf *buf); +int get_patch_filename(struct commit *commit, int nr, const char *suffix, + int check, struct strbuf *buf); #endif -- 1.6.2.2.446.gfbdc0 -- To unsubscribe from this list: 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