88 */
99
1010#include "cache.h"
11+ #include "alloc.h"
1112#include "config.h"
1213#include "builtin.h"
1314#include "gettext.h"
2728#include "worktree.h"
2829#include "write-or-die.h"
2930
31+ static char * separator = "\n" ;
3032static const char * const git_notes_usage [] = {
3133 N_ ("git notes [--ref <notes-ref>] [list [<object>]]" ),
32- N_ ("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]" ),
34+ N_ ("git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--separator=<paragraph-break>] [- m <msg> | -F <file> | (-c | -C) <object>] [<object>]" ),
3335 N_ ("git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" ),
34- N_ ("git notes [--ref <notes-ref>] append [--allow-empty] [-m <msg> | -F <file> | (-c | -C) <object>] [<object>]" ),
36+ N_ ("git notes [--ref <notes-ref>] append [--allow-empty] [--separator=<paragraph-break>] [- m <msg> | -F <file> | (-c | -C) <object>] [<object>]" ),
3537 N_ ("git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" ),
3638 N_ ("git notes [--ref <notes-ref>] show [<object>]" ),
3739 N_ ("git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>" ),
@@ -99,11 +101,19 @@ static const char * const git_notes_get_ref_usage[] = {
99101static const char note_template [] =
100102 N_ ("Write/edit the notes for the following object:" );
101103
104+ struct note_msg {
105+ int stripspace ;
106+ struct strbuf buf ;
107+ };
108+
102109struct note_data {
103110 int given ;
104111 int use_editor ;
105112 char * edit_path ;
106113 struct strbuf buf ;
114+ struct note_msg * * messages ;
115+ size_t msg_nr ;
116+ size_t msg_alloc ;
107117};
108118
109119static void free_note_data (struct note_data * d )
@@ -113,6 +123,12 @@ static void free_note_data(struct note_data *d)
113123 free (d -> edit_path );
114124 }
115125 strbuf_release (& d -> buf );
126+
127+ while (d -> msg_nr -- ) {
128+ strbuf_release (& d -> messages [d -> msg_nr ]-> buf );
129+ free (d -> messages [d -> msg_nr ]);
130+ }
131+ free (d -> messages );
116132}
117133
118134static int list_each_note (const struct object_id * object_oid ,
@@ -213,65 +229,97 @@ static void write_note_data(struct note_data *d, struct object_id *oid)
213229 }
214230}
215231
232+ static void insert_separator (struct strbuf * message , size_t pos )
233+ {
234+ size_t sep_len = strlen (separator );
235+ if (sep_len && separator [sep_len - 1 ] == '\n' )
236+ strbuf_insertstr (message , pos , separator );
237+ else
238+ strbuf_insertf (message , pos , "%s%s" , separator , "\n" );
239+ }
240+
241+ static void concat_messages (struct note_data * d )
242+ {
243+ struct strbuf msg = STRBUF_INIT ;
244+
245+ size_t i ;
246+ for (i = 0 ; i < d -> msg_nr ; i ++ ) {
247+ if (d -> buf .len )
248+ insert_separator (& d -> buf , d -> buf .len );
249+ strbuf_add (& msg , d -> messages [i ]-> buf .buf , d -> messages [i ]-> buf .len );
250+ strbuf_addbuf (& d -> buf , & msg );
251+ if (d -> messages [i ]-> stripspace )
252+ strbuf_stripspace (& d -> buf , 0 );
253+ strbuf_reset (& msg );
254+ }
255+ strbuf_release (& msg );
256+ }
257+
216258static int parse_msg_arg (const struct option * opt , const char * arg , int unset )
217259{
218260 struct note_data * d = opt -> value ;
261+ struct note_msg * msg = xmalloc (sizeof (* msg ));
219262
220263 BUG_ON_OPT_NEG (unset );
221264
222- if (d -> buf .len )
223- strbuf_addch (& d -> buf , '\n' );
224- strbuf_addstr (& d -> buf , arg );
225- strbuf_stripspace (& d -> buf , 0 );
226-
227- d -> given = 1 ;
265+ strbuf_init (& msg -> buf , strlen (arg ));
266+ strbuf_addstr (& msg -> buf , arg );
267+ ALLOC_GROW_BY (d -> messages , d -> msg_nr , 1 , d -> msg_alloc );
268+ d -> messages [d -> msg_nr - 1 ] = msg ;
269+ msg -> stripspace = 1 ;
228270 return 0 ;
229271}
230272
231273static int parse_file_arg (const struct option * opt , const char * arg , int unset )
232274{
233275 struct note_data * d = opt -> value ;
276+ struct note_msg * msg = xmalloc (sizeof (* msg ));
234277
235278 BUG_ON_OPT_NEG (unset );
236279
237- if (d -> buf .len )
238- strbuf_addch (& d -> buf , '\n' );
280+ strbuf_init (& msg -> buf , 0 );
239281 if (!strcmp (arg , "-" )) {
240- if (strbuf_read (& d -> buf , 0 , 1024 ) < 0 )
282+ if (strbuf_read (& msg -> buf , 0 , 1024 ) < 0 )
241283 die_errno (_ ("cannot read '%s'" ), arg );
242- } else if (strbuf_read_file (& d -> buf , arg , 1024 ) < 0 )
284+ } else if (strbuf_read_file (& msg -> buf , arg , 1024 ) < 0 )
243285 die_errno (_ ("could not open or read '%s'" ), arg );
244- strbuf_stripspace (& d -> buf , 0 );
245286
246- d -> given = 1 ;
287+ ALLOC_GROW_BY (d -> messages , d -> msg_nr , 1 , d -> msg_alloc );
288+ d -> messages [d -> msg_nr - 1 ] = msg ;
289+ msg -> stripspace = 1 ;
247290 return 0 ;
248291}
249292
250293static int parse_reuse_arg (const struct option * opt , const char * arg , int unset )
251294{
252295 struct note_data * d = opt -> value ;
253- char * buf ;
296+ struct note_msg * msg = xmalloc (sizeof (* msg ));
297+ char * value ;
254298 struct object_id object ;
255299 enum object_type type ;
256300 unsigned long len ;
257301
258302 BUG_ON_OPT_NEG (unset );
259303
260- if (d -> buf .len )
261- strbuf_addch (& d -> buf , '\n' );
262-
304+ strbuf_init (& msg -> buf , 0 );
263305 if (repo_get_oid (the_repository , arg , & object ))
264306 die (_ ("failed to resolve '%s' as a valid ref." ), arg );
265- if (!(buf = repo_read_object_file (the_repository , & object , & type , & len )))
307+ if (!(value = repo_read_object_file (the_repository , & object , & type , & len )))
266308 die (_ ("failed to read object '%s'." ), arg );
267309 if (type != OBJ_BLOB ) {
268- free (buf );
310+ strbuf_release (& msg -> buf );
311+ free (value );
312+ free (msg );
269313 die (_ ("cannot read note data from non-blob object '%s'." ), arg );
270314 }
271- strbuf_add (& d -> buf , buf , len );
272- free (buf );
273315
274- d -> given = 1 ;
316+ strbuf_add (& msg -> buf , value , len );
317+ free (value );
318+
319+ msg -> buf .len = len ;
320+ ALLOC_GROW_BY (d -> messages , d -> msg_nr , 1 , d -> msg_alloc );
321+ d -> messages [d -> msg_nr - 1 ] = msg ;
322+ msg -> stripspace = 0 ;
275323 return 0 ;
276324}
277325
@@ -406,6 +454,7 @@ static int add(int argc, const char **argv, const char *prefix)
406454 struct object_id object , new_note ;
407455 const struct object_id * note ;
408456 struct note_data d = { .buf = STRBUF_INIT };
457+
409458 struct option options [] = {
410459 OPT_CALLBACK_F ('m' , "message" , & d , N_ ("message" ),
411460 N_ ("note contents as a string" ), PARSE_OPT_NONEG ,
@@ -422,6 +471,8 @@ static int add(int argc, const char **argv, const char *prefix)
422471 OPT_BOOL (0 , "allow-empty" , & allow_empty ,
423472 N_ ("allow storing empty note" )),
424473 OPT__FORCE (& force , N_ ("replace existing notes" ), PARSE_OPT_NOCOMPLETE ),
474+ OPT_STRING (0 , "separator" , & separator , N_ ("separator" ),
475+ N_ ("insert <paragraph-break> between paragraphs" )),
425476 OPT_END ()
426477 };
427478
@@ -433,6 +484,10 @@ static int add(int argc, const char **argv, const char *prefix)
433484 usage_with_options (git_notes_add_usage , options );
434485 }
435486
487+ if (d .msg_nr )
488+ concat_messages (& d );
489+ d .given = !!d .buf .len ;
490+
436491 object_ref = argc > 1 ? argv [1 ] : "HEAD" ;
437492
438493 if (repo_get_oid (the_repository , object_ref , & object ))
@@ -587,6 +642,8 @@ static int append_edit(int argc, const char **argv, const char *prefix)
587642 parse_reuse_arg ),
588643 OPT_BOOL (0 , "allow-empty" , & allow_empty ,
589644 N_ ("allow storing empty note" )),
645+ OPT_STRING (0 , "separator" , & separator , N_ ("separator" ),
646+ N_ ("insert <paragraph-break> between paragraphs" )),
590647 OPT_END ()
591648 };
592649 int edit = !strcmp (argv [0 ], "edit" );
@@ -600,6 +657,10 @@ static int append_edit(int argc, const char **argv, const char *prefix)
600657 usage_with_options (usage , options );
601658 }
602659
660+ if (d .msg_nr )
661+ concat_messages (& d );
662+ d .given = !!d .buf .len ;
663+
603664 if (d .given && edit )
604665 fprintf (stderr , _ ("The -m/-F/-c/-C options have been deprecated "
605666 "for the 'edit' subcommand.\n"
@@ -623,7 +684,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
623684 & type , & size );
624685
625686 if (d .buf .len && prev_buf && size )
626- strbuf_insertstr (& d .buf , 0 , "\n" );
687+ insert_separator (& d .buf , 0 );
627688 if (prev_buf && size )
628689 strbuf_insert (& d .buf , 0 , prev_buf , size );
629690 free (prev_buf );
0 commit comments