Git fork

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

+83 -8
+5
Documentation/config/format.txt
··· 94 Set a custom directory to store the resulting files instead of the 95 current working directory. All directory components will be created. 96 97 format.useAutoBase:: 98 A boolean value which lets you enable the `--base=auto` option of 99 format-patch by default. Can also be set to "whenAble" to allow
··· 94 Set a custom directory to store the resulting files instead of the 95 current working directory. All directory components will be created. 96 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 + 102 format.useAutoBase:: 103 A boolean value which lets you enable the `--base=auto` option of 104 format-patch by default. Can also be set to "whenAble" to allow
+8
Documentation/git-format-patch.txt
··· 28 [--no-notes | --notes[=<ref>]] 29 [--interdiff=<previous>] 30 [--range-diff=<previous> [--creation-factor=<percent>]] 31 [--progress] 32 [<common diff options>] 33 [ <since> | <revision range> ] ··· 199 line, instead use '[<subject prefix>]'. This 200 allows for useful naming of a patch series, and can be 201 combined with the `--numbered` option. 202 203 --rfc:: 204 Alias for `--subject-prefix="RFC PATCH"`. RFC means "Request For
··· 28 [--no-notes | --notes[=<ref>]] 29 [--interdiff=<previous>] 30 [--range-diff=<previous> [--creation-factor=<percent>]] 31 + [--filename-max-length=<n>] 32 [--progress] 33 [<common diff options>] 34 [ <since> | <revision range> ] ··· 200 line, instead use '[<subject prefix>]'. This 201 allows for useful naming of a patch series, and can be 202 combined with the `--numbered` option. 203 + 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 211 --rfc:: 212 Alias for `--subject-prefix="RFC PATCH"`. RFC means "Request For
+14 -6
builtin/log.c
··· 37 38 #define MAIL_DEFAULT_WRAP 72 39 #define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100 40 41 /* Set a default date-time format for git log ("log.date" config variable) */ 42 static const char *default_date_mode = NULL; ··· 50 static int decoration_given; 51 static int use_mailmap_config = 1; 52 static const char *fmt_patch_subject_prefix = "PATCH"; 53 static const char *fmt_pretty; 54 55 static const char * const builtin_log_usage[] = { ··· 150 rev->abbrev_commit = default_abbrev_commit; 151 rev->show_root_diff = default_show_root; 152 rev->subject_prefix = fmt_patch_subject_prefix; 153 rev->show_signature = default_show_signature; 154 rev->encode_email_headers = default_encode_email_headers; 155 rev->diffopt.flags.allow_textconv = 1; ··· 457 return git_config_string(&fmt_pretty, var, value); 458 if (!strcmp(var, "format.subjectprefix")) 459 return git_config_string(&fmt_patch_subject_prefix, var, value); 460 if (!strcmp(var, "format.encodeemailheaders")) { 461 default_encode_email_headers = git_config_bool(var, value); 462 return 0; ··· 958 struct rev_info *rev, int quiet) 959 { 960 struct strbuf filename = STRBUF_INIT; 961 - int suffix_len = strlen(rev->patch_suffix) + 1; 962 963 if (output_directory) { 964 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 - } 970 strbuf_complete(&filename, '/'); 971 } 972 ··· 1754 N_("start numbering patches at <n> instead of 1")), 1755 OPT_INTEGER('v', "reroll-count", &reroll_count, 1756 N_("mark the series as Nth re-roll")), 1757 OPT_CALLBACK_F(0, "rfc", &rev, NULL, 1758 N_("Use [RFC PATCH] instead of [PATCH]"), 1759 PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback), ··· 1854 PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN | 1855 PARSE_OPT_KEEP_DASHDASH); 1856 1857 if (cover_from_description_arg) 1858 cover_from_description_mode = parse_cover_from_description(cover_from_description_arg); 1859 ··· 1938 rev.diffopt.output_format |= DIFF_FORMAT_PATCH; 1939 1940 rev.zero_commit = zero_commit; 1941 1942 if (!rev.diffopt.flags.text && !no_binary_diff) 1943 rev.diffopt.flags.binary = 1;
··· 37 38 #define MAIL_DEFAULT_WRAP 72 39 #define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100 40 + #define FORMAT_PATCH_NAME_MAX_DEFAULT 64 41 42 /* Set a default date-time format for git log ("log.date" config variable) */ 43 static const char *default_date_mode = NULL; ··· 51 static int decoration_given; 52 static int use_mailmap_config = 1; 53 static const char *fmt_patch_subject_prefix = "PATCH"; 54 + static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT; 55 static const char *fmt_pretty; 56 57 static const char * const builtin_log_usage[] = { ··· 152 rev->abbrev_commit = default_abbrev_commit; 153 rev->show_root_diff = default_show_root; 154 rev->subject_prefix = fmt_patch_subject_prefix; 155 + rev->patch_name_max = fmt_patch_name_max; 156 rev->show_signature = default_show_signature; 157 rev->encode_email_headers = default_encode_email_headers; 158 rev->diffopt.flags.allow_textconv = 1; ··· 460 return git_config_string(&fmt_pretty, var, value); 461 if (!strcmp(var, "format.subjectprefix")) 462 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 + } 467 if (!strcmp(var, "format.encodeemailheaders")) { 468 default_encode_email_headers = git_config_bool(var, value); 469 return 0; ··· 965 struct rev_info *rev, int quiet) 966 { 967 struct strbuf filename = STRBUF_INIT; 968 969 if (output_directory) { 970 strbuf_addstr(&filename, output_directory); 971 strbuf_complete(&filename, '/'); 972 } 973 ··· 1755 N_("start numbering patches at <n> instead of 1")), 1756 OPT_INTEGER('v', "reroll-count", &reroll_count, 1757 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")), 1760 OPT_CALLBACK_F(0, "rfc", &rev, NULL, 1761 N_("Use [RFC PATCH] instead of [PATCH]"), 1762 PARSE_OPT_NOARG | PARSE_OPT_NONEG, rfc_callback), ··· 1857 PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN | 1858 PARSE_OPT_KEEP_DASHDASH); 1859 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 + 1864 if (cover_from_description_arg) 1865 cover_from_description_mode = parse_cover_from_description(cover_from_description_arg); 1866 ··· 1945 rev.diffopt.output_format |= DIFF_FORMAT_PATCH; 1946 1947 rev.zero_commit = zero_commit; 1948 + rev.patch_name_max = fmt_patch_name_max; 1949 1950 if (!rev.diffopt.flags.text && !no_binary_diff) 1951 rev.diffopt.flags.binary = 1;
+1 -1
log-tree.c
··· 367 const char *suffix = info->patch_suffix; 368 int nr = info->nr; 369 int start_len = filename->len; 370 - int max_len = start_len + FORMAT_PATCH_NAME_MAX - (strlen(suffix) + 1); 371 372 if (0 < info->reroll_count) 373 strbuf_addf(filename, "v%d-", info->reroll_count);
··· 367 const char *suffix = info->patch_suffix; 368 int nr = info->nr; 369 int start_len = filename->len; 370 + int max_len = start_len + info->patch_name_max - (strlen(suffix) + 1); 371 372 if (0 < info->reroll_count) 373 strbuf_addf(filename, "v%d-", info->reroll_count);
-1
log-tree.h
··· 33 int maybe_multipart); 34 void load_ref_decorations(struct decoration_filter *filter, int flags); 35 36 - #define FORMAT_PATCH_NAME_MAX 64 37 void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *); 38 void fmt_output_subject(struct strbuf *, const char *subject, struct rev_info *); 39 void fmt_output_email_subject(struct strbuf *, struct rev_info *);
··· 33 int maybe_multipart); 34 void load_ref_decorations(struct decoration_filter *filter, int flags); 35 36 void fmt_output_commit(struct strbuf *, struct commit *, struct rev_info *); 37 void fmt_output_subject(struct strbuf *, const char *subject, struct rev_info *); 38 void fmt_output_email_subject(struct strbuf *, struct rev_info *);
+1
revision.h
··· 238 const char *extra_headers; 239 const char *log_reencode; 240 const char *subject_prefix; 241 int no_inline; 242 int show_log_size; 243 struct string_list *mailmap;
··· 238 const char *extra_headers; 239 const char *log_reencode; 240 const char *subject_prefix; 241 + int patch_name_max; 242 int no_inline; 243 int show_log_size; 244 struct string_list *mailmap;
+54
t/t4014-format-patch.sh
··· 313 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 314 ' 315 316 test_expect_success 'reroll count' ' 317 rm -fr patches && 318 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&
··· 313 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 314 ' 315 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 + 370 test_expect_success 'reroll count' ' 371 rm -fr patches && 372 git format-patch -o patches --cover-letter --reroll-count 4 master..side >list &&