@@ -37,11 +37,11 @@ static unsigned char head_sha1[20];
37
37
static int branch_use_color = -1 ;
38
38
static char branch_colors [][COLOR_MAXLEN ] = {
39
39
GIT_COLOR_RESET ,
40
- GIT_COLOR_NORMAL , /* PLAIN */
41
- GIT_COLOR_RED , /* REMOTE */
42
- GIT_COLOR_NORMAL , /* LOCAL */
43
- GIT_COLOR_GREEN , /* CURRENT */
44
- GIT_COLOR_BLUE , /* UPSTREAM */
40
+ GIT_COLOR_NORMAL , /* PLAIN */
41
+ GIT_COLOR_RED , /* REMOTE */
42
+ GIT_COLOR_NORMAL , /* LOCAL */
43
+ GIT_COLOR_GREEN , /* CURRENT */
44
+ GIT_COLOR_BLUE , /* UPSTREAM */
45
45
};
46
46
enum color_branch {
47
47
BRANCH_COLOR_RESET = 0 ,
@@ -280,180 +280,88 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
280
280
return (ret );
281
281
}
282
282
283
- static void fill_tracking_info (struct strbuf * stat , const char * branch_name ,
284
- int show_upstream_ref )
283
+ static int calc_maxwidth (struct ref_array * refs , int remote_bonus )
285
284
{
286
- int ours , theirs ;
287
- char * ref = NULL ;
288
- struct branch * branch = branch_get (branch_name );
289
- const char * upstream ;
290
- struct strbuf fancy = STRBUF_INIT ;
291
- int upstream_is_gone = 0 ;
292
- int added_decoration = 1 ;
293
-
294
- if (stat_tracking_info (branch , & ours , & theirs , & upstream ) < 0 ) {
295
- if (!upstream )
296
- return ;
297
- upstream_is_gone = 1 ;
298
- }
299
-
300
- if (show_upstream_ref ) {
301
- ref = shorten_unambiguous_ref (upstream , 0 );
302
- if (want_color (branch_use_color ))
303
- strbuf_addf (& fancy , "%s%s%s" ,
304
- branch_get_color (BRANCH_COLOR_UPSTREAM ),
305
- ref , branch_get_color (BRANCH_COLOR_RESET ));
306
- else
307
- strbuf_addstr (& fancy , ref );
308
- }
285
+ int i , max = 0 ;
286
+ for (i = 0 ; i < refs -> nr ; i ++ ) {
287
+ struct ref_array_item * it = refs -> items [i ];
288
+ const char * desc = it -> refname ;
289
+ int w ;
309
290
310
- if (upstream_is_gone ) {
311
- if (show_upstream_ref )
312
- strbuf_addf (stat , _ ("[%s: gone]" ), fancy .buf );
313
- else
314
- added_decoration = 0 ;
315
- } else if (!ours && !theirs ) {
316
- if (show_upstream_ref )
317
- strbuf_addf (stat , _ ("[%s]" ), fancy .buf );
318
- else
319
- added_decoration = 0 ;
320
- } else if (!ours ) {
321
- if (show_upstream_ref )
322
- strbuf_addf (stat , _ ("[%s: behind %d]" ), fancy .buf , theirs );
323
- else
324
- strbuf_addf (stat , _ ("[behind %d]" ), theirs );
291
+ skip_prefix (it -> refname , "refs/heads/" , & desc );
292
+ skip_prefix (it -> refname , "refs/remotes/" , & desc );
293
+ if (it -> kind == FILTER_REFS_DETACHED_HEAD ) {
294
+ char * head_desc = get_head_description ();
295
+ w = utf8_strwidth (head_desc );
296
+ free (head_desc );
297
+ } else
298
+ w = utf8_strwidth (desc );
325
299
326
- } else if (!theirs ) {
327
- if (show_upstream_ref )
328
- strbuf_addf (stat , _ ("[%s: ahead %d]" ), fancy .buf , ours );
329
- else
330
- strbuf_addf (stat , _ ("[ahead %d]" ), ours );
331
- } else {
332
- if (show_upstream_ref )
333
- strbuf_addf (stat , _ ("[%s: ahead %d, behind %d]" ),
334
- fancy .buf , ours , theirs );
335
- else
336
- strbuf_addf (stat , _ ("[ahead %d, behind %d]" ),
337
- ours , theirs );
300
+ if (it -> kind == FILTER_REFS_REMOTES )
301
+ w += remote_bonus ;
302
+ if (w > max )
303
+ max = w ;
338
304
}
339
- strbuf_release (& fancy );
340
- if (added_decoration )
341
- strbuf_addch (stat , ' ' );
342
- free (ref );
305
+ return max ;
343
306
}
344
307
345
- static void add_verbose_info (struct strbuf * out , struct ref_array_item * item ,
346
- struct ref_filter * filter , const char * refname )
308
+ static const char * quote_literal_for_format (const char * s )
347
309
{
348
- struct strbuf subject = STRBUF_INIT , stat = STRBUF_INIT ;
349
- const char * sub = _ (" **** invalid ref ****" );
350
- struct commit * commit = item -> commit ;
310
+ static struct strbuf buf = STRBUF_INIT ;
351
311
352
- if (!parse_commit (commit )) {
353
- pp_commit_easy (CMIT_FMT_ONELINE , commit , & subject );
354
- sub = subject .buf ;
312
+ strbuf_reset (& buf );
313
+ while (* s ) {
314
+ const char * ep = strchrnul (s , '%' );
315
+ if (s < ep )
316
+ strbuf_add (& buf , s , ep - s );
317
+ if (* ep == '%' ) {
318
+ strbuf_addstr (& buf , "%%" );
319
+ s = ep + 1 ;
320
+ } else {
321
+ s = ep ;
322
+ }
355
323
}
356
-
357
- if (item -> kind == FILTER_REFS_BRANCHES )
358
- fill_tracking_info (& stat , refname , filter -> verbose > 1 );
359
-
360
- strbuf_addf (out , " %s %s%s" ,
361
- find_unique_abbrev (item -> commit -> object .oid .hash , filter -> abbrev ),
362
- stat .buf , sub );
363
- strbuf_release (& stat );
364
- strbuf_release (& subject );
324
+ return buf .buf ;
365
325
}
366
326
367
- static void format_and_print_ref_item (struct ref_array_item * item , int maxwidth ,
368
- struct ref_filter * filter , const char * remote_prefix )
327
+ static char * build_format (struct ref_filter * filter , int maxwidth , const char * remote_prefix )
369
328
{
370
- char c ;
371
- int current = 0 ;
372
- int color ;
373
- struct strbuf out = STRBUF_INIT , name = STRBUF_INIT ;
374
- const char * prefix_to_show = "" ;
375
- const char * prefix_to_skip = NULL ;
376
- const char * desc = item -> refname ;
377
- char * to_free = NULL ;
378
-
379
- switch (item -> kind ) {
380
- case FILTER_REFS_BRANCHES :
381
- prefix_to_skip = "refs/heads/" ;
382
- skip_prefix (desc , prefix_to_skip , & desc );
383
- if (!filter -> detached && !strcmp (desc , head ))
384
- current = 1 ;
385
- else
386
- color = BRANCH_COLOR_LOCAL ;
387
- break ;
388
- case FILTER_REFS_REMOTES :
389
- prefix_to_skip = "refs/remotes/" ;
390
- skip_prefix (desc , prefix_to_skip , & desc );
391
- color = BRANCH_COLOR_REMOTE ;
392
- prefix_to_show = remote_prefix ;
393
- break ;
394
- case FILTER_REFS_DETACHED_HEAD :
395
- desc = to_free = get_head_description ();
396
- current = 1 ;
397
- break ;
398
- default :
399
- color = BRANCH_COLOR_PLAIN ;
400
- break ;
401
- }
329
+ struct strbuf fmt = STRBUF_INIT ;
330
+ struct strbuf local = STRBUF_INIT ;
331
+ struct strbuf remote = STRBUF_INIT ;
402
332
403
- c = ' ' ;
404
- if (current ) {
405
- c = '*' ;
406
- color = BRANCH_COLOR_CURRENT ;
407
- }
333
+ strbuf_addf (& fmt , "%%(if)%%(HEAD)%%(then)* %s%%(else) %%(end)" ,
334
+ branch_get_color (BRANCH_COLOR_CURRENT ));
408
335
409
- strbuf_addf (& name , "%s%s" , prefix_to_show , desc );
410
336
if (filter -> verbose ) {
411
- int utf8_compensation = strlen (name .buf ) - utf8_strwidth (name .buf );
412
- strbuf_addf (& out , "%c %s%-*s%s" , c , branch_get_color (color ),
413
- maxwidth + utf8_compensation , name .buf ,
337
+ strbuf_addf (& local , "%%(align:%d,left)%%(refname:lstrip=2)%%(end)" , maxwidth );
338
+ strbuf_addf (& local , "%s" , branch_get_color (BRANCH_COLOR_RESET ));
339
+ strbuf_addf (& local , " %%(objectname:short=7) " );
340
+
341
+ if (filter -> verbose > 1 )
342
+ strbuf_addf (& local , "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s%%(if)%%(upstream:track)"
343
+ "%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)" ,
344
+ branch_get_color (BRANCH_COLOR_UPSTREAM ), branch_get_color (BRANCH_COLOR_RESET ));
345
+ else
346
+ strbuf_addf (& local , "%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)" );
347
+
348
+ strbuf_addf (& remote , "%s%%(align:%d,left)%s%%(refname:lstrip=2)%%(end)%s%%(if)%%(symref)%%(then) -> %%(symref:short)"
349
+ "%%(else) %%(objectname:short=7) %%(contents:subject)%%(end)" ,
350
+ branch_get_color (BRANCH_COLOR_REMOTE ), maxwidth , quote_literal_for_format (remote_prefix ),
414
351
branch_get_color (BRANCH_COLOR_RESET ));
415
- } else
416
- strbuf_addf (& out , "%c %s%s%s" , c , branch_get_color (color ),
417
- name .buf , branch_get_color (BRANCH_COLOR_RESET ));
418
-
419
- if (item -> symref ) {
420
- const char * symref = item -> symref ;
421
- if (prefix_to_skip )
422
- skip_prefix (symref , prefix_to_skip , & symref );
423
- strbuf_addf (& out , " -> %s" , symref );
424
- }
425
- else if (filter -> verbose )
426
- /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
427
- add_verbose_info (& out , item , filter , desc );
428
- if (column_active (colopts )) {
429
- assert (!filter -> verbose && "--column and --verbose are incompatible" );
430
- string_list_append (& output , out .buf );
431
352
} else {
432
- printf ("%s\n" , out .buf );
353
+ strbuf_addf (& local , "%%(refname:lstrip=2)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)" ,
354
+ branch_get_color (BRANCH_COLOR_RESET ));
355
+ strbuf_addf (& remote , "%s%s%%(refname:lstrip=2)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)" ,
356
+ branch_get_color (BRANCH_COLOR_REMOTE ), quote_literal_for_format (remote_prefix ),
357
+ branch_get_color (BRANCH_COLOR_RESET ));
433
358
}
434
- strbuf_release (& name );
435
- strbuf_release (& out );
436
- free (to_free );
437
- }
438
-
439
- static int calc_maxwidth (struct ref_array * refs , int remote_bonus )
440
- {
441
- int i , max = 0 ;
442
- for (i = 0 ; i < refs -> nr ; i ++ ) {
443
- struct ref_array_item * it = refs -> items [i ];
444
- const char * desc = it -> refname ;
445
- int w ;
446
359
447
- skip_prefix (it -> refname , "refs/heads/" , & desc );
448
- skip_prefix (it -> refname , "refs/remotes/" , & desc );
449
- w = utf8_strwidth (desc );
360
+ strbuf_addf (& fmt , "%%(if:notequals=refs/remotes)%%(refname:rstrip=-2)%%(then)%s%%(else)%s%%(end)" , local .buf , remote .buf );
450
361
451
- if (it -> kind == FILTER_REFS_REMOTES )
452
- w += remote_bonus ;
453
- if (w > max )
454
- max = w ;
455
- }
456
- return max ;
362
+ strbuf_release (& local );
363
+ strbuf_release (& remote );
364
+ return strbuf_detach (& fmt , NULL );
457
365
}
458
366
459
367
static void print_ref_list (struct ref_filter * filter , struct ref_sorting * sorting )
@@ -462,6 +370,8 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
462
370
struct ref_array array ;
463
371
int maxwidth = 0 ;
464
372
const char * remote_prefix = "" ;
373
+ struct strbuf out = STRBUF_INIT ;
374
+ char * format ;
465
375
466
376
/*
467
377
* If we are listing more than just remote branches,
@@ -473,18 +383,31 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
473
383
474
384
memset (& array , 0 , sizeof (array ));
475
385
476
- verify_ref_format ("%(refname)%(symref)" );
477
386
filter_refs (& array , filter , filter -> kind | FILTER_REFS_INCLUDE_BROKEN );
478
387
479
388
if (filter -> verbose )
480
389
maxwidth = calc_maxwidth (& array , strlen (remote_prefix ));
481
390
391
+ format = build_format (filter , maxwidth , remote_prefix );
392
+ verify_ref_format (format );
393
+
482
394
ref_array_sort (sorting , & array );
483
395
484
- for (i = 0 ; i < array .nr ; i ++ )
485
- format_and_print_ref_item (array .items [i ], maxwidth , filter , remote_prefix );
396
+ for (i = 0 ; i < array .nr ; i ++ ) {
397
+ format_ref_array_item (array .items [i ], format , 0 , & out );
398
+ if (column_active (colopts )) {
399
+ assert (!filter -> verbose && "--column and --verbose are incompatible" );
400
+ /* format to a string_list to let print_columns() do its job */
401
+ string_list_append (& output , out .buf );
402
+ } else {
403
+ fwrite (out .buf , 1 , out .len , stdout );
404
+ putchar ('\n' );
405
+ }
406
+ strbuf_release (& out );
407
+ }
486
408
487
409
ref_array_clear (& array );
410
+ free (format );
488
411
}
489
412
490
413
static void reject_rebase_or_bisect_branch (const char * target )
0 commit comments