Skip to content

Commit 473c622

Browse files
committed
Merge branch 'jc/format-patch-name-max'
The maximum length of output filenames "git format-patch" creates has become configurable (used to be capped at 64). * jc/format-patch-name-max: format-patch: make output filename configurable
2 parents faefdd6 + 3baf58b commit 473c622

File tree

7 files changed

+83
-8
lines changed

7 files changed

+83
-8
lines changed

Documentation/config/format.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ format.outputDirectory::
9494
Set a custom directory to store the resulting files instead of the
9595
current working directory. All directory components will be created.
9696

97+
format.filenameMaxLength::
98+
The maximum length of the output filenames generated by the
99+
`format-patch` command; defaults to 64. Can be overridden
100+
by the `--filename-max-length=<n>` command line option.
101+
97102
format.useAutoBase::
98103
A boolean value which lets you enable the `--base=auto` option of
99104
format-patch by default. Can also be set to "whenAble" to allow

Documentation/git-format-patch.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SYNOPSIS
2828
[--no-notes | --notes[=<ref>]]
2929
[--interdiff=<previous>]
3030
[--range-diff=<previous> [--creation-factor=<percent>]]
31+
[--filename-max-length=<n>]
3132
[--progress]
3233
[<common diff options>]
3334
[ <since> | <revision range> ]
@@ -200,6 +201,13 @@ populated with placeholder text.
200201
allows for useful naming of a patch series, and can be
201202
combined with the `--numbered` option.
202203

204+
--filename-max-length=<n>::
205+
Instead of the standard 64 bytes, chomp the generated output
206+
filenames at around '<n>' bytes (too short a value will be
207+
silently raised to a reasonable length). Defaults to the
208+
value of the `format.filenameMaxLength` configuration
209+
variable, or 64 if unconfigured.
210+
203211
--rfc::
204212
Alias for `--subject-prefix="RFC PATCH"`. RFC means "Request For
205213
Comments"; use this when sending an experimental patch for

builtin/log.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#define MAIL_DEFAULT_WRAP 72
3939
#define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100
40+
#define FORMAT_PATCH_NAME_MAX_DEFAULT 64
4041

4142
/* Set a default date-time format for git log ("log.date" config variable) */
4243
static const char *default_date_mode = NULL;
@@ -50,6 +51,7 @@ static int decoration_style;
5051
static int decoration_given;
5152
static int use_mailmap_config = 1;
5253
static const char *fmt_patch_subject_prefix = "PATCH";
54+
static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT;
5355
static const char *fmt_pretty;
5456

5557
static const char * const builtin_log_usage[] = {
@@ -150,6 +152,7 @@ static void cmd_log_init_defaults(struct rev_info *rev)
150152
rev->abbrev_commit = default_abbrev_commit;
151153
rev->show_root_diff = default_show_root;
152154
rev->subject_prefix = fmt_patch_subject_prefix;
155+
rev->patch_name_max = fmt_patch_name_max;
153156
rev->show_signature = default_show_signature;
154157
rev->encode_email_headers = default_encode_email_headers;
155158
rev->diffopt.flags.allow_textconv = 1;
@@ -457,6 +460,10 @@ static int git_log_config(const char *var, const char *value, void *cb)
457460
return git_config_string(&fmt_pretty, var, value);
458461
if (!strcmp(var, "format.subjectprefix"))
459462
return git_config_string(&fmt_patch_subject_prefix, var, value);
463+
if (!strcmp(var, "format.filenamemaxlength")) {
464+
fmt_patch_name_max = git_config_int(var, value);
465+
return 0;
466+
}
460467
if (!strcmp(var, "format.encodeemailheaders")) {
461468
default_encode_email_headers = git_config_bool(var, value);
462469
return 0;
@@ -958,15 +965,9 @@ static int open_next_file(struct commit *commit, const char *subject,
958965
struct rev_info *rev, int quiet)
959966
{
960967
struct strbuf filename = STRBUF_INIT;
961-
int suffix_len = strlen(rev->patch_suffix) + 1;
962968

963969
if (output_directory) {
964970
strbuf_addstr(&filename, output_directory);
965-
if (filename.len >=
966-
PATH_MAX - FORMAT_PATCH_NAME_MAX - suffix_len) {
967-
strbuf_release(&filename);
968-
return error(_("name of output directory is too long"));
969-
}
970971
strbuf_complete(&filename, '/');
971972
}
972973

@@ -1754,6 +1755,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
17541755
N_("start numbering patches at <n> instead of 1")),
17551756
OPT_INTEGER('v', "reroll-count", &reroll_count,
17561757
N_("mark the series as Nth re-roll")),
1758+
OPT_INTEGER(0, "filename-max-length", &fmt_patch_name_max,
1759+
N_("max length of output filename")),
17571760
OPT_CALLBACK_F(0, "rfc", &rev, NULL,
17581761
N_("Use [RFC PATCH] instead of [PATCH]"),
17591762
PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback),
@@ -1854,6 +1857,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
18541857
PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN |
18551858
PARSE_OPT_KEEP_DASHDASH);
18561859

1860+
/* Make sure "0000-$sub.patch" gives non-negative length for $sub */
1861+
if (fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix))
1862+
fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix);
1863+
18571864
if (cover_from_description_arg)
18581865
cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
18591866

@@ -1938,6 +1945,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
19381945
rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
19391946

19401947
rev.zero_commit = zero_commit;
1948+
rev.patch_name_max = fmt_patch_name_max;
19411949

19421950
if (!rev.diffopt.flags.text && !no_binary_diff)
19431951
rev.diffopt.flags.binary = 1;

log-tree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ void fmt_output_subject(struct strbuf *filename,
367367
const char *suffix = info->patch_suffix;
368368
int nr = info->nr;
369369
int start_len = filename->len;
370-
int max_len = start_len + FORMAT_PATCH_NAME_MAX - (strlen(suffix) + 1);
370+
int max_len = start_len + info->patch_name_max - (strlen(suffix) + 1);
371371

372372
if (0 < info->reroll_count)
373373
strbuf_addf(filename, "v%d-", info->reroll_count);

log-tree.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
3333
int maybe_multipart);
3434
void load_ref_decorations(struct decoration_filter *filter, int flags);
3535

36-
#define FORMAT_PATCH_NAME_MAX 64
3736
void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *);
3837
void fmt_output_subject(struct strbuf *, const char *subject, struct rev_info *);
3938
void fmt_output_email_subject(struct strbuf *, struct rev_info *);

revision.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ struct rev_info {
238238
const char *extra_headers;
239239
const char *log_reencode;
240240
const char *subject_prefix;
241+
int patch_name_max;
241242
int no_inline;
242243
int show_log_size;
243244
struct string_list *mailmap;

t/t4014-format-patch.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,60 @@ test_expect_success 'multiple files' '
313313
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
314314
'
315315

316+
test_expect_success 'filename length limit' '
317+
test_when_finished "rm -f 000*" &&
318+
rm -rf 000[1-9]-*.patch &&
319+
for len in 15 25 35
320+
do
321+
git format-patch --filename-max-length=$len -3 side &&
322+
max=$(
323+
for patch in 000[1-9]-*.patch
324+
do
325+
echo "$patch" | wc -c
326+
done |
327+
sort -nr |
328+
head -n 1
329+
) &&
330+
test $max -le $len || return 1
331+
done
332+
'
333+
334+
test_expect_success 'filename length limit from config' '
335+
test_when_finished "rm -f 000*" &&
336+
rm -rf 000[1-9]-*.patch &&
337+
for len in 15 25 35
338+
do
339+
git -c format.filenameMaxLength=$len format-patch -3 side &&
340+
max=$(
341+
for patch in 000[1-9]-*.patch
342+
do
343+
echo "$patch" | wc -c
344+
done |
345+
sort -nr |
346+
head -n 1
347+
) &&
348+
test $max -le $len || return 1
349+
done
350+
'
351+
352+
test_expect_success 'filename limit applies only to basename' '
353+
test_when_finished "rm -rf patches/" &&
354+
rm -rf patches/ &&
355+
for len in 15 25 35
356+
do
357+
git format-patch -o patches --filename-max-length=$len -3 side &&
358+
max=$(
359+
for patch in patches/000[1-9]-*.patch
360+
do
361+
echo "${patch#patches/}" | wc -c
362+
done |
363+
sort -nr |
364+
head -n 1
365+
) &&
366+
test $max -le $len || return 1
367+
done
368+
'
369+
316370
test_expect_success 'reroll count' '
317371
rm -fr patches &&
318372
git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&

0 commit comments

Comments
 (0)