@@ -270,125 +270,6 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
270
270
return (ret );
271
271
}
272
272
273
- static char * resolve_symref (const char * src , const char * prefix )
274
- {
275
- unsigned char sha1 [20 ];
276
- int flag ;
277
- const char * dst ;
278
-
279
- dst = resolve_ref_unsafe (src , 0 , sha1 , & flag );
280
- if (!(dst && (flag & REF_ISSYMREF )))
281
- return NULL ;
282
- if (prefix )
283
- skip_prefix (dst , prefix , & dst );
284
- return xstrdup (dst );
285
- }
286
-
287
- static int match_patterns (const char * * pattern , const char * refname )
288
- {
289
- if (!* pattern )
290
- return 1 ; /* no pattern always matches */
291
- while (* pattern ) {
292
- if (!wildmatch (* pattern , refname , 0 , NULL ))
293
- return 1 ;
294
- pattern ++ ;
295
- }
296
- return 0 ;
297
- }
298
-
299
- /*
300
- * Allocate memory for a new ref_array_item and insert that into the
301
- * given ref_array. Doesn't take the objectname unlike
302
- * new_ref_array_item(). This is a temporary function which will be
303
- * removed when we port branch.c to use ref-filter APIs.
304
- */
305
- static struct ref_array_item * ref_array_append (struct ref_array * array , const char * refname )
306
- {
307
- size_t len = strlen (refname );
308
- struct ref_array_item * ref = xcalloc (1 , sizeof (struct ref_array_item ) + len + 1 );
309
- memcpy (ref -> refname , refname , len );
310
- ref -> refname [len ] = '\0' ;
311
- REALLOC_ARRAY (array -> items , array -> nr + 1 );
312
- array -> items [array -> nr ++ ] = ref ;
313
- return ref ;
314
- }
315
-
316
- static int append_ref (const char * refname , const struct object_id * oid , int flags , void * cb_data )
317
- {
318
- struct ref_filter_cbdata * cb = (struct ref_filter_cbdata * )(cb_data );
319
- struct ref_filter * filter = cb -> filter ;
320
- struct ref_array * array = cb -> array ;
321
- struct ref_array_item * item ;
322
- struct commit * commit ;
323
- int kind , i ;
324
- const char * prefix , * orig_refname = refname ;
325
-
326
- static struct {
327
- int kind ;
328
- const char * prefix ;
329
- } ref_kind [] = {
330
- { FILTER_REFS_BRANCHES , "refs/heads/" },
331
- { FILTER_REFS_REMOTES , "refs/remotes/" },
332
- };
333
-
334
- /* Detect kind */
335
- for (i = 0 ; i < ARRAY_SIZE (ref_kind ); i ++ ) {
336
- prefix = ref_kind [i ].prefix ;
337
- if (skip_prefix (refname , prefix , & refname )) {
338
- kind = ref_kind [i ].kind ;
339
- break ;
340
- }
341
- }
342
- if (ARRAY_SIZE (ref_kind ) <= i ) {
343
- if (!strcmp (refname , "HEAD" ))
344
- kind = FILTER_REFS_DETACHED_HEAD ;
345
- else
346
- return 0 ;
347
- }
348
-
349
- /* Don't add types the caller doesn't want */
350
- if ((kind & filter -> kind ) == 0 )
351
- return 0 ;
352
-
353
- if (!match_patterns (filter -> name_patterns , refname ))
354
- return 0 ;
355
-
356
- commit = NULL ;
357
- if (filter -> verbose || filter -> with_commit || filter -> merge != REF_FILTER_MERGED_NONE ) {
358
- commit = lookup_commit_reference_gently (oid -> hash , 1 );
359
- if (!commit )
360
- return 0 ;
361
-
362
- /* Filter with with_commit if specified */
363
- if (!is_descendant_of (commit , filter -> with_commit ))
364
- return 0 ;
365
-
366
- if (filter -> merge != REF_FILTER_MERGED_NONE )
367
- add_pending_object (array -> revs ,
368
- (struct object * )commit , refname );
369
- }
370
-
371
- item = ref_array_append (array , refname );
372
-
373
- /* Record the new item */
374
- item -> kind = kind ;
375
- item -> commit = commit ;
376
- item -> symref = resolve_symref (orig_refname , prefix );
377
- item -> ignore = 0 ;
378
-
379
- return 0 ;
380
- }
381
-
382
- static int ref_cmp (const void * r1 , const void * r2 )
383
- {
384
- struct ref_array_item * c1 = * ((struct ref_array_item * * )r1 );
385
- struct ref_array_item * c2 = * ((struct ref_array_item * * )r2 );
386
-
387
- if (c1 -> kind != c2 -> kind )
388
- return c1 -> kind - c2 -> kind ;
389
- return strcmp (c1 -> refname , c2 -> refname );
390
- }
391
-
392
273
static void fill_tracking_info (struct strbuf * stat , const char * branch_name ,
393
274
int show_upstream_ref )
394
275
{
@@ -452,7 +333,7 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
452
333
}
453
334
454
335
static void add_verbose_info (struct strbuf * out , struct ref_array_item * item ,
455
- struct ref_filter * filter )
336
+ struct ref_filter * filter , const char * refname )
456
337
{
457
338
struct strbuf subject = STRBUF_INIT , stat = STRBUF_INIT ;
458
339
const char * sub = _ (" **** invalid ref ****" );
@@ -464,7 +345,7 @@ static void add_verbose_info(struct strbuf *out, struct ref_array_item *item,
464
345
}
465
346
466
347
if (item -> kind == FILTER_REFS_BRANCHES )
467
- fill_tracking_info (& stat , item -> refname , filter -> verbose > 1 );
348
+ fill_tracking_info (& stat , refname , filter -> verbose > 1 );
468
349
469
350
strbuf_addf (out , " %s %s%s" ,
470
351
find_unique_abbrev (item -> commit -> object .sha1 , filter -> abbrev ),
@@ -504,8 +385,8 @@ static char *get_head_description(void)
504
385
return strbuf_detach (& desc , NULL );
505
386
}
506
387
507
- static void print_ref_item (struct ref_array_item * item , int maxwidth ,
508
- struct ref_filter * filter , const char * remote_prefix )
388
+ static void format_and_print_ref_item (struct ref_array_item * item , int maxwidth ,
389
+ struct ref_filter * filter , const char * remote_prefix )
509
390
{
510
391
char c ;
511
392
int current = 0 ;
@@ -515,17 +396,16 @@ static void print_ref_item(struct ref_array_item *item, int maxwidth,
515
396
const char * desc = item -> refname ;
516
397
char * to_free = NULL ;
517
398
518
- if (item -> ignore )
519
- return ;
520
-
521
399
switch (item -> kind ) {
522
400
case FILTER_REFS_BRANCHES :
523
- if (!filter -> detached && !strcmp (item -> refname , head ))
401
+ skip_prefix (desc , "refs/heads/" , & desc );
402
+ if (!filter -> detached && !strcmp (desc , head ))
524
403
current = 1 ;
525
404
else
526
405
color = BRANCH_COLOR_LOCAL ;
527
406
break ;
528
407
case FILTER_REFS_REMOTES :
408
+ skip_prefix (desc , "refs/remotes/" , & desc );
529
409
color = BRANCH_COLOR_REMOTE ;
530
410
prefix = remote_prefix ;
531
411
break ;
@@ -554,11 +434,13 @@ static void print_ref_item(struct ref_array_item *item, int maxwidth,
554
434
strbuf_addf (& out , "%c %s%s%s" , c , branch_get_color (color ),
555
435
name .buf , branch_get_color (BRANCH_COLOR_RESET ));
556
436
557
- if (item -> symref )
558
- strbuf_addf (& out , " -> %s" , item -> symref );
437
+ if (item -> symref ) {
438
+ skip_prefix (item -> symref , "refs/remotes/" , & desc );
439
+ strbuf_addf (& out , " -> %s" , desc );
440
+ }
559
441
else if (filter -> verbose )
560
442
/* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
561
- add_verbose_info (& out , item , filter );
443
+ add_verbose_info (& out , item , filter , desc );
562
444
if (column_active (colopts )) {
563
445
assert (!filter -> verbose && "--column and --verbose are incompatible" );
564
446
string_list_append (& output , out .buf );
@@ -575,11 +457,13 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
575
457
int i , max = 0 ;
576
458
for (i = 0 ; i < refs -> nr ; i ++ ) {
577
459
struct ref_array_item * it = refs -> items [i ];
460
+ const char * desc = it -> refname ;
578
461
int w ;
579
462
580
- if (it -> ignore )
581
- continue ;
582
- w = utf8_strwidth (it -> refname );
463
+ skip_prefix (it -> refname , "refs/heads/" , & desc );
464
+ skip_prefix (it -> refname , "refs/remotes/" , & desc );
465
+ w = utf8_strwidth (desc );
466
+
583
467
if (it -> kind == FILTER_REFS_REMOTES )
584
468
w += remote_bonus ;
585
469
if (w > max )
@@ -588,14 +472,12 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
588
472
return max ;
589
473
}
590
474
591
- static void print_ref_list (struct ref_filter * filter )
475
+ static void print_ref_list (struct ref_filter * filter , struct ref_sorting * sorting )
592
476
{
593
477
int i ;
594
478
struct ref_array array ;
595
- struct ref_filter_cbdata data ;
596
479
int maxwidth = 0 ;
597
480
const char * remote_prefix = "" ;
598
- struct rev_info revs ;
599
481
600
482
/*
601
483
* If we are listing more than just remote branches,
@@ -606,54 +488,26 @@ static void print_ref_list(struct ref_filter *filter)
606
488
remote_prefix = "remotes/" ;
607
489
608
490
memset (& array , 0 , sizeof (array ));
609
- if (filter -> merge != REF_FILTER_MERGED_NONE )
610
- init_revisions (& revs , NULL );
611
-
612
- data .array = & array ;
613
- data .filter = filter ;
614
- array .revs = & revs ;
615
-
616
- /*
617
- * First we obtain all regular branch refs and if the HEAD is
618
- * detached then we insert that ref to the end of the ref_fist
619
- * so that it can be printed and removed first.
620
- */
621
- for_each_rawref (append_ref , & data );
622
- if (filter -> detached )
623
- head_ref (append_ref , & data );
624
- /*
625
- * The following implementation is currently duplicated in ref-filter. It
626
- * will eventually be removed when we port branch.c to use ref-filter APIs.
627
- */
628
- if (filter -> merge != REF_FILTER_MERGED_NONE ) {
629
- filter -> merge_commit -> object .flags |= UNINTERESTING ;
630
- add_pending_object (& revs , & filter -> merge_commit -> object , "" );
631
- revs .limited = 1 ;
632
-
633
- if (prepare_revision_walk (& revs ))
634
- die (_ ("revision walk setup failed" ));
635
-
636
- for (i = 0 ; i < array .nr ; i ++ ) {
637
- struct ref_array_item * item = array .items [i ];
638
- struct commit * commit = item -> commit ;
639
- int is_merged = !!(commit -> object .flags & UNINTERESTING );
640
- item -> ignore = is_merged != (filter -> merge == REF_FILTER_MERGED_INCLUDE );
641
- }
642
491
643
- for (i = 0 ; i < array .nr ; i ++ ) {
644
- struct ref_array_item * item = array .items [i ];
645
- clear_commit_marks (item -> commit , ALL_REV_FLAGS );
646
- }
647
- clear_commit_marks (filter -> merge_commit , ALL_REV_FLAGS );
648
- }
492
+ verify_ref_format ("%(refname)%(symref)" );
493
+ filter_refs (& array , filter , filter -> kind | FILTER_REFS_INCLUDE_BROKEN );
649
494
650
495
if (filter -> verbose )
651
496
maxwidth = calc_maxwidth (& array , strlen (remote_prefix ));
652
497
653
- qsort (array .items , array .nr , sizeof (struct ref_array_item * ), ref_cmp );
498
+ /*
499
+ * If no sorting parameter is given then we default to sorting
500
+ * by 'refname'. This would give us an alphabetically sorted
501
+ * array with the 'HEAD' ref at the beginning followed by
502
+ * local branches 'refs/heads/...' and finally remote-tacking
503
+ * branches 'refs/remotes/...'.
504
+ */
505
+ if (!sorting )
506
+ sorting = ref_default_sorting ();
507
+ ref_array_sort (sorting , & array );
654
508
655
509
for (i = 0 ; i < array .nr ; i ++ )
656
- print_ref_item (array .items [i ], maxwidth , filter , remote_prefix );
510
+ format_and_print_ref_item (array .items [i ], maxwidth , filter , remote_prefix );
657
511
658
512
ref_array_clear (& array );
659
513
}
@@ -755,6 +609,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
755
609
const char * new_upstream = NULL ;
756
610
enum branch_track track ;
757
611
struct ref_filter filter ;
612
+ static struct ref_sorting * sorting = NULL , * * sorting_tail = & sorting ;
758
613
759
614
struct option options [] = {
760
615
OPT_GROUP (N_ ("Generic options" )),
@@ -789,6 +644,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
789
644
OPT_MERGED (& filter , N_ ("print only branches that are merged" )),
790
645
OPT_NO_MERGED (& filter , N_ ("print only branches that are not merged" )),
791
646
OPT_COLUMN (0 , "column" , & colopts , N_ ("list branches in columns" )),
647
+ OPT_CALLBACK (0 , "sort" , sorting_tail , N_ ("key" ),
648
+ N_ ("field name to sort on" ), & parse_opt_ref_sorting ),
792
649
OPT_END (),
793
650
};
794
651
@@ -847,7 +704,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
847
704
if ((filter .kind & FILTER_REFS_BRANCHES ) && filter .detached )
848
705
filter .kind |= FILTER_REFS_DETACHED_HEAD ;
849
706
filter .name_patterns = argv ;
850
- print_ref_list (& filter );
707
+ print_ref_list (& filter , sorting );
851
708
print_columns (& output , colopts , NULL );
852
709
string_list_clear (& output , 0 );
853
710
return 0 ;
0 commit comments