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