Skip to content

Commit 0ea5292

Browse files
bonzinigitster
authored andcommitted
interpret-trailers: add options for actions
Allow using non-default values for trailers without having to set them up in .gitconfig first. For example, if you have the following configuration trailer.signed-off-by.where = end you may use "--where before" when a patch author forgets his Signed-off-by and provides it in a separate email. Likewise for --if-exists and --if-missing Reverting to the behavior specified by .gitconfig is done with --no-where, --no-if-exists and --no-if-missing. Signed-off-by: Paolo Bonzini <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 51166b8 commit 0ea5292

File tree

5 files changed

+156
-6
lines changed

5 files changed

+156
-6
lines changed

Documentation/git-interpret-trailers.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,29 @@ OPTIONS
8080
trailer to the input messages. See the description of this
8181
command.
8282

83+
--where <placement>::
84+
--no-where::
85+
Specify where all new trailers will be added. A setting
86+
provided with '--where' overrides all configuration variables
87+
and applies to all '--trailer' options until the next occurrence of
88+
'--where' or '--no-where'.
89+
90+
--if-exists <action>::
91+
--no-if-exists::
92+
Specify what action will be performed when there is already at
93+
least one trailer with the same <token> in the message. A setting
94+
provided with '--if-exists' overrides all configuration variables
95+
and applies to all '--trailer' options until the next occurrence of
96+
'--if-exists' or '--no-if-exists'.
97+
98+
--if-missing <action>::
99+
--no-if-missing::
100+
Specify what action will be performed when there is no other
101+
trailer with the same <token> in the message. A setting
102+
provided with '--if-missing' overrides all configuration variables
103+
and applies to all '--trailer' options until the next occurrence of
104+
'--if-missing' or '--no-if-missing'.
105+
83106
CONFIGURATION VARIABLES
84107
-----------------------
85108

builtin/interpret-trailers.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,28 @@ static const char * const git_interpret_trailers_usage[] = {
1616
NULL
1717
};
1818

19+
static enum trailer_where where;
20+
static enum trailer_if_exists if_exists;
21+
static enum trailer_if_missing if_missing;
22+
23+
static int option_parse_where(const struct option *opt,
24+
const char *arg, int unset)
25+
{
26+
return trailer_set_where(&where, arg);
27+
}
28+
29+
static int option_parse_if_exists(const struct option *opt,
30+
const char *arg, int unset)
31+
{
32+
return trailer_set_if_exists(&if_exists, arg);
33+
}
34+
35+
static int option_parse_if_missing(const struct option *opt,
36+
const char *arg, int unset)
37+
{
38+
return trailer_set_if_missing(&if_missing, arg);
39+
}
40+
1941
static void new_trailers_clear(struct list_head *trailers)
2042
{
2143
struct list_head *pos, *tmp;
@@ -44,6 +66,9 @@ static int option_parse_trailer(const struct option *opt,
4466

4567
item = xmalloc(sizeof(*item));
4668
item->text = arg;
69+
item->where = where;
70+
item->if_exists = if_exists;
71+
item->if_missing = if_missing;
4772
list_add_tail(&item->list, trailers);
4873
return 0;
4974
}
@@ -58,6 +83,13 @@ int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
5883
OPT_BOOL(0, "in-place", &in_place, N_("edit files in place")),
5984
OPT_BOOL(0, "trim-empty", &trim_empty, N_("trim empty trailers")),
6085

86+
OPT_CALLBACK(0, "where", NULL, N_("action"),
87+
N_("where to place the new trailer"), option_parse_where),
88+
OPT_CALLBACK(0, "if-exists", NULL, N_("action"),
89+
N_("action if trailer already exists"), option_parse_if_exists),
90+
OPT_CALLBACK(0, "if-missing", NULL, N_("action"),
91+
N_("action if trailer is missing"), option_parse_if_missing),
92+
6193
OPT_CALLBACK(0, "trailer", &trailers, N_("trailer"),
6294
N_("trailer(s) to add"), option_parse_trailer),
6395
OPT_END()

t/t7513-interpret-trailers.sh

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,36 @@ test_expect_success 'using "where = before"' '
681681
test_cmp expected actual
682682
'
683683

684+
test_expect_success 'overriding configuration with "--where after"' '
685+
git config trailer.ack.where "before" &&
686+
cat complex_message_body >expected &&
687+
sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
688+
Fixes: Z
689+
Acked-by= Z
690+
Acked-by= Peff
691+
Reviewed-by: Z
692+
Signed-off-by: Z
693+
EOF
694+
git interpret-trailers --where after --trailer "ack: Peff" \
695+
complex_message >actual &&
696+
test_cmp expected actual
697+
'
698+
699+
test_expect_success 'using "where = before" with "--no-where"' '
700+
cat complex_message_body >expected &&
701+
sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
702+
Bug #42
703+
Fixes: Z
704+
Acked-by= Peff
705+
Acked-by= Z
706+
Reviewed-by: Z
707+
Signed-off-by: Z
708+
EOF
709+
git interpret-trailers --where after --no-where --trailer "ack: Peff" \
710+
--trailer "bug: 42" complex_message >actual &&
711+
test_cmp expected actual
712+
'
713+
684714
test_expect_success 'using "where = after"' '
685715
git config trailer.ack.where "after" &&
686716
cat complex_message_body >expected &&
@@ -947,6 +977,23 @@ test_expect_success 'using "ifExists = add" with "where = after"' '
947977
test_cmp expected actual
948978
'
949979

980+
test_expect_success 'overriding configuration with "--if-exists replace"' '
981+
git config trailer.fix.key "Fixes: " &&
982+
git config trailer.fix.ifExists "add" &&
983+
cat complex_message_body >expected &&
984+
sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
985+
Bug #42
986+
Acked-by= Z
987+
Reviewed-by:
988+
Signed-off-by: Z
989+
Fixes: 22
990+
EOF
991+
git interpret-trailers --if-exists replace --trailer "review:" \
992+
--trailer "fix=53" --trailer "fix=22" --trailer "bug: 42" \
993+
<complex_message >actual &&
994+
test_cmp expected actual
995+
'
996+
950997
test_expect_success 'using "ifExists = replace"' '
951998
git config trailer.fix.key "Fixes: " &&
952999
git config trailer.fix.ifExists "replace" &&
@@ -1026,6 +1073,25 @@ test_expect_success 'the default is "ifMissing = add"' '
10261073
test_cmp expected actual
10271074
'
10281075

1076+
test_expect_success 'overriding configuration with "--if-missing doNothing"' '
1077+
git config trailer.ifmissing "add" &&
1078+
cat complex_message_body >expected &&
1079+
sed -e "s/ Z\$/ /" >>expected <<-\EOF &&
1080+
Fixes: Z
1081+
Acked-by= Z
1082+
Acked-by= Junio
1083+
Acked-by= Peff
1084+
Reviewed-by:
1085+
Signed-off-by: Z
1086+
EOF
1087+
git interpret-trailers --if-missing doNothing \
1088+
--trailer "review:" --trailer "fix=53" \
1089+
--trailer "cc=Linus" --trailer "ack: Junio" \
1090+
--trailer "fix=22" --trailer "bug: 42" --trailer "ack: Peff" \
1091+
<complex_message >actual &&
1092+
test_cmp expected actual
1093+
'
1094+
10291095
test_expect_success 'when default "ifMissing" is "doNothing"' '
10301096
git config trailer.ifmissing "doNothing" &&
10311097
cat complex_message_body >expected &&

trailer.c

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,9 @@ static void apply_arg_if_exists(struct trailer_item *in_tok,
295295
else
296296
free_arg_item(arg_tok);
297297
break;
298+
default:
299+
die("BUG: trailer.c: unhandled value %d",
300+
arg_tok->conf.if_exists);
298301
}
299302
}
300303

@@ -316,6 +319,10 @@ static void apply_arg_if_missing(struct list_head *head,
316319
list_add_tail(&to_add->list, head);
317320
else
318321
list_add(&to_add->list, head);
322+
break;
323+
default:
324+
die("BUG: trailer.c: unhandled value %d",
325+
arg_tok->conf.if_missing);
319326
}
320327
}
321328

@@ -370,7 +377,9 @@ static void process_trailers_lists(struct list_head *head,
370377

371378
int trailer_set_where(enum trailer_where *item, const char *value)
372379
{
373-
if (!strcasecmp("after", value))
380+
if (!value)
381+
*item = WHERE_DEFAULT;
382+
else if (!strcasecmp("after", value))
374383
*item = WHERE_AFTER;
375384
else if (!strcasecmp("before", value))
376385
*item = WHERE_BEFORE;
@@ -385,7 +394,9 @@ int trailer_set_where(enum trailer_where *item, const char *value)
385394

386395
int trailer_set_if_exists(enum trailer_if_exists *item, const char *value)
387396
{
388-
if (!strcasecmp("addIfDifferent", value))
397+
if (!value)
398+
*item = EXISTS_DEFAULT;
399+
else if (!strcasecmp("addIfDifferent", value))
389400
*item = EXISTS_ADD_IF_DIFFERENT;
390401
else if (!strcasecmp("addIfDifferentNeighbor", value))
391402
*item = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR;
@@ -402,7 +413,9 @@ int trailer_set_if_exists(enum trailer_if_exists *item, const char *value)
402413

403414
int trailer_set_if_missing(enum trailer_if_missing *item, const char *value)
404415
{
405-
if (!strcasecmp("doNothing", value))
416+
if (!value)
417+
*item = MISSING_DEFAULT;
418+
else if (!strcasecmp("doNothing", value))
406419
*item = MISSING_DO_NOTHING;
407420
else if (!strcasecmp("add", value))
408421
*item = MISSING_ADD;
@@ -659,12 +672,21 @@ static struct trailer_item *add_trailer_item(struct list_head *head, char *tok,
659672
}
660673

661674
static void add_arg_item(struct list_head *arg_head, char *tok, char *val,
662-
const struct conf_info *conf)
675+
const struct conf_info *conf,
676+
const struct new_trailer_item *new_trailer_item)
663677
{
664678
struct arg_item *new = xcalloc(sizeof(*new), 1);
665679
new->token = tok;
666680
new->value = val;
667681
duplicate_conf(&new->conf, conf);
682+
if (new_trailer_item) {
683+
if (new_trailer_item->where != WHERE_DEFAULT)
684+
new->conf.where = new_trailer_item->where;
685+
if (new_trailer_item->if_exists != EXISTS_DEFAULT)
686+
new->conf.if_exists = new_trailer_item->if_exists;
687+
if (new_trailer_item->if_missing != MISSING_DEFAULT)
688+
new->conf.if_missing = new_trailer_item->if_missing;
689+
}
668690
list_add_tail(&new->list, arg_head);
669691
}
670692

@@ -690,7 +712,7 @@ static void process_command_line_args(struct list_head *arg_head,
690712
add_arg_item(arg_head,
691713
xstrdup(token_from_item(item, NULL)),
692714
xstrdup(""),
693-
&item->conf);
715+
&item->conf, NULL);
694716
}
695717

696718
/* Add an arg item for each trailer on the command line */
@@ -712,7 +734,7 @@ static void process_command_line_args(struct list_head *arg_head,
712734
add_arg_item(arg_head,
713735
strbuf_detach(&tok, NULL),
714736
strbuf_detach(&val, NULL),
715-
conf);
737+
conf, tr);
716738
}
717739
}
718740

trailer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,22 @@
44
#include "list.h"
55

66
enum trailer_where {
7+
WHERE_DEFAULT,
78
WHERE_END,
89
WHERE_AFTER,
910
WHERE_BEFORE,
1011
WHERE_START
1112
};
1213
enum trailer_if_exists {
14+
EXISTS_DEFAULT,
1315
EXISTS_ADD_IF_DIFFERENT_NEIGHBOR,
1416
EXISTS_ADD_IF_DIFFERENT,
1517
EXISTS_ADD,
1618
EXISTS_REPLACE,
1719
EXISTS_DO_NOTHING
1820
};
1921
enum trailer_if_missing {
22+
MISSING_DEFAULT,
2023
MISSING_ADD,
2124
MISSING_DO_NOTHING
2225
};
@@ -54,6 +57,10 @@ struct new_trailer_item {
5457
struct list_head list;
5558

5659
const char *text;
60+
61+
enum trailer_where where;
62+
enum trailer_if_exists if_exists;
63+
enum trailer_if_missing if_missing;
5764
};
5865

5966
void process_trailers(const char *file, int in_place, int trim_empty,

0 commit comments

Comments
 (0)