{"thread":{"id":"17033","subject":"[PATCH] gitweb: support the rel=vcs microformat","startedAt":"2009-01-07T04:25:18Z","lastAt":"2009-01-10T01:44:50Z","messageCount":22,"participants":["Joey Hess","Giuseppe Bilotta","J.H.","Miklos Vajna","Johannes Schindelin","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"99538","messageId":"20090107042518.GB24735@gnu.kitenet.net","threadId":"17033","inReplyTo":null,"subject":"[PATCH] gitweb: support the rel=vcs microformat","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2009-01-07T04:25:18Z","receivedAt":"2009-01-07T04:25:18Z","isPatch":true,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"The rel=vcs microformat allows a web page to indicate the locations of\nrepositories related to it in a machine-parseable manner.\n(See http://kitenet.net/~joey/rfc/rel-vcs/)\n\nMake gitweb use the microformat in the header of pages it generates,\nif it has been configured with project url information in any of the usual\nways.\n\nSince getting the urls can require hitting disk, I avoided putting the\nmicroformat on *every* page gitweb generates. Just put it on the project\nsummary page, the project list page, and the forks list page.\nThe first of these already looks up the urls, so adding the microformat was\nfree. There is a small overhead in including the microformat on the\nlatter two pages, but getting the project descriptions for those pages\nalready incurs a similar overhead, and the ability to get every repo url\nin one place seems worthwhile.\n\nThis changes git_get_project_description() to not check wantarray, and only\nreturn in list context -- the only way it is used AFAICS.\n\nSigned-off-by: Joey Hess <joey@gnu.kitenet.net>\n---\n gitweb/gitweb.perl |   38 ++++++++++++++++++++++++++------------\n 1 files changed, 26 insertions(+), 12 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 99f71b4..3f8a228 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -789,6 +789,9 @@ $git_dir = \"$projectroot/$project\" if $project;\n our @snapshot_fmts = gitweb_get_feature('snapshot');\n @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);\n \n+# populated later with git urls for the project\n+our @git_url_list;\n+\n # dispatch\n if (!defined $action) {\n \tif (defined $hash) {\n@@ -2100,17 +2103,22 @@ sub git_show_project_tagcloud {\n }\n \n sub git_get_project_url_list {\n+\t# use per project git URL list in $projectroot/$path/cloneurl\n+\t# or make project git URL from git base URL and project name\n \tmy $path = shift;\n \n+\tmy @ret;\n+\n \t$git_dir = \"$projectroot/$path\";\n-\topen my $fd, \"$git_dir/cloneurl\"\n-\t\tor return wantarray ?\n-\t\t@{ config_to_multi(git_get_project_config('url')) } :\n-\t\t   config_to_multi(git_get_project_config('url'));\n-\tmy @git_project_url_list = map { chomp; $_ } <$fd>;\n-\tclose $fd;\n+\tif (open my $fd, \"$git_dir/cloneurl\") {\n+\t\t@ret = map { chomp; $_ } <$fd>;\n+\t\tclose $fd;\n+\t}\n+\telse {\n+\t       @ret = @{ config_to_multi(git_get_project_config('url')) };\n+\t}\n \n-\treturn wantarray ? @git_project_url_list : \\@git_project_url_list;\n+\treturn @ret ? @ret : map { \"$_/$project\" } @git_base_url_list;\n }\n \n sub git_get_projects_list {\n@@ -2953,6 +2961,10 @@ EOF\n \t\tprint qq(<link rel=\"shortcut icon\" href=\"$favicon\" type=\"image/png\" />\\n);\n \t}\n \n+\tforeach my $url (@git_url_list) {\n+\t\tprint qq{<link rel=\"vcs\" type=\"git\" href=\"$url\" />\\n};\n+\t}\n+\n \tprint \"</head>\\n\" .\n \t      \"<body>\\n\";\n \n@@ -4380,6 +4392,8 @@ sub git_project_list {\n \t\tdie_error(404, \"No projects found\");\n \t}\n \n+\t@git_url_list = map { git_get_project_url_list($_->{path}) } @list;\n+\n \tgit_header_html();\n \tif (-f $home_text) {\n \t\tprint \"<div class=\\\"index_include\\\">\\n\";\n@@ -4400,6 +4414,8 @@ sub git_forks {\n \tif (defined $order && $order !~ m/none|project|descr|owner|age/) {\n \t\tdie_error(400, \"Unknown order parameter\");\n \t}\n+\t\n+\t@git_url_list = map { git_get_project_url_list($_->{path}) } @list;\n \n \tmy @list = git_get_projects_list($project);\n \tif (!@list) {\n@@ -4457,6 +4473,8 @@ sub git_summary {\n \t\t@forklist = git_get_projects_list($project);\n \t}\n \n+\t@git_url_list = git_get_project_url_list($project);\n+\n \tgit_header_html();\n \tgit_print_page_nav('summary','', $head);\n \n@@ -4468,12 +4486,8 @@ sub git_summary {\n \t\tprint \"<tr id=\\\"metadata_lchange\\\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\\n\";\n \t}\n \n-\t# use per project git URL list in $projectroot/$project/cloneurl\n-\t# or make project git URL from git base URL and project name\n \tmy $url_tag = \"URL\";\n-\tmy @url_list = git_get_project_url_list($project);\n-\t@url_list = map { \"$_/$project\" } @git_base_url_list unless @url_list;\n-\tforeach my $git_url (@url_list) {\n+\tforeach my $git_url (@git_url_list) {\n \t\tnext unless $git_url;\n \t\tprint \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>$git_url</td></tr>\\n\";\n \t\t$url_tag = \"\";\n-- \n1.5.6.5\n"},{"id":"99575","messageId":"gk2794$djn$1@ger.gmane.org","threadId":"17033","inReplyTo":"20090107042518.GB24735@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Giuseppe Bilotta","fromEmail":"giuseppe.bilotta@gmail.com","sentAt":"2009-01-07T12:30:13Z","receivedAt":"2009-01-07T12:30:13Z","isPatch":true,"sender":{"key":"giuseppe.bilotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1464?v=4"},"body":"On Wednesday 07 January 2009 05:25, Joey Hess wrote:\n\n> The rel=vcs microformat allows a web page to indicate the locations of\n> repositories related to it in a machine-parseable manner.\n> (See http://kitenet.net/~joey/rfc/rel-vcs/)\n\nInteresting idea, I like it. However, I see a problem in the proposed\nimplementation versus the spec. According to the spec:\n\n\"\"\"\nThe \"title\" is optional, but recommended if there are multiple, different\nrepositories linked to on one page. It is a human-readable description of the\nrepository.\n[...]\nIf there are multiple repositories listed, without titles, tools should assume\nthey are different repositories.\n\"\"\"\n\nIn this patch you do NOT add titles to the rel=vcs links, which means that\neverything works fine only if there is a single URL for each project. If a\nproject has different URLs, it's going to appear multiple times as _different_\nprojects to a spec-compliant reader.\n\nA possible solution would be to make @git_url_list into a map keyed by the\nproject name and having the description and repo URL(s) as values.\n\nSince there is the possibility of different projects having the same\ndescription (e.g. the default one), the link title could be composed of\n\"$project - $description\" rather than simply $description.\n\nNote that both in summary and in project list view you already retrieve the\ndescription, so there are no additional disk hits.\n\n> Make gitweb use the microformat in the header of pages it generates,\n> if it has been configured with project url information in any of the usual\n> ways.\n> \n> Since getting the urls can require hitting disk, I avoided putting the\n> microformat on *every* page gitweb generates. Just put it on the project\n> summary page, the project list page, and the forks list page.\n> The first of these already looks up the urls, so adding the microformat was\n> free. There is a small overhead in including the microformat on the\n> latter two pages, but getting the project descriptions for those pages\n> already incurs a similar overhead, and the ability to get every repo url\n> in one place seems worthwhile.\n> \n> This changes git_get_project_description() to not check wantarray, and only\n> return in list context -- the only way it is used AFAICS.\n\nI assume you mean git_get_project_url_list()?\n\n> \n> Signed-off-by: Joey Hess <joey@gnu.kitenet.net>\n> ---\n>  gitweb/gitweb.perl |   38 ++++++++++++++++++++++++++------------\n>  1 files changed, 26 insertions(+), 12 deletions(-)\n> \n> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\n> index 99f71b4..3f8a228 100755\n> --- a/gitweb/gitweb.perl\n> +++ b/gitweb/gitweb.perl\n> @@ -789,6 +789,9 @@ $git_dir = \"$projectroot/$project\" if $project;\n>  our @snapshot_fmts = gitweb_get_feature('snapshot');\n>  @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);\n>  \n> +# populated later with git urls for the project\n> +our @git_url_list;\n> +\n>  # dispatch\n>  if (!defined $action) {\n>       if (defined $hash) {\n> @@ -2100,17 +2103,22 @@ sub git_show_project_tagcloud {\n>  }\n>  \n>  sub git_get_project_url_list {\n> +     # use per project git URL list in $projectroot/$path/cloneurl\n> +     # or make project git URL from git base URL and project name\n>       my $path = shift;\n>  \n> +     my @ret;\n> +\n>       $git_dir = \"$projectroot/$path\";\n> -     open my $fd, \"$git_dir/cloneurl\"\n> -             or return wantarray ?\n> -             @{ config_to_multi(git_get_project_config('url')) } :\n> -                config_to_multi(git_get_project_config('url'));\n> -     my @git_project_url_list = map { chomp; $_ } <$fd>;\n> -     close $fd;\n> +     if (open my $fd, \"$git_dir/cloneurl\") {\n> +             @ret = map { chomp; $_ } <$fd>;\n> +             close $fd;\n> +     }\n> +     else {\n\nCoding style: } else {\n\n> +            @ret = @{ config_to_multi(git_get_project_config('url')) };\n> +     }\n>  \n> -     return wantarray ? @git_project_url_list : \\@git_project_url_list;\n> +     return @ret ? @ret : map { \"$_/$project\" } @git_base_url_list;\n>  }\n>  \n>  sub git_get_projects_list {\n> @@ -2953,6 +2961,10 @@ EOF\n>               print qq(<link rel=\"shortcut icon\" href=\"$favicon\" type=\"image/png\" />\\n);\n>       }\n>  \n> +     foreach my $url (@git_url_list) {\n> +             print qq{<link rel=\"vcs\" type=\"git\" href=\"$url\" />\\n};\n> +     }\n> +\n>       print \"</head>\\n\" .\n>             \"<body>\\n\";\n>  \n> @@ -4380,6 +4392,8 @@ sub git_project_list {\n>               die_error(404, \"No projects found\");\n>       }\n>  \n> +     @git_url_list = map { git_get_project_url_list($_->{path}) } @list;\n> +\n>       git_header_html();\n>       if (-f $home_text) {\n>               print \"<div class=\\\"index_include\\\">\\n\";\n> @@ -4400,6 +4414,8 @@ sub git_forks {\n>       if (defined $order && $order !~ m/none|project|descr|owner|age/) {\n>               die_error(400, \"Unknown order parameter\");\n>       }\n> +     \n> +     @git_url_list = map { git_get_project_url_list($_->{path}) } @list;\n>  \n>       my @list = git_get_projects_list($project);\n>       if (!@list) {\n> @@ -4457,6 +4473,8 @@ sub git_summary {\n>               @forklist = git_get_projects_list($project);\n>       }\n>  \n> +     @git_url_list = git_get_project_url_list($project);\n> +\n>       git_header_html();\n>       git_print_page_nav('summary','', $head);\n>  \n> @@ -4468,12 +4486,8 @@ sub git_summary {\n>               print \"<tr id=\\\"metadata_lchange\\\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\\n\";\n>       }\n>  \n> -     # use per project git URL list in $projectroot/$project/cloneurl\n> -     # or make project git URL from git base URL and project name\n>       my $url_tag = \"URL\";\n> -     my @url_list = git_get_project_url_list($project);\n> -     @url_list = map { \"$_/$project\" } @git_base_url_list unless @url_list;\n> -     foreach my $git_url (@url_list) {\n> +     foreach my $git_url (@git_url_list) {\n>               next unless $git_url;\n>               print \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>$git_url</td></tr>\\n\";\n>               $url_tag = \"\";\n\n-- \nGiuseppe \"Oblomov\" Bilotta\n"},{"id":"99589","messageId":"20090107155023.GA16540@gnu.kitenet.net","threadId":"17033","inReplyTo":"gk2794$djn$1@ger.gmane.org","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2009-01-07T15:50:23Z","receivedAt":"2009-01-07T15:50:23Z","isPatch":true,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"Giuseppe Bilotta wrote:\n> In this patch you do NOT add titles to the rel=vcs links, which means that\n> everything works fine only if there is a single URL for each project. If a\n> project has different URLs, it's going to appear multiple times as _different_\n> projects to a spec-compliant reader.\n> \n> A possible solution would be to make @git_url_list into a map keyed by the\n> project name and having the description and repo URL(s) as values.\n\nYes. I considered doing that, but didn't immediatly see a way to get the\nproject description w/o additional overhead (of looking it up a second\ntime).\n\n> > This changes git_get_project_description() to not check wantarray, and only\n> > return in list context -- the only way it is used AFAICS.\n> \n> I assume you mean git_get_project_url_list()?\n\nIn fact yes.\n \n\nThanks for the feedback. There are some changes happening to the\nmicroformat that should make gitweb's job slightly easier, I'll respin\nthe patch soon.\n\n-- \nsee shy jo\n"},{"id":"99597","messageId":"cb7bb73a0901071003m77482a99wf6f3988beb5b5e78@mail.gmail.com","threadId":"17033","inReplyTo":"20090107155023.GA16540@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Giuseppe Bilotta","fromEmail":"giuseppe.bilotta@gmail.com","sentAt":"2009-01-07T18:03:04Z","receivedAt":"2009-01-07T18:03:04Z","isPatch":true,"sender":{"key":"giuseppe.bilotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1464?v=4"},"body":"On Wed, Jan 7, 2009 at 4:50 PM, Joey Hess <joey@kitenet.net> wrote:\n> Giuseppe Bilotta wrote:\n>> In this patch you do NOT add titles to the rel=vcs links, which means that\n>> everything works fine only if there is a single URL for each project. If a\n>> project has different URLs, it's going to appear multiple times as _different_\n>> projects to a spec-compliant reader.\n>>\n>> A possible solution would be to make @git_url_list into a map keyed by the\n>> project name and having the description and repo URL(s) as values.\n>\n> Yes. I considered doing that, but didn't immediatly see a way to get the\n> project description w/o additional overhead (of looking it up a second\n> time).\n\nThe solution I have in mind would be something like this: in summary\nor projects list view (which are the views in which we put the links,\nand also the views in which we loop up the repo URL and the\ndescription anyway), you fill up former @git_url_list (now\n%project_metadata) looking up the repo description and URLs. You then\nuse this information both in the link tag and in the appropriate\nplaces for the visible part of the webpage: you don't have a\nsignificant overhead, because you're just moving the project\ndescription retrieval early on.\n\nYou probably want to refactor the code by making a\ngit_get_project_metadata() sub that extends the current URL retrieval\nby retrieving description and URLs. The routine can then be used\neither for one or for all the projects, as needed.\n\n> Thanks for the feedback. There are some changes happening to the\n> microformat that should make gitweb's job slightly easier, I'll respin\n> the patch soon.\n\nLet me know about this too, I very much like the idea of this microformat.\n\n-- \nGiuseppe \"Oblomov\" Bilotta\n"},{"id":"99602","messageId":"20090107184113.GA31795@gnu.kitenet.net","threadId":"17033","inReplyTo":"cb7bb73a0901071003m77482a99wf6f3988beb5b5e78@mail.gmail.com","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2009-01-07T18:41:13Z","receivedAt":"2009-01-07T18:41:13Z","isPatch":true,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"Giuseppe Bilotta wrote:\n> > Thanks for the feedback. There are some changes happening to the\n> > microformat that should make gitweb's job slightly easier, I'll respin\n> > the patch soon.\n> \n> Let me know about this too, I very much like the idea of this microformat.\n\nFYI, I've updated the microformat's page with the changes. The\nsignificant one for gitweb is that it can now be applied to <a> links.\nSo on the project page, the display of the git URL could be converted to\na link using the microformat, and there's no need to get the info\nearlier to put it in the header. Unfortunatly, the same can't be done to\nthe project list page, unless it's changed to have \"git\" links as seen\non vger.kernel.org's gitweb.\n\n-- \nsee shy jo\n"},{"id":"99603","messageId":"20090107184515.GB31795@gnu.kitenet.net","threadId":"17033","inReplyTo":"cb7bb73a0901071003m77482a99wf6f3988beb5b5e78@mail.gmail.com","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2009-01-07T18:45:15Z","receivedAt":"2009-01-07T18:45:15Z","isPatch":true,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"Giuseppe Bilotta wrote:\n> The solution I have in mind would be something like this: in summary\n> or projects list view (which are the views in which we put the links,\n> and also the views in which we loop up the repo URL and the\n> description anyway), you fill up former @git_url_list (now\n> %project_metadata) looking up the repo description and URLs. You then\n> use this information both in the link tag and in the appropriate\n> places for the visible part of the webpage: you don't have a\n> significant overhead, because you're just moving the project\n> description retrieval early on.\n> \n> You probably want to refactor the code by making a\n> git_get_project_metadata() sub that extends the current URL retrieval\n> by retrieving description and URLs. The routine can then be used\n> either for one or for all the projects, as needed.\n\nAnother approach would be to just memoize git_get_project_description\nand git_get_project_url_list.\n \n-- \nsee shy jo\n"},{"id":"99605","messageId":"20090107190238.GA3909@gnu.kitenet.net","threadId":"17033","inReplyTo":"20090107184515.GB31795@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2009-01-07T19:02:38Z","receivedAt":"2009-01-07T19:02:38Z","isPatch":true,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"Joey Hess wrote:\n> Another approach would be to just memoize git_get_project_description\n> and git_get_project_url_list.\n\nEspecially since git_get_project_description is already called more than\nonce for some pages.\n\n-- \nsee shy jo\n"},{"id":"99631","messageId":"20090107232427.GA18958@gnu.kitenet.net","threadId":"17033","inReplyTo":"20090107190238.GA3909@gnu.kitenet.net","subject":"[PATCH] gitweb: support the rel=vcs-* microformat","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2009-01-07T23:24:27Z","receivedAt":"2009-01-07T23:24:27Z","isPatch":true,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"The rel=vcs-* microformat allows a web page to indicate the locations of\nrepositories related to it in a machine-parseable manner.\n(See http://kitenet.net/~joey/rfc/rel-vcs/)\n\nMake gitweb use the microformat if it has been configured with project url\ninformation in any of the usual ways. On the project summary page, the\nrepository URL display is simply marked up using the microformat. On the\nproject list page and forks list page, the microformat is embedded in the\nheader, since the URLs do not appear on the page.\n\nThe microformat could be included on other pages too, but I've skipped\ndoing so for now, since it would mean reading another file for every page\ndisplayed.\n\nThere is a small overhead in including the microformat on project list\nand forks list pages, but getting the project descriptions for those pages\nalready incurs a similar overhead, and the ability to get every repo url\nin one place seems worthwhile.\n\nThis changes git_get_project_url_list() to not check wantarray, and only\nreturn in list context -- the only way it is used AFAICS. It memoizes\nboth that function and git_get_project_description(), to avoid redundant\nfile reads.\n\nSigned-off-by: Joey Hess <joey@gnu.kitenet.net>\n---\n gitweb/gitweb.perl |   78 +++++++++++++++++++++++++++++++++++++++++----------\n 1 files changed, 62 insertions(+), 16 deletions(-)\n\nThis incorporates Giuseppe Bilotta's feedback, and uses new features\nof the microformat. You can see this version running at\nhttp://git.ikiwiki.info/\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 99f71b4..c238717 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2020,9 +2020,14 @@ sub git_get_path_by_hash {\n ## ......................................................................\n ## git utility functions, directly accessing git repository\n \n+{\n+my %project_descriptions; # cache\n+\n sub git_get_project_description {\n \tmy $path = shift;\n \n+\treturn $project_descriptions{$path} if exists $project_descriptions{$path};\n+\n \t$git_dir = \"$projectroot/$path\";\n \topen my $fd, \"$git_dir/description\"\n \t\tor return git_get_project_config('description');\n@@ -2031,7 +2036,9 @@ sub git_get_project_description {\n \tif (defined $descr) {\n \t\tchomp $descr;\n \t}\n-\treturn $descr;\n+\treturn $project_descriptions{$path}=$descr;\n+}\n+\n }\n \n sub git_get_project_ctags {\n@@ -2099,18 +2106,30 @@ sub git_show_project_tagcloud {\n \t}\n }\n \n+{\n+my %project_url_lists; # cache\n+\n sub git_get_project_url_list {\n+\t# use per project git URL list in $projectroot/$path/cloneurl\n+\t# or make project git URL from git base URL and project name\n \tmy $path = shift;\n \n+\treturn @{$project_url_lists{$path}} if exists $project_url_lists{$path};\n+\n+\tmy @ret;\n \t$git_dir = \"$projectroot/$path\";\n-\topen my $fd, \"$git_dir/cloneurl\"\n-\t\tor return wantarray ?\n-\t\t@{ config_to_multi(git_get_project_config('url')) } :\n-\t\t   config_to_multi(git_get_project_config('url'));\n-\tmy @git_project_url_list = map { chomp; $_ } <$fd>;\n-\tclose $fd;\n+\tif (open my $fd, \"$git_dir/cloneurl\") {\n+\t\t@ret = map { chomp; $_ } <$fd>;\n+\t\tclose $fd;\n+\t} else {\n+\t       @ret = @{ config_to_multi(git_get_project_config('url')) };\n+\t}\n+\t@ret=map { \"$_/$project\" } @git_base_url_list if ! @ret;\n+\n+\t$project_url_lists{$path}=\\@ret;\n+\treturn @ret;\n+}\n \n-\treturn wantarray ? @git_project_url_list : \\@git_project_url_list;\n }\n \n sub git_get_projects_list {\n@@ -2856,6 +2875,7 @@ sub blob_contenttype {\n sub git_header_html {\n \tmy $status = shift || \"200 OK\";\n \tmy $expires = shift;\n+\tmy $extraheader = shift;\n \n \tmy $title = \"$site_name\";\n \tif (defined $project) {\n@@ -2953,6 +2973,8 @@ EOF\n \t\tprint qq(<link rel=\"shortcut icon\" href=\"$favicon\" type=\"image/png\" />\\n);\n \t}\n \n+\tprint $extraheader if defined $extraheader;\n+\n \tprint \"</head>\\n\" .\n \t      \"<body>\\n\";\n \n@@ -4365,6 +4387,26 @@ sub git_search_grep_body {\n \tprint \"</table>\\n\";\n }\n \n+sub git_link_title {\n+\tmy $project=shift;\n+\t\n+\tmy $description=git_get_project_description($project);\n+\treturn $project.(length $description ? \" - $description\" : \"\");\n+}\n+\n+# generates header with links to the specified projects\n+sub git_links_header {\n+\tmy $ret='';\n+\tforeach my $project (@_) {\n+\t\t# rel=vcs-* microformat\n+\t\tmy $title=git_link_title($project);\n+\t\tforeach my $url git_get_project_url_list($project) {\n+\t\t\t$ret.=qq{<link rel=\"vcs-git\" href=\"$url\" title=\"$title\"/>\\n}\n+\t\t}\n+\t}\n+\treturn $ret;\n+}\n+\n ## ======================================================================\n ## ======================================================================\n ## actions\n@@ -4380,7 +4422,9 @@ sub git_project_list {\n \t\tdie_error(404, \"No projects found\");\n \t}\n \n-\tgit_header_html();\n+\tmy $extraheader=git_links_header(map { $_->{path} } @list);\n+\n+\tgit_header_html(undef, undef, $extraheader);\n \tif (-f $home_text) {\n \t\tprint \"<div class=\\\"index_include\\\">\\n\";\n \t\tinsert_file($home_text);\n@@ -4405,8 +4449,10 @@ sub git_forks {\n \tif (!@list) {\n \t\tdie_error(404, \"No forks found\");\n \t}\n+\t\n+\tmy $extraheader=git_links_header(map { $_->{path} } @list);\n \n-\tgit_header_html();\n+\tgit_header_html(undef, undef, $extraheader);\n \tgit_print_page_nav('','');\n \tgit_print_header_div('summary', \"$project forks\");\n \tgit_project_list_body(\\@list, $order);\n@@ -4468,14 +4514,14 @@ sub git_summary {\n \t\tprint \"<tr id=\\\"metadata_lchange\\\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\\n\";\n \t}\n \n-\t# use per project git URL list in $projectroot/$project/cloneurl\n-\t# or make project git URL from git base URL and project name\n \tmy $url_tag = \"URL\";\n-\tmy @url_list = git_get_project_url_list($project);\n-\t@url_list = map { \"$_/$project\" } @git_base_url_list unless @url_list;\n-\tforeach my $git_url (@url_list) {\n+\tmy $title=git_link_title($project);\n+\tforeach my $git_url (git_get_project_url_list($project)) {\n \t\tnext unless $git_url;\n-\t\tprint \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>$git_url</td></tr>\\n\";\n+\t\tprint \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>\".\n+\t\t      # rel=vcs-* microformat\n+\t\t      \"<a rel=\\\"vcs-git\\\" href=\\\"$git_url\\\" title=\\\"$title\\\">$git_url</a>\".\n+\t\t      \"</td></tr>\\n\";\n \t\t$url_tag = \"\";\n \t}\n \n-- \n1.5.6.5\n\n\n\n-- \nsee shy jo\n"},{"id":"99679","messageId":"gk4bk5$9dq$1@ger.gmane.org","threadId":"17033","inReplyTo":"20090107232427.GA18958@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs-* microformat","fromName":"Giuseppe Bilotta","fromEmail":"giuseppe.bilotta@gmail.com","sentAt":"2009-01-08T07:56:37Z","receivedAt":"2009-01-08T07:56:37Z","isPatch":true,"sender":{"key":"giuseppe.bilotta@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1464?v=4"},"body":"Hello Joey,\n\nOn Thursday 08 January 2009 00:24, Joey Hess wrote:\n\n> The rel=vcs-* microformat allows a web page to indicate the locations of\n> repositories related to it in a machine-parseable manner.\n> (See http://kitenet.net/~joey/rfc/rel-vcs/)\n\nHave you considered submitting the microformat to microformats.org?\nThat would make the microformat more official and would be an good\nfirst step to have wider coverage of it, and additional reviews.\n\n> Make gitweb use the microformat if it has been configured with project url\n> information in any of the usual ways. On the project summary page, the\n> repository URL display is simply marked up using the microformat. On the\n> project list page and forks list page, the microformat is embedded in the\n> header, since the URLs do not appear on the page.\n> \n> The microformat could be included on other pages too, but I've skipped\n> doing so for now, since it would mean reading another file for every page\n> displayed.\n> \n> There is a small overhead in including the microformat on project list\n> and forks list pages, but getting the project descriptions for those pages\n> already incurs a similar overhead, and the ability to get every repo url\n> in one place seems worthwhile.\n\nI agree with this, although people with very large project lists may\ndiffer ... do we have timings on these?\n \n> This changes git_get_project_url_list() to not check wantarray, and only\n> return in list context -- the only way it is used AFAICS. It memoizes\n> both that function and git_get_project_description(), to avoid redundant\n> file reads.\n\nYou may want to consider splitting the patch into three: memoizing\nof git_get_project_description(), reworking of\ngit_get_project_url_list(), and the actual rel=vc-* insertions.\n\n> Signed-off-by: Joey Hess <joey@gnu.kitenet.net>\n> ---\n>  gitweb/gitweb.perl |   78 +++++++++++++++++++++++++++++++++++++++++----------\n>  1 files changed, 62 insertions(+), 16 deletions(-)\n> \n> This incorporates Giuseppe Bilotta's feedback, and uses new features\n> of the microformat. You can see this version running at\n> http://git.ikiwiki.info/\n\nOh, and do consider cc'ing jnareb and paski when submitting patches\nfor gitweb, as they are the (unofficial?) maintainers. I usually cc\ngitster (Junio C Hamano) too.\n\n[ Also cc'ing me for this round would have been a nice idea too,\nsince we had the review going on ;-) ]\n\n> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\n> index 99f71b4..c238717 100755\n> --- a/gitweb/gitweb.perl\n> +++ b/gitweb/gitweb.perl\n> @@ -2020,9 +2020,14 @@ sub git_get_path_by_hash {\n>  ## ......................................................................\n>  ## git utility functions, directly accessing git repository\n>  \n> +{\n> +my %project_descriptions; # cache\n> +\n\nOut of curiosity, why the grouping? I would have had\n\nour %project_descriptions;\n\nup above with all the global variables.\n\n>  sub git_get_project_description {\n>       my $path = shift;\n>  \n> +     return $project_descriptions{$path} if exists $project_descriptions{$path};\n> +\n\nThis line is bordering on the 80 characters, so you may want to\nconsider moving 'my $descr' here, with something such as\n\nmy $descr = $project_descriptions{$path};\nreturn $descr if exists $descr;\n\nAlso, I'm no perl guru so I'm not sure about exists vs defined here.\n\n>       $git_dir = \"$projectroot/$path\";\n>       open my $fd, \"$git_dir/description\"\n>               or return git_get_project_config('description');\n> @@ -2031,7 +2036,9 @@ sub git_get_project_description {\n>       if (defined $descr) {\n>               chomp $descr;\n>       }\n> -     return $descr;\n> +     return $project_descriptions{$path}=$descr;\n> +}\n> +\n>  }\n\n[This is where I would end the first patch]\n\n>  \n>  sub git_get_project_ctags {\n> @@ -2099,18 +2106,30 @@ sub git_show_project_tagcloud {\n>       }\n>  }\n>  \n> +{\n> +my %project_url_lists; # cache\n> +\n\nDitto for this: why not our %project_url_lists; without scoping?\n\n>  sub git_get_project_url_list {\n> +     # use per project git URL list in $projectroot/$path/cloneurl\n> +     # or make project git URL from git base URL and project name\n>       my $path = shift;\n>  \n> +     return @{$project_url_lists{$path}} if exists $project_url_lists{$path};\n> +\n> +     my @ret;\n>       $git_dir = \"$projectroot/$path\";\n> -     open my $fd, \"$git_dir/cloneurl\"\n> -             or return wantarray ?\n> -             @{ config_to_multi(git_get_project_config('url')) } :\n> -                config_to_multi(git_get_project_config('url'));\n> -     my @git_project_url_list = map { chomp; $_ } <$fd>;\n> -     close $fd;\n> +     if (open my $fd, \"$git_dir/cloneurl\") {\n> +             @ret = map { chomp; $_ } <$fd>;\n> +             close $fd;\n> +     } else {\n> +            @ret = @{ config_to_multi(git_get_project_config('url')) };\n> +     }\n> +     @ret=map { \"$_/$project\" } @git_base_url_list if ! @ret;\n> +\n> +     $project_url_lists{$path}=\\@ret;\n> +     return @ret;\n> +}\n>  \n> -     return wantarray ? @git_project_url_list : \\@git_project_url_list;\n>  }\n\n[This is where I would end the second patch]\n\n>  \n>  sub git_get_projects_list {\n> @@ -2856,6 +2875,7 @@ sub blob_contenttype {\n>  sub git_header_html {\n>       my $status = shift || \"200 OK\";\n>       my $expires = shift;\n> +     my $extraheader = shift;\n>  \n>       my $title = \"$site_name\";\n>       if (defined $project) {\n> @@ -2953,6 +2973,8 @@ EOF\n>               print qq(<link rel=\"shortcut icon\" href=\"$favicon\" type=\"image/png\" />\\n);\n>       }\n>  \n> +     print $extraheader if defined $extraheader;\n> +\n>       print \"</head>\\n\" .\n>             \"<body>\\n\";\n>  \n> @@ -4365,6 +4387,26 @@ sub git_search_grep_body {\n>       print \"</table>\\n\";\n>  }\n>  \n> +sub git_link_title {\n> +     my $project=shift;\n> +     \n> +     my $description=git_get_project_description($project);\n> +     return $project.(length $description ? \" - $description\" : \"\");\n> +}\n\nNice.\n\n> +\n> +# generates header with links to the specified projects\n> +sub git_links_header {\n> +     my $ret='';\n> +     foreach my $project (@_) {\n> +             # rel=vcs-* microformat\n> +             my $title=git_link_title($project);\n> +             foreach my $url git_get_project_url_list($project) {\n> +                     $ret.=qq{<link rel=\"vcs-git\" href=\"$url\" title=\"$title\"/>\\n}\n> +             }\n> +     }\n> +     return $ret;\n> +}\n> +\n>  ## ======================================================================\n>  ## ======================================================================\n>  ## actions\n> @@ -4380,7 +4422,9 @@ sub git_project_list {\n>               die_error(404, \"No projects found\");\n>       }\n>  \n> -     git_header_html();\n> +     my $extraheader=git_links_header(map { $_->{path} } @list);\n> +\n> +     git_header_html(undef, undef, $extraheader);\n>       if (-f $home_text) {\n>               print \"<div class=\\\"index_include\\\">\\n\";\n>               insert_file($home_text);\n> @@ -4405,8 +4449,10 @@ sub git_forks {\n>       if (!@list) {\n>               die_error(404, \"No forks found\");\n>       }\n> +     \n> +     my $extraheader=git_links_header(map { $_->{path} } @list);\n>  \n> -     git_header_html();\n> +     git_header_html(undef, undef, $extraheader);\n\nThis makes me wonder if it would be worth it to turn git_header_html\ninto -param => value style, but I'm not really sure it's worth it.\n\n>       git_print_page_nav('','');\n>       git_print_header_div('summary', \"$project forks\");\n>       git_project_list_body(\\@list, $order);\n> @@ -4468,14 +4514,14 @@ sub git_summary {\n>               print \"<tr id=\\\"metadata_lchange\\\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\\n\";\n>       }\n>  \n> -     # use per project git URL list in $projectroot/$project/cloneurl\n> -     # or make project git URL from git base URL and project name\n>       my $url_tag = \"URL\";\n> -     my @url_list = git_get_project_url_list($project);\n> -     @url_list = map { \"$_/$project\" } @git_base_url_list unless @url_list;\n> -     foreach my $git_url (@url_list) {\n> +     my $title=git_link_title($project);\n> +     foreach my $git_url (git_get_project_url_list($project)) {\n>               next unless $git_url;\n> -             print \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>$git_url</td></tr>\\n\";\n> +             print \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>\".\n> +                   # rel=vcs-* microformat\n> +                   \"<a rel=\\\"vcs-git\\\" href=\\\"$git_url\\\" title=\\\"$title\\\">$git_url</a>\".\n> +                   \"</td></tr>\\n\";\n>               $url_tag = \"\";\n>       }\n\nGood. Of course the comment removal (which is actually a due move to\ngit_get_project_url_list) would go in the appropriate patch if you\nsplit them 8-)\n\n-- \nGiuseppe \"Oblomov\" Bilotta\n"},{"id":"99737","messageId":"20090108195446.GB18025@gnu.kitenet.net","threadId":"17033","inReplyTo":"gk4bk5$9dq$1@ger.gmane.org","subject":"gitweb index performance (Re: [PATCH] gitweb: support the rel=vcs-* microformat)","fromName":"Joey Hess","fromEmail":"joey@kitenet.net","sentAt":"2009-01-08T19:54:46Z","receivedAt":"2009-01-08T19:54:46Z","isPatch":true,"sender":{"key":"joey@kitenet.net","avatar":"https://avatars.githubusercontent.com/u/16392?v=4"},"body":"Giuseppe Bilotta wrote:\n> > There is a small overhead in including the microformat on project list\n> > and forks list pages, but getting the project descriptions for those pages\n> > already incurs a similar overhead, and the ability to get every repo url\n> > in one place seems worthwhile.\n> \n> I agree with this, although people with very large project lists may\n> differ ... do we have timings on these?\n\nAFAICS, when displaying the project list, gitweb reads each project's\ndescription file, falling back to reading its config file if there is no\ndescription file.\n\nIf performance was a problem here, the thing to do would be to add\nproject descriptions to the $project_list file, and use those in\npreference to the description files. If a large site has done that,\nthey've not sent in the patch. :-)\n\nWith my patch, it will read each cloneurl file too. The best way to\noptimise that for large sites seems to be to add an option that would\nignore the cloneurl files and config file and always use\n@git_base_url_list.\n\nI checked the only large site I have access to (git.debian.org) and they\nuse a $project_list file, but I see no other performance tuning. That's\na 2 ghz machine; it takes gitweb 28 (!) seconds to generate the nearly 1\nMB index web page for 1671 repositories:\n\n/srv/git.debian.org/http/cgi-bin/gitweb.cgi  3.04s user 9.24s system 43% cpu 28.515 total\n\nNotice that most of the time is spent by child processes. For each\nrepository, gitweb runs git-for-each-ref to determine the time of the\nlast commit.\n\nIf that is removed (say if there were a way to get the info w/o\nforking), performance improves nicely:\n\n./gitweb.cgi > /dev/null  1.29s user 1.08s system 69% cpu 3.389 total\n\nMaking it not read description files for each project, as I suggest above,\nis the next best optimisation:\n\n./gitweb.cgi > /dev/null  1.08s user 0.05s system 96% cpu 1.170 total\n\nSo, I think it makes sense to optimise gitweb and offer knobs for performance\ntuning at the expense of the flexability of description and cloneurl files.\nBut, git-for-each-ref is swamping everything else.\n\n-- \nsee shy jo\n"},{"id":"99748","messageId":"496691EC.1070805@eaglescrag.net","threadId":"17033","inReplyTo":"20090108195446.GB18025@gnu.kitenet.net","subject":"Re: gitweb index performance (Re: [PATCH] gitweb: support the rel=vcs-* microformat)","fromName":"J.H.","fromEmail":"warthog19@eaglescrag.net","sentAt":"2009-01-08T23:53:16Z","receivedAt":"2009-01-08T23:53:16Z","isPatch":true,"sender":{"key":"warthog19@eaglescrag.net","avatar":null},"body":"Joey Hess wrote:\n> Giuseppe Bilotta wrote:\n>   \n>>> There is a small overhead in including the microformat on project list\n>>> and forks list pages, but getting the project descriptions for those pages\n>>> already incurs a similar overhead, and the ability to get every repo url\n>>> in one place seems worthwhile.\n>>>       \n>> I agree with this, although people with very large project lists may\n>> differ ... do we have timings on these?\n>>     \n>\n> AFAICS, when displaying the project list, gitweb reads each project's\n> description file, falling back to reading its config file if there is no\n> description file.\n>\n> If performance was a problem here, the thing to do would be to add\n> project descriptions to the $project_list file, and use those in\n> preference to the description files. If a large site has done that,\n> they've not sent in the patch. :-)\n>   \n\nNo because all the large sites have pain points and issues elsewhere in \nthe app.  Most of the large sites (which I can at least speak for \nKernel.org) went and have built in full caching layers into gitweb \nitself to deal with the problem.  This means that we don't have to worry \nabout nickle and dime performance improvements that are specific to one \nsection, but can do a very broad sweep and get dramatically better \nperformance across all of gitweb.  Those patches have all made it back \nout onto the mailing list, but for a number of different reasons none \nhave been accepted into the mainline branch.\n\n> With my patch, it will read each cloneurl file too. The best way to\n> optimise that for large sites seems to be to add an option that would\n> ignore the cloneurl files and config file and always use\n> @git_base_url_list.\n>\n> I checked the only large site I have access to (git.debian.org) and they\n> use a $project_list file, but I see no other performance tuning. That's\n> a 2 ghz machine; it takes gitweb 28 (!) seconds to generate the nearly 1\n> MB index web page for 1671 repositories:\n>   \n\nLook at either Lea's or my caching engines, it will help dramatically on \nsomething of that size.\n\n> /srv/git.debian.org/http/cgi-bin/gitweb.cgi  3.04s user 9.24s system 43% cpu 28.515 total\n>\n> Notice that most of the time is spent by child processes. For each\n> repository, gitweb runs git-for-each-ref to determine the time of the\n> last commit.\n>\n> If that is removed (say if there were a way to get the info w/o\n> forking), performance improves nicely:\n>\n> ./gitweb.cgi > /dev/null  1.29s user 1.08s system 69% cpu 3.389 total\n>\n> Making it not read description files for each project, as I suggest above,\n> is the next best optimisation:\n>\n> ./gitweb.cgi > /dev/null  1.08s user 0.05s system 96% cpu 1.170 total\n>\n> So, I think it makes sense to optimise gitweb and offer knobs for performance\n> tuning at the expense of the flexability of description and cloneurl files.\n> But, git-for-each-ref is swamping everything else\nThe problem is the knobs are going to be very fine grained, you really \nare better off looking at one of the caching engines that's available \nnow.  Performance options are hard, because it's difficult to relay to \nanyone the complex tradeoffs, thus keeping knobs like that to a minimum \nare really a necessity.\n\n- John 'Warthog9' Hawley\n"},{"id":"99752","messageId":"20090109001647.GI21154@genesis.frugalware.org","threadId":"17033","inReplyTo":"496691EC.1070805@eaglescrag.net","subject":"Re: gitweb index performance (Re: [PATCH] gitweb: support the rel=vcs-* microformat)","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2009-01-09T00:16:47Z","receivedAt":"2009-01-09T00:16:47Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Thu, Jan 08, 2009 at 03:53:16PM -0800, \"J.H.\" <warthog19@eaglescrag.net> wrote:\n> Look at either Lea's or my caching engines, it will help dramatically on \n> something of that size.\n\nrepo.or.cz uses a single patch for caching the project list only:\n\nhttp://repo.or.cz/w/git/repo.git?a=commit;h=152fb0b22d36c6981ac3c4403b69ad91b27a1bc6\n\nyou are probably better off with such a small patch instead of using a\ngitweb fork.\n"},{"id":"99753","messageId":"alpine.DEB.1.00.0901090118431.30769@pacific.mpi-cbg.de","threadId":"17033","inReplyTo":"496691EC.1070805@eaglescrag.net","subject":"Re: gitweb index performance (Re: [PATCH] gitweb: support the rel=vcs-* microformat)","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2009-01-09T00:19:21Z","receivedAt":"2009-01-09T00:19:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Thu, 8 Jan 2009, J.H. wrote:\n\n> Look at either Lea's or my caching engines, it will help dramatically on \n> something of that size.\n\nSpeaking of which, do you have any performance comparisons between the \ntwo?\n\nCiao,\nDscho\n"},{"id":"99756","messageId":"496699D0.1080006@eaglescrag.net","threadId":"17033","inReplyTo":"alpine.DEB.1.00.0901090118431.30769@pacific.mpi-cbg.de","subject":"Re: gitweb index performance (Re: [PATCH] gitweb: support the rel=vcs-* microformat)","fromName":"J.H.","fromEmail":"warthog19@eaglescrag.net","sentAt":"2009-01-09T00:26:56Z","receivedAt":"2009-01-09T00:26:56Z","isPatch":true,"sender":{"key":"warthog19@eaglescrag.net","avatar":null},"body":"Johannes Schindelin wrote:\n> Hi,\n>\n> On Thu, 8 Jan 2009, J.H. wrote:\n>\n>   \n>> Look at either Lea's or my caching engines, it will help dramatically on \n>> something of that size.\n>>     \n>\n> Speaking of which, do you have any performance comparisons between the \n> two?\n>   \nLea's got some - I can see if I can dig up my copy (or if she's paying \nattention maybe she can publish them), though either one is orders of \nmagnitude faster than the normal code.  Beyond that it waffles back and \nforth which one is faster & why mainly because of the approaches we each \ntook on the caching.  Generally speaking I would push people more \ntowards Lea's than my work, if nothing else hers is more in line with \ncurrent gitweb, though I have had some thoughts about undoing my file \nbreakout and getting my code base back up to speed.\n\n- John 'Warthog9' Hawley\n"},{"id":"99825","messageId":"m3skns11mk.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"20090107042518.GB24735@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-09T23:49:25Z","receivedAt":"2009-01-09T23:49:25Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Joey Hess <joey@kitenet.net> writes:\n\n> The rel=vcs microformat allows a web page to indicate the locations of\n> repositories related to it in a machine-parseable manner.\n> (See http://kitenet.net/~joey/rfc/rel-vcs/)\n\nLet me put here an example from avove mentioned page:\n\n  <head>\n  <link rel=\"vcs-git\" href=\"git://example.org/foo.git\" \n        title=\"foo git repository\" />\n  </head>\n\n  <a rel=\"vcs-git\" href=\"git://example.org/foo.git\" \n     title=\"git repository\">git://example.org/foo.git</a>\n  <a rel=\"vcs-git\" href=\"git://example.org/foo.git\">git repository</a>\n\nThere is one problem that is not solved in above microformat, but it\nis problem only for git hosting sites like repo.or.cz or GitHub,\nnamely it does not allow to distinguish between fetch (read) link, and\npush (write, publish) link.  This is not a problem for standard\n(unmodified) gitweb as it shows only read-only git repositories links.\n\nWe also have to decide what to put in the 'title' attribute; I think\nthe simplest would be to put \"$project git repository\" or something\n(for example \"git/git.git git repository\").\n\nOne thing I worry about is that those links (or at least some of those\nlinks) are not meant for the browser to open; also SCP/SSH-like syntax\nfor SSH protocol in the form of 'user@host:/path/to/repo.git/' which\ndoes not follow URL rules.\n\n> \n> Make gitweb use the microformat in the header of pages it generates,\n> if it has been configured with project url information in any of the usual\n> ways.\n\nThere are two bit separate issues here: marking existing and future\nURLs (current project fetch URLs which IIRC are not hyperlinked now;\nplanned/future 'git' links in project list page; perhaps also links in\nOPML and RSS/Atom feeds) with 'rel=\"vcs-git\"', and adding <link .../>\nelements to page header.\n\n> \n> Since getting the urls can require hitting disk, I avoided putting the\n> microformat on *every* page gitweb generates. Just put it on the project\n> summary page, the project list page, and the forks list page.\n>\n> The first of these already looks up the urls, so adding the microformat was\n> free. \n\nI assume that this patch is only about adding <link ... /> elements to\nhead?  I think in the case of 'summary' view for a project it is an\nexcellent idea (similar to having 'prev' and 'next' link elements in\nchaptered on-line book in HTML), and would allow for automation using\ngitweb as a kind of service announcement.\n\n> There is a small overhead in including the microformat on the latter\n> two pages [projects list and list of forks], but getting the project\n> descriptions for those pages already incurs a similar overhead, and\n> the ability to get every repo url in one place seems worthwhile.\n\nThere is also OPML, which might be worth checking.\n\nBy the way, for 'projects_list' action and 'forks' actions we have to\ndecide whether to show _all_ links for each project (there can be more\nthan one), or whether we show only some main git link (like in the\ncase of proposed 'git' link).  And whether we trust @git_base_url_list\nor do we take it as default and examine per-repository configuration\n(more costly).\n\nWhat is more important: 'project_list' page is already overly large\nwhen hosting very large number of repositories (there were some\npatches adding pagination for 'project_list', and perhaps they would\nbe resend).  Adding <link .../> elements would only add to its size;\nand if will be divided into pages we would have also to take it into\naccount.\n\n> \n> This changes git_get_project_description() to not check wantarray, and only\n> return in list context -- the only way it is used AFAICS.\n\nErrr... what? Why do you change git_get_project_description()\nsubroutine? I don't think it would be good source for 'title'\nattribute; perhaps for 'desc' attribute, and only aftre sanitizing\n\"Unnamed repository; edit this file to name it for gitweb.\"\n\nErrata: ah, it is git_get_project_url_list() subroutine...\n\n> \n> Signed-off-by: Joey Hess <joey@gnu.kitenet.net>\n> ---\n>  gitweb/gitweb.perl |   38 ++++++++++++++++++++++++++------------\n>  1 files changed, 26 insertions(+), 12 deletions(-)\n> \n> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\n> index 99f71b4..3f8a228 100755\n> --- a/gitweb/gitweb.perl\n> +++ b/gitweb/gitweb.perl\n> @@ -789,6 +789,9 @@ $git_dir = \"$projectroot/$project\" if $project;\n>  our @snapshot_fmts = gitweb_get_feature('snapshot');\n>  @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts);\n>  \n> +# populated later with git urls for the project\n> +our @git_url_list;\n> +\n\nI'm not sure why this have to be global, but I assume that you want to\navoid recalculationg it in git_header_html\n\n>  # dispatch\n>  if (!defined $action) {\n>  \tif (defined $hash) {\n> @@ -2100,17 +2103,22 @@ sub git_show_project_tagcloud {\n>  }\n>  \n>  sub git_get_project_url_list {\n> +\t# use per project git URL list in $projectroot/$path/cloneurl\n> +\t# or make project git URL from git base URL and project name\n\nI'd rather use separate subroutine for the second, I think.\n\n>  \tmy $path = shift;\n>  \n> +\tmy @ret;\n> +\n>  \t$git_dir = \"$projectroot/$path\";\n> -\topen my $fd, \"$git_dir/cloneurl\"\n> -\t\tor return wantarray ?\n> -\t\t@{ config_to_multi(git_get_project_config('url')) } :\n> -\t\t   config_to_multi(git_get_project_config('url'));\n> -\tmy @git_project_url_list = map { chomp; $_ } <$fd>;\n> -\tclose $fd;\n> +\tif (open my $fd, \"$git_dir/cloneurl\") {\n> +\t\t@ret = map { chomp; $_ } <$fd>;\n> +\t\tclose $fd;\n> +\t}\n> +\telse {\n\nStyle: \"} else {\"\n\n> +\t       @ret = @{ config_to_multi(git_get_project_config('url')) };\n> +\t}\n>  \n> -\treturn wantarray ? @git_project_url_list : \\@git_project_url_list;\n> +\treturn @ret ? @ret : map { \"$_/$project\" } @git_base_url_list;\n>  }\n\nHmmm... currently gitweb does it at caller:\n\n\tmy @url_list = git_get_project_url_list($project);\n\t@url_list = map { \"$_/$project\" } @git_base_url_list unless @url_list;\n\nWhy do you want to put this in git_get_project_url_list()? Please\nexplain (here and in the commit message too; it has to be mentioned in\ncommit message that you cnage semantics a bit, and explain why you did\nso).\n\n>  \n>  sub git_get_projects_list {\n> @@ -2953,6 +2961,10 @@ EOF\n\nSidenote: this should be\n\n  @@ -2953,6 +2961,10 @@ sub git_header_html {\n\nbut I'm not sure if it would be possible to automate...\n\n>  \t\tprint qq(<link rel=\"shortcut icon\" href=\"$favicon\" type=\"image/png\" />\\n);\n>  \t}\n>  \n> +\tforeach my $url (@git_url_list) {\n> +\t\tprint qq{<link rel=\"vcs\" type=\"git\" href=\"$url\" />\\n};\n> +\t}\n> +\n\nErrr... in mentioned http://kitenet.net/~joey/rel-vcs/ it is\n\n  <link rel=\"vcs-git\" href=\"$url\" title=\"$project git repository\" />\n\nand not\n\n  <link rel=\"vcs\" type=\"git\" href=\"$url\" />\n\nBesides, 'type' attribute for A and LINK elements is about advisory\nconent-type of the document pointed by link:\n\n type = content-type [CI]\n    This attribute gives an advisory hint as to the content type of\n    the content available at the link target address. It allows user\n    agents to opt to use a fallback mechanism rather than fetch the\n    content if they are advised that they will get content in a\n    content type they do not support.  Authors who use this attribute\n    take responsibility to manage the risk that it may become\n    inconsistent with the content available at the link target\n    address.  \n    For the current list of registered content types, please consult\n    [MIMETYPES].\n\n>  \tprint \"</head>\\n\" .\n>  \t      \"<body>\\n\";\n>  \n> @@ -4380,6 +4392,8 @@ sub git_project_list {\n>  \t\tdie_error(404, \"No projects found\");\n>  \t}\n>  \n> +\t@git_url_list = map { git_get_project_url_list($_->{path}) } @list;\n> +\n>  \tgit_header_html();\n>  \tif (-f $home_text) {\n>  \t\tprint \"<div class=\\\"index_include\\\">\\n\";\n> @@ -4400,6 +4414,8 @@ sub git_forks {\n>  \tif (defined $order && $order !~ m/none|project|descr|owner|age/) {\n>  \t\tdie_error(400, \"Unknown order parameter\");\n>  \t}\n> +\t\n> +\t@git_url_list = map { git_get_project_url_list($_->{path}) } @list;\n>  \n>  \tmy @list = git_get_projects_list($project);\n>  \tif (!@list) {\n\nThose two are pretty straightforward, but please note that\n'project_list' view (action) might be _already_ too large...\n\n> @@ -4457,6 +4473,8 @@ sub git_summary {\n>  \t\t@forklist = git_get_projects_list($project);\n>  \t}\n>  \n> +\t@git_url_list = git_get_project_url_list($project);\n> +\n>  \tgit_header_html();\n>  \tgit_print_page_nav('summary','', $head);\n>  \n> @@ -4468,12 +4486,8 @@ sub git_summary {\n>  \t\tprint \"<tr id=\\\"metadata_lchange\\\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\\n\";\n>  \t}\n>  \n> -\t# use per project git URL list in $projectroot/$project/cloneurl\n> -\t# or make project git URL from git base URL and project name\n>  \tmy $url_tag = \"URL\";\n> -\tmy @url_list = git_get_project_url_list($project);\n> -\t@url_list = map { \"$_/$project\" } @git_base_url_list unless @url_list;\n> -\tforeach my $git_url (@url_list) {\n> +\tforeach my $git_url (@git_url_list) {\n>  \t\tnext unless $git_url;\n>  \t\tprint \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>$git_url</td></tr>\\n\";\n>  \t\t$url_tag = \"\";\n> -- \n> 1.5.6.5\n\nThis is also pretty straightforward: it moves calculation earlier for\nresults to be shared with git_header_html (and uses global variable).\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"99826","messageId":"m3ocyg11bb.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"gk2794$djn$1@ger.gmane.org","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-09T23:56:07Z","receivedAt":"2009-01-09T23:56:07Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Giuseppe Bilotta <giuseppe.bilotta@gmail.com> writes:\n\n> On Wednesday 07 January 2009 05:25, Joey Hess wrote:\n> \n> > The rel=vcs microformat allows a web page to indicate the locations of\n> > repositories related to it in a machine-parseable manner.\n> > (See http://kitenet.net/~joey/rfc/rel-vcs/)\n> \n> Interesting idea, I like it. However, I see a problem in the proposed\n> implementation versus the spec. According to the spec:\n> \n> \"\"\"\n> The \"title\" is optional, but recommended if there are multiple, different\n> repositories linked to on one page. It is a human-readable description of the\n> repository.\n> [...]\n> If there are multiple repositories listed, without titles, tools\n> should assume they are different repositories.\n> \"\"\"\n\nGood catch.\n\n> \n> In this patch you do NOT add titles to the rel=vcs links, which means that\n> everything works fine only if there is a single URL for each project. If a\n> project has different URLs, it's going to appear multiple times as _different_\n> projects to a spec-compliant reader.\n> \n> A possible solution would be to make @git_url_list into a map keyed by the\n> project name and having the description and repo URL(s) as values.\n> \n> Since there is the possibility of different projects having the same\n> description (e.g. the default one), the link title could be composed of\n> \"$project - $description\" rather than simply $description.\n> \n> Note that both in summary and in project list view you already retrieve the\n> description, so there are no additional disk hits.\n\nWouldn't \"$project git repository\" (i.e. do not use description at\nall) be a simpler, faster and also _better_ solution?\n \n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"99827","messageId":"m3k594111k.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"20090107184113.GA31795@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-10T00:01:59Z","receivedAt":"2009-01-10T00:01:59Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Joey Hess <joey@kitenet.net> writes:\n> Giuseppe Bilotta wrote:\n> > Joey Hess <joey@kitenet.net> writes:\n\n> > > Thanks for the feedback. There are some changes happening to the\n> > > microformat that should make gitweb's job slightly easier, I'll respin\n> > > the patch soon.\n> > \n> > Let me know about this too, I very much like the idea of this microformat.\n> \n> FYI, I've updated the microformat's page with the changes. The\n> significant one for gitweb is that it can now be applied to <a> links.\n> So on the project page, the display of the git URL could be converted to\n> a link using the microformat, and there's no need to get the info\n> earlier to put it in the header. Unfortunatly, the same can't be done to\n> the project list page, unless it's changed to have \"git\" links as seen\n> on vger.kernel.org's gitweb.\n\nI'm not sure if making repository URLs to be hyperlinks is a good\nidea.  You cannot (should not) click on those in ordinary web browser;\nthey are to be used by git (that is also additional reason why I am\nnot so sure about 'git' link on projects_list page idea).\n\nBesides LINK elements in page HEAD are meant mainly for machine; I\nthink it might be more important to add them for machine there, even\nif they are as A elements (links) or just plain text URLs somewhere\nelse.  For example we have LINK elements with alternate versions,\namong others OPML for projectless pages, and RSS/Atom for project\npages, aven though those links are also in page body.\n\nSo I'd rather have them LINKs...\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"99828","messageId":"m3fxjs10zb.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"20090107190238.GA3909@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs microformat","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-10T00:03:20Z","receivedAt":"2009-01-10T00:03:20Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Joey Hess <joey@kitenet.net> writes:\n> Joey Hess wrote:\n\n> > Another approach would be to just memoize git_get_project_description\n> > and git_get_project_url_list.\n> \n> Especially since git_get_project_description is already called more than\n> once for some pages.\n\nHmmm... this is an idea worth checking.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"99830","messageId":"m3bpug0ypn.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"20090107232427.GA18958@gnu.kitenet.net","subject":"Re: [PATCH] gitweb: support the rel=vcs-* microformat","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-10T00:52:20Z","receivedAt":"2009-01-10T00:52:20Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Joey Hess <joey@kitenet.net> writes:\n\n> The rel=vcs-* microformat allows a web page to indicate the locations of\n> repositories related to it in a machine-parseable manner.\n> (See http://kitenet.net/~joey/rfc/rel-vcs/)\n> \n> Make gitweb use the microformat if it has been configured with project url\n> information in any of the usual ways. On the project summary page, the\n> repository URL display is simply marked up using the microformat. On the\n> project list page and forks list page, the microformat is embedded in the\n> header, since the URLs do not appear on the page.\n\nI think having LINK elements also for 'summary' page would be a good\nidea. This microformat is I think mainly for machines, and machines\ncan I guess read better a few LINK elements in fairly small HEAD of\npage, than scan all of many link (A) elements on the page for those\nmatching vcs-* microformat.\n\nBeside I am not sure if for example hyperlinking SCP-style repository\nURL makes sense at all; I am also not sure if hyperlinking links on\nwhich you cannot click on makes good sense (unless you use SPAN or\nABBR instead of A to mark repo links...)\n\n> \n> The microformat could be included on other pages too, but I've skipped\n> doing so for now, since it would mean reading another file for every page\n> displayed.\n\nAlso it is not necessary: if some tool want to get repo links for\ngiven project, it can get 'summary' page; if some tool want to get\nlist of all repos, it can access one of projects list actions.\n\n> \n> There is a small overhead in including the microformat on project list\n> and forks list pages, but getting the project descriptions for those pages\n> already incurs a similar overhead, and the ability to get every repo url\n> in one place seems worthwhile.\n\nBy the way, do you have any benchmarks for that?\n\n> \n> This changes git_get_project_url_list() to not check wantarray, and only\n> return in list context -- the only way it is used AFAICS. It memoizes\n> both that function and git_get_project_description(), to avoid redundant\n> file reads.\n\nI would also add that, from what I understand, you have made\ngit_get_project_url_list() subroutine to be self-sufficient: it now\nconsiders both per-repository configuration (gitweb.url in config,\ncloneurl file in $GIT_DIR) and global gitweb configuration\n(@git_base_url_list variable).\n\nSimplification of code so it always return list and does nto check\ncontents is a side issue, orthogonal to issue mentioned above.\n\n> \n> Signed-off-by: Joey Hess <joey@gnu.kitenet.net>\n> ---\n>  gitweb/gitweb.perl |   78 +++++++++++++++++++++++++++++++++++++++++----------\n>  1 files changed, 62 insertions(+), 16 deletions(-)\n> \n> This incorporates Giuseppe Bilotta's feedback, and uses new features\n> of the microformat. You can see this version running at\n> http://git.ikiwiki.info/\n> \n> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\n> index 99f71b4..c238717 100755\n> --- a/gitweb/gitweb.perl\n> +++ b/gitweb/gitweb.perl\n> @@ -2020,9 +2020,14 @@ sub git_get_path_by_hash {\n>  ## ......................................................................\n>  ## git utility functions, directly accessing git repository\n>  \n> +{\n> +my %project_descriptions; # cache\n> +\n\nWon't we get warnings (and perhaps errors) from mod_perl? Shouldn't\nthis be \"our %project_descriptions;\"?\n\n>  sub git_get_project_description {\n>  \tmy $path = shift;\n>  \n> +\treturn $project_descriptions{$path} if exists $project_descriptions{$path};\n> +\n>  \t$git_dir = \"$projectroot/$path\";\n>  \topen my $fd, \"$git_dir/description\"\n>  \t\tor return git_get_project_config('description');\n> @@ -2031,7 +2036,9 @@ sub git_get_project_description {\n>  \tif (defined $descr) {\n>  \t\tchomp $descr;\n>  \t}\n> -\treturn $descr;\n> +\treturn $project_descriptions{$path}=$descr;\n> +}\n> +\n>  }\n\nIf we use 'title=\"$project git repository\" for 'rel=\"vcs-git\"' links,\nis it still worth it extra complication to avoid double calculation of\nproject description in the case of 'summary' view for a project?\nBecause IIRC for 'projects_list' view it is already cached in\n@projects list as 'descr' key...\n\n>  \n>  sub git_get_project_ctags {\n> @@ -2099,18 +2106,30 @@ sub git_show_project_tagcloud {\n>  \t}\n>  }\n>  \n> +{\n> +my %project_url_lists; # cache\n> +\n\nSame question: would it work correctly for mod_perl?\n\n>  sub git_get_project_url_list {\n> +\t# use per project git URL list in $projectroot/$path/cloneurl\n> +\t# or make project git URL from git base URL and project name\n>  \tmy $path = shift;\n>  \n> +\treturn @{$project_url_lists{$path}} if exists $project_url_lists{$path};\n> +\n> +\tmy @ret;\n>  \t$git_dir = \"$projectroot/$path\";\n> -\topen my $fd, \"$git_dir/cloneurl\"\n> -\t\tor return wantarray ?\n> -\t\t@{ config_to_multi(git_get_project_config('url')) } :\n> -\t\t   config_to_multi(git_get_project_config('url'));\n> -\tmy @git_project_url_list = map { chomp; $_ } <$fd>;\n> -\tclose $fd;\n> +\tif (open my $fd, \"$git_dir/cloneurl\") {\n> +\t\t@ret = map { chomp; $_ } <$fd>;\n> +\t\tclose $fd;\n> +\t} else {\n> +\t       @ret = @{ config_to_multi(git_get_project_config('url')) };\n> +\t}\n> +\t@ret=map { \"$_/$project\" } @git_base_url_list if ! @ret;\n\nStyle: \n\n+\t@ret = map { \"$_/$project\" } @git_base_url_list if !@ret;\n\nor even\n\n+\t@ret = map { \"$_/$project\" } @git_base_url_list unless @ret;\n\n> +\n> +\t$project_url_lists{$path}=\\@ret;\n> +\treturn @ret;\n> +}\n>  \n> -\treturn wantarray ? @git_project_url_list : \\@git_project_url_list;\n>  }\n\nAgain: is it worth caching? It is only for 'summary'; for\n'projects_list' it might be better to extend @projects list instead\n\n>  \n>  sub git_get_projects_list {\n> @@ -2856,6 +2875,7 @@ sub blob_contenttype {\n>  sub git_header_html {\n>  \tmy $status = shift || \"200 OK\";\n>  \tmy $expires = shift;\n> +\tmy $extraheader = shift;\n>  \n>  \tmy $title = \"$site_name\";\n>  \tif (defined $project) {\n> @@ -2953,6 +2973,8 @@ EOF\n>  \t\tprint qq(<link rel=\"shortcut icon\" href=\"$favicon\" type=\"image/png\" />\\n);\n>  \t}\n>  \n> +\tprint $extraheader if defined $extraheader;\n> +\n>  \tprint \"</head>\\n\" .\n>  \t      \"<body>\\n\";\n>  \n\nGood solution, but shouldn't this be better put into separate commit,\nsimply extending git_header_html to allow to add extra data (no need\nto name it $extraheader I think, $extra would be enough) to the HTML\nheader (HEAD element contents)?\n\n> @@ -4365,6 +4387,26 @@ sub git_search_grep_body {\n>  \tprint \"</table>\\n\";\n>  }\n>  \n> +sub git_link_title {\n> +\tmy $project=shift;\n> +\t\n> +\tmy $description=git_get_project_description($project);\n> +\treturn $project.(length $description ? \" - $description\" : \"\");\n> +}\n\nStyle (whitespace around '='), and the fact that IMHO \"$project git\nrepository\" is better than \"$project - $description\", also because of\n  \"Unnamed repository; edit this file to name it for gitweb.\" \ndefault template\n\n> +\n> +# generates header with links to the specified projects\n> +sub git_links_header {\n\nGood abstraction, but I'm not so sure about subroutine name.\n\n> +\tmy $ret='';\n> +\tforeach my $project (@_) {\n\nStyle: I'd rather use named variables, like \"my @projects = @_\";\nalso everywhere else we use spaces around '=' usually.\n\n> +\t\t# rel=vcs-* microformat\n> +\t\tmy $title=git_link_title($project);\n\nGood abstraction.\n\n> +\t\tforeach my $url git_get_project_url_list($project) {\n> +\t\t\t$ret.=qq{<link rel=\"vcs-git\" href=\"$url\" title=\"$title\"/>\\n}\n\nTo be HTML compatibile, it is better to use \n\n> +\t\t\t$ret.=qq{<link rel=\"vcs-git\" href=\"$url\" title=\"$title\" />\\n}\n\n(note the space before \"/>\").\n\n> +\t\t}\n> +\t}\n> +\treturn $ret;\n> +}\n> +\n>  ## ======================================================================\n>  ## ======================================================================\n>  ## actions\n> @@ -4380,7 +4422,9 @@ sub git_project_list {\n>  \t\tdie_error(404, \"No projects found\");\n>  \t}\n>  \n> -\tgit_header_html();\n> +\tmy $extraheader=git_links_header(map { $_->{path} } @list);\n> +\n> +\tgit_header_html(undef, undef, $extraheader);\n>  \tif (-f $home_text) {\n>  \t\tprint \"<div class=\\\"index_include\\\">\\n\";\n>  \t\tinsert_file($home_text);\n> @@ -4405,8 +4449,10 @@ sub git_forks {\n>  \tif (!@list) {\n>  \t\tdie_error(404, \"No forks found\");\n>  \t}\n> +\t\n> +\tmy $extraheader=git_links_header(map { $_->{path} } @list);\n>  \n> -\tgit_header_html();\n> +\tgit_header_html(undef, undef, $extraheader);\n>  \tgit_print_page_nav('','');\n>  \tgit_print_header_div('summary', \"$project forks\");\n>  \tgit_project_list_body(\\@list, $order);\n> @@ -4468,14 +4514,14 @@ sub git_summary {\n>  \t\tprint \"<tr id=\\\"metadata_lchange\\\"><td>last change</td><td>$cd{'rfc2822'}</td></tr>\\n\";\n>  \t}\n>  \n> -\t# use per project git URL list in $projectroot/$project/cloneurl\n> -\t# or make project git URL from git base URL and project name\n>  \tmy $url_tag = \"URL\";\n> -\tmy @url_list = git_get_project_url_list($project);\n> -\t@url_list = map { \"$_/$project\" } @git_base_url_list unless @url_list;\n> -\tforeach my $git_url (@url_list) {\n> +\tmy $title=git_link_title($project);\n> +\tforeach my $git_url (git_get_project_url_list($project)) {\n>  \t\tnext unless $git_url;\n> -\t\tprint \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>$git_url</td></tr>\\n\";\n> +\t\tprint \"<tr class=\\\"metadata_url\\\"><td>$url_tag</td><td>\".\n> +\t\t      # rel=vcs-* microformat\n> +\t\t      \"<a rel=\\\"vcs-git\\\" href=\\\"$git_url\\\" title=\\\"$title\\\">$git_url</a>\".\n> +\t\t      \"</td></tr>\\n\";\n>  \t\t$url_tag = \"\";\n>  \t}\n\nNon clickable hyperlink... hmmm...\n\n>  \n> -- \n> 1.5.6.5\n> \n> \n> \n> -- \n> see shy jo\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"99832","messageId":"m37i540y5o.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"gk4bk5$9dq$1@ger.gmane.org","subject":"Re: [PATCH] gitweb: support the rel=vcs-* microformat","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-10T01:04:25Z","receivedAt":"2009-01-10T01:04:25Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Giuseppe Bilotta <giuseppe.bilotta@gmail.com> writes: \n> On Thursday 08 January 2009 00:24, Joey Hess wrote:\n> \n> > The rel=vcs-* microformat allows a web page to indicate the locations of\n> > repositories related to it in a machine-parseable manner.\n> > (See http://kitenet.net/~joey/rfc/rel-vcs/)\n> \n> Have you considered submitting the microformat to microformats.org?\n> That would make the microformat more official and would be an good\n> first step to have wider coverage of it, and additional reviews.\n\nGood thinking.  BTW. microformats.org is IIRC wiki (or at least part\nof it is wiki), so it should be easy to do...\n\n> \n> > Make gitweb use the microformat if it has been configured with project url\n> > information in any of the usual ways. On the project summary page, the\n> > repository URL display is simply marked up using the microformat. On the\n> > project list page and forks list page, the microformat is embedded in the\n> > header, since the URLs do not appear on the page.\n> > \n> > The microformat could be included on other pages too, but I've skipped\n> > doing so for now, since it would mean reading another file for every page\n> > displayed.\n> > \n> > There is a small overhead in including the microformat on project list\n> > and forks list pages, but getting the project descriptions for those pages\n> > already incurs a similar overhead, and the ability to get every repo url\n> > in one place seems worthwhile.\n> \n> I agree with this, although people with very large project lists may\n> differ ... do we have timings on these?\n\nI think while adding this microformat to 'summary' page is non-issue,\nwe might want to be able configure it out so it is not used for\nprojects_list page (which might be very large).\n\nAnd what about OPML, RSS and Atom formats?\n\n>  \n> > This changes git_get_project_url_list() to not check wantarray, and only\n> > return in list context -- the only way it is used AFAICS. It memoizes\n> > both that function and git_get_project_description(), to avoid redundant\n> > file reads.\n> \n> You may want to consider splitting the patch into three: memoizing\n> of git_get_project_description(), reworking of\n> git_get_project_url_list(), and the actual rel=vc-* insertions.\n\nVery good idea.  Small, single feature patches are nice.\n\n[...]\n> >  sub git_get_project_description {\n> >       my $path = shift;\n> >  \n> > +     return $project_descriptions{$path} if exists $project_descriptions{$path};\n> > +\n> \n> This line is bordering on the 80 characters, so you may want to\n> consider moving 'my $descr' here, with something such as\n> \n> my $descr = $project_descriptions{$path};\n> return $descr if exists $descr;\n> \n> Also, I'm no perl guru so I'm not sure about exists vs defined here.\n\nYou might have undefined value in existing key, but I guess that we\ncan assume that those are equivalent for this.  While 'exists' seems\nmore up to what you check (does the key exosts in hash) you further on\nrely on the fact that $descr is not undefined.\n\n[...]\n> >  ## ======================================================================\n> >  ## ======================================================================\n> >  ## actions\n> > @@ -4380,7 +4422,9 @@ sub git_project_list {\n> >               die_error(404, \"No projects found\");\n> >       }\n> >  \n> > -     git_header_html();\n> > +     my $extraheader=git_links_header(map { $_->{path} } @list);\n> > +\n> > +     git_header_html(undef, undef, $extraheader);\n> >       if (-f $home_text) {\n> >               print \"<div class=\\\"index_include\\\">\\n\";\n> >               insert_file($home_text);\n> > @@ -4405,8 +4449,10 @@ sub git_forks {\n> >       if (!@list) {\n> >               die_error(404, \"No forks found\");\n> >       }\n> > +     \n> > +     my $extraheader=git_links_header(map { $_->{path} } @list);\n> >  \n> > -     git_header_html();\n> > +     git_header_html(undef, undef, $extraheader);\n> \n> This makes me wonder if it would be worth it to turn git_header_html\n> into -param => value style, but I'm not really sure it's worth it.\n\nIt is git_header_html(STATUS, EXPIRES, EXTRA)\n\nHmmm... now I have checked we use either git_header_html() in gitweb\n(which is most common), or git_header_html(STATUS) in die_error, or in\na few cases git_header_html(undef, $expires); and now\ngit_header_html(undef, undef, $extra), so named parameters might be a\ngood idea... I don't have opinion here...\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"99833","messageId":"m33afs0xtm.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"20090108195446.GB18025@gnu.kitenet.net","subject":"Re: gitweb index performance (Re: [PATCH] gitweb: support the rel=vcs-* microformat)","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-10T01:11:34Z","receivedAt":"2009-01-10T01:11:34Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Joey Hess <joey@kitenet.net> writes:\n> Giuseppe Bilotta wrote:\n\n> > > There is a small overhead in including the microformat on project list\n> > > and forks list pages, but getting the project descriptions for those pages\n> > > already incurs a similar overhead, and the ability to get every repo url\n> > > in one place seems worthwhile.\n> > \n> > I agree with this, although people with very large project lists may\n> > differ ... do we have timings on these?\n> \n> AFAICS, when displaying the project list, gitweb reads each project's\n> description file, falling back to reading its config file if there is no\n> description file.\n> \n> If performance was a problem here, the thing to do would be to add\n> project descriptions to the $project_list file, and use those in\n> preference to the description files. If a large site has done that,\n> they've not sent in the patch. :-)\n\nThere was such patch sent by me, but IIRC it fall out, also because it\nwas sent IIRC in feature freeze time.  I have \"gitweb: Extend\nproject_index file format by project description\" in my StGit stack.\n\n> \n> With my patch, it will read each cloneurl file too. The best way to\n> optimise that for large sites seems to be to add an option that would\n> ignore the cloneurl files and config file and always use\n> @git_base_url_list.\n\nGood idea.\n\n> \n> I checked the only large site I have access to (git.debian.org) and they\n> use a $project_list file, but I see no other performance tuning. That's\n> a 2 ghz machine; it takes gitweb 28 (!) seconds to generate the nearly 1\n> MB index web page for 1671 repositories:\n> \n> /srv/git.debian.org/http/cgi-bin/gitweb.cgi  3.04s user 9.24s system 43% cpu 28.515 total\n>\n> \n> Notice that most of the time is spent by child processes. For each\n> repository, gitweb runs git-for-each-ref to determine the time of the\n> last commit.\n> \n> If that is removed (say if there were a way to get the info w/o\n> forking), performance improves nicely:\n> \n> ./gitweb.cgi > /dev/null  1.29s user 1.08s system 69% cpu 3.389 total\n> \n> Making it not read description files for each project, as I suggest above,\n> is the next best optimisation:\n> \n> ./gitweb.cgi > /dev/null  1.08s user 0.05s system 96% cpu 1.170 total\n> \n> So, I think it makes sense to optimise gitweb and offer knobs for performance\n> tuning at the expense of the flexability of description and cloneurl files.\n> But, git-for-each-ref is swamping everything else.\n\nOne solution would be to limit number of projects displayed on the\npage, for example to 100 projects, although that would mainly reduce\nproblem with dealing with large page on client size, less so server\nload unless we _do not_ sort projects by age.\n\nAnother solution would be to use caching: repo.or.cz uses one solution\n(caching only of projects_list action), kernel.org other solution\n(gitweb caching from GSoC 2008 project).\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"99841","messageId":"m3y6xkylwu.fsf@localhost.localdomain","threadId":"17033","inReplyTo":"496691EC.1070805@eaglescrag.net","subject":"Re: gitweb index performance (Re: [PATCH] gitweb: support the rel=vcs-* microformat)","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2009-01-10T01:44:50Z","receivedAt":"2009-01-10T01:44:50Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"\"J.H.\" <warthog19@eaglescrag.net> writes:\n> Joey Hess wrote:\n>> Giuseppe Bilotta wrote:\n>>\n>>>> There is a small overhead in including the microformat on project list\n>>>> and forks list pages, but getting the project descriptions for those pages\n>>>> already incurs a similar overhead, and the ability to get every repo url\n>>>> in one place seems worthwhile.\n>>>>\n>>> I agree with this, although people with very large project lists may\n>>> differ ... do we have timings on these?\n>>>\n>>\n>> AFAICS, when displaying the project list, gitweb reads each project's\n>> description file, falling back to reading its config file if there is no\n>> description file.\n>>\n>> If performance was a problem here, the thing to do would be to add\n>> project descriptions to the $project_list file, and use those in\n>> preference to the description files. If a large site has done that,\n>> they've not sent in the patch. :-)\n> \n> No because all the large sites have pain points and issues elsewhere\n> in the app.  Most of the large sites (which I can at least speak for\n> Kernel.org) went and have built in full caching layers into gitweb\n> itself to deal with the problem.  This means that we don't have to\n> worry about nickle and dime performance improvements that are specific\n> to one section, but can do a very broad sweep and get dramatically\n> better performance across all of gitweb.  Those patches have all made\n> it back out onto the mailing list, but for a number of different\n> reasons none have been accepted into the mainline branch.\n\nAdditional issue is that when you add or delete repository (project),\nyou have to correct or regenerate projects_index file.  While it is I\nthink quite easy for git hosting sites such as repo.or.cz, it is\nharder for sites which offer gitweb just like they ofer WWW homepages:\nas a service, with repositories created (and descriptions updated)\noutside of gitweb control.\n\n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"}]}