@@ -548,6 +548,20 @@ sub evaluate_uri {
548
548
' sub' => sub { feature_bool(' remote_heads' , @_ ) },
549
549
' override' => 0,
550
550
' default' => [0]},
551
+
552
+ # Enable showing branches under other refs in addition to heads
553
+
554
+ # To set system wide extra branch refs have in $GITWEB_CONFIG
555
+ # $feature{'extra-branch-refs'}{'default'} = ['dirs', 'of', 'choice'];
556
+ # To have project specific config enable override in $GITWEB_CONFIG
557
+ # $feature{'extra-branch-refs'}{'override'} = 1;
558
+ # and in project config gitweb.extrabranchrefs = dirs of choice
559
+ # Every directory is separated with whitespace.
560
+
561
+ ' extra-branch-refs' => {
562
+ ' sub' => \&feature_extra_branch_refs,
563
+ ' override' => 0,
564
+ ' default' => []},
551
565
);
552
566
553
567
sub gitweb_get_feature {
@@ -626,6 +640,21 @@ sub feature_avatar {
626
640
return @val ? @val : @_ ;
627
641
}
628
642
643
+ sub feature_extra_branch_refs {
644
+ my (@branch_refs ) = @_ ;
645
+ my $values = git_get_project_config(' extrabranchrefs' );
646
+
647
+ if ($values ) {
648
+ $values = config_to_multi ($values );
649
+ @branch_refs = ();
650
+ foreach my $value (@{$values }) {
651
+ push @branch_refs , split /\s +/, $value ;
652
+ }
653
+ }
654
+
655
+ return @branch_refs ;
656
+ }
657
+
629
658
# checking HEAD file with -e is fragile if the repository was
630
659
# initialized long time ago (i.e. symlink HEAD) and was pack-ref'ed
631
660
# and then pruned.
@@ -656,6 +685,18 @@ sub filter_snapshot_fmts {
656
685
!$known_snapshot_formats {$_ }{' disabled' }} @fmts ;
657
686
}
658
687
688
+ sub filter_and_validate_refs {
689
+ my @refs = @_ ;
690
+ my %unique_refs = ();
691
+
692
+ foreach my $ref (@refs ) {
693
+ die_error(500, " Invalid ref '$ref ' in 'extra-branch-refs' feature" ) unless (is_valid_ref_format($ref ));
694
+ # 'heads' are added implicitly in get_branch_refs().
695
+ $unique_refs {$ref } = 1 if ($ref ne ' heads' );
696
+ }
697
+ return sort keys %unique_refs ;
698
+ }
699
+
659
700
# If it is set to code reference, it is code that it is to be run once per
660
701
# request, allowing updating configurations that change with each request,
661
702
# while running other code in config file only once.
@@ -1113,7 +1154,7 @@ sub evaluate_git_dir {
1113
1154
our $git_dir = " $projectroot /$project " if $project ;
1114
1155
}
1115
1156
1116
- our (@snapshot_fmts , $git_avatar );
1157
+ our (@snapshot_fmts , $git_avatar , @extra_branch_refs );
1117
1158
sub configure_gitweb_features {
1118
1159
# list of supported snapshot formats
1119
1160
our @snapshot_fmts = gitweb_get_feature(' snapshot' );
@@ -1131,6 +1172,13 @@ sub configure_gitweb_features {
1131
1172
} else {
1132
1173
$git_avatar = ' ' ;
1133
1174
}
1175
+
1176
+ our @extra_branch_refs = gitweb_get_feature(' extra-branch-refs' );
1177
+ @extra_branch_refs = filter_and_validate_refs (@extra_branch_refs );
1178
+ }
1179
+
1180
+ sub get_branch_refs {
1181
+ return (' heads' , @extra_branch_refs );
1134
1182
}
1135
1183
1136
1184
# custom error handler: 'die <message>' is Internal Server Error
@@ -2527,19 +2575,25 @@ sub format_snapshot_links {
2527
2575
sub get_feed_info {
2528
2576
my $format = shift || ' Atom' ;
2529
2577
my %res = (action => lc ($format ));
2578
+ my $matched_ref = 0;
2530
2579
2531
2580
# feed links are possible only for project views
2532
2581
return unless (defined $project );
2533
2582
# some views should link to OPML, or to generic project feed,
2534
2583
# or don't have specific feed yet (so they should use generic)
2535
2584
return if (!$action || $action =~ / ^(?:tags|heads|forks|tag|search)$ /x );
2536
2585
2537
- my $branch ;
2538
- # branches refs uses 'refs/heads/' prefix (fullname) to differentiate
2539
- # from tag links; this also makes possible to detect branch links
2540
- if ((defined $hash_base && $hash_base =~ m ! ^refs/heads/(.*)$ ! ) ||
2541
- (defined $hash && $hash =~ m ! ^refs/heads/(.*)$ ! )) {
2542
- $branch = $1 ;
2586
+ my $branch = undef ;
2587
+ # branches refs uses 'refs/' + $get_branch_refs()[x] + '/' prefix
2588
+ # (fullname) to differentiate from tag links; this also makes
2589
+ # possible to detect branch links
2590
+ for my $ref (get_branch_refs()) {
2591
+ if ((defined $hash_base && $hash_base =~ m ! ^refs/\Q $ref \E /(.*)$ ! ) ||
2592
+ (defined $hash && $hash =~ m ! ^refs/\Q $ref \E /(.*)$ ! )) {
2593
+ $branch = $1 ;
2594
+ $matched_ref = $ref ;
2595
+ last ;
2596
+ }
2543
2597
}
2544
2598
# find log type for feed description (title)
2545
2599
my $type = ' log' ;
@@ -2552,7 +2606,7 @@ sub get_feed_info {
2552
2606
}
2553
2607
2554
2608
$res {-title} = $type ;
2555
- $res {' hash' } = (defined $branch ? " refs/heads /$branch " : undef );
2609
+ $res {' hash' } = (defined $branch ? " refs/$matched_ref /$branch " : undef );
2556
2610
$res {' file_name' } = $file_name ;
2557
2611
2558
2612
return %res ;
@@ -3205,7 +3259,7 @@ sub git_get_last_activity {
3205
3259
' --format=%(committer)' ,
3206
3260
' --sort=-committerdate' ,
3207
3261
' --count=1' ,
3208
- ' refs/heads ' ) or return ;
3262
+ map { " refs/$_ " } get_branch_refs () ) or return ;
3209
3263
my $most_recent = <$fd >;
3210
3264
close $fd or return ;
3211
3265
if (defined $most_recent &&
@@ -3656,7 +3710,7 @@ sub parse_from_to_diffinfo {
3656
3710
3657
3711
sub git_get_heads_list {
3658
3712
my ($limit , @classes ) = @_ ;
3659
- @classes = ( ' heads ' ) unless @classes ;
3713
+ @classes = get_branch_refs( ) unless @classes ;
3660
3714
my @patterns = map { " refs/$_ " } @classes ;
3661
3715
my @headslist ;
3662
3716
@@ -3674,7 +3728,8 @@ sub git_get_heads_list {
3674
3728
my ($committer , $epoch , $tz ) =
3675
3729
($committerinfo =~ / ^(.*) ([0-9]+) (.*)$ / );
3676
3730
$ref_item {' fullname' } = $name ;
3677
- $name =~ s ! ^refs/(?:head|remote)s/!! ;
3731
+ my $strip_refs = join ' |' , map { quotemeta } get_branch_refs();
3732
+ $name =~ s ! ^refs/($strip_refs|remotes)/!! ;
3678
3733
3679
3734
$ref_item {' name' } = $name ;
3680
3735
$ref_item {' id' } = $hash ;
@@ -7191,7 +7246,8 @@ sub snapshot_name {
7191
7246
$ver = $1 ;
7192
7247
} else {
7193
7248
# branches and other need shortened SHA-1 hash
7194
- if ($hash =~ m ! ^refs/(?:heads|remotes)/(.*)$ ! ) {
7249
+ my $strip_refs = join ' |' , map { quotemeta } get_branch_refs();
7250
+ if ($hash =~ m ! ^refs/($strip_refs |remotes)/(.*)$ ! ) {
7195
7251
$ver = $1 ;
7196
7252
}
7197
7253
$ver .= ' -' . git_get_short_hash($project , $hash );
0 commit comments