28
28
#include "date.h"
29
29
#include "write-or-die.h"
30
30
#include "object-file-convert.h"
31
+ #include "trailer.h"
31
32
32
33
static const char * const git_tag_usage [] = {
33
34
N_ ("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
35
+ " [(--trailer <token>[(=|:)<value>])...]\n"
34
36
" <tagname> [<commit> | <object>]" ),
35
37
N_ ("git tag -d <tagname>..." ),
36
38
N_ ("git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]\n"
@@ -290,10 +292,12 @@ static const char message_advice_nested_tag[] =
290
292
static void create_tag (const struct object_id * object , const char * object_ref ,
291
293
const char * tag ,
292
294
struct strbuf * buf , struct create_tag_options * opt ,
293
- struct object_id * prev , struct object_id * result , char * path )
295
+ struct object_id * prev , struct object_id * result ,
296
+ struct strvec * trailer_args , char * path )
294
297
{
295
298
enum object_type type ;
296
299
struct strbuf header = STRBUF_INIT ;
300
+ int should_edit ;
297
301
298
302
type = oid_object_info (the_repository , object , NULL );
299
303
if (type <= OBJ_NONE )
@@ -313,13 +317,15 @@ static void create_tag(const struct object_id *object, const char *object_ref,
313
317
tag ,
314
318
git_committer_info (IDENT_STRICT ));
315
319
316
- if (!opt -> message_given || opt -> use_editor ) {
320
+ should_edit = opt -> use_editor || !opt -> message_given ;
321
+ if (should_edit || trailer_args -> nr ) {
317
322
int fd ;
318
323
319
324
/* write the template message before editing: */
320
325
fd = xopen (path , O_CREAT | O_TRUNC | O_WRONLY , 0600 );
321
326
322
- if (opt -> message_given ) {
327
+ if (opt -> message_given && buf -> len ) {
328
+ strbuf_complete (buf , '\n' );
323
329
write_or_die (fd , buf -> buf , buf -> len );
324
330
strbuf_reset (buf );
325
331
} else if (!is_null_oid (prev )) {
@@ -338,10 +344,19 @@ static void create_tag(const struct object_id *object, const char *object_ref,
338
344
}
339
345
close (fd );
340
346
341
- if (launch_editor (path , buf , NULL )) {
342
- fprintf (stderr ,
343
- _ ("Please supply the message using either -m or -F option.\n" ));
344
- exit (1 );
347
+ if (trailer_args -> nr && amend_file_with_trailers (path , trailer_args ))
348
+ die (_ ("unable to pass trailers to --trailers" ));
349
+
350
+ if (should_edit ) {
351
+ if (launch_editor (path , buf , NULL )) {
352
+ fprintf (stderr ,
353
+ _ ("Please supply the message using either -m or -F option.\n" ));
354
+ exit (1 );
355
+ }
356
+ } else if (trailer_args -> nr ) {
357
+ strbuf_reset (buf );
358
+ if (strbuf_read_file (buf , path , 0 ) < 0 )
359
+ die_errno (_ ("failed to read '%s'" ), path );
345
360
}
346
361
}
347
362
@@ -463,6 +478,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
463
478
struct ref_sorting * sorting ;
464
479
struct string_list sorting_options = STRING_LIST_INIT_DUP ;
465
480
struct ref_format format = REF_FORMAT_INIT ;
481
+ struct strvec trailer_args = STRVEC_INIT ;
466
482
int icase = 0 ;
467
483
int edit_flag = 0 ;
468
484
struct option options [] = {
@@ -479,6 +495,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
479
495
OPT_CALLBACK_F ('m' , "message" , & msg , N_ ("message" ),
480
496
N_ ("tag message" ), PARSE_OPT_NONEG , parse_msg_arg ),
481
497
OPT_FILENAME ('F' , "file" , & msgfile , N_ ("read message from file" )),
498
+ OPT_PASSTHRU_ARGV (0 , "trailer" , & trailer_args , N_ ("trailer" ),
499
+ N_ ("add custom trailer(s)" ), PARSE_OPT_NONEG ),
482
500
OPT_BOOL ('e' , "edit" , & edit_flag , N_ ("force edit of tag message" )),
483
501
OPT_BOOL ('s' , "sign" , & opt .sign , N_ ("annotated and GPG-signed tag" )),
484
502
OPT_CLEANUP (& cleanup_arg ),
@@ -548,7 +566,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
548
566
opt .sign = 1 ;
549
567
set_signing_key (keyid );
550
568
}
551
- create_tag_object = (opt .sign || annotate || msg .given || msgfile );
569
+ create_tag_object = (opt .sign || annotate || msg .given || msgfile ||
570
+ edit_flag || trailer_args .nr );
552
571
553
572
if ((create_tag_object || force ) && (cmdmode != 0 ))
554
573
usage_with_options (git_tag_usage , options );
@@ -654,7 +673,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
654
673
opt .sign = 1 ;
655
674
path = git_pathdup ("TAG_EDITMSG" );
656
675
create_tag (& object , object_ref , tag , & buf , & opt , & prev , & object ,
657
- path );
676
+ & trailer_args , path );
658
677
}
659
678
660
679
transaction = ref_transaction_begin (& err );
@@ -686,6 +705,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
686
705
strbuf_release (& reflog_msg );
687
706
strbuf_release (& msg .buf );
688
707
strbuf_release (& err );
708
+ strvec_clear (& trailer_args );
689
709
free (msgfile );
690
710
return ret ;
691
711
}
0 commit comments