builtin/log: stop using globals for format config
This commit does the exact same as the preceding commit, only for the format configuration instead of the log configuration. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Patrick Steinhardt committed
May 27, 2024 at 13:46 UTC
83024d98f78684fce3d4d0598e6b2b147a4b2ffa
1 file changed
+265
-202
builtin/log.c
+265
-202
@@ -945,36 +945,6 @@ int cmd_log(int argc, const char **argv, const char *prefix)
945
946
/* format-patch */
947
948
-static const char *fmt_patch_suffix = ".patch";
949
-static int numbered = 0;
950
-static int auto_number = 1;
951
-
952
-static char *default_attach = NULL;
953
-
954
-static struct string_list extra_hdr = STRING_LIST_INIT_NODUP;
955
-static struct string_list extra_to = STRING_LIST_INIT_NODUP;
956
-static struct string_list extra_cc = STRING_LIST_INIT_NODUP;
957
-
958
-static void add_header(const char *value)
959
-{
960
- struct string_list_item *item;
961
- int len = strlen(value);
962
- while (len && value[len - 1] == '\n')
963
- len--;
964
-
965
- if (!strncasecmp(value, "to: ", 4)) {
966
- item = string_list_append(&extra_to, value + 4);
967
- len -= 4;
968
- } else if (!strncasecmp(value, "cc: ", 4)) {
969
- item = string_list_append(&extra_cc, value + 4);
970
- len -= 4;
971
- } else {
972
- item = string_list_append(&extra_hdr, value);
973
- }
974
-
975
- item->string[len] = '\0';
976
-}
977
-
948
enum cover_setting {
949
COVER_UNSET,
950
COVER_OFF,
@@ -1001,17 +971,61 @@ enum auto_base_setting {
971
AUTO_BASE_WHEN_ABLE
972
};
973
1004
-static enum thread_level thread;
1005
-static int do_signoff;
1006
-static enum auto_base_setting auto_base;
1007
-static char *from;
1008
-static const char *signature = git_version_string;
1009
-static char *signature_file;
1010
-static enum cover_setting config_cover_letter;
1011
-static const char *config_output_directory;
1012
-static enum cover_from_description cover_from_description_mode = COVER_FROM_MESSAGE;
1013
-static int show_notes;
1014
-static struct display_notes_opt notes_opt;
974
+struct format_config {
975
+ struct log_config log;
976
+ enum thread_level thread;
977
+ int do_signoff;
978
+ enum auto_base_setting auto_base;
979
+ char *base_commit;
980
+ char *from;
981
+ char *signature;
982
+ char *signature_file;
983
+ enum cover_setting config_cover_letter;
984
+ char *config_output_directory;
985
+ enum cover_from_description cover_from_description_mode;
986
+ int show_notes;
987
+ struct display_notes_opt notes_opt;
988
+ int numbered_cmdline_opt;
989
+ int numbered;
990
+ int auto_number;
991
+ char *default_attach;
992
+ struct string_list extra_hdr;
993
+ struct string_list extra_to;
994
+ struct string_list extra_cc;
995
+ int keep_subject;
996
+ int subject_prefix;
997
+ struct strbuf sprefix;
998
+ char *fmt_patch_suffix;
999
+};
1000
+
1001
+static void format_config_init(struct format_config *cfg)
1002
+{
1003
+ memset(cfg, 0, sizeof(*cfg));
1004
+ log_config_init(&cfg->log);
1005
+ cfg->cover_from_description_mode = COVER_FROM_MESSAGE;
1006
+ cfg->auto_number = 1;
1007
+ string_list_init_dup(&cfg->extra_hdr);
1008
+ string_list_init_dup(&cfg->extra_to);
1009
+ string_list_init_dup(&cfg->extra_cc);
1010
+ strbuf_init(&cfg->sprefix, 0);
1011
+ cfg->fmt_patch_suffix = xstrdup(".patch");
1012
+}
1013
+
1014
+static void format_config_release(struct format_config *cfg)
1015
+{
1016
+ log_config_release(&cfg->log);
1017
+ free(cfg->base_commit);
1018
+ free(cfg->from);
1019
+ free(cfg->signature);
1020
+ free(cfg->signature_file);
1021
+ free(cfg->config_output_directory);
1022
+ free(cfg->default_attach);
1023
+ string_list_clear(&cfg->extra_hdr, 0);
1024
+ string_list_clear(&cfg->extra_to, 0);
1025
+ string_list_clear(&cfg->extra_cc, 0);
1026
+ strbuf_release(&cfg->sprefix);
1027
+ free(cfg->fmt_patch_suffix);
1028
+}
1029
1030
static enum cover_from_description parse_cover_from_description(const char *arg)
1031
{
@@ -1029,27 +1043,51 @@ static enum cover_from_description parse_cover_from_description(const char *arg)
1043
die(_("%s: invalid cover from description mode"), arg);
1044
}
1045
1046
+static void add_header(struct format_config *cfg, const char *value)
1047
+{
1048
+ struct string_list_item *item;
1049
+ int len = strlen(value);
1050
+ while (len && value[len - 1] == '\n')
1051
+ len--;
1052
+
1053
+ if (!strncasecmp(value, "to: ", 4)) {
1054
+ item = string_list_append(&cfg->extra_to, value + 4);
1055
+ len -= 4;
1056
+ } else if (!strncasecmp(value, "cc: ", 4)) {
1057
+ item = string_list_append(&cfg->extra_cc, value + 4);
1058
+ len -= 4;
1059
+ } else {
1060
+ item = string_list_append(&cfg->extra_hdr, value);
1061
+ }
1062
+
1063
+ item->string[len] = '\0';
1064
+}
1065
+
1066
static int git_format_config(const char *var, const char *value,
1067
const struct config_context *ctx, void *cb)
1068
{
1069
+ struct format_config *cfg = cb;
1070
+
1071
if (!strcmp(var, "format.headers")) {
1072
if (!value)
1073
die(_("format.headers without value"));
1038
- add_header(value);
1074
+ add_header(cfg, value);
1075
return 0;
1076
}
1041
- if (!strcmp(var, "format.suffix"))
1042
- return git_config_string(&fmt_patch_suffix, var, value);
1077
+ if (!strcmp(var, "format.suffix")) {
1078
+ FREE_AND_NULL(cfg->fmt_patch_suffix);
1079
+ return git_config_string((const char **) &cfg->fmt_patch_suffix, var, value);
1080
+ }
1081
if (!strcmp(var, "format.to")) {
1082
if (!value)
1083
return config_error_nonbool(var);
1046
- string_list_append(&extra_to, value);
1084
+ string_list_append(&cfg->extra_to, value);
1085
return 0;
1086
}
1087
if (!strcmp(var, "format.cc")) {
1088
if (!value)
1089
return config_error_nonbool(var);
1052
- string_list_append(&extra_cc, value);
1090
+ string_list_append(&cfg->extra_cc, value);
1091
return 0;
1092
}
1093
if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff") ||
@@ -1058,69 +1096,76 @@ static int git_format_config(const char *var, const char *value,
1096
}
1097
if (!strcmp(var, "format.numbered")) {
1098
if (value && !strcasecmp(value, "auto")) {
1061
- auto_number = 1;
1099
+ cfg->auto_number = 1;
1100
return 0;
1101
}
1064
- numbered = git_config_bool(var, value);
1065
- auto_number = auto_number && numbered;
1102
+ cfg->numbered = git_config_bool(var, value);
1103
+ cfg->auto_number = cfg->auto_number && cfg->numbered;
1104
return 0;
1105
}
1106
if (!strcmp(var, "format.attach")) {
1069
- if (value && *value)
1070
- default_attach = xstrdup(value);
1071
- else if (value && !*value)
1072
- FREE_AND_NULL(default_attach);
1073
- else
1074
- default_attach = xstrdup(git_version_string);
1107
+ if (value && *value) {
1108
+ FREE_AND_NULL(cfg->default_attach);
1109
+ cfg->default_attach = xstrdup(value);
1110
+ } else if (value && !*value) {
1111
+ FREE_AND_NULL(cfg->default_attach);
1112
+ } else {
1113
+ FREE_AND_NULL(cfg->default_attach);
1114
+ cfg->default_attach = xstrdup(git_version_string);
1115
+ }
1116
return 0;
1117
}
1118
if (!strcmp(var, "format.thread")) {
1119
if (value && !strcasecmp(value, "deep")) {
1079
- thread = THREAD_DEEP;
1120
+ cfg->thread = THREAD_DEEP;
1121
return 0;
1122
}
1123
if (value && !strcasecmp(value, "shallow")) {
1083
- thread = THREAD_SHALLOW;
1124
+ cfg->thread = THREAD_SHALLOW;
1125
return 0;
1126
}
1086
- thread = git_config_bool(var, value) ? THREAD_SHALLOW : THREAD_UNSET;
1127
+ cfg->thread = git_config_bool(var, value) ? THREAD_SHALLOW : THREAD_UNSET;
1128
return 0;
1129
}
1130
if (!strcmp(var, "format.signoff")) {
1090
- do_signoff = git_config_bool(var, value);
1131
+ cfg->do_signoff = git_config_bool(var, value);
1132
return 0;
1133
}
1093
- if (!strcmp(var, "format.signature"))
1094
- return git_config_string(&signature, var, value);
1095
- if (!strcmp(var, "format.signaturefile"))
1096
- return git_config_pathname(&signature_file, var, value);
1134
+ if (!strcmp(var, "format.signature")) {
1135
+ FREE_AND_NULL(cfg->signature);
1136
+ return git_config_string((const char **) &cfg->signature, var, value);
1137
+ }
1138
+ if (!strcmp(var, "format.signaturefile")) {
1139
+ FREE_AND_NULL(cfg->signature_file);
1140
+ return git_config_pathname(&cfg->signature_file, var, value);
1141
+ }
1142
if (!strcmp(var, "format.coverletter")) {
1143
if (value && !strcasecmp(value, "auto")) {
1099
- config_cover_letter = COVER_AUTO;
1144
+ cfg->config_cover_letter = COVER_AUTO;
1145
return 0;
1146
}
1102
- config_cover_letter = git_config_bool(var, value) ? COVER_ON : COVER_OFF;
1147
+ cfg->config_cover_letter = git_config_bool(var, value) ? COVER_ON : COVER_OFF;
1148
return 0;
1149
}
1105
- if (!strcmp(var, "format.outputdirectory"))
1106
- return git_config_string(&config_output_directory, var, value);
1150
+ if (!strcmp(var, "format.outputdirectory")) {
1151
+ FREE_AND_NULL(cfg->config_output_directory);
1152
+ return git_config_string((const char **) &cfg->config_output_directory, var, value);
1153
+ }
1154
if (!strcmp(var, "format.useautobase")) {
1155
if (value && !strcasecmp(value, "whenAble")) {
1109
- auto_base = AUTO_BASE_WHEN_ABLE;
1156
+ cfg->auto_base = AUTO_BASE_WHEN_ABLE;
1157
return 0;
1158
}
1112
- auto_base = git_config_bool(var, value) ? AUTO_BASE_ALWAYS : AUTO_BASE_NEVER;
1159
+ cfg->auto_base = git_config_bool(var, value) ? AUTO_BASE_ALWAYS : AUTO_BASE_NEVER;
1160
return 0;
1161
}
1162
if (!strcmp(var, "format.from")) {
1163
int b = git_parse_maybe_bool(value);
1117
- free(from);
1164
+ FREE_AND_NULL(cfg->from);
1165
if (b < 0)
1119
- from = xstrdup(value);
1166
+ cfg->from = xstrdup(value);
1167
else if (b)
1121
- from = xstrdup(git_committer_info(IDENT_NO_DATE));
1122
- else
1123
- from = NULL;
1168
+ cfg->from = xstrdup(git_committer_info(IDENT_NO_DATE));
1169
return 0;
1170
}
1171
if (!strcmp(var, "format.forceinbodyfrom")) {
@@ -1130,15 +1175,15 @@ static int git_format_config(const char *var, const char *value,
1175
if (!strcmp(var, "format.notes")) {
1176
int b = git_parse_maybe_bool(value);
1177
if (b < 0)
1133
- enable_ref_display_notes(¬es_opt, &show_notes, value);
1178
+ enable_ref_display_notes(&cfg->notes_opt, &cfg->show_notes, value);
1179
else if (b)
1135
- enable_default_display_notes(¬es_opt, &show_notes);
1180
+ enable_default_display_notes(&cfg->notes_opt, &cfg->show_notes);
1181
else
1137
- disable_display_notes(¬es_opt, &show_notes);
1182
+ disable_display_notes(&cfg->notes_opt, &cfg->show_notes);
1183
return 0;
1184
}
1185
if (!strcmp(var, "format.coverfromdescription")) {
1141
- cover_from_description_mode = parse_cover_from_description(value);
1186
+ cfg->cover_from_description_mode = parse_cover_from_description(value);
1187
return 0;
1188
}
1189
if (!strcmp(var, "format.mboxrd")) {
@@ -1159,7 +1204,7 @@ static int git_format_config(const char *var, const char *value,
1204
if (!strcmp(var, "diff.noprefix"))
1205
return 0;
1206
1162
- return git_log_config(var, value, ctx, cb);
1207
+ return git_log_config(var, value, ctx, &cfg->log);
1208
}
1209
1210
static const char *output_directory = NULL;
@@ -1247,7 +1292,7 @@ static void gen_message_id(struct rev_info *info, char *base)
1292
info->message_id = strbuf_detach(&buf, NULL);
1293
}
1294
1250
-static void print_signature(FILE *file)
1295
+static void print_signature(const char *signature, FILE *file)
1296
{
1297
if (!signature || !*signature)
1298
return;
@@ -1317,14 +1362,15 @@ static void prepare_cover_text(struct pretty_print_context *pp,
1362
const char *branch_name,
1363
struct strbuf *sb,
1364
const char *encoding,
1320
- int need_8bit_cte)
1365
+ int need_8bit_cte,
1366
+ const struct format_config *cfg)
1367
{
1368
const char *subject = "*** SUBJECT HERE ***";
1369
const char *body = "*** BLURB HERE ***";
1370
struct strbuf description_sb = STRBUF_INIT;
1371
struct strbuf subject_sb = STRBUF_INIT;
1372
1327
- if (cover_from_description_mode == COVER_FROM_NONE)
1373
+ if (cfg->cover_from_description_mode == COVER_FROM_NONE)
1374
goto do_pp;
1375
1376
if (description_file && *description_file)
@@ -1334,13 +1380,13 @@ static void prepare_cover_text(struct pretty_print_context *pp,
1380
if (!description_sb.len)
1381
goto do_pp;
1382
1337
- if (cover_from_description_mode == COVER_FROM_SUBJECT ||
1338
- cover_from_description_mode == COVER_FROM_AUTO)
1383
+ if (cfg->cover_from_description_mode == COVER_FROM_SUBJECT ||
1384
+ cfg->cover_from_description_mode == COVER_FROM_AUTO)
1385
body = format_subject(&subject_sb, description_sb.buf, " ");
1386
1341
- if (cover_from_description_mode == COVER_FROM_MESSAGE ||
1342
- (cover_from_description_mode == COVER_FROM_AUTO &&
1343
- subject_sb.len > COVER_FROM_AUTO_MAX_SUBJECT_LEN))
1387
+ if (cfg->cover_from_description_mode == COVER_FROM_MESSAGE ||
1388
+ (cfg->cover_from_description_mode == COVER_FROM_AUTO &&
1389
+ subject_sb.len > COVER_FROM_AUTO_MAX_SUBJECT_LEN))
1390
body = description_sb.buf;
1391
else
1392
subject = subject_sb.buf;
@@ -1377,7 +1423,8 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
1423
int nr, struct commit **list,
1424
const char *description_file,
1425
const char *branch_name,
1380
- int quiet)
1426
+ int quiet,
1427
+ const struct format_config *cfg)
1428
{
1429
const char *committer;
1430
struct shortlog log;
@@ -1416,7 +1463,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file,
1463
pp.encode_email_headers = rev->encode_email_headers;
1464
pp_user_info(&pp, NULL, &sb, committer, encoding);
1465
prepare_cover_text(&pp, description_file, branch_name, &sb,
1419
- encoding, need_8bit_cte);
1466
+ encoding, need_8bit_cte, cfg);
1467
fprintf(rev->diffopt.file, "%s\n", sb.buf);
1468
1469
free(pp.after_subject);
@@ -1517,29 +1564,30 @@ static const char * const builtin_format_patch_usage[] = {
1564
NULL
1565
};
1566
1520
-static int keep_subject = 0;
1567
+struct keep_callback_data {
1568
+ struct format_config *cfg;
1569
+ struct rev_info *revs;
1570
+};
1571
1572
static int keep_callback(const struct option *opt, const char *arg, int unset)
1573
{
1574
+ struct keep_callback_data *data = opt->value;
1575
BUG_ON_OPT_NEG(unset);
1576
BUG_ON_OPT_ARG(arg);
1526
- ((struct rev_info *)opt->value)->total = -1;
1527
- keep_subject = 1;
1577
+ data->revs->total = -1;
1578
+ data->cfg->keep_subject = 1;
1579
return 0;
1580
}
1581
1531
-static int subject_prefix = 0;
1532
-
1582
static int subject_prefix_callback(const struct option *opt, const char *arg,
1583
int unset)
1584
{
1536
- struct strbuf *sprefix;
1585
+ struct format_config *cfg = opt->value;
1586
1587
BUG_ON_OPT_NEG(unset);
1539
- sprefix = opt->value;
1540
- subject_prefix = 1;
1541
- strbuf_reset(sprefix);
1542
- strbuf_addstr(sprefix, arg);
1588
+ cfg->subject_prefix = 1;
1589
+ strbuf_reset(&cfg->sprefix);
1590
+ strbuf_addstr(&cfg->sprefix, arg);
1591
return 0;
1592
}
1593
@@ -1556,15 +1604,14 @@ static int rfc_callback(const struct option *opt, const char *arg,
1604
return 0;
1605
}
1606
1559
-static int numbered_cmdline_opt = 0;
1560
-
1607
static int numbered_callback(const struct option *opt, const char *arg,
1608
int unset)
1609
{
1610
+ struct format_config *cfg = opt->value;
1611
BUG_ON_OPT_ARG(arg);
1565
- *(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1;
1612
+ cfg->numbered = cfg->numbered_cmdline_opt = unset ? 0 : 1;
1613
if (unset)
1567
- auto_number = 0;
1614
+ cfg->auto_number = 0;
1615
return 0;
1616
}
1617
@@ -1588,13 +1635,14 @@ static int output_directory_callback(const struct option *opt, const char *arg,
1635
1636
static int thread_callback(const struct option *opt, const char *arg, int unset)
1637
{
1591
- enum thread_level *thread = (enum thread_level *)opt->value;
1638
+ struct format_config *cfg = opt->value;
1639
+
1640
if (unset)
1593
- *thread = THREAD_UNSET;
1641
+ cfg->thread = THREAD_UNSET;
1642
else if (!arg || !strcmp(arg, "shallow"))
1595
- *thread = THREAD_SHALLOW;
1643
+ cfg->thread = THREAD_SHALLOW;
1644
else if (!strcmp(arg, "deep"))
1597
- *thread = THREAD_DEEP;
1645
+ cfg->thread = THREAD_DEEP;
1646
/*
1647
* Please update _git_formatpatch() in git-completion.bash
1648
* when you add new options.
@@ -1630,15 +1678,17 @@ static int inline_callback(const struct option *opt, const char *arg, int unset)
1678
return 0;
1679
}
1680
1633
-static int header_callback(const struct option *opt UNUSED, const char *arg,
1681
+static int header_callback(const struct option *opt, const char *arg,
1682
int unset)
1683
{
1684
+ struct format_config *cfg = opt->value;
1685
+
1686
if (unset) {
1637
- string_list_clear(&extra_hdr, 0);
1638
- string_list_clear(&extra_to, 0);
1639
- string_list_clear(&extra_cc, 0);
1687
+ string_list_clear(&cfg->extra_hdr, 0);
1688
+ string_list_clear(&cfg->extra_to, 0);
1689
+ string_list_clear(&cfg->extra_cc, 0);
1690
} else {
1641
- add_header(arg);
1691
+ add_header(cfg, arg);
1692
}
1693
return 0;
1694
}
@@ -1660,17 +1710,17 @@ static int from_callback(const struct option *opt, const char *arg, int unset)
1710
1711
static int base_callback(const struct option *opt, const char *arg, int unset)
1712
{
1663
- const char **base_commit = opt->value;
1713
+ struct format_config *cfg = opt->value;
1714
1715
if (unset) {
1666
- auto_base = AUTO_BASE_NEVER;
1667
- *base_commit = NULL;
1716
+ cfg->auto_base = AUTO_BASE_NEVER;
1717
+ FREE_AND_NULL(cfg->base_commit);
1718
} else if (!strcmp(arg, "auto")) {
1669
- auto_base = AUTO_BASE_ALWAYS;
1670
- *base_commit = NULL;
1719
+ cfg->auto_base = AUTO_BASE_ALWAYS;
1720
+ FREE_AND_NULL(cfg->base_commit);
1721
} else {
1672
- auto_base = AUTO_BASE_NEVER;
1673
- *base_commit = arg;
1722
+ cfg->auto_base = AUTO_BASE_NEVER;
1723
+ cfg->base_commit = xstrdup(arg);
1724
}
1725
return 0;
1726
}
@@ -1681,7 +1731,7 @@ struct base_tree_info {
1731
struct object_id *patch_id;
1732
};
1733
1684
-static struct commit *get_base_commit(const char *base_commit,
1734
+static struct commit *get_base_commit(const struct format_config *cfg,
1735
struct commit **list,
1736
int total)
1737
{
@@ -1689,9 +1739,9 @@ static struct commit *get_base_commit(const char *base_commit,
1739
struct commit **rev;
1740
int i = 0, rev_nr = 0, auto_select, die_on_failure, ret;
1741
1692
- switch (auto_base) {
1742
+ switch (cfg->auto_base) {
1743
case AUTO_BASE_NEVER:
1694
- if (base_commit) {
1744
+ if (cfg->base_commit) {
1745
auto_select = 0;
1746
die_on_failure = 1;
1747
} else {
@@ -1701,11 +1751,11 @@ static struct commit *get_base_commit(const char *base_commit,
1751
break;
1752
case AUTO_BASE_ALWAYS:
1753
case AUTO_BASE_WHEN_ABLE:
1704
- if (base_commit) {
1754
+ if (cfg->base_commit) {
1755
BUG("requested automatic base selection but a commit was provided");
1756
} else {
1757
auto_select = 1;
1708
- die_on_failure = auto_base == AUTO_BASE_ALWAYS;
1758
+ die_on_failure = cfg->auto_base == AUTO_BASE_ALWAYS;
1759
}
1760
break;
1761
default:
@@ -1713,9 +1763,9 @@ static struct commit *get_base_commit(const char *base_commit,
1763
}
1764
1765
if (!auto_select) {
1716
- base = lookup_commit_reference_by_name(base_commit);
1766
+ base = lookup_commit_reference_by_name(cfg->base_commit);
1767
if (!base)
1718
- die(_("unknown commit %s"), base_commit);
1768
+ die(_("unknown commit %s"), cfg->base_commit);
1769
} else {
1770
struct branch *curr_branch = branch_get(NULL);
1771
const char *upstream = branch_get_upstream(curr_branch, NULL);
@@ -1933,7 +1983,7 @@ static void infer_range_diff_ranges(struct strbuf *r1,
1983
1984
int cmd_format_patch(int argc, const char **argv, const char *prefix)
1985
{
1936
- struct log_config cfg;
1986
+ struct format_config cfg;
1987
struct commit *commit;
1988
struct commit **list = NULL;
1989
struct rev_info rev;
@@ -1958,7 +2008,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2008
char *cover_from_description_arg = NULL;
2009
char *description_file = NULL;
2010
char *branch_name = NULL;
1961
- char *base_commit = NULL;
2011
struct base_tree_info bases;
2012
struct commit *base;
2013
int show_progress = 0;
@@ -1969,18 +2018,24 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2018
struct strbuf rdiff1 = STRBUF_INIT;
2019
struct strbuf rdiff2 = STRBUF_INIT;
2020
struct strbuf rdiff_title = STRBUF_INIT;
1972
- struct strbuf sprefix = STRBUF_INIT;
2021
const char *rfc = NULL;
2022
int creation_factor = -1;
2023
+ const char *signature = git_version_string;
2024
+ const char *signature_file_arg = NULL;
2025
+ struct keep_callback_data keep_callback_data = {
2026
+ .cfg = &cfg,
2027
+ .revs = &rev,
2028
+ };
2029
+ const char *fmt_patch_suffix = NULL;
2030
2031
const struct option builtin_format_patch_options[] = {
1977
- OPT_CALLBACK_F('n', "numbered", &numbered, NULL,
2032
+ OPT_CALLBACK_F('n', "numbered", &cfg, NULL,
2033
N_("use [PATCH n/m] even with a single patch"),
2034
PARSE_OPT_NOARG, numbered_callback),
1980
- OPT_CALLBACK_F('N', "no-numbered", &numbered, NULL,
2035
+ OPT_CALLBACK_F('N', "no-numbered", &cfg, NULL,
2036
N_("use [PATCH] even with multiple patches"),
2037
PARSE_OPT_NOARG | PARSE_OPT_NONEG, no_numbered_callback),
1983
- OPT_BOOL('s', "signoff", &do_signoff, N_("add a Signed-off-by trailer")),
2038
+ OPT_BOOL('s', "signoff", &cfg.do_signoff, N_("add a Signed-off-by trailer")),
2039
OPT_BOOL(0, "stdout", &use_stdout,
2040
N_("print patches to standard out")),
2041
OPT_BOOL(0, "cover-letter", &cover_letter,
@@ -1993,7 +2048,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2048
N_("start numbering patches at <n> instead of 1")),
2049
OPT_STRING('v', "reroll-count", &reroll_count, N_("reroll-count"),
2050
N_("mark the series as Nth re-roll")),
1996
- OPT_INTEGER(0, "filename-max-length", &cfg.fmt_patch_name_max,
2051
+ OPT_INTEGER(0, "filename-max-length", &cfg.log.fmt_patch_name_max,
2052
N_("max length of output filename")),
2053
OPT_CALLBACK_F(0, "rfc", &rfc, N_("rfc"),
2054
N_("add <rfc> (default 'RFC') before 'PATCH'"),
@@ -2003,13 +2058,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2058
N_("generate parts of a cover letter based on a branch's description")),
2059
OPT_FILENAME(0, "description-file", &description_file,
2060
N_("use branch description from file")),
2006
- OPT_CALLBACK_F(0, "subject-prefix", &sprefix, N_("prefix"),
2061
+ OPT_CALLBACK_F(0, "subject-prefix", &cfg, N_("prefix"),
2062
N_("use [<prefix>] instead of [PATCH]"),
2063
PARSE_OPT_NONEG, subject_prefix_callback),
2064
OPT_CALLBACK_F('o', "output-directory", &output_directory,
2065
N_("dir"), N_("store resulting files in <dir>"),
2066
PARSE_OPT_NONEG, output_directory_callback),
2012
- OPT_CALLBACK_F('k', "keep-subject", &rev, NULL,
2067
+ OPT_CALLBACK_F('k', "keep-subject", &keep_callback_data, NULL,
2068
N_("don't strip/add [PATCH]"),
2069
PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback),
2070
OPT_BOOL(0, "no-binary", &no_binary_diff,
@@ -2022,11 +2077,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2077
N_("show patch format instead of default (patch + stat)"),
2078
1, PARSE_OPT_NONEG),
2079
OPT_GROUP(N_("Messaging")),
2025
- OPT_CALLBACK(0, "add-header", NULL, N_("header"),
2080
+ OPT_CALLBACK(0, "add-header", &cfg, N_("header"),
2081
N_("add email header"), header_callback),
2027
- OPT_STRING_LIST(0, "to", &extra_to, N_("email"), N_("add To: header")),
2028
- OPT_STRING_LIST(0, "cc", &extra_cc, N_("email"), N_("add Cc: header")),
2029
- OPT_CALLBACK_F(0, "from", &from, N_("ident"),
2082
+ OPT_STRING_LIST(0, "to", &cfg.extra_to, N_("email"), N_("add To: header")),
2083
+ OPT_STRING_LIST(0, "cc", &cfg.extra_cc, N_("email"), N_("add Cc: header")),
2084
+ OPT_CALLBACK_F(0, "from", &cfg.from, N_("ident"),
2085
N_("set From address to <ident> (or committer ident if absent)"),
2086
PARSE_OPT_OPTARG, from_callback),
2087
OPT_STRING(0, "in-reply-to", &in_reply_to, N_("message-id"),
@@ -2038,15 +2093,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2093
N_("inline the patch"),
2094
PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
2095
inline_callback),
2041
- OPT_CALLBACK_F(0, "thread", &thread, N_("style"),
2096
+ OPT_CALLBACK_F(0, "thread", &cfg, N_("style"),
2097
N_("enable message threading, styles: shallow, deep"),
2098
PARSE_OPT_OPTARG, thread_callback),
2099
OPT_STRING(0, "signature", &signature, N_("signature"),
2100
N_("add a signature")),
2046
- OPT_CALLBACK_F(0, "base", &base_commit, N_("base-commit"),
2101
+ OPT_CALLBACK_F(0, "base", &cfg, N_("base-commit"),
2102
N_("add prerequisite tree info to the patch series"),
2103
0, base_callback),
2049
- OPT_FILENAME(0, "signature-file", &signature_file,
2104
+ OPT_FILENAME(0, "signature-file", &signature_file_arg,
2105
N_("add a signature from a file")),
2106
OPT__QUIET(&quiet, N_("don't print the patch filenames")),
2107
OPT_BOOL(0, "progress", &show_progress,
@@ -2063,21 +2118,17 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2118
OPT_END()
2119
};
2120
2066
- extra_hdr.strdup_strings = 1;
2067
- extra_to.strdup_strings = 1;
2068
- extra_cc.strdup_strings = 1;
2069
-
2070
- log_config_init(&cfg);
2121
+ format_config_init(&cfg);
2122
init_diff_ui_defaults();
2072
- init_display_notes(¬es_opt);
2123
+ init_display_notes(&cfg.notes_opt);
2124
git_config(git_format_config, &cfg);
2125
repo_init_revisions(the_repository, &rev, prefix);
2126
git_config(grep_config, &rev.grep_filter);
2127
2077
- rev.show_notes = show_notes;
2078
- memcpy(&rev.notes_opt, ¬es_opt, sizeof(notes_opt));
2128
+ rev.show_notes = cfg.show_notes;
2129
+ memcpy(&rev.notes_opt, &cfg.notes_opt, sizeof(cfg.notes_opt));
2130
rev.commit_format = CMIT_FMT_EMAIL;
2080
- rev.encode_email_headers = cfg.default_encode_email_headers;
2131
+ rev.encode_email_headers = cfg.log.default_encode_email_headers;
2132
rev.expand_tabs_in_log_default = 0;
2133
rev.verbose_header = 1;
2134
rev.diff = 1;
@@ -2088,12 +2139,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2139
s_r_opt.def = "HEAD";
2140
s_r_opt.revarg_opt = REVARG_COMMITTISH;
2141
2091
- strbuf_addstr(&sprefix, cfg.fmt_patch_subject_prefix);
2142
+ strbuf_addstr(&cfg.sprefix, cfg.log.fmt_patch_subject_prefix);
2143
if (format_no_prefix)
2144
diff_set_noprefix(&rev.diffopt);
2145
2095
- if (default_attach) {
2096
- rev.mime_boundary = default_attach;
2146
+ if (cfg.default_attach) {
2147
+ rev.mime_boundary = cfg.default_attach;
2148
rev.no_inline = 1;
2149
}
2150
@@ -2109,60 +2160,63 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2160
2161
rev.force_in_body_from = force_in_body_from;
2162
2163
+ if (!fmt_patch_suffix)
2164
+ fmt_patch_suffix = cfg.fmt_patch_suffix;
2165
+
2166
/* Make sure "0000-$sub.patch" gives non-negative length for $sub */
2113
- if (cfg.fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix))
2114
- cfg.fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix);
2167
+ if (cfg.log.fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix))
2168
+ cfg.log.fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix);
2169
2170
if (cover_from_description_arg)
2117
- cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
2171
+ cfg.cover_from_description_mode = parse_cover_from_description(cover_from_description_arg);
2172
2173
if (rfc && rfc[0]) {
2120
- subject_prefix = 1;
2174
+ cfg.subject_prefix = 1;
2175
if (rfc[0] == '-')
2122
- strbuf_addf(&sprefix, " %s", rfc + 1);
2176
+ strbuf_addf(&cfg.sprefix, " %s", rfc + 1);
2177
else
2124
- strbuf_insertf(&sprefix, 0, "%s ", rfc);
2178
+ strbuf_insertf(&cfg.sprefix, 0, "%s ", rfc);
2179
}
2180
2181
if (reroll_count) {
2128
- strbuf_addf(&sprefix, " v%s", reroll_count);
2182
+ strbuf_addf(&cfg.sprefix, " v%s", reroll_count);
2183
rev.reroll_count = reroll_count;
2184
}
2185
2132
- rev.subject_prefix = sprefix.buf;
2186
+ rev.subject_prefix = cfg.sprefix.buf;
2187
2134
- for (i = 0; i < extra_hdr.nr; i++) {
2135
- strbuf_addstr(&buf, extra_hdr.items[i].string);
2188
+ for (i = 0; i < cfg.extra_hdr.nr; i++) {
2189
+ strbuf_addstr(&buf, cfg.extra_hdr.items[i].string);
2190
strbuf_addch(&buf, '\n');
2191
}
2192
2139
- if (extra_to.nr)
2193
+ if (cfg.extra_to.nr)
2194
strbuf_addstr(&buf, "To: ");
2141
- for (i = 0; i < extra_to.nr; i++) {
2195
+ for (i = 0; i < cfg.extra_to.nr; i++) {
2196
if (i)
2197
strbuf_addstr(&buf, " ");
2144
- strbuf_addstr(&buf, extra_to.items[i].string);
2145
- if (i + 1 < extra_to.nr)
2198
+ strbuf_addstr(&buf, cfg.extra_to.items[i].string);
2199
+ if (i + 1 < cfg.extra_to.nr)
2200
strbuf_addch(&buf, ',');
2201
strbuf_addch(&buf, '\n');
2202
}
2203
2150
- if (extra_cc.nr)
2204
+ if (cfg.extra_cc.nr)
2205
strbuf_addstr(&buf, "Cc: ");
2152
- for (i = 0; i < extra_cc.nr; i++) {
2206
+ for (i = 0; i < cfg.extra_cc.nr; i++) {
2207
if (i)
2208
strbuf_addstr(&buf, " ");
2155
- strbuf_addstr(&buf, extra_cc.items[i].string);
2156
- if (i + 1 < extra_cc.nr)
2209
+ strbuf_addstr(&buf, cfg.extra_cc.items[i].string);
2210
+ if (i + 1 < cfg.extra_cc.nr)
2211
strbuf_addch(&buf, ',');
2212
strbuf_addch(&buf, '\n');
2213
}
2214
2215
rev.extra_headers = to_free = strbuf_detach(&buf, NULL);
2216
2163
- if (from) {
2164
- if (split_ident_line(&rev.from_ident, from, strlen(from)))
2165
- die(_("invalid ident line: %s"), from);
2217
+ if (cfg.from) {
2218
+ if (split_ident_line(&rev.from_ident, cfg.from, strlen(cfg.from)))
2219
+ die(_("invalid ident line: %s"), cfg.from);
2220
}
2221
2222
if (start_number < 0)
@@ -2173,14 +2227,14 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2227
* and it would conflict with --keep-subject (-k) from the
2228
* command line, reset "numbered".
2229
*/
2176
- if (numbered && keep_subject && !numbered_cmdline_opt)
2177
- numbered = 0;
2230
+ if (cfg.numbered && cfg.keep_subject && !cfg.numbered_cmdline_opt)
2231
+ cfg.numbered = 0;
2232
2179
- if (numbered && keep_subject)
2233
+ if (cfg.numbered && cfg.keep_subject)
2234
die(_("options '%s' and '%s' cannot be used together"), "-n", "-k");
2181
- if (keep_subject && subject_prefix)
2235
+ if (cfg.keep_subject && cfg.subject_prefix)
2236
die(_("options '%s' and '%s' cannot be used together"), "--subject-prefix/--rfc", "-k");
2183
- rev.preserve_subject = keep_subject;
2237
+ rev.preserve_subject = cfg.keep_subject;
2238
2239
argc = setup_revisions(argc, argv, &rev, &s_r_opt);
2240
if (argc > 1)
@@ -2207,7 +2261,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2261
rev.always_show_header = 1;
2262
2263
rev.zero_commit = zero_commit;
2210
- rev.patch_name_max = cfg.fmt_patch_name_max;
2264
+ rev.patch_name_max = cfg.log.fmt_patch_name_max;
2265
2266
if (!rev.diffopt.flags.text && !no_binary_diff)
2267
rev.diffopt.flags.binary = 1;
@@ -2228,7 +2282,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2282
int saved;
2283
2284
if (!output_directory)
2231
- output_directory = config_output_directory;
2285
+ output_directory = cfg.config_output_directory;
2286
output_directory = set_outdir(prefix, output_directory);
2287
2288
if (rev.diffopt.use_color != GIT_COLOR_ALWAYS)
@@ -2326,14 +2380,14 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2380
goto done;
2381
total = nr;
2382
if (cover_letter == -1) {
2329
- if (config_cover_letter == COVER_AUTO)
2383
+ if (cfg.config_cover_letter == COVER_AUTO)
2384
cover_letter = (total > 1);
2385
else
2332
- cover_letter = (config_cover_letter == COVER_ON);
2386
+ cover_letter = (cfg.config_cover_letter == COVER_ON);
2387
}
2334
- if (!keep_subject && auto_number && (total > 1 || cover_letter))
2335
- numbered = 1;
2336
- if (numbered)
2388
+ if (!cfg.keep_subject && cfg.auto_number && (total > 1 || cover_letter))
2389
+ cfg.numbered = 1;
2390
+ if (cfg.numbered)
2391
rev.total = total + start_number - 1;
2392
2393
if (idiff_prev.nr) {
@@ -2365,27 +2419,40 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2419
_("Range-diff against v%d:"));
2420
}
2421
2422
+ /*
2423
+ * The order of precedence is:
2424
+ *
2425
+ * 1. The `--signature` and `--no-signature` options.
2426
+ * 2. The `--signature-file` option.
2427
+ * 3. The `format.signature` config.
2428
+ * 4. The `format.signatureFile` config.
2429
+ * 5. Default `git_version_string`.
2430
+ */
2431
if (!signature) {
2432
; /* --no-signature inhibits all signatures */
2433
} else if (signature && signature != git_version_string) {
2434
; /* non-default signature already set */
2372
- } else if (signature_file) {
2435
+ } else if (signature_file_arg || (cfg.signature_file && !cfg.signature)) {
2436
struct strbuf buf = STRBUF_INIT;
2437
+ const char *signature_file = signature_file_arg ?
2438
+ signature_file_arg : cfg.signature_file;
2439
2440
if (strbuf_read_file(&buf, signature_file, 128) < 0)
2441
die_errno(_("unable to read signature file '%s'"), signature_file);
2442
signature = strbuf_detach(&buf, NULL);
2443
+ } else if (cfg.signature) {
2444
+ signature = cfg.signature;
2445
}
2446
2447
memset(&bases, 0, sizeof(bases));
2381
- base = get_base_commit(base_commit, list, nr);
2448
+ base = get_base_commit(&cfg, list, nr);
2449
if (base) {
2450
reset_revision_walk();
2451
clear_object_flags(UNINTERESTING);
2452
prepare_bases(&bases, base, list, nr);
2453
}
2454
2388
- if (in_reply_to || thread || cover_letter) {
2455
+ if (in_reply_to || cfg.thread || cover_letter) {
2456
rev.ref_message_ids = xmalloc(sizeof(*rev.ref_message_ids));
2457
string_list_init_dup(rev.ref_message_ids);
2458
}
@@ -2396,19 +2463,19 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2463
rev.numbered_files = just_numbers;
2464
rev.patch_suffix = fmt_patch_suffix;
2465
if (cover_letter) {
2399
- if (thread)
2466
+ if (cfg.thread)
2467
gen_message_id(&rev, "cover");
2468
make_cover_letter(&rev, !!output_directory,
2402
- origin, nr, list, description_file, branch_name, quiet);
2469
+ origin, nr, list, description_file, branch_name, quiet, &cfg);
2470
print_bases(&bases, rev.diffopt.file);
2404
- print_signature(rev.diffopt.file);
2471
+ print_signature(signature, rev.diffopt.file);
2472
total++;
2473
start_number--;
2474
/* interdiff/range-diff in cover-letter; omit from patches */
2475
rev.idiff_oid1 = NULL;
2476
rev.rdiff1 = NULL;
2477
}
2411
- rev.add_signoff = do_signoff;
2478
+ rev.add_signoff = cfg.do_signoff;
2479
2480
if (show_progress)
2481
progress = start_delayed_progress(_("Generating patches"), total);
@@ -2418,7 +2485,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2485
commit = list[nr];
2486
rev.nr = total - nr + (start_number - 1);
2487
/* Make the second and subsequent mails replies to the first */
2421
- if (thread) {
2488
+ if (cfg.thread) {
2489
/* Have we already had a message ID? */
2490
if (rev.message_id) {
2491
/*
@@ -2442,7 +2509,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2509
* letter is a reply to the
2510
* --in-reply-to, if specified.
2511
*/
2445
- if (thread == THREAD_SHALLOW
2512
+ if (cfg.thread == THREAD_SHALLOW
2513
&& rev.ref_message_ids->nr > 0
2514
&& (!cover_letter || rev.nr > 1))
2515
free(rev.message_id);
@@ -2475,7 +2542,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2542
mime_boundary_leader,
2543
rev.mime_boundary);
2544
else
2478
- print_signature(rev.diffopt.file);
2545
+ print_signature(signature, rev.diffopt.file);
2546
}
2547
if (output_directory)
2548
fclose(rev.diffopt.file);
@@ -2483,9 +2550,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
2550
stop_progress(&progress);
2551
free(list);
2552
free(branch_name);
2486
- string_list_clear(&extra_to, 0);
2487
- string_list_clear(&extra_cc, 0);
2488
- string_list_clear(&extra_hdr, 0);
2553
if (ignore_if_in_upstream)
2554
free_patch_ids(&ids);
2555
@@ -2495,14 +2559,13 @@ done:
2559
strbuf_release(&rdiff1);
2560
strbuf_release(&rdiff2);
2561
strbuf_release(&rdiff_title);
2498
- strbuf_release(&sprefix);
2562
free(to_free);
2563
free(rev.message_id);
2564
if (rev.ref_message_ids)
2565
string_list_clear(rev.ref_message_ids, 0);
2566
free(rev.ref_message_ids);
2567
release_revisions(&rev);
2505
- log_config_release(&cfg);
2568
+ format_config_release(&cfg);
2569
return 0;
2570
}
2571