]> Lady’s Gitweb - Gitweb/blobdiff - gitweb.perl
gitweb: separate heads and remotes lists
[Gitweb] / gitweb.perl
index df186d8d2a107ef28ad8ca7e3724963b6519db39b4c90d64b416d9a23508d1a5..b5ac7c0e10cdf18e6579743905f1b049f81835e0ac5d35917c27df46188bef1c 100755 (executable)
@@ -17,12 +17,10 @@ use Encode;
 use Fcntl ':mode';
 use File::Find qw();
 use File::Basename qw(basename);
 use Fcntl ':mode';
 use File::Find qw();
 use File::Basename qw(basename);
+use Time::HiRes qw(gettimeofday tv_interval);
 binmode STDOUT, ':utf8';
 
 binmode STDOUT, ':utf8';
 
-our $t0;
-if (eval { require Time::HiRes; 1; }) {
-       $t0 = [Time::HiRes::gettimeofday()];
-}
+our $t0 = [ gettimeofday() ];
 our $number_of_git_cmds = 0;
 
 BEGIN {
 our $number_of_git_cmds = 0;
 
 BEGIN {
@@ -494,6 +492,18 @@ our %feature = (
                'sub' => sub { feature_bool('highlight', @_) },
                'override' => 0,
                'default' => [0]},
                'sub' => sub { feature_bool('highlight', @_) },
                'override' => 0,
                'default' => [0]},
+
+       # Enable displaying of remote heads in the heads list
+
+       # To enable system wide have in $GITWEB_CONFIG
+       # $feature{'remote_heads'}{'default'} = [1];
+       # To have project specific config enable override in $GITWEB_CONFIG
+       # $feature{'remote_heads'}{'override'} = 1;
+       # and in project config gitweb.remote_heads = 0|1;
+       'remote_heads' => {
+               'sub' => sub { feature_bool('remote_heads', @_) },
+               'override' => 0,
+               'default' => [0]},
 );
 
 sub gitweb_get_feature {
 );
 
 sub gitweb_get_feature {
@@ -708,6 +718,7 @@ our %actions = (
        "log" => \&git_log,
        "patch" => \&git_patch,
        "patches" => \&git_patches,
        "log" => \&git_log,
        "patch" => \&git_patch,
        "patches" => \&git_patches,
+       "remotes" => \&git_remotes,
        "rss" => \&git_rss,
        "atom" => \&git_atom,
        "search" => \&git_search,
        "rss" => \&git_rss,
        "atom" => \&git_atom,
        "search" => \&git_search,
@@ -821,8 +832,15 @@ sub evaluate_path_info {
                # hash_base instead. It should also be noted that hand-crafted
                # links having 'history' as an action and no pathname or hash
                # set will fail, but that happens regardless of PATH_INFO.
                # hash_base instead. It should also be noted that hand-crafted
                # links having 'history' as an action and no pathname or hash
                # set will fail, but that happens regardless of PATH_INFO.
-               $input_params{'action'} ||= "shortlog";
-               if (grep { $_ eq $input_params{'action'} } @wants_base) {
+               if (defined $parentrefname) {
+                       # if there is parent let the default be 'shortlog' action
+                       # (for http://git.example.com/repo.git/A..B links); if there
+                       # is no parent, dispatch will detect type of object and set
+                       # action appropriately if required (if action is not set)
+                       $input_params{'action'} ||= "shortlog";
+               }
+               if ($input_params{'action'} &&
+                   grep { $_ eq $input_params{'action'} } @wants_base) {
                        $input_params{'hash_base'} ||= $refname;
                } else {
                        $input_params{'hash'} ||= $refname;
                        $input_params{'hash_base'} ||= $refname;
                } else {
                        $input_params{'hash'} ||= $refname;
@@ -1059,7 +1077,7 @@ sub dispatch {
 }
 
 sub reset_timer {
 }
 
 sub reset_timer {
-       our $t0 = [Time::HiRes::gettimeofday()]
+       our $t0 = [ gettimeofday() ]
                if defined $t0;
        our $number_of_git_cmds = 0;
 }
                if defined $t0;
        our $number_of_git_cmds = 0;
 }
@@ -3151,13 +3169,15 @@ sub parse_from_to_diffinfo {
 ## parse to array of hashes functions
 
 sub git_get_heads_list {
 ## parse to array of hashes functions
 
 sub git_get_heads_list {
-       my $limit = shift;
+       my ($limit, @classes) = @_;
+       @classes = ('heads') unless @classes;
+       my @patterns = map { "refs/$_" } @classes;
        my @headslist;
 
        open my $fd, '-|', git_cmd(), 'for-each-ref',
                ($limit ? '--count='.($limit+1) : ()), '--sort=-committerdate',
                '--format=%(objectname) %(refname) %(subject)%00%(committer)',
        my @headslist;
 
        open my $fd, '-|', git_cmd(), 'for-each-ref',
                ($limit ? '--count='.($limit+1) : ()), '--sort=-committerdate',
                '--format=%(objectname) %(refname) %(subject)%00%(committer)',
-               'refs/heads'
+               @patterns
                or return;
        while (my $line = <$fd>) {
                my %ref_item;
                or return;
        while (my $line = <$fd>) {
                my %ref_item;
@@ -3168,7 +3188,7 @@ sub git_get_heads_list {
                my ($committer, $epoch, $tz) =
                        ($committerinfo =~ /^(.*) ([0-9]+) (.*)$/);
                $ref_item{'fullname'}  = $name;
                my ($committer, $epoch, $tz) =
                        ($committerinfo =~ /^(.*) ([0-9]+) (.*)$/);
                $ref_item{'fullname'}  = $name;
-               $name =~ s!^refs/heads/!!;
+               $name =~ s!^refs/(?:head|remote)s/!!;
 
                $ref_item{'name'}  = $name;
                $ref_item{'id'}    = $hash;
 
                $ref_item{'name'}  = $name;
                $ref_item{'id'}    = $hash;
@@ -3584,7 +3604,7 @@ sub git_footer_html {
                print "<div id=\"generating_info\">\n";
                print 'This page took '.
                      '<span id="generating_time" class="time_span">'.
                print "<div id=\"generating_info\">\n";
                print 'This page took '.
                      '<span id="generating_time" class="time_span">'.
-                     Time::HiRes::tv_interval($t0, [Time::HiRes::gettimeofday()]).
+                     tv_interval($t0, [ gettimeofday() ]).
                      ' seconds </span>'.
                      ' and '.
                      '<span id="generating_cmd">'.
                      ' seconds </span>'.
                      ' and '.
                      '<span id="generating_cmd">'.
@@ -4954,7 +4974,7 @@ sub git_heads_body {
                      "<td class=\"link\">" .
                      $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'})}, "shortlog") . " | " .
                      $cgi->a({-href => href(action=>"log", hash=>$ref{'fullname'})}, "log") . " | " .
                      "<td class=\"link\">" .
                      $cgi->a({-href => href(action=>"shortlog", hash=>$ref{'fullname'})}, "shortlog") . " | " .
                      $cgi->a({-href => href(action=>"log", hash=>$ref{'fullname'})}, "log") . " | " .
-                     $cgi->a({-href => href(action=>"tree", hash=>$ref{'fullname'}, hash_base=>$ref{'name'})}, "tree") .
+                     $cgi->a({-href => href(action=>"tree", hash=>$ref{'fullname'}, hash_base=>$ref{'fullname'})}, "tree") .
                      "</td>\n" .
                      "</tr>";
        }
                      "</td>\n" .
                      "</tr>";
        }
@@ -5103,6 +5123,7 @@ sub git_summary {
        my %co = parse_commit("HEAD");
        my %cd = %co ? parse_date($co{'committer_epoch'}, $co{'committer_tz'}) : ();
        my $head = $co{'id'};
        my %co = parse_commit("HEAD");
        my %cd = %co ? parse_date($co{'committer_epoch'}, $co{'committer_tz'}) : ();
        my $head = $co{'id'};
+       my $remote_heads = gitweb_check_feature('remote_heads');
 
        my $owner = git_get_project_owner($project);
 
 
        my $owner = git_get_project_owner($project);
 
@@ -5111,6 +5132,7 @@ sub git_summary {
        # there are more ...
        my @taglist  = git_get_tags_list(16);
        my @headlist = git_get_heads_list(16);
        # there are more ...
        my @taglist  = git_get_tags_list(16);
        my @headlist = git_get_heads_list(16);
+       my @remotelist = $remote_heads ? git_get_heads_list(16, 'remotes') : ();
        my @forklist;
        my $check_forks = gitweb_check_feature('forks');
 
        my @forklist;
        my $check_forks = gitweb_check_feature('forks');
 
@@ -5188,6 +5210,13 @@ sub git_summary {
                               $cgi->a({-href => href(action=>"heads")}, "..."));
        }
 
                               $cgi->a({-href => href(action=>"heads")}, "..."));
        }
 
+       if (@remotelist) {
+               git_print_header_div('remotes');
+               git_heads_body(\@remotelist, $head, 0, 15,
+                              $#remotelist <= 15 ? undef :
+                              $cgi->a({-href => href(action=>"remotes")}, "..."));
+       }
+
        if (@forklist) {
                git_print_header_div('forks');
                git_project_list_body(\@forklist, 'age', 0, 15,
        if (@forklist) {
                git_print_header_div('forks');
                git_project_list_body(\@forklist, 'age', 0, 15,
@@ -5292,7 +5321,7 @@ sub git_blame_common {
                print 'END';
                if (defined $t0 && gitweb_check_feature('timed')) {
                        print ' '.
                print 'END';
                if (defined $t0 && gitweb_check_feature('timed')) {
                        print ' '.
-                             Time::HiRes::tv_interval($t0, [Time::HiRes::gettimeofday()]).
+                             tv_interval($t0, [ gettimeofday() ]).
                              ' '.$number_of_git_cmds;
                }
                print "\n";
                              ' '.$number_of_git_cmds;
                }
                print "\n";
@@ -5502,6 +5531,22 @@ sub git_heads {
        git_footer_html();
 }
 
        git_footer_html();
 }
 
+sub git_remotes {
+       gitweb_check_feature('remote_heads')
+               or die_error(403, "Remote heads view is disabled");
+
+       my $head = git_get_head_hash($project);
+       git_header_html();
+       git_print_page_nav('','', $head,undef,$head);
+       git_print_header_div('summary', $project);
+
+       my @remotelist = git_get_heads_list(undef, 'remotes');
+       if (@remotelist) {
+               git_heads_body(\@remotelist, $head);
+       }
+       git_footer_html();
+}
+
 sub git_blob_plain {
        my $type = shift;
        my $expires;
 sub git_blob_plain {
        my $type = shift;
        my $expires;
This page took 0.25813 seconds and 4 git commands to generate.