diff options
author | Junio C Hamano <junkio@cox.net> | 2006-11-04 17:13:38 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-11-04 17:13:38 -0800 |
commit | 9004dcbe8278b6d66f41e6e401f6d564a64fd1e1 (patch) | |
tree | dccd6e577522c6526259d5657953d996046f32c0 /gitweb | |
parent | a622f6b35eb72b0ce738c03d6b49f760501bce78 (diff) | |
parent | e30496dfcb98a305a57b835c248cbc3aa2376bfc (diff) | |
download | git-9004dcbe8278b6d66f41e6e401f6d564a64fd1e1.tar.gz git-9004dcbe8278b6d66f41e6e401f6d564a64fd1e1.tar.xz |
Merge branch 'pb/web'
* pb/web:
gitweb: Support for 'forks'
Diffstat (limited to 'gitweb')
-rwxr-xr-x | gitweb/gitweb.perl | 256 |
1 files changed, 174 insertions, 82 deletions
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 3759be37b..3c6fd7ca4 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -160,6 +160,21 @@ our %feature = ( 'pathinfo' => { 'override' => 0, 'default' => [0]}, + + # Make gitweb consider projects in project root subdirectories + # to be forks of existing projects. Given project $projname.git, + # projects matching $projname/*.git will not be shown in the main + # projects list, instead a '+' mark will be added to $projname + # there and a 'forks' view will be enabled for the project, listing + # all the forks. This feature is supported only if project list + # is taken from a directory, not file. + + # To enable system wide have in $GITWEB_CONFIG + # $feature{'forks'}{'default'} = [1]; + # Project specific override is not supported. + 'forks' => { + 'override' => 0, + 'default' => [0]}, ); sub gitweb_check_feature { @@ -405,6 +420,7 @@ my %actions = ( "commitdiff" => \&git_commitdiff, "commitdiff_plain" => \&git_commitdiff_plain, "commit" => \&git_commit, + "forks" => \&git_forks, "heads" => \&git_heads, "history" => \&git_history, "log" => \&git_log, @@ -897,15 +913,21 @@ sub git_get_project_url_list { } sub git_get_projects_list { + my ($filter) = @_; my @list; + $filter ||= ''; + $filter =~ s/\.git$//; + if (-d $projects_list) { # search in directory - my $dir = $projects_list; + my $dir = $projects_list . ($filter ? "/$filter" : ''); # remove the trailing "/" $dir =~ s!/+$!!; my $pfxlen = length("$dir"); + my $check_forks = gitweb_check_feature('forks'); + File::Find::find({ follow_fast => 1, # follow symbolic links dangling_symlinks => 0, # ignore dangling symlinks, silently @@ -917,8 +939,10 @@ sub git_get_projects_list { my $subdir = substr($File::Find::name, $pfxlen + 1); # we check related file in $projectroot - if (check_export_ok("$projectroot/$subdir")) { - push @list, { path => $subdir }; + if ($check_forks and $subdir =~ m#/.#) { + $File::Find::prune = 1; + } elsif (check_export_ok("$projectroot/$filter/$subdir")) { + push @list, { path => ($filter ? "$filter/" : '') . $subdir }; $File::Find::prune = 1; } }, @@ -2185,6 +2209,124 @@ sub git_patchset_body { # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +sub git_project_list_body { + my ($projlist, $order, $from, $to, $extra, $no_header) = @_; + + my $check_forks = gitweb_check_feature('forks'); + + my @projects; + foreach my $pr (@$projlist) { + my (@aa) = git_get_last_activity($pr->{'path'}); + unless (@aa) { + next; + } + ($pr->{'age'}, $pr->{'age_string'}) = @aa; + if (!defined $pr->{'descr'}) { + my $descr = git_get_project_description($pr->{'path'}) || ""; + $pr->{'descr'} = chop_str($descr, 25, 5); + } + if (!defined $pr->{'owner'}) { + $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || ""; + } + if ($check_forks) { + my $pname = $pr->{'path'}; + $pname =~ s/\.git$//; + $pr->{'forks'} = -d "$projectroot/$pname"; + } + push @projects, $pr; + } + + $order ||= "project"; + $from = 0 unless defined $from; + $to = $#projects if (!defined $to || $#projects < $to); + + print "<table class=\"project_list\">\n"; + unless ($no_header) { + print "<tr>\n"; + if ($check_forks) { + print "<th></th>\n"; + } + if ($order eq "project") { + @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects; + print "<th>Project</th>\n"; + } else { + print "<th>" . + $cgi->a({-href => href(project=>undef, order=>'project'), + -class => "header"}, "Project") . + "</th>\n"; + } + if ($order eq "descr") { + @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects; + print "<th>Description</th>\n"; + } else { + print "<th>" . + $cgi->a({-href => href(project=>undef, order=>'descr'), + -class => "header"}, "Description") . + "</th>\n"; + } + if ($order eq "owner") { + @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects; + print "<th>Owner</th>\n"; + } else { + print "<th>" . + $cgi->a({-href => href(project=>undef, order=>'owner'), + -class => "header"}, "Owner") . + "</th>\n"; + } + if ($order eq "age") { + @projects = sort {$a->{'age'} <=> $b->{'age'}} @projects; + print "<th>Last Change</th>\n"; + } else { + print "<th>" . + $cgi->a({-href => href(project=>undef, order=>'age'), + -class => "header"}, "Last Change") . + "</th>\n"; + } + print "<th></th>\n" . + "</tr>\n"; + } + my $alternate = 1; + for (my $i = $from; $i <= $to; $i++) { + my $pr = $projects[$i]; + if ($alternate) { + print "<tr class=\"dark\">\n"; + } else { + print "<tr class=\"light\">\n"; + } + $alternate ^= 1; + if ($check_forks) { + print "<td>"; + if ($pr->{'forks'}) { + print $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "+"); + } + print "</td>\n"; + } + print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"), + -class => "list"}, esc_html($pr->{'path'})) . "</td>\n" . + "<td>" . esc_html($pr->{'descr'}) . "</td>\n" . + "<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n"; + print "<td class=\"". age_class($pr->{'age'}) . "\">" . + $pr->{'age_string'} . "</td>\n" . + "<td class=\"link\">" . + $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " . + $cgi->a({-href => '/git-browser/by-commit.html?r='.$pr->{'path'}}, "graphiclog") . " | " . + $cgi->a({-href => href(project=>$pr->{'path'}, action=>"log")}, "log") . " | " . + $cgi->a({-href => href(project=>$pr->{'path'}, action=>"tree")}, "tree") . + ($pr->{'forks'} ? " | " . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"forks")}, "forks") : '') . + "</td>\n" . + "</tr>\n"; + } + if (defined $extra) { + print "<tr>\n"; + if ($check_forks) { + print "<td></td>\n"; + } + print "<td colspan=\"5\">$extra</td>\n" . + "</tr>\n"; + } + print "</table>\n"; +} + sub git_shortlog_body { # uses global variable $project my ($revlist, $from, $to, $refs, $extra) = @_; @@ -2402,25 +2544,9 @@ sub git_project_list { } my @list = git_get_projects_list(); - my @projects; if (!@list) { die_error(undef, "No projects found"); } - foreach my $pr (@list) { - my (@aa) = git_get_last_activity($pr->{'path'}); - unless (@aa) { - next; - } - ($pr->{'age'}, $pr->{'age_string'}) = @aa; - if (!defined $pr->{'descr'}) { - my $descr = git_get_project_description($pr->{'path'}) || ""; - $pr->{'descr'} = chop_str($descr, 25, 5); - } - if (!defined $pr->{'owner'}) { - $pr->{'owner'} = get_file_owner("$projectroot/$pr->{'path'}") || ""; - } - push @projects, $pr; - } git_header_html(); if (-f $home_text) { @@ -2430,75 +2556,30 @@ sub git_project_list { close $fd; print "</div>\n"; } - print "<table class=\"project_list\">\n" . - "<tr>\n"; - $order ||= "project"; - if ($order eq "project") { - @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects; - print "<th>Project</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'project'), - -class => "header"}, "Project") . - "</th>\n"; - } - if ($order eq "descr") { - @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects; - print "<th>Description</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'descr'), - -class => "header"}, "Description") . - "</th>\n"; - } - if ($order eq "owner") { - @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects; - print "<th>Owner</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'owner'), - -class => "header"}, "Owner") . - "</th>\n"; - } - if ($order eq "age") { - @projects = sort {$a->{'age'} <=> $b->{'age'}} @projects; - print "<th>Last Change</th>\n"; - } else { - print "<th>" . - $cgi->a({-href => href(project=>undef, order=>'age'), - -class => "header"}, "Last Change") . - "</th>\n"; + git_project_list_body(\@list, $order); + git_footer_html(); +} + +sub git_forks { + my $order = $cgi->param('o'); + if (defined $order && $order !~ m/project|descr|owner|age/) { + die_error(undef, "Unknown order parameter"); } - print "<th></th>\n" . - "</tr>\n"; - my $alternate = 1; - foreach my $pr (@projects) { - if ($alternate) { - print "<tr class=\"dark\">\n"; - } else { - print "<tr class=\"light\">\n"; - } - $alternate ^= 1; - print "<td>" . $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary"), - -class => "list"}, esc_html($pr->{'path'})) . "</td>\n" . - "<td>" . esc_html($pr->{'descr'}) . "</td>\n" . - "<td><i>" . chop_str($pr->{'owner'}, 15) . "</i></td>\n"; - print "<td class=\"". age_class($pr->{'age'}) . "\">" . - $pr->{'age_string'} . "</td>\n" . - "<td class=\"link\">" . - $cgi->a({-href => href(project=>$pr->{'path'}, action=>"summary")}, "summary") . " | " . - $cgi->a({-href => href(project=>$pr->{'path'}, action=>"shortlog")}, "shortlog") . " | " . - $cgi->a({-href => href(project=>$pr->{'path'}, action=>"log")}, "log") . " | " . - $cgi->a({-href => href(project=>$pr->{'path'}, action=>"tree")}, "tree") . - "</td>\n" . - "</tr>\n"; + + my @list = git_get_projects_list($project); + if (!@list) { + die_error(undef, "No forks found"); } - print "</table>\n"; + + git_header_html(); + git_print_page_nav('',''); + git_print_header_div('summary', "$project forks"); + git_project_list_body(\@list, $order); git_footer_html(); } sub git_project_index { - my @projects = git_get_projects_list(); + my @projects = git_get_projects_list($project); print $cgi->header( -type => 'text/plain', @@ -2532,6 +2613,10 @@ sub git_summary { my $refs = git_get_references(); my @taglist = git_get_tags_list(15); my @headlist = git_get_heads_list(15); + my @forklist; + if (gitweb_check_feature('forks')) { + @forklist = git_get_projects_list($project); + } git_header_html(); git_print_page_nav('summary','', $head); @@ -2582,6 +2667,13 @@ sub git_summary { $cgi->a({-href => href(action=>"heads")}, "...")); } + if (@forklist) { + git_print_header_div('forks'); + git_project_list_body(\@forklist, undef, 0, 15, + $cgi->a({-href => href(action=>"forks")}, "..."), + 'noheader'); + } + git_footer_html(); } |