[--no-notes | --notes[=<ref>]]
[--interdiff=<previous>]
[--range-diff=<previous> [--creation-factor=<percent>]]
+ [--filename-max-length=<n>]
[--progress]
[<common diff options>]
[ <since> | <revision range> ]
allows for useful naming of a patch series, and can be
combined with the `--numbered` option.
+--filename-max-length=<n>::
+ Instead of the standard 64 bytes, chomp the generated output
+ filenames at around '<n>' bytes (too short a value will be
+ silently raised to a reasonable length). Defaults to the
+ value of the `format.filenameMaxLength` configuration
+ variable, or 64 if unconfigured.
+
--rfc::
Alias for `--subject-prefix="RFC PATCH"`. RFC means "Request For
Comments"; use this when sending an experimental patch for
#define MAIL_DEFAULT_WRAP 72
#define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100
+#define FORMAT_PATCH_NAME_MAX_DEFAULT 64
/* Set a default date-time format for git log ("log.date" config variable) */
static const char *default_date_mode = NULL;
static int decoration_given;
static int use_mailmap_config = 1;
static const char *fmt_patch_subject_prefix = "PATCH";
+static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT;
static const char *fmt_pretty;
static const char * const builtin_log_usage[] = {
rev->abbrev_commit = default_abbrev_commit;
rev->show_root_diff = default_show_root;
rev->subject_prefix = fmt_patch_subject_prefix;
+ rev->patch_name_max = fmt_patch_name_max;
rev->show_signature = default_show_signature;
rev->encode_email_headers = default_encode_email_headers;
rev->diffopt.flags.allow_textconv = 1;
return git_config_string(&fmt_pretty, var, value);
if (!strcmp(var, "format.subjectprefix"))
return git_config_string(&fmt_patch_subject_prefix, var, value);
+ if (!strcmp(var, "format.filenamemaxlength")) {
+ fmt_patch_name_max = git_config_int(var, value);
+ return 0;
+ }
if (!strcmp(var, "format.encodeemailheaders")) {
default_encode_email_headers = git_config_bool(var, value);
return 0;
struct rev_info *rev, int quiet)
{
struct strbuf filename = STRBUF_INIT;
- int suffix_len = strlen(rev->patch_suffix) + 1;
if (output_directory) {
strbuf_addstr(&filename, output_directory);
- if (filename.len >=
- PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len) {
- strbuf_release(&filename);
- return error(_("name of output directory is too long"));
- }
strbuf_complete(&filename, '/');
}
N_("start numbering patches at <n> instead of 1")),
OPT_INTEGER('v', "reroll-count", &reroll_count,
N_("mark the series as Nth re-roll")),
+ OPT_INTEGER(0, "filename-max-length", &fmt_patch_name_max,
+ N_("max length of output filename")),
OPT_CALLBACK_F(0, "rfc", &rev, NULL,
N_("Use [RFC PATCH] instead of [PATCH]"),
PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback),
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
PARSE_OPT_KEEP_DASHDASH);
+ /* Make sure "0000-$sub.patch" gives non-negative length for $sub */
+ if (fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix))
+ fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix);
+
if (cover_from_description_arg)
cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
rev.zero_commit = zero_commit;
+ rev.patch_name_max = fmt_patch_name_max;
if (!rev.diffopt.flags.text && !no_binary_diff)
rev.diffopt.flags.binary = 1;
ls patches/0001-Side-changes-1.patch patches/0002-Side-changes-2.patch patches/0003-Side-changes-3-with-n-backslash-n-in-it.patch
'
+test_expect_success 'filename length limit' '
+ test_when_finished "rm -f 000*" &&
+ rm -rf 000[1-9]-*.patch &&
+ for len in 15 25 35
+ do
+ git format-patch --filename-max-length=$len -3 side &&
+ max=$(
+ for patch in 000[1-9]-*.patch
+ do
+ echo "$patch" | wc -c
+ done |
+ sort -nr |
+ head -n 1
+ ) &&
+ test $max -le $len || return 1
+ done
+'
+
+test_expect_success 'filename length limit from config' '
+ test_when_finished "rm -f 000*" &&
+ rm -rf 000[1-9]-*.patch &&
+ for len in 15 25 35
+ do
+ git -c format.filenameMaxLength=$len format-patch -3 side &&
+ max=$(
+ for patch in 000[1-9]-*.patch
+ do
+ echo "$patch" | wc -c
+ done |
+ sort -nr |
+ head -n 1
+ ) &&
+ test $max -le $len || return 1
+ done
+'
+
+test_expect_success 'filename limit applies only to basename' '
+ test_when_finished "rm -rf patches/" &&
+ rm -rf patches/ &&
+ for len in 15 25 35
+ do
+ git format-patch -o patches --filename-max-length=$len -3 side &&
+ max=$(
+ for patch in patches/000[1-9]-*.patch
+ do
+ echo "${patch#patches/}" | wc -c
+ done |
+ sort -nr |
+ head -n 1
+ ) &&
+ test $max -le $len || return 1
+ done
+'
+
test_expect_success 'reroll count' '
rm -fr patches &&
git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&