8
8
*/
9
9
10
10
#include "cache.h"
11
+ #include "alloc.h"
11
12
#include "config.h"
12
13
#include "builtin.h"
13
14
#include "gettext.h"
27
28
#include "worktree.h"
28
29
#include "write-or-die.h"
29
30
31
+ static char * separator = "\n" ;
30
32
static const char * const git_notes_usage [] = {
31
33
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>]" ),
33
35
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>]" ),
35
37
N_ ("git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" ),
36
38
N_ ("git notes [--ref <notes-ref>] show [<object>]" ),
37
39
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[] = {
99
101
static const char note_template [] =
100
102
N_ ("Write/edit the notes for the following object:" );
101
103
104
+ struct note_msg {
105
+ int stripspace ;
106
+ struct strbuf buf ;
107
+ };
108
+
102
109
struct note_data {
103
110
int given ;
104
111
int use_editor ;
105
112
char * edit_path ;
106
113
struct strbuf buf ;
114
+ struct note_msg * * messages ;
115
+ size_t msg_nr ;
116
+ size_t msg_alloc ;
107
117
};
108
118
109
119
static void free_note_data (struct note_data * d )
@@ -113,6 +123,12 @@ static void free_note_data(struct note_data *d)
113
123
free (d -> edit_path );
114
124
}
115
125
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 );
116
132
}
117
133
118
134
static 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)
213
229
}
214
230
}
215
231
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
+
216
258
static int parse_msg_arg (const struct option * opt , const char * arg , int unset )
217
259
{
218
260
struct note_data * d = opt -> value ;
261
+ struct note_msg * msg = xmalloc (sizeof (* msg ));
219
262
220
263
BUG_ON_OPT_NEG (unset );
221
264
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 ;
228
270
return 0 ;
229
271
}
230
272
231
273
static int parse_file_arg (const struct option * opt , const char * arg , int unset )
232
274
{
233
275
struct note_data * d = opt -> value ;
276
+ struct note_msg * msg = xmalloc (sizeof (* msg ));
234
277
235
278
BUG_ON_OPT_NEG (unset );
236
279
237
- if (d -> buf .len )
238
- strbuf_addch (& d -> buf , '\n' );
280
+ strbuf_init (& msg -> buf , 0 );
239
281
if (!strcmp (arg , "-" )) {
240
- if (strbuf_read (& d -> buf , 0 , 1024 ) < 0 )
282
+ if (strbuf_read (& msg -> buf , 0 , 1024 ) < 0 )
241
283
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 )
243
285
die_errno (_ ("could not open or read '%s'" ), arg );
244
- strbuf_stripspace (& d -> buf , 0 );
245
286
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 ;
247
290
return 0 ;
248
291
}
249
292
250
293
static int parse_reuse_arg (const struct option * opt , const char * arg , int unset )
251
294
{
252
295
struct note_data * d = opt -> value ;
253
- char * buf ;
296
+ struct note_msg * msg = xmalloc (sizeof (* msg ));
297
+ char * value ;
254
298
struct object_id object ;
255
299
enum object_type type ;
256
300
unsigned long len ;
257
301
258
302
BUG_ON_OPT_NEG (unset );
259
303
260
- if (d -> buf .len )
261
- strbuf_addch (& d -> buf , '\n' );
262
-
304
+ strbuf_init (& msg -> buf , 0 );
263
305
if (repo_get_oid (the_repository , arg , & object ))
264
306
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 )))
266
308
die (_ ("failed to read object '%s'." ), arg );
267
309
if (type != OBJ_BLOB ) {
268
- free (buf );
310
+ strbuf_release (& msg -> buf );
311
+ free (value );
312
+ free (msg );
269
313
die (_ ("cannot read note data from non-blob object '%s'." ), arg );
270
314
}
271
- strbuf_add (& d -> buf , buf , len );
272
- free (buf );
273
315
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 ;
275
323
return 0 ;
276
324
}
277
325
@@ -406,6 +454,7 @@ static int add(int argc, const char **argv, const char *prefix)
406
454
struct object_id object , new_note ;
407
455
const struct object_id * note ;
408
456
struct note_data d = { .buf = STRBUF_INIT };
457
+
409
458
struct option options [] = {
410
459
OPT_CALLBACK_F ('m' , "message" , & d , N_ ("message" ),
411
460
N_ ("note contents as a string" ), PARSE_OPT_NONEG ,
@@ -422,6 +471,8 @@ static int add(int argc, const char **argv, const char *prefix)
422
471
OPT_BOOL (0 , "allow-empty" , & allow_empty ,
423
472
N_ ("allow storing empty note" )),
424
473
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" )),
425
476
OPT_END ()
426
477
};
427
478
@@ -433,6 +484,10 @@ static int add(int argc, const char **argv, const char *prefix)
433
484
usage_with_options (git_notes_add_usage , options );
434
485
}
435
486
487
+ if (d .msg_nr )
488
+ concat_messages (& d );
489
+ d .given = !!d .buf .len ;
490
+
436
491
object_ref = argc > 1 ? argv [1 ] : "HEAD" ;
437
492
438
493
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)
587
642
parse_reuse_arg ),
588
643
OPT_BOOL (0 , "allow-empty" , & allow_empty ,
589
644
N_ ("allow storing empty note" )),
645
+ OPT_STRING (0 , "separator" , & separator , N_ ("separator" ),
646
+ N_ ("insert <paragraph-break> between paragraphs" )),
590
647
OPT_END ()
591
648
};
592
649
int edit = !strcmp (argv [0 ], "edit" );
@@ -600,6 +657,10 @@ static int append_edit(int argc, const char **argv, const char *prefix)
600
657
usage_with_options (usage , options );
601
658
}
602
659
660
+ if (d .msg_nr )
661
+ concat_messages (& d );
662
+ d .given = !!d .buf .len ;
663
+
603
664
if (d .given && edit )
604
665
fprintf (stderr , _ ("The -m/-F/-c/-C options have been deprecated "
605
666
"for the 'edit' subcommand.\n"
@@ -623,7 +684,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
623
684
& type , & size );
624
685
625
686
if (d .buf .len && prev_buf && size )
626
- strbuf_insertstr (& d .buf , 0 , "\n" );
687
+ insert_separator (& d .buf , 0 );
627
688
if (prev_buf && size )
628
689
strbuf_insert (& d .buf , 0 , prev_buf , size );
629
690
free (prev_buf );
0 commit comments