@@ -132,7 +132,9 @@ static void read_from_stdin(struct shortlog *log)
132
132
match = committer_match ;
133
133
break ;
134
134
case SHORTLOG_GROUP_TRAILER :
135
- die (_ ("using --group=trailer with stdin is not supported" ));
135
+ die (_ ("using %s with stdin is not supported" ), "--group=trailer" );
136
+ case SHORTLOG_GROUP_FORMAT :
137
+ die (_ ("using %s with stdin is not supported" ), "--group=format" );
136
138
default :
137
139
BUG ("unhandled shortlog group" );
138
140
}
@@ -170,6 +172,9 @@ static void insert_records_from_trailers(struct shortlog *log,
170
172
const char * commit_buffer , * body ;
171
173
struct strbuf ident = STRBUF_INIT ;
172
174
175
+ if (!log -> trailers .nr )
176
+ return ;
177
+
173
178
/*
174
179
* Using format_commit_message("%B") would be simpler here, but
175
180
* this saves us copying the message.
@@ -200,9 +205,34 @@ static void insert_records_from_trailers(struct shortlog *log,
200
205
unuse_commit_buffer (commit , commit_buffer );
201
206
}
202
207
208
+ static int shortlog_needs_dedup (const struct shortlog * log )
209
+ {
210
+ return HAS_MULTI_BITS (log -> groups ) || log -> format .nr > 1 || log -> trailers .nr ;
211
+ }
212
+
213
+ static void insert_records_from_format (struct shortlog * log ,
214
+ struct strset * dups ,
215
+ struct commit * commit ,
216
+ struct pretty_print_context * ctx ,
217
+ const char * oneline )
218
+ {
219
+ struct strbuf buf = STRBUF_INIT ;
220
+ struct string_list_item * item ;
221
+
222
+ for_each_string_list_item (item , & log -> format ) {
223
+ strbuf_reset (& buf );
224
+
225
+ format_commit_message (commit , item -> string , & buf , ctx );
226
+
227
+ if (!shortlog_needs_dedup (log ) || strset_add (dups , buf .buf ))
228
+ insert_one_record (log , buf .buf , oneline );
229
+ }
230
+
231
+ strbuf_release (& buf );
232
+ }
233
+
203
234
void shortlog_add_commit (struct shortlog * log , struct commit * commit )
204
235
{
205
- struct strbuf ident = STRBUF_INIT ;
206
236
struct strbuf oneline = STRBUF_INIT ;
207
237
struct strset dups = STRSET_INIT ;
208
238
struct pretty_print_context ctx = {0 };
@@ -211,7 +241,7 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
211
241
ctx .fmt = CMIT_FMT_USERFORMAT ;
212
242
ctx .abbrev = log -> abbrev ;
213
243
ctx .print_email_subject = 1 ;
214
- ctx .date_mode . type = DATE_NORMAL ;
244
+ ctx .date_mode = log -> date_mode ;
215
245
ctx .output_encoding = get_log_output_encoding ();
216
246
217
247
if (!log -> summary ) {
@@ -222,30 +252,10 @@ void shortlog_add_commit(struct shortlog *log, struct commit *commit)
222
252
}
223
253
oneline_str = oneline .len ? oneline .buf : "<none>" ;
224
254
225
- if (log -> groups & SHORTLOG_GROUP_AUTHOR ) {
226
- strbuf_reset (& ident );
227
- format_commit_message (commit ,
228
- log -> email ? "%aN <%aE>" : "%aN" ,
229
- & ident , & ctx );
230
- if (!HAS_MULTI_BITS (log -> groups ) ||
231
- strset_add (& dups , ident .buf ))
232
- insert_one_record (log , ident .buf , oneline_str );
233
- }
234
- if (log -> groups & SHORTLOG_GROUP_COMMITTER ) {
235
- strbuf_reset (& ident );
236
- format_commit_message (commit ,
237
- log -> email ? "%cN <%cE>" : "%cN" ,
238
- & ident , & ctx );
239
- if (!HAS_MULTI_BITS (log -> groups ) ||
240
- strset_add (& dups , ident .buf ))
241
- insert_one_record (log , ident .buf , oneline_str );
242
- }
243
- if (log -> groups & SHORTLOG_GROUP_TRAILER ) {
244
- insert_records_from_trailers (log , & dups , commit , & ctx , oneline_str );
245
- }
255
+ insert_records_from_trailers (log , & dups , commit , & ctx , oneline_str );
256
+ insert_records_from_format (log , & dups , commit , & ctx , oneline_str );
246
257
247
258
strset_clear (& dups );
248
- strbuf_release (& ident );
249
259
strbuf_release (& oneline );
250
260
}
251
261
@@ -314,15 +324,23 @@ static int parse_group_option(const struct option *opt, const char *arg, int uns
314
324
if (unset ) {
315
325
log -> groups = 0 ;
316
326
string_list_clear (& log -> trailers , 0 );
327
+ string_list_clear (& log -> format , 0 );
317
328
} else if (!strcasecmp (arg , "author" ))
318
329
log -> groups |= SHORTLOG_GROUP_AUTHOR ;
319
330
else if (!strcasecmp (arg , "committer" ))
320
331
log -> groups |= SHORTLOG_GROUP_COMMITTER ;
321
332
else if (skip_prefix (arg , "trailer:" , & field )) {
322
333
log -> groups |= SHORTLOG_GROUP_TRAILER ;
323
334
string_list_append (& log -> trailers , field );
324
- } else
335
+ } else if (skip_prefix (arg , "format:" , & field )) {
336
+ log -> groups |= SHORTLOG_GROUP_FORMAT ;
337
+ string_list_append (& log -> format , field );
338
+ } else if (strchr (arg , '%' )) {
339
+ log -> groups |= SHORTLOG_GROUP_FORMAT ;
340
+ string_list_append (& log -> format , arg );
341
+ } else {
325
342
return error (_ ("unknown group type: %s" ), arg );
343
+ }
326
344
327
345
return 0 ;
328
346
}
@@ -340,6 +358,19 @@ void shortlog_init(struct shortlog *log)
340
358
log -> in2 = DEFAULT_INDENT2 ;
341
359
log -> trailers .strdup_strings = 1 ;
342
360
log -> trailers .cmp = strcasecmp ;
361
+ log -> format .strdup_strings = 1 ;
362
+ }
363
+
364
+ void shortlog_finish_setup (struct shortlog * log )
365
+ {
366
+ if (log -> groups & SHORTLOG_GROUP_AUTHOR )
367
+ string_list_append (& log -> format ,
368
+ log -> email ? "%aN <%aE>" : "%aN" );
369
+ if (log -> groups & SHORTLOG_GROUP_COMMITTER )
370
+ string_list_append (& log -> format ,
371
+ log -> email ? "%cN <%cE>" : "%cN" );
372
+
373
+ string_list_sort (& log -> trailers );
343
374
}
344
375
345
376
int cmd_shortlog (int argc , const char * * argv , const char * prefix )
@@ -407,10 +438,11 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
407
438
log .user_format = rev .commit_format == CMIT_FMT_USERFORMAT ;
408
439
log .abbrev = rev .abbrev ;
409
440
log .file = rev .diffopt .file ;
441
+ log .date_mode = rev .date_mode ;
410
442
411
443
if (!log .groups )
412
444
log .groups = SHORTLOG_GROUP_AUTHOR ;
413
- string_list_sort (& log . trailers );
445
+ shortlog_finish_setup (& log );
414
446
415
447
/* assume HEAD if from a tty */
416
448
if (!nongit && !rev .pending .nr && isatty (0 ))
@@ -479,4 +511,5 @@ void shortlog_output(struct shortlog *log)
479
511
log -> list .strdup_strings = 1 ;
480
512
string_list_clear (& log -> list , 1 );
481
513
clear_mailmap (& log -> mailmap );
514
+ string_list_clear (& log -> format , 0 );
482
515
}
0 commit comments