@@ -214,6 +214,15 @@ static const char tag_template[] =
214214 N_ ("\n"
215215 "#\n"
216216 "# Write a tag message\n"
217+ "# Lines starting with '#' will be ignored.\n"
218+ "#\n" );
219+
220+ static const char tag_template_nocleanup [] =
221+ N_ ("\n"
222+ "#\n"
223+ "# Write a tag message\n"
224+ "# Lines starting with '#' will be kept; you may remove them"
225+ " yourself if you want to.\n"
217226 "#\n" );
218227
219228static int git_tag_config (const char * var , const char * value , void * cb )
@@ -255,8 +264,18 @@ static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result)
255264 return 0 ;
256265}
257266
267+ struct create_tag_options {
268+ unsigned int message_given :1 ;
269+ unsigned int sign ;
270+ enum {
271+ CLEANUP_NONE ,
272+ CLEANUP_SPACE ,
273+ CLEANUP_ALL
274+ } cleanup_mode ;
275+ };
276+
258277static void create_tag (const unsigned char * object , const char * tag ,
259- struct strbuf * buf , int message , int sign ,
278+ struct strbuf * buf , struct create_tag_options * opt ,
260279 unsigned char * prev , unsigned char * result )
261280{
262281 enum object_type type ;
@@ -281,7 +300,7 @@ static void create_tag(const unsigned char *object, const char *tag,
281300 if (header_len > sizeof (header_buf ) - 1 )
282301 die (_ ("tag header too big." ));
283302
284- if (!message ) {
303+ if (!opt -> message_given ) {
285304 int fd ;
286305
287306 /* write the template message before editing: */
@@ -292,8 +311,12 @@ static void create_tag(const unsigned char *object, const char *tag,
292311
293312 if (!is_null_sha1 (prev ))
294313 write_tag_body (fd , prev );
314+ else if (opt -> cleanup_mode == CLEANUP_ALL )
315+ write_or_die (fd , _ (tag_template ),
316+ strlen (_ (tag_template )));
295317 else
296- write_or_die (fd , _ (tag_template ), strlen (_ (tag_template )));
318+ write_or_die (fd , _ (tag_template_nocleanup ),
319+ strlen (_ (tag_template_nocleanup )));
297320 close (fd );
298321
299322 if (launch_editor (path , buf , NULL )) {
@@ -303,14 +326,15 @@ static void create_tag(const unsigned char *object, const char *tag,
303326 }
304327 }
305328
306- stripspace (buf , 1 );
329+ if (opt -> cleanup_mode != CLEANUP_NONE )
330+ stripspace (buf , opt -> cleanup_mode == CLEANUP_ALL );
307331
308- if (!message && !buf -> len )
332+ if (!opt -> message_given && !buf -> len )
309333 die (_ ("no tag message?" ));
310334
311335 strbuf_insert (buf , 0 , header_buf , header_len );
312336
313- if (build_tag_object (buf , sign , result ) < 0 ) {
337+ if (build_tag_object (buf , opt -> sign , result ) < 0 ) {
314338 if (path )
315339 fprintf (stderr , _ ("The tag message has been left in %s\n" ),
316340 path );
@@ -358,9 +382,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
358382 unsigned char object [20 ], prev [20 ];
359383 const char * object_ref , * tag ;
360384 struct ref_lock * lock ;
361-
362- int annotate = 0 , sign = 0 , force = 0 , lines = -1 ,
363- list = 0 , delete = 0 , verify = 0 ;
385+ struct create_tag_options opt ;
386+ char * cleanup_arg = NULL ;
387+ int annotate = 0 , force = 0 , lines = -1 , list = 0 ,
388+ delete = 0 , verify = 0 ;
364389 const char * msgfile = NULL , * keyid = NULL ;
365390 struct msg_arg msg = { 0 , STRBUF_INIT };
366391 struct commit_list * with_commit = NULL ;
@@ -378,7 +403,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
378403 OPT_CALLBACK ('m' , "message" , & msg , "message" ,
379404 "tag message" , parse_msg_arg ),
380405 OPT_FILENAME ('F' , "file" , & msgfile , "read message from file" ),
381- OPT_BOOLEAN ('s' , "sign" , & sign , "annotated and GPG-signed tag" ),
406+ OPT_BOOLEAN ('s' , "sign" , & opt .sign , "annotated and GPG-signed tag" ),
407+ OPT_STRING (0 , "cleanup" , & cleanup_arg , "mode" ,
408+ "how to strip spaces and #comments from message" ),
382409 OPT_STRING ('u' , "local-user" , & keyid , "key-id" ,
383410 "use another key to sign the tag" ),
384411 OPT__FORCE (& force , "replace the tag if exists" ),
@@ -395,13 +422,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
395422
396423 git_config (git_tag_config , NULL );
397424
425+ memset (& opt , 0 , sizeof (opt ));
426+
398427 argc = parse_options (argc , argv , prefix , options , git_tag_usage , 0 );
399428
400429 if (keyid ) {
401- sign = 1 ;
430+ opt . sign = 1 ;
402431 set_signing_key (keyid );
403432 }
404- if (sign )
433+ if (opt . sign )
405434 annotate = 1 ;
406435 if (argc == 0 && !(delete || verify ))
407436 list = 1 ;
@@ -459,9 +488,19 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
459488 else if (!force )
460489 die (_ ("tag '%s' already exists" ), tag );
461490
491+ opt .message_given = msg .given || msgfile ;
492+
493+ if (!cleanup_arg || !strcmp (cleanup_arg , "strip" ))
494+ opt .cleanup_mode = CLEANUP_ALL ;
495+ else if (!strcmp (cleanup_arg , "verbatim" ))
496+ opt .cleanup_mode = CLEANUP_NONE ;
497+ else if (!strcmp (cleanup_arg , "whitespace" ))
498+ opt .cleanup_mode = CLEANUP_SPACE ;
499+ else
500+ die (_ ("Invalid cleanup mode %s" ), cleanup_arg );
501+
462502 if (annotate )
463- create_tag (object , tag , & buf , msg .given || msgfile ,
464- sign , prev , object );
503+ create_tag (object , tag , & buf , & opt , prev , object );
465504
466505 lock = lock_any_ref_for_update (ref .buf , prev , 0 );
467506 if (!lock )
0 commit comments