{"thread":{"id":"5242","subject":"[PATCH 0/9] gitweb: Great subroutine renaming + task separation into subroutines + improvements","startedAt":"2006-08-14T00:02:45Z","lastAt":"2006-08-15T16:45:35Z","messageCount":23,"participants":["Jakub Narebski","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"25236","messageId":"200608140202.46160.jnareb@gmail.com","threadId":"5242","inReplyTo":null,"subject":"[PATCH 0/9] gitweb: Great subroutine renaming + task separation into subroutines + improvements","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:02:45Z","receivedAt":"2006-08-14T00:02:45Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This series of patches is based on the 'next' branch, commit\n10a6653c818f78c6032d45e1d4da544085e1f28b (v1.4.2-g10a6653)\n\nIt begins with:\n* [PATCH 1/9] gitweb: Great subroutines renaming\n\nThen there is series of patches which separate task into subroutine; \n'refactor' in patch subject here means that we use new subroutine in \nmore than one place, 'separate' here means that new subroutine is (for \nnow) used only in one place\n* [PATCH 2/9] gitweb: Separate ref parsing in git_get_refs_list \n  into parse_ref\n* [PATCH 3/9] gitweb: Refactor printing shortened title \n  in git_shortlog_body and git_tags_body\n* [PATCH 4/9] gitweb: Separate main part of git_history \n  into git_history_body\n* [PATCH 5/9] gitweb: Separate finding project owner \n  into git_get_project_owner\n\nThen there is couple of improvements\n* [PATCH 6/9] gitweb: Change appereance of marker of refs pointing \n  to given object\n* [PATCH 7/9] gitweb: Skip comments in mime.types like file\n* [PATCH 8/9] gitweb: True fix: Support for the standard mime.types map\n  in gitweb\n\nAnd finally yet another separation of task into subroutine, with small \nimprovements (and perhaps to be reused)\n* [PATCH 9/9] gitweb: Separate printing difftree in git_commit into\n  git_difftree_body\n\n\n-- \nJakub Narebski\nPoland\n"},{"id":"25244","messageId":"200608140205.47380.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 1/9] gitweb: Great subroutines renaming","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:05:47Z","receivedAt":"2006-08-14T00:05:47Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Rename some of subroutines to better reflect what they do.\nSome renames were not performed because subroutine name\nreflects hash key.\n\nSubroutines name guideline:\n* git_ prefix for subroutines related to git commands,\n  git repository, or to gitweb actions\n* git_get_ prefix for inner subroutines calling git command\n  or reading some file in the repository and returning some output\n* parse_ prefix for subroutines parsing some text (or reading and\n  parsing some text) into hash or list\n* format_ prefix for subroutines formatting, post-processing\n  or generating some HTML/text fragment\n* _get_ infix for subroutines which return result\n* _print_ infix for subroutines which print fragment of output\n* _body suffix for subroutines which outputs main part (body)\n  of related action (usually table)\n* _nav suffix for subroutines related to navigation bars\n* _div suffix for subroutines returning or printing div element\n* subroutine names should not be based on how the result is obtained,\n  as this might change easily\n\nRenames performed:\n- git_get_referencing => format_ref_marker\n- git_get_paging_nav => format_paging_nav\n- git_read_head => git_get_head_hash\n- git_read_hash => git_get_hash_by_ref\n- git_read_description => git_get_project_description\n- git_read_projects => git_get_projects_list\n- read_info_ref => git_get_references\n- git_read_refs => git_get_refs_list\n- date_str => parse_date\n- git_read_tag => parse_tag\n- git_read_commit => parse_commit\n- git_blob_plain_mimetype => blob_mimetype\n- git_page_nav => git_print_page_nav\n- git_header_div => git_print_header_div\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nI'm not sure if to add script used to create this commit, and to\nport changes to be \"post-rename\". Here it is:\n\n#!/bin/bash\nif test -z \"$1\"; then\n\tFILE=`git rev-parse --show-cdup`gitweb/gitweb.perl\nelse\n\tFILE=$1\nfi\necho \"Great subroutine renaming: $FILE\"\nperl -s -p -i.re~ \\\n\t-e 's/\\bgit_get_referencing\\b/format_ref_marker/;' \\\n\t-e 's/\\bgit_get_paging_nav\\b/format_paging_nav/;' \\\n\t\\\n\t-e 's/\\bgit_read_head\\b/git_get_head_hash/;' \\\n\t-e 's/\\bgit_read_hash\\b/git_get_hash_by_ref/;' \\\n\t-e 's/\\bgit_read_description\\b/git_get_project_description/;' \\\n\t-e 's/\\bgit_read_projects\\b/git_get_projects_list/;' \\\n\t-e 's/\\bread_info_ref\\b/git_get_references/;' \\\n\t-e 's/\\bgit_read_refs\\b/git_get_refs_list/;' \\\n\t\\\n\t-e 's/\\bdate_str\\b/parse_date/;' \\\n\t-e 's/\\bgit_read_tag\\b/parse_tag/;' \\\n\t-e 's/\\bgit_read_commit\\b/parse_commit/;' \\\n\t\\\n\t-e 's/\\bgit_blob_plain_mimetype\\b/blob_mimetype/;' \\\n\t\\\n\t-e 's/\\bgit_page_nav\\b/git_print_page_nav/;' \\\n\t-e 's/\\bgit_header_div\\b/git_print_header_div/;' \\\n\t\"$FILE\"\n# end of gitweb-rename.sh\n\n\n gitweb/gitweb.perl |  250 ++++++++++++++++++++++++++--------------------------\n 1 files changed, 125 insertions(+), 125 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 626fcc9..28df59e 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -362,7 +362,7 @@ sub format_log_line_html {\n }\n \n # format marker of refs pointing to given object\n-sub git_get_referencing {\n+sub format_ref_marker {\n \tmy ($refs, $id) = @_;\n \n \tif (defined $refs->{$id}) {\n@@ -376,7 +376,7 @@ ## -------------------------------------\n ## git utility subroutines, invoking git commands\n \n # get HEAD ref of given project as hash\n-sub git_read_head {\n+sub git_get_head_hash {\n \tmy $project = shift;\n \tmy $oENV = $ENV{'GIT_DIR'};\n \tmy $retval = undef;\n@@ -445,7 +445,7 @@ ## .....................................\n ## git utility functions, directly accessing git repository\n \n # assumes that PATH is not symref\n-sub git_read_hash {\n+sub git_get_hash_by_ref {\n \tmy $path = shift;\n \n \topen my $fd, \"$projectroot/$path\" or return undef;\n@@ -457,7 +457,7 @@ sub git_read_hash {\n \t}\n }\n \n-sub git_read_description {\n+sub git_get_project_description {\n \tmy $path = shift;\n \n \topen my $fd, \"$projectroot/$path/description\" or return undef;\n@@ -467,7 +467,7 @@ sub git_read_description {\n \treturn $descr;\n }\n \n-sub git_read_projects {\n+sub git_get_projects_list {\n \tmy @list;\n \n \tif (-d $projects_list) {\n@@ -511,7 +511,7 @@ sub git_read_projects {\n \treturn @list;\n }\n \n-sub read_info_ref {\n+sub git_get_references {\n \tmy $type = shift || \"\";\n \tmy %refs;\n \t# 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c\trefs/tags/v2.6.11\n@@ -536,7 +536,7 @@ sub read_info_ref {\n ## ----------------------------------------------------------------------\n ## parse to hash functions\n \n-sub date_str {\n+sub parse_date {\n \tmy $epoch = shift;\n \tmy $tz = shift || \"-0000\";\n \n@@ -561,7 +561,7 @@ sub date_str {\n \treturn %date;\n }\n \n-sub git_read_tag {\n+sub parse_tag {\n \tmy $tag_id = shift;\n \tmy %tag;\n \tmy @comment;\n@@ -596,7 +596,7 @@ sub git_read_tag {\n \treturn %tag\n }\n \n-sub git_read_commit {\n+sub parse_commit {\n \tmy $commit_id = shift;\n \tmy $commit_text = shift;\n \n@@ -693,7 +693,7 @@ sub git_read_commit {\n ## ......................................................................\n ## parse to array of hashes functions\n \n-sub git_read_refs {\n+sub git_get_refs_list {\n \tmy $ref_dir = shift;\n \tmy @reflist;\n \n@@ -707,7 +707,7 @@ sub git_read_refs {\n \t}, \"$projectroot/$project/$ref_dir\");\n \n \tforeach my $ref_file (@refs) {\n-\t\tmy $ref_id = git_read_hash(\"$project/$ref_dir/$ref_file\");\n+\t\tmy $ref_id = git_get_hash_by_ref(\"$project/$ref_dir/$ref_file\");\n \t\tmy $type = git_get_type($ref_id) || next;\n \t\tmy %ref_item;\n \t\tmy %co;\n@@ -716,10 +716,10 @@ sub git_read_refs {\n \t\t$ref_item{'epoch'} = 0;\n \t\t$ref_item{'age'} = \"unknown\";\n \t\tif ($type eq \"tag\") {\n-\t\t\tmy %tag = git_read_tag($ref_id);\n+\t\t\tmy %tag = parse_tag($ref_id);\n \t\t\t$ref_item{'comment'} = $tag{'comment'};\n \t\t\tif ($tag{'type'} eq \"commit\") {\n-\t\t\t\t%co = git_read_commit($tag{'object'});\n+\t\t\t\t%co = parse_commit($tag{'object'});\n \t\t\t\t$ref_item{'epoch'} = $co{'committer_epoch'};\n \t\t\t\t$ref_item{'age'} = $co{'age_string'};\n \t\t\t} elsif (defined($tag{'epoch'})) {\n@@ -731,7 +731,7 @@ sub git_read_refs {\n \t\t\t$ref_item{'name'} = $tag{'name'};\n \t\t\t$ref_item{'refid'} = $tag{'object'};\n \t\t} elsif ($type eq \"commit\"){\n-\t\t\t%co = git_read_commit($ref_id);\n+\t\t\t%co = parse_commit($ref_id);\n \t\t\t$ref_item{'reftype'} = \"commit\";\n \t\t\t$ref_item{'name'} = $ref_file;\n \t\t\t$ref_item{'title'} = $co{'title'};\n@@ -806,7 +806,7 @@ sub mimetype_guess {\n \treturn $mime;\n }\n \n-sub git_blob_plain_mimetype {\n+sub blob_mimetype {\n \tmy $fd = shift;\n \tmy $filename = shift;\n \n@@ -925,7 +925,7 @@ EOF\n sub git_footer_html {\n \tprint \"<div class=\\\"page_footer\\\">\\n\";\n \tif (defined $project) {\n-\t\tmy $descr = git_read_description($project);\n+\t\tmy $descr = git_get_project_description($project);\n \t\tif (defined $descr) {\n \t\t\tprint \"<div class=\\\"page_footer_text\\\">\" . esc_html($descr) . \"</div>\\n\";\n \t\t}\n@@ -955,7 +955,7 @@ sub die_error {\n ## ----------------------------------------------------------------------\n ## functions printing or outputting HTML: navigation\n \n-sub git_page_nav {\n+sub git_print_page_nav {\n \tmy ($current, $suppress, $head, $treehead, $treebase, $extra) = @_;\n \t$extra = '' if !defined $extra; # pager or formats\n \n@@ -989,7 +989,7 @@ sub git_page_nav {\n \t      \"</div>\\n\";\n }\n \n-sub git_get_paging_nav {\n+sub format_paging_nav {\n \tmy ($action, $hash, $head, $page, $nrevs) = @_;\n \tmy $paging_nav;\n \n@@ -1022,7 +1022,7 @@ sub git_get_paging_nav {\n ## ......................................................................\n ## functions printing or outputting HTML: div\n \n-sub git_header_div {\n+sub git_print_header_div {\n \tmy ($action, $title, $hash, $hash_base) = @_;\n \tmy $rest = '';\n \n@@ -1062,9 +1062,9 @@ sub git_shortlog_body {\n \tmy $alternate = 0;\n \tfor (my $i = $from; $i <= $to; $i++) {\n \t\tmy $commit = $revlist->[$i];\n-\t\t#my $ref = defined $refs ? git_get_referencing($refs, $commit) : '';\n-\t\tmy $ref = git_get_referencing($refs, $commit);\n-\t\tmy %co = git_read_commit($commit);\n+\t\t#my $ref = defined $refs ? format_ref_marker($refs, $commit) : '';\n+\t\tmy $ref = format_ref_marker($refs, $commit);\n+\t\tmy %co = parse_commit($commit);\n \t\tif ($alternate) {\n \t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n \t\t} else {\n@@ -1282,24 +1282,24 @@ sub git_project_list {\n \t\tdie_error(undef, \"Unknown order parameter\");\n \t}\n \n-\tmy @list = git_read_projects();\n+\tmy @list = git_get_projects_list();\n \tmy @projects;\n \tif (!@list) {\n \t\tdie_error(undef, \"No projects found\");\n \t}\n \tforeach my $pr (@list) {\n-\t\tmy $head = git_read_head($pr->{'path'});\n+\t\tmy $head = git_get_head_hash($pr->{'path'});\n \t\tif (!defined $head) {\n \t\t\tnext;\n \t\t}\n \t\t$ENV{'GIT_DIR'} = \"$projectroot/$pr->{'path'}\";\n-\t\tmy %co = git_read_commit($head);\n+\t\tmy %co = parse_commit($head);\n \t\tif (!%co) {\n \t\t\tnext;\n \t\t}\n \t\t$pr->{'commit'} = \\%co;\n \t\tif (!defined $pr->{'descr'}) {\n-\t\t\tmy $descr = git_read_description($pr->{'path'}) || \"\";\n+\t\t\tmy $descr = git_get_project_description($pr->{'path'}) || \"\";\n \t\t\t$pr->{'descr'} = chop_str($descr, 25, 5);\n \t\t}\n \t\tif (!defined $pr->{'owner'}) {\n@@ -1383,10 +1383,10 @@ sub git_project_list {\n }\n \n sub git_summary {\n-\tmy $descr = git_read_description($project) || \"none\";\n-\tmy $head = git_read_head($project);\n-\tmy %co = git_read_commit($head);\n-\tmy %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'});\n+\tmy $descr = git_get_project_description($project) || \"none\";\n+\tmy $head = git_get_head_hash($project);\n+\tmy %co = parse_commit($head);\n+\tmy %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'});\n \n \tmy $owner;\n \tif (-f $projects_list) {\n@@ -1407,9 +1407,9 @@ sub git_summary {\n \t\t$owner = get_file_owner(\"$projectroot/$project\");\n \t}\n \n-\tmy $refs = read_info_ref();\n+\tmy $refs = git_get_references();\n \tgit_header_html();\n-\tgit_page_nav('summary','', $head);\n+\tgit_print_page_nav('summary','', $head);\n \n \tprint \"<div class=\\\"title\\\">&nbsp;</div>\\n\";\n \tprint \"<table cellspacing=\\\"0\\\">\\n\" .\n@@ -1418,24 +1418,24 @@ sub git_summary {\n \t      \"<tr><td>last change</td><td>$cd{'rfc2822'}</td></tr>\\n\" .\n \t      \"</table>\\n\";\n \n-\topen my $fd, \"-|\", $GIT, \"rev-list\", \"--max-count=17\", git_read_head($project)\n+\topen my $fd, \"-|\", $GIT, \"rev-list\", \"--max-count=17\", git_get_head_hash($project)\n \t\tor die_error(undef, \"Open git-rev-list failed\");\n \tmy @revlist = map { chomp; $_ } <$fd>;\n \tclose $fd;\n-\tgit_header_div('shortlog');\n+\tgit_print_header_div('shortlog');\n \tgit_shortlog_body(\\@revlist, 0, 15, $refs,\n \t                  $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=shortlog\")}, \"...\"));\n \n-\tmy $taglist = git_read_refs(\"refs/tags\");\n+\tmy $taglist = git_get_refs_list(\"refs/tags\");\n \tif (defined @$taglist) {\n-\t\tgit_header_div('tags');\n+\t\tgit_print_header_div('tags');\n \t\tgit_tags_body($taglist, 0, 15,\n \t\t              $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=tags\")}, \"...\"));\n \t}\n \n-\tmy $headlist = git_read_refs(\"refs/heads\");\n+\tmy $headlist = git_get_refs_list(\"refs/heads\");\n \tif (defined @$headlist) {\n-\t\tgit_header_div('heads');\n+\t\tgit_print_header_div('heads');\n \t\tgit_heads_body($headlist, $head, 0, 15,\n \t\t               $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=heads\")}, \"...\"));\n \t}\n@@ -1444,11 +1444,11 @@ sub git_summary {\n }\n \n sub git_tag {\n-\tmy $head = git_read_head($project);\n+\tmy $head = git_get_head_hash($project);\n \tgit_header_html();\n-\tgit_page_nav('','', $head,undef,$head);\n-\tmy %tag = git_read_tag($hash);\n-\tgit_header_div('commit', esc_html($tag{'name'}), $hash);\n+\tgit_print_page_nav('','', $head,undef,$head);\n+\tmy %tag = parse_tag($hash);\n+\tgit_print_header_div('commit', esc_html($tag{'name'}), $hash);\n \tprint \"<div class=\\\"title_text\\\">\\n\" .\n \t      \"<table cellspacing=\\\"0\\\">\\n\" .\n \t      \"<tr>\\n\" .\n@@ -1457,7 +1457,7 @@ sub git_tag {\n \t      \"<td class=\\\"link\\\">\" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=$tag{'type'};h=$tag{'object'}\")}, $tag{'type'}) . \"</td>\\n\" .\n \t      \"</tr>\\n\";\n \tif (defined($tag{'author'})) {\n-\t\tmy %ad = date_str($tag{'epoch'}, $tag{'tz'});\n+\t\tmy %ad = parse_date($tag{'epoch'}, $tag{'tz'});\n \t\tprint \"<tr><td>author</td><td>\" . esc_html($tag{'author'}) . \"</td></tr>\\n\";\n \t\tprint \"<tr><td></td><td>\" . $ad{'rfc2822'} . sprintf(\" (%02d:%02d %s)\", $ad{'hour_local'}, $ad{'minute_local'}, $ad{'tz_local'}) . \"</td></tr>\\n\";\n \t}\n@@ -1477,9 +1477,9 @@ sub git_blame2 {\n \tmy $ftype;\n \tdie_error(undef, \"Permission denied\") if (!git_get_project_config_bool ('blame'));\n \tdie_error('404 Not Found', \"File name not defined\") if (!$file_name);\n-\t$hash_base ||= git_read_head($project);\n+\t$hash_base ||= git_get_head_hash($project);\n \tdie_error(undef, \"Couldn't find base commit\") unless ($hash_base);\n-\tmy %co = git_read_commit($hash_base)\n+\tmy %co = parse_commit($hash_base)\n \t\tor die_error(undef, \"Reading commit failed\");\n \tif (!defined $hash) {\n \t\t$hash = git_get_hash_by_path($hash_base, $file_name, \"blob\")\n@@ -1495,8 +1495,8 @@ sub git_blame2 {\n \tmy $formats_nav =\n \t\t$cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name\")}, \"blob\") .\n \t\t\" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blame;f=$file_name\")}, \"head\");\n-\tgit_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n-\tgit_header_div('commit', esc_html($co{'title'}), $hash_base);\n+\tgit_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n+\tgit_print_header_div('commit', esc_html($co{'title'}), $hash_base);\n \tgit_print_page_path($file_name, $ftype);\n \tmy @rev_color = (qw(light2 dark2));\n \tmy $num_colors = scalar(@rev_color);\n@@ -1535,9 +1535,9 @@ sub git_blame {\n \tmy $fd;\n \tdie_error('403 Permission denied', \"Permission denied\") if (!git_get_project_config_bool ('blame'));\n \tdie_error('404 Not Found', \"File name not defined\") if (!$file_name);\n-\t$hash_base ||= git_read_head($project);\n+\t$hash_base ||= git_get_head_hash($project);\n \tdie_error(undef, \"Couldn't find base commit\") unless ($hash_base);\n-\tmy %co = git_read_commit($hash_base)\n+\tmy %co = parse_commit($hash_base)\n \t\tor die_error(undef, \"Reading commit failed\");\n \tif (!defined $hash) {\n \t\t$hash = git_get_hash_by_path($hash_base, $file_name, \"blob\")\n@@ -1549,8 +1549,8 @@ sub git_blame {\n \tmy $formats_nav =\n \t\t$cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$hash;hb=$hash_base;f=$file_name\")}, \"blob\") .\n \t\t\" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blame;f=$file_name\")}, \"head\");\n-\tgit_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n-\tgit_header_div('commit', esc_html($co{'title'}), $hash_base);\n+\tgit_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n+\tgit_print_header_div('commit', esc_html($co{'title'}), $hash_base);\n \tgit_print_page_path($file_name, 'blob');\n \tprint \"<div class=\\\"page_body\\\">\\n\";\n \tprint <<HTML;\n@@ -1618,12 +1618,12 @@ HTML\n }\n \n sub git_tags {\n-\tmy $head = git_read_head($project);\n+\tmy $head = git_get_head_hash($project);\n \tgit_header_html();\n-\tgit_page_nav('','', $head,undef,$head);\n-\tgit_header_div('summary', $project);\n+\tgit_print_page_nav('','', $head,undef,$head);\n+\tgit_print_header_div('summary', $project);\n \n-\tmy $taglist = git_read_refs(\"refs/tags\");\n+\tmy $taglist = git_get_refs_list(\"refs/tags\");\n \tif (defined @$taglist) {\n \t\tgit_tags_body($taglist);\n \t}\n@@ -1631,12 +1631,12 @@ sub git_tags {\n }\n \n sub git_heads {\n-\tmy $head = git_read_head($project);\n+\tmy $head = git_get_head_hash($project);\n \tgit_header_html();\n-\tgit_page_nav('','', $head,undef,$head);\n-\tgit_header_div('summary', $project);\n+\tgit_print_page_nav('','', $head,undef,$head);\n+\tgit_print_header_div('summary', $project);\n \n-\tmy $taglist = git_read_refs(\"refs/heads\");\n+\tmy $taglist = git_get_refs_list(\"refs/heads\");\n \tif (defined @$taglist) {\n \t\tgit_heads_body($taglist, $head);\n \t}\n@@ -1646,7 +1646,7 @@ sub git_heads {\n sub git_blob_plain {\n \tif (!defined $hash) {\n \t\tif (defined $file_name) {\n-\t\t\tmy $base = $hash_base || git_read_head($project);\n+\t\t\tmy $base = $hash_base || git_get_head_hash($project);\n \t\t\t$hash = git_get_hash_by_path($base, $file_name, \"blob\")\n \t\t\t\tor die_error(undef, \"Error lookup file\");\n \t\t} else {\n@@ -1657,7 +1657,7 @@ sub git_blob_plain {\n \topen my $fd, \"-|\", $GIT, \"cat-file\", \"blob\", $hash\n \t\tor die_error(undef, \"Couldn't cat $file_name, $hash\");\n \n-\t$type ||= git_blob_plain_mimetype($fd, $file_name);\n+\t$type ||= blob_mimetype($fd, $file_name);\n \n \t# save as filename, even when no $file_name is given\n \tmy $save_as = \"$hash\";\n@@ -1679,7 +1679,7 @@ sub git_blob_plain {\n sub git_blob {\n \tif (!defined $hash) {\n \t\tif (defined $file_name) {\n-\t\t\tmy $base = $hash_base || git_read_head($project);\n+\t\t\tmy $base = $hash_base || git_get_head_hash($project);\n \t\t\t$hash = git_get_hash_by_path($base, $file_name, \"blob\")\n \t\t\t\tor die_error(undef, \"Error lookup file\");\n \t\t} else {\n@@ -1689,14 +1689,14 @@ sub git_blob {\n \tmy $have_blame = git_get_project_config_bool ('blame');\n \topen my $fd, \"-|\", $GIT, \"cat-file\", \"blob\", $hash\n \t\tor die_error(undef, \"Couldn't cat $file_name, $hash\");\n-\tmy $mimetype = git_blob_plain_mimetype($fd, $file_name);\n+\tmy $mimetype = blob_mimetype($fd, $file_name);\n \tif ($mimetype !~ m/^text\\//) {\n \t\tclose $fd;\n \t\treturn git_blob_plain($mimetype);\n \t}\n \tgit_header_html();\n \tmy $formats_nav = '';\n-\tif (defined $hash_base && (my %co = git_read_commit($hash_base))) {\n+\tif (defined $hash_base && (my %co = parse_commit($hash_base))) {\n \t\tif (defined $file_name) {\n \t\t\tif ($have_blame) {\n \t\t\t\t$formats_nav .= $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blame;h=$hash;hb=$hash_base;f=$file_name\")}, \"blame\") . \" | \";\n@@ -1707,8 +1707,8 @@ sub git_blob {\n \t\t} else {\n \t\t\t$formats_nav .= $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob_plain;h=$hash\")}, \"plain\");\n \t\t}\n-\t\tgit_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n-\t\tgit_header_div('commit', esc_html($co{'title'}), $hash_base);\n+\t\tgit_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n+\t\tgit_print_header_div('commit', esc_html($co{'title'}), $hash_base);\n \t} else {\n \t\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n \t\t      \"<br/><br/></div>\\n\" .\n@@ -1730,7 +1730,7 @@ sub git_blob {\n \n sub git_tree {\n \tif (!defined $hash) {\n-\t\t$hash = git_read_head($project);\n+\t\t$hash = git_get_head_hash($project);\n \t\tif (defined $file_name) {\n \t\t\tmy $base = $hash_base || $hash;\n \t\t\t$hash = git_get_hash_by_path($base, $file_name, \"tree\");\n@@ -1746,16 +1746,16 @@ sub git_tree {\n \tclose $fd or die_error(undef, \"Reading tree failed\");\n \t$/ = \"\\n\";\n \n-\tmy $refs = read_info_ref();\n-\tmy $ref = git_get_referencing($refs, $hash_base);\n+\tmy $refs = git_get_references();\n+\tmy $ref = format_ref_marker($refs, $hash_base);\n \tgit_header_html();\n \tmy $base_key = \"\";\n \tmy $base = \"\";\n \tmy $have_blame = git_get_project_config_bool ('blame');\n-\tif (defined $hash_base && (my %co = git_read_commit($hash_base))) {\n+\tif (defined $hash_base && (my %co = parse_commit($hash_base))) {\n \t\t$base_key = \";hb=$hash_base\";\n-\t\tgit_page_nav('tree','', $hash_base);\n-\t\tgit_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);\n+\t\tgit_print_page_nav('tree','', $hash_base);\n+\t\tgit_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash_base);\n \t} else {\n \t\tprint \"<div class=\\\"page_nav\\\">\\n\";\n \t\tprint \"<br/><br/></div>\\n\";\n@@ -1811,14 +1811,14 @@ sub git_tree {\n }\n \n sub git_log {\n-\tmy $head = git_read_head($project);\n+\tmy $head = git_get_head_hash($project);\n \tif (!defined $hash) {\n \t\t$hash = $head;\n \t}\n \tif (!defined $page) {\n \t\t$page = 0;\n \t}\n-\tmy $refs = read_info_ref();\n+\tmy $refs = git_get_references();\n \n \tmy $limit = sprintf(\"--max-count=%i\", (100 * ($page+1)));\n \topen my $fd, \"-|\", $GIT, \"rev-list\", $limit, $hash\n@@ -1826,24 +1826,24 @@ sub git_log {\n \tmy @revlist = map { chomp; $_ } <$fd>;\n \tclose $fd;\n \n-\tmy $paging_nav = git_get_paging_nav('log', $hash, $head, $page, $#revlist);\n+\tmy $paging_nav = format_paging_nav('log', $hash, $head, $page, $#revlist);\n \n \tgit_header_html();\n-\tgit_page_nav('log','', $hash,undef,undef, $paging_nav);\n+\tgit_print_page_nav('log','', $hash,undef,undef, $paging_nav);\n \n \tif (!@revlist) {\n-\t\tmy %co = git_read_commit($hash);\n+\t\tmy %co = parse_commit($hash);\n \n-\t\tgit_header_div('summary', $project);\n+\t\tgit_print_header_div('summary', $project);\n \t\tprint \"<div class=\\\"page_body\\\"> Last change $co{'age_string'}.<br/><br/></div>\\n\";\n \t}\n \tfor (my $i = ($page * 100); $i <= $#revlist; $i++) {\n \t\tmy $commit = $revlist[$i];\n-\t\tmy $ref = git_get_referencing($refs, $commit);\n-\t\tmy %co = git_read_commit($commit);\n+\t\tmy $ref = format_ref_marker($refs, $commit);\n+\t\tmy %co = parse_commit($commit);\n \t\tnext if !%co;\n-\t\tmy %ad = date_str($co{'author_epoch'});\n-\t\tgit_header_div('commit',\n+\t\tmy %ad = parse_date($co{'author_epoch'});\n+\t\tgit_print_header_div('commit',\n \t\t               \"<span class=\\\"age\\\">$co{'age_string'}</span>\" .\n \t\t               esc_html($co{'title'}) . $ref,\n \t\t               $commit);\n@@ -1881,12 +1881,12 @@ sub git_log {\n }\n \n sub git_commit {\n-\tmy %co = git_read_commit($hash);\n+\tmy %co = parse_commit($hash);\n \tif (!%co) {\n \t\tdie_error(undef, \"Unknown commit object\");\n \t}\n-\tmy %ad = date_str($co{'author_epoch'}, $co{'author_tz'});\n-\tmy %cd = date_str($co{'committer_epoch'}, $co{'committer_tz'});\n+\tmy %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});\n+\tmy %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'});\n \n \tmy $parent = $co{'parent'};\n \tif (!defined $parent) {\n@@ -1902,22 +1902,22 @@ sub git_commit {\n \tif ($hash =~ m/^[0-9a-fA-F]{40}$/) {\n \t\t$expires = \"+1d\";\n \t}\n-\tmy $refs = read_info_ref();\n-\tmy $ref = git_get_referencing($refs, $co{'id'});\n+\tmy $refs = git_get_references();\n+\tmy $ref = format_ref_marker($refs, $co{'id'});\n \tmy $formats_nav = '';\n \tif (defined $file_name && defined $co{'parent'}) {\n \t\tmy $parent = $co{'parent'};\n \t\t$formats_nav .= $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blame;hb=$parent;f=$file_name\")}, \"blame\");\n \t}\n \tgit_header_html(undef, $expires);\n-\tgit_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff',\n+\tgit_print_page_nav('commit', defined $co{'parent'} ? '' : 'commitdiff',\n \t             $hash, $co{'tree'}, $hash,\n \t             $formats_nav);\n \n \tif (defined $co{'parent'}) {\n-\t\tgit_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash);\n+\t\tgit_print_header_div('commitdiff', esc_html($co{'title'}) . $ref, $hash);\n \t} else {\n-\t\tgit_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash);\n+\t\tgit_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash);\n \t}\n \tprint \"<div class=\\\"title_text\\\">\\n\" .\n \t      \"<table cellspacing=\\\"0\\\">\\n\";\n@@ -2079,11 +2079,11 @@ sub git_commit {\n sub git_blobdiff {\n \tmkdir($git_temp, 0700);\n \tgit_header_html();\n-\tif (defined $hash_base && (my %co = git_read_commit($hash_base))) {\n+\tif (defined $hash_base && (my %co = parse_commit($hash_base))) {\n \t\tmy $formats_nav =\n \t\t\t$cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff_plain;h=$hash;hp=$hash_parent\")}, \"plain\");\n-\t\tgit_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n-\t\tgit_header_div('commit', esc_html($co{'title'}), $hash_base);\n+\t\tgit_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n+\t\tgit_print_header_div('commit', esc_html($co{'title'}), $hash_base);\n \t} else {\n \t\tprint \"<div class=\\\"page_nav\\\">\\n\" .\n \t\t      \"<br/><br/></div>\\n\" .\n@@ -2109,7 +2109,7 @@ sub git_blobdiff_plain {\n \n sub git_commitdiff {\n \tmkdir($git_temp, 0700);\n-\tmy %co = git_read_commit($hash);\n+\tmy %co = parse_commit($hash);\n \tif (!%co) {\n \t\tdie_error(undef, \"Unknown commit object\");\n \t}\n@@ -2126,13 +2126,13 @@ sub git_commitdiff {\n \tif ($hash =~ m/^[0-9a-fA-F]{40}$/) {\n \t\t$expires = \"+1d\";\n \t}\n-\tmy $refs = read_info_ref();\n-\tmy $ref = git_get_referencing($refs, $co{'id'});\n+\tmy $refs = git_get_references();\n+\tmy $ref = format_ref_marker($refs, $co{'id'});\n \tmy $formats_nav =\n \t\t$cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commitdiff_plain;h=$hash;hp=$hash_parent\")}, \"plain\");\n \tgit_header_html(undef, $expires);\n-\tgit_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);\n-\tgit_header_div('commit', esc_html($co{'title'}) . $ref, $hash);\n+\tgit_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);\n+\tgit_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash);\n \tprint \"<div class=\\\"page_body\\\">\\n\";\n \tmy $comment = $co{'comment'};\n \tmy $empty = 0;\n@@ -2200,7 +2200,7 @@ sub git_commitdiff {\n \n sub git_commitdiff_plain {\n \tmkdir($git_temp, 0700);\n-\tmy %co = git_read_commit($hash);\n+\tmy %co = parse_commit($hash);\n \tif (!%co) {\n \t\tdie_error(undef, \"Unknown commit object\");\n \t}\n@@ -2214,7 +2214,7 @@ sub git_commitdiff_plain {\n \n \t# try to figure out the next tag after this commit\n \tmy $tagname;\n-\tmy $refs = read_info_ref(\"tags\");\n+\tmy $refs = git_get_references(\"tags\");\n \topen $fd, \"-|\", $GIT, \"rev-list\", \"HEAD\";\n \tmy @commits = map { chomp; $_ } <$fd>;\n \tclose $fd;\n@@ -2228,7 +2228,7 @@ sub git_commitdiff_plain {\n \t}\n \n \tprint $cgi->header(-type => \"text/plain\", -charset => 'utf-8', '-content-disposition' => \"inline; filename=\\\"git-$hash.patch\\\"\");\n-\tmy %ad = date_str($co{'author_epoch'}, $co{'author_tz'});\n+\tmy %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});\n \tmy $comment = $co{'comment'};\n \tprint \"From: $co{'author'}\\n\" .\n \t      \"Date: $ad{'rfc2822'} ($ad{'tz_local'})\\n\".\n@@ -2264,17 +2264,17 @@ sub git_commitdiff_plain {\n \n sub git_history {\n \tif (!defined $hash_base) {\n-\t\t$hash_base = git_read_head($project);\n+\t\t$hash_base = git_get_head_hash($project);\n \t}\n \tmy $ftype;\n-\tmy %co = git_read_commit($hash_base);\n+\tmy %co = parse_commit($hash_base);\n \tif (!%co) {\n \t\tdie_error(undef, \"Unknown commit object\");\n \t}\n-\tmy $refs = read_info_ref();\n+\tmy $refs = git_get_references();\n \tgit_header_html();\n-\tgit_page_nav('','', $hash_base,$co{'tree'},$hash_base);\n-\tgit_header_div('commit', esc_html($co{'title'}), $hash_base);\n+\tgit_print_page_nav('','', $hash_base,$co{'tree'},$hash_base);\n+\tgit_print_header_div('commit', esc_html($co{'title'}), $hash_base);\n \tif (!defined $hash && defined $file_name) {\n \t\t$hash = git_get_hash_by_path($hash_base, $file_name);\n \t}\n@@ -2290,11 +2290,11 @@ sub git_history {\n \twhile (my $line = <$fd>) {\n \t\tif ($line =~ m/^([0-9a-fA-F]{40})/){\n \t\t\tmy $commit = $1;\n-\t\t\tmy %co = git_read_commit($commit);\n+\t\t\tmy %co = parse_commit($commit);\n \t\t\tif (!%co) {\n \t\t\t\tnext;\n \t\t\t}\n-\t\t\tmy $ref = git_get_referencing($refs, $commit);\n+\t\t\tmy $ref = format_ref_marker($refs, $commit);\n \t\t\tif ($alternate) {\n \t\t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n \t\t\t} else {\n@@ -2330,9 +2330,9 @@ sub git_search {\n \t\tdie_error(undef, \"Text field empty\");\n \t}\n \tif (!defined $hash) {\n-\t\t$hash = git_read_head($project);\n+\t\t$hash = git_get_head_hash($project);\n \t}\n-\tmy %co = git_read_commit($hash);\n+\tmy %co = parse_commit($hash);\n \tif (!%co) {\n \t\tdie_error(undef, \"Unknown commit object\");\n \t}\n@@ -2351,8 +2351,8 @@ sub git_search {\n \t\t$pickaxe_search = 1;\n \t}\n \tgit_header_html();\n-\tgit_page_nav('','', $hash,$co{'tree'},$hash);\n-\tgit_header_div('commit', esc_html($co{'title'}), $hash);\n+\tgit_print_page_nav('','', $hash,$co{'tree'},$hash);\n+\tgit_print_header_div('commit', esc_html($co{'title'}), $hash);\n \n \tprint \"<table cellspacing=\\\"0\\\">\\n\";\n \tmy $alternate = 0;\n@@ -2370,7 +2370,7 @@ sub git_search {\n \t\t\t\tnext;\n \t\t\t}\n \t\t\tmy @commit_lines = split \"\\n\", $commit_text;\n-\t\t\tmy %co = git_read_commit(undef, \\@commit_lines);\n+\t\t\tmy %co = parse_commit(undef, \\@commit_lines);\n \t\t\tif (!%co) {\n \t\t\t\tnext;\n \t\t\t}\n@@ -2451,7 +2451,7 @@ sub git_search {\n \t\t\t\t\tprint \"</td>\\n\" .\n \t\t\t\t\t      \"</tr>\\n\";\n \t\t\t\t}\n-\t\t\t\t%co = git_read_commit($1);\n+\t\t\t\t%co = parse_commit($1);\n \t\t\t}\n \t\t}\n \t\tclose $fd;\n@@ -2461,14 +2461,14 @@ sub git_search {\n }\n \n sub git_shortlog {\n-\tmy $head = git_read_head($project);\n+\tmy $head = git_get_head_hash($project);\n \tif (!defined $hash) {\n \t\t$hash = $head;\n \t}\n \tif (!defined $page) {\n \t\t$page = 0;\n \t}\n-\tmy $refs = read_info_ref();\n+\tmy $refs = git_get_references();\n \n \tmy $limit = sprintf(\"--max-count=%i\", (100 * ($page+1)));\n \topen my $fd, \"-|\", $GIT, \"rev-list\", $limit, $hash\n@@ -2476,7 +2476,7 @@ sub git_shortlog {\n \tmy @revlist = map { chomp; $_ } <$fd>;\n \tclose $fd;\n \n-\tmy $paging_nav = git_get_paging_nav('shortlog', $hash, $head, $page, $#revlist);\n+\tmy $paging_nav = format_paging_nav('shortlog', $hash, $head, $page, $#revlist);\n \tmy $next_link = '';\n \tif ($#revlist >= (100 * ($page+1)-1)) {\n \t\t$next_link =\n@@ -2486,8 +2486,8 @@ sub git_shortlog {\n \n \n \tgit_header_html();\n-\tgit_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav);\n-\tgit_header_div('summary', $project);\n+\tgit_print_page_nav('shortlog','', $hash,$hash,$hash, $paging_nav);\n+\tgit_print_header_div('summary', $project);\n \n \tgit_shortlog_body(\\@revlist, ($page * 100), $#revlist, $refs, $next_link);\n \n@@ -2499,7 +2499,7 @@ ## feeds (RSS, OPML)\n \n sub git_rss {\n \t# http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ\n-\topen my $fd, \"-|\", $GIT, \"rev-list\", \"--max-count=150\", git_read_head($project)\n+\topen my $fd, \"-|\", $GIT, \"rev-list\", \"--max-count=150\", git_get_head_hash($project)\n \t\tor die_error(undef, \"Open git-rev-list failed\");\n \tmy @revlist = map { chomp; $_ } <$fd>;\n \tclose $fd or die_error(undef, \"Reading git-rev-list failed\");\n@@ -2514,12 +2514,12 @@ sub git_rss {\n \n \tfor (my $i = 0; $i <= $#revlist; $i++) {\n \t\tmy $commit = $revlist[$i];\n-\t\tmy %co = git_read_commit($commit);\n+\t\tmy %co = parse_commit($commit);\n \t\t# we read 150, we always show 30 and the ones more recent than 48 hours\n \t\tif (($i >= 20) && ((time - $co{'committer_epoch'}) > 48*60*60)) {\n \t\t\tlast;\n \t\t}\n-\t\tmy %cd = date_str($co{'committer_epoch'});\n+\t\tmy %cd = parse_date($co{'committer_epoch'});\n \t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', $co{'parent'}, $co{'id'} or next;\n \t\tmy @difftree = map { chomp; $_ } <$fd>;\n \t\tclose $fd or next;\n@@ -2556,7 +2556,7 @@ sub git_rss {\n }\n \n sub git_opml {\n-\tmy @list = git_read_projects();\n+\tmy @list = git_get_projects_list();\n \n \tprint $cgi->header(-type => 'text/xml', -charset => 'utf-8');\n \tprint \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\".\n@@ -2569,12 +2569,12 @@ sub git_opml {\n \n \tforeach my $pr (@list) {\n \t\tmy %proj = %$pr;\n-\t\tmy $head = git_read_head($proj{'path'});\n+\t\tmy $head = git_get_head_hash($proj{'path'});\n \t\tif (!defined $head) {\n \t\t\tnext;\n \t\t}\n \t\t$ENV{'GIT_DIR'} = \"$projectroot/$proj{'path'}\";\n-\t\tmy %co = git_read_commit($head);\n+\t\tmy %co = parse_commit($head);\n \t\tif (!%co) {\n \t\t\tnext;\n \t\t}\n-- \n1.4.1.1\n"},{"id":"25239","messageId":"200608140207.01108.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 2/9] gitweb: Separate ref parsing in git_get_refs_list into parse_ref","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:07:00Z","receivedAt":"2006-08-14T00:07:00Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Note that for each ref there are usually two calls to git subroutines:\nfirst to get the type of ref, second to parse ref if ref is of commit\nor tag type.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |   80 +++++++++++++++++++++++++++++-----------------------\n 1 files changed, 45 insertions(+), 35 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 28df59e..0c4ec92 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -690,6 +690,49 @@ sub parse_commit {\n \treturn %co;\n }\n \n+# parse ref from ref_file, given by ref_id, with given type\n+sub parse_ref {\n+\tmy $ref_file = shift;\n+\tmy $ref_id = shift;\n+\tmy $type = shift || git_get_type($ref_id);\n+\tmy %ref_item;\n+\n+\t$ref_item{'type'} = $type;\n+\t$ref_item{'id'} = $ref_id;\n+\t$ref_item{'epoch'} = 0;\n+\t$ref_item{'age'} = \"unknown\";\n+\tif ($type eq \"tag\") {\n+\t\tmy %tag = parse_tag($ref_id);\n+\t\t$ref_item{'comment'} = $tag{'comment'};\n+\t\tif ($tag{'type'} eq \"commit\") {\n+\t\t\tmy %co = parse_commit($tag{'object'});\n+\t\t\t$ref_item{'epoch'} = $co{'committer_epoch'};\n+\t\t\t$ref_item{'age'} = $co{'age_string'};\n+\t\t} elsif (defined($tag{'epoch'})) {\n+\t\t\tmy $age = time - $tag{'epoch'};\n+\t\t\t$ref_item{'epoch'} = $tag{'epoch'};\n+\t\t\t$ref_item{'age'} = age_string($age);\n+\t\t}\n+\t\t$ref_item{'reftype'} = $tag{'type'};\n+\t\t$ref_item{'name'} = $tag{'name'};\n+\t\t$ref_item{'refid'} = $tag{'object'};\n+\t} elsif ($type eq \"commit\"){\n+\t\tmy %co = parse_commit($ref_id);\n+\t\t$ref_item{'reftype'} = \"commit\";\n+\t\t$ref_item{'name'} = $ref_file;\n+\t\t$ref_item{'title'} = $co{'title'};\n+\t\t$ref_item{'refid'} = $ref_id;\n+\t\t$ref_item{'epoch'} = $co{'committer_epoch'};\n+\t\t$ref_item{'age'} = $co{'age_string'};\n+\t} else {\n+\t\t$ref_item{'reftype'} = $type;\n+\t\t$ref_item{'name'} = $ref_file;\n+\t\t$ref_item{'refid'} = $ref_id;\n+\t}\n+\n+\treturn %ref_item;\n+}\n+\n ## ......................................................................\n ## parse to array of hashes functions\n \n@@ -709,44 +752,11 @@ sub git_get_refs_list {\n \tforeach my $ref_file (@refs) {\n \t\tmy $ref_id = git_get_hash_by_ref(\"$project/$ref_dir/$ref_file\");\n \t\tmy $type = git_get_type($ref_id) || next;\n-\t\tmy %ref_item;\n-\t\tmy %co;\n-\t\t$ref_item{'type'} = $type;\n-\t\t$ref_item{'id'} = $ref_id;\n-\t\t$ref_item{'epoch'} = 0;\n-\t\t$ref_item{'age'} = \"unknown\";\n-\t\tif ($type eq \"tag\") {\n-\t\t\tmy %tag = parse_tag($ref_id);\n-\t\t\t$ref_item{'comment'} = $tag{'comment'};\n-\t\t\tif ($tag{'type'} eq \"commit\") {\n-\t\t\t\t%co = parse_commit($tag{'object'});\n-\t\t\t\t$ref_item{'epoch'} = $co{'committer_epoch'};\n-\t\t\t\t$ref_item{'age'} = $co{'age_string'};\n-\t\t\t} elsif (defined($tag{'epoch'})) {\n-\t\t\t\tmy $age = time - $tag{'epoch'};\n-\t\t\t\t$ref_item{'epoch'} = $tag{'epoch'};\n-\t\t\t\t$ref_item{'age'} = age_string($age);\n-\t\t\t}\n-\t\t\t$ref_item{'reftype'} = $tag{'type'};\n-\t\t\t$ref_item{'name'} = $tag{'name'};\n-\t\t\t$ref_item{'refid'} = $tag{'object'};\n-\t\t} elsif ($type eq \"commit\"){\n-\t\t\t%co = parse_commit($ref_id);\n-\t\t\t$ref_item{'reftype'} = \"commit\";\n-\t\t\t$ref_item{'name'} = $ref_file;\n-\t\t\t$ref_item{'title'} = $co{'title'};\n-\t\t\t$ref_item{'refid'} = $ref_id;\n-\t\t\t$ref_item{'epoch'} = $co{'committer_epoch'};\n-\t\t\t$ref_item{'age'} = $co{'age_string'};\n-\t\t} else {\n-\t\t\t$ref_item{'reftype'} = $type;\n-\t\t\t$ref_item{'name'} = $ref_file;\n-\t\t\t$ref_item{'refid'} = $ref_id;\n-\t\t}\n+\t\tmy %ref_item = parse_ref($ref_file, $ref_id, $type);\n \n \t\tpush @reflist, \\%ref_item;\n \t}\n-\t# sort tags by age\n+\t# sort refs by age\n \t@reflist = sort {$b->{'epoch'} <=> $a->{'epoch'}} @reflist;\n \treturn \\@reflist;\n }\n-- \n1.4.1.1\n"},{"id":"25237","messageId":"200608140208.27246.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 3/9] gitweb: Refactor printing shortened title in git_shortlog_body and git_tags_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:08:27Z","receivedAt":"2006-08-14T00:08:27Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Separate printing of perhaps shortened title (subject) in\ngit_shortlog_body and git_tags_body into format_subject_html.\n\nWhile at it, remove presentation element <b>...</b> used to format\ntitle (subject) and move formatting to CSS.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nCSS is used in such a way as to not change output\n\n gitweb/gitweb.css  |    5 +++++\n gitweb/gitweb.perl |   34 ++++++++++++++++++----------------\n 2 files changed, 23 insertions(+), 16 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 47c1ade..f58a418 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -117,9 +117,14 @@ div.list_head {\n \n a.list {\n \ttext-decoration: none;\n+\tfont-weight: bold;\n \tcolor: #000000;\n }\n \n+table.tags a.list {\n+\tfont-weight: normal;\n+}\n+\n a.list:hover {\n \ttext-decoration: underline;\n \tcolor: #880000;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 0c4ec92..c4d6eab 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -372,6 +372,22 @@ sub format_ref_marker {\n \t}\n }\n \n+# format, perhaps shortened and with markers, title line\n+sub format_subject_html {\n+\tmy ($long, $short, $query, $extra) = @_;\n+\t$extra = '' unless defined($extra);\n+\n+\tif (length($short) < length($long)) {\n+\t\treturn $cgi->a({-href => \"$my_uri?\" . esc_param($query),\n+\t\t               -class => \"list\", -title => $long},\n+\t\t       esc_html($short) . $extra);\n+\t} else {\n+\t\treturn $cgi->a({-href => \"$my_uri?\" . esc_param($query),\n+\t\t               -class => \"list\"},\n+\t\t       esc_html($long)  . $extra);\n+\t}\n+}\n+\n ## ----------------------------------------------------------------------\n ## git utility subroutines, invoking git commands\n \n@@ -1085,15 +1101,7 @@ sub git_shortlog_body {\n \t\tprint \"<td title=\\\"$co{'age_string_age'}\\\"><i>$co{'age_string_date'}</i></td>\\n\" .\n \t\t      \"<td><i>\" . esc_html(chop_str($co{'author_name'}, 10)) . \"</i></td>\\n\" .\n \t\t      \"<td>\";\n-\t\tif (length($co{'title_short'}) < length($co{'title'})) {\n-\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commit;h=$commit\"),\n-\t\t\t               -class => \"list\", -title => \"$co{'title'}\"},\n-\t\t\t      \"<b>\" . esc_html($co{'title_short'}) . \"$ref</b>\");\n-\t\t} else {\n-\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commit;h=$commit\"),\n-\t\t\t               -class => \"list\"},\n-\t\t\t      \"<b>\" . esc_html($co{'title'}) . \"$ref</b>\");\n-\t\t}\n+\t\tprint format_subject_html($co{'title'}, $co{'title_short'}, \"p=$project;a=commit;h=$commit\", $ref);\n \t\tprint \"</td>\\n\" .\n \t\t      \"<td class=\\\"link\\\">\" .\n \t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commit;h=$commit\")}, \"commit\") . \" | \" .\n@@ -1139,13 +1147,7 @@ sub git_tags_body {\n \t\t      \"</td>\\n\" .\n \t\t      \"<td>\";\n \t\tif (defined $comment) {\n-\t\t\tif (length($comment_short) < length($comment)) {\n-\t\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=tag;h=$tag{'id'}\"),\n-\t\t\t\t               -class => \"list\", -title => $comment}, $comment_short);\n-\t\t\t} else {\n-\t\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=tag;h=$tag{'id'}\"),\n-\t\t\t\t               -class => \"list\"}, $comment);\n-\t\t\t}\n+\t\t\tprint format_subject_html($comment, $comment_short, \"p=$project;a=tag;h=$tag{'id'}\");\n \t\t}\n \t\tprint \"</td>\\n\" .\n \t\t      \"<td class=\\\"selflink\\\">\";\n-- \n1.4.1.1\n"},{"id":"25246","messageId":"200608140209.09189.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 4/9] gitweb: Separate main part of git_history into git_history_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:09:08Z","receivedAt":"2006-08-14T00:09:08Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Separates main part of git_history into git_history_body subroutine,\nand makes output more similar to git_shortlog.  Adds \"diff to current\"\nlink only for history of regular file (blob).\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |   96 +++++++++++++++++++++++++++++++++-------------------\n 1 files changed, 60 insertions(+), 36 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c4d6eab..5af6e77 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1117,6 +1117,64 @@ sub git_shortlog_body {\n \tprint \"</table>\\n\";\n }\n \n+sub git_history_body {\n+\t# Warning: assumes constant type (blob or tree) during history\n+\tmy ($fd, $refs, $hash_base, $ftype, $extra) = @_;\n+\n+\tprint \"<table class=\\\"history\\\" cellspacing=\\\"0\\\">\\n\";\n+\tmy $alternate = 0;\n+\twhile (my $line = <$fd>) {\n+\t\tif ($line !~ m/^([0-9a-fA-F]{40})/) {\n+\t\t\tnext;\n+\t\t}\n+\n+\t\tmy $commit = $1;\n+\t\tmy %co = parse_commit($commit);\n+\t\tif (!%co) {\n+\t\t\tnext;\n+\t\t}\n+\n+\t\tmy $ref = format_ref_marker($refs, $commit);\n+\n+\t\tif ($alternate) {\n+\t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n+\t\t} else {\n+\t\t\tprint \"<tr class=\\\"light\\\">\\n\";\n+\t\t}\n+\t\t$alternate ^= 1;\n+\t\tprint \"<td title=\\\"$co{'age_string_age'}\\\"><i>$co{'age_string_date'}</i></td>\\n\" .\n+\t\t      # shortlog uses      chop_str($co{'author_name'}, 10)\n+\t\t      \"<td><i>\" . esc_html(chop_str($co{'author_name'}, 15, 3)) . \"</i></td>\\n\" .\n+\t\t      \"<td>\";\n+\t\t# originally git_history used chop_str($co{'title'}, 50)\n+\t\tprint format_subject_html($co{'title'}, $co{'title_short'}, \"p=$project;a=commit;h=$commit\", $ref);\n+\t\tprint \"</td>\\n\" .\n+\t\t      \"<td class=\\\"link\\\">\" .\n+\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commit;h=$commit\")}, \"commit\") . \" | \" .\n+\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commitdiff;h=$commit\")}, \"commitdiff\") . \" | \" .\n+\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=$ftype;hb=$commit;f=$file_name\")}, $ftype);\n+\n+\t\tif ($ftype eq 'blob') {\n+\t\t\tmy $blob_current = git_get_hash_by_path($hash_base, $file_name);\n+\t\t\tmy $blob_parent  = git_get_hash_by_path($commit, $file_name);\n+\t\t\tif (defined $blob_current && defined $blob_parent &&\n+\t\t\t\t\t$blob_current ne $blob_parent) {\n+\t\t\t\tprint \" | \" .\n+\t\t\t\t\t$cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff;h=$blob_current;hp=$blob_parent;hb=$commit;f=$file_name\")},\n+\t\t\t\t\t        \"diff to current\");\n+\t\t\t}\n+\t\t}\n+\t\tprint \"</td>\\n\" .\n+\t\t      \"</tr>\\n\";\n+\t}\n+\tif (defined $extra) {\n+\t\tprint \"<tr>\\n\" .\n+\t\t      \"<td colspan=\\\"4\\\">$extra</td>\\n\" .\n+\t\t      \"</tr>\\n\";\n+\t}\n+\tprint \"</table>\\n\";\n+}\n+\n sub git_tags_body {\n \t# uses global variable $project\n \tmy ($taglist, $from, $to, $extra) = @_;\n@@ -2297,42 +2355,8 @@ sub git_history {\n \n \topen my $fd, \"-|\",\n \t\t$GIT, \"rev-list\", \"--full-history\", $hash_base, \"--\", $file_name;\n-\tprint \"<table cellspacing=\\\"0\\\">\\n\";\n-\tmy $alternate = 0;\n-\twhile (my $line = <$fd>) {\n-\t\tif ($line =~ m/^([0-9a-fA-F]{40})/){\n-\t\t\tmy $commit = $1;\n-\t\t\tmy %co = parse_commit($commit);\n-\t\t\tif (!%co) {\n-\t\t\t\tnext;\n-\t\t\t}\n-\t\t\tmy $ref = format_ref_marker($refs, $commit);\n-\t\t\tif ($alternate) {\n-\t\t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n-\t\t\t} else {\n-\t\t\t\tprint \"<tr class=\\\"light\\\">\\n\";\n-\t\t\t}\n-\t\t\t$alternate ^= 1;\n-\t\t\tprint \"<td title=\\\"$co{'age_string_age'}\\\"><i>$co{'age_string_date'}</i></td>\\n\" .\n-\t\t\t      \"<td><i>\" . esc_html(chop_str($co{'author_name'}, 15, 3)) . \"</i></td>\\n\" .\n-\t\t\t      \"<td>\" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commit;h=$commit\"), -class => \"list\"}, \"<b>\" .\n-\t\t\t      esc_html(chop_str($co{'title'}, 50)) . \"$ref</b>\") . \"</td>\\n\" .\n-\t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commit;h=$commit\")}, \"commit\") .\n-\t\t\t      \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=commitdiff;h=$commit\")}, \"commitdiff\") .\n-\t\t\t      \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=$ftype;hb=$commit;f=$file_name\")}, $ftype);\n-\t\t\tmy $blob = git_get_hash_by_path($hash_base, $file_name);\n-\t\t\tmy $blob_parent = git_get_hash_by_path($commit, $file_name);\n-\t\t\tif (defined $blob && defined $blob_parent && $blob ne $blob_parent) {\n-\t\t\t\tprint \" | \" .\n-\t\t\t\t$cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff;h=$blob;hp=$blob_parent;hb=$commit;f=$file_name\")},\n-\t\t\t\t\"diff to current\");\n-\t\t\t}\n-\t\t\tprint \"</td>\\n\" .\n-\t\t\t      \"</tr>\\n\";\n-\t\t}\n-\t}\n-\tprint \"</table>\\n\";\n+\tgit_history_body($fd, $refs, $hash_base, $ftype);\n+\n \tclose $fd;\n \tgit_footer_html();\n }\n-- \n1.4.1.1\n"},{"id":"25240","messageId":"200608140210.06961.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 5/9] gitweb: Separate finding project owner into git_get_project_owner","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:10:06Z","receivedAt":"2006-08-14T00:10:06Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Signed-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nAnd added some comments, while at it.\n\n gitweb/gitweb.perl |   50 ++++++++++++++++++++++++++++++++------------------\n 1 files changed, 32 insertions(+), 18 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 5af6e77..6be6c55 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -527,6 +527,37 @@ sub git_get_projects_list {\n \treturn @list;\n }\n \n+sub git_get_project_owner {\n+\tmy $project = shift;\n+\tmy $owner;\n+\n+\treturn undef unless $project;\n+\n+\t# read from file (url-encoded):\n+\t# 'git%2Fgit.git Linus+Torvalds'\n+\t# 'libs%2Fklibc%2Fklibc.git H.+Peter+Anvin'\n+\t# 'linux%2Fhotplug%2Fudev.git Greg+Kroah-Hartman'\n+\tif (-f $projects_list) {\n+\t\topen (my $fd , $projects_list);\n+\t\twhile (my $line = <$fd>) {\n+\t\t\tchomp $line;\n+\t\t\tmy ($pr, $ow) = split ' ', $line;\n+\t\t\t$pr = unescape($pr);\n+\t\t\t$ow = unescape($ow);\n+\t\t\tif ($pr eq $project) {\n+\t\t\t\t$owner = decode(\"utf8\", $ow, Encode::FB_DEFAULT);\n+\t\t\t\tlast;\n+\t\t\t}\n+\t\t}\n+\t\tclose $fd;\n+\t}\n+\tif (!defined $owner) {\n+\t\t$owner = get_file_owner(\"$projectroot/$project\");\n+\t}\n+\n+\treturn $owner;\n+}\n+\n sub git_get_references {\n \tmy $type = shift || \"\";\n \tmy %refs;\n@@ -1458,24 +1489,7 @@ sub git_summary {\n \tmy %co = parse_commit($head);\n \tmy %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'});\n \n-\tmy $owner;\n-\tif (-f $projects_list) {\n-\t\topen (my $fd , $projects_list);\n-\t\twhile (my $line = <$fd>) {\n-\t\t\tchomp $line;\n-\t\t\tmy ($pr, $ow) = split ' ', $line;\n-\t\t\t$pr = unescape($pr);\n-\t\t\t$ow = unescape($ow);\n-\t\t\tif ($pr eq $project) {\n-\t\t\t\t$owner = decode(\"utf8\", $ow, Encode::FB_DEFAULT);\n-\t\t\t\tlast;\n-\t\t\t}\n-\t\t}\n-\t\tclose $fd;\n-\t}\n-\tif (!defined $owner) {\n-\t\t$owner = get_file_owner(\"$projectroot/$project\");\n-\t}\n+\tmy $owner = git_get_project_owner($project);\n \n \tmy $refs = git_get_references();\n \tgit_header_html();\n-- \n1.4.1.1\n"},{"id":"25245","messageId":"200608140214.20450.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 6/9] gitweb: Change appereance of marker of refs pointing to given object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:14:20Z","receivedAt":"2006-08-14T00:14:20Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Change git_get_references to include type of ref in the %refs value, which\nmeans putting everything after 'refs/' as a ref name, not only last\npart of the name.  Instead of separating refs pointing to the same\nobject by \" / \" separator, use anonymous array reference to store all\nrefs pointing to given object.\n\nUse 'git-ls-remote .' if $projectroot/$project/info/refs does not\nexist.  (Perhaps it should be used always.)\n\nRefs are now in separate span elements.  Class is dependent on the ref\ntype: currently known classes are 'tag', 'head', 'remote', and 'ref'\n(last one for HEAD and other refs in the main directory).  There is\nencompassing span element of class refs, just in case of unknown ref\ntype.\n\nThis might be considered cleaner separating of git_get_references into\nfilling %refs hash only, and not taking part in formatting ref marker.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nAlternate solution to the one proposed by Thomas Kolejka in\n \"[PATCH] gitweb: Different colours for tags and heads\"\n  Message-Id: <20060811151224.177110@gmx.net>\n\nCSS and format_ref_marker is conservative: as of now it should not be\n\"ref\" (generic) type of references. \n\n gitweb/gitweb.css  |   19 +++++++++++++++++--\n gitweb/gitweb.perl |   37 ++++++++++++++++++++++++++++++-------\n 2 files changed, 47 insertions(+), 9 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex f58a418..21ce99c 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -326,15 +326,30 @@ a.rss_logo:hover {\n \tbackground-color: #ee5500;\n }\n \n-span.tag {\n+span.refs span {\n \tpadding: 0px 4px;\n \tfont-size: 10px;\n \tfont-weight: normal;\n-\tbackground-color: #ffffaa;\n \tborder: 1px solid;\n+\tbackground-color: #ffaaff;\n+\tborder-color: #ffccff #ff00ee #ff00ee #ffccff;\n+}\n+\n+span.refs span.ref {\n+\tbackground-color: #aaaaff;\n+\tborder-color: #ccccff #0033cc #0033cc #ccccff;\n+}\n+\n+span.refs span.tag {\n+\tbackground-color: #ffffaa;\n \tborder-color: #ffffcc #ffee00 #ffee00 #ffffcc;\n }\n \n+span.refs span.head {\n+\tbackground-color: #aaffaa;\n+\tborder-color: #ccffcc #00cc33 #00cc33 #ccffcc;\n+}\n+\n span.atnight {\n \tcolor: #cc0000;\n }\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 6be6c55..4fe3fc7 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -364,9 +364,26 @@ sub format_log_line_html {\n # format marker of refs pointing to given object\n sub format_ref_marker {\n \tmy ($refs, $id) = @_;\n+\tmy $markers = '';\n \n \tif (defined $refs->{$id}) {\n-\t\treturn ' <span class=\"tag\">' . esc_html($refs->{$id}) . '</span>';\n+\t\tforeach my $ref (@{$refs->{$id}}) {\n+\t\t\tmy ($type, $name) = qw();\n+\t\t\t# e.g. tags/v2.6.11 or heads/next\n+\t\t\tif ($ref =~ m!^(.*?)s?/(.*)$!) {\n+\t\t\t\t$type = $1;\n+\t\t\t\t$name = $2;\n+\t\t\t} else {\n+\t\t\t\t$type = \"ref\";\n+\t\t\t\t$name = $ref;\n+\t\t\t}\n+\n+\t\t\t$markers .= \" <span class=\\\"$type\\\">\" . esc_html($name) . \"</span>\";\n+\t\t}\n+\t}\n+\n+\tif ($markers) {\n+\t\treturn ' <span class=\"refs\">'. $markers . '</span>';\n \t} else {\n \t\treturn \"\";\n \t}\n@@ -561,18 +578,24 @@ sub git_get_project_owner {\n sub git_get_references {\n \tmy $type = shift || \"\";\n \tmy %refs;\n+\tmy $fd;\n \t# 5dc01c595e6c6ec9ccda4f6f69c131c0dd945f8c\trefs/tags/v2.6.11\n \t# c39ae07f393806ccf406ef966e9a15afc43cc36a\trefs/tags/v2.6.11^{}\n-\topen my $fd, \"$projectroot/$project/info/refs\" or return;\n+\tif (-f \"$projectroot/$project/info/refs\") {\n+\t\topen $fd, \"$projectroot/$project/info/refs\"\n+\t\t\tor return;\n+\t} else {\n+\t\topen $fd, \"-|\", $GIT, \"ls-remote\", \".\"\n+\t\t\tor return;\n+\t}\n+\n \twhile (my $line = <$fd>) {\n \t\tchomp $line;\n-\t\t# attention: for $type == \"\" it saves only last path part of ref name\n-\t\t# e.g. from 'refs/heads/jn/gitweb' it would leave only 'gitweb'\n-\t\tif ($line =~ m/^([0-9a-fA-F]{40})\\t.*$type\\/([^\\^]+)/) {\n+\t\tif ($line =~ m/^([0-9a-fA-F]{40})\\trefs\\/($type\\/?[^\\^]+)/) {\n \t\t\tif (defined $refs{$1}) {\n-\t\t\t\t$refs{$1} .= \" / $2\";\n+\t\t\t\tpush @{$refs{$1}}, $2;\n \t\t\t} else {\n-\t\t\t\t$refs{$1} = $2;\n+\t\t\t\t$refs{$1} = [ $2 ];\n \t\t\t}\n \t\t}\n \t}\n-- \n1.4.1.1\n"},{"id":"25242","messageId":"200608140215.22378.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 7/9] gitweb: Skip comments in mime.types like file","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:15:22Z","receivedAt":"2006-08-14T00:15:22Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Signed-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 4fe3fc7..52ae2aa 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -858,6 +858,7 @@ sub mimetype_guess_file {\n \tmy %mimemap;\n \topen(MIME, $mimemap) or return undef;\n \twhile (<MIME>) {\n+\t\tnext if m/^#/; # skip comments\n \t\tmy ($mime, $exts) = split(/\\t+/);\n \t\tif (defined $exts) {\n \t\t\tmy @exts = split(/\\s+/, $exts);\n-- \n1.4.1.1\n"},{"id":"25241","messageId":"200608140216.34150.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 8/9] gitweb: True fix: Support for the standard mime.types map in gitweb","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:16:33Z","receivedAt":"2006-08-14T00:16:33Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"True fix for error in mimetype_guess, error introduced in original commit\n2d00737489b8c61ed616b261c7c9bd314e2b0b41 and later fixed temporarily\nby commenting out the line that caused error in commit\n57bd4d3523efecf60197040cad34154aff4ddf80.\n\nGitweb now supports mime.types map $mimetypes_file relative to project.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nPerhaps commit message should consist only of:\n\ngitweb: Gitweb now supports mime.types map $mimetypes_file relative to project.\n\n gitweb/gitweb.perl |    5 ++++-\n 1 files changed, 4 insertions(+), 1 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 52ae2aa..15875a8 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -880,7 +880,10 @@ sub mimetype_guess {\n \n \tif ($mimetypes_file) {\n \t\tmy $file = $mimetypes_file;\n-\t\t#$file =~ m#^/# or $file = \"$projectroot/$path/$file\";\n+\t\tif ($file !~ m!^/!) { # if it is relative path\n+\t\t\t# it is relative to project\n+\t\t\t$file = \"$projectroot/$project/$file\";\n+\t\t}\n \t\t$mime = mimetype_guess_file($filename, $file);\n \t}\n \t$mime ||= mimetype_guess_file($filename, '/etc/mime.types');\n-- \n1.4.1.1\n"},{"id":"25238","messageId":"200608140218.33872.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"[PATCH 9/9] gitweb: Separate printing difftree in git_commit into git_difftree_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T00:18:33Z","receivedAt":"2006-08-14T00:18:33Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Separate printing difftree in git_commit into separate\ngit_difftree_body subroutine. Add support for \"C\" (copied) status. For\n\"M\" and \"C\" add parameter 'fp' (filename parent) to the \"diff\" link;\ncurrently not supported by git_blobdiff (\"blobdiff\" action).\n\nReindented, realigned, added comments.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.css  |    4 +\n gitweb/gitweb.perl |  237 +++++++++++++++++++++++++++++++---------------------\n 2 files changed, 146 insertions(+), 95 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 21ce99c..9013895 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -226,6 +226,10 @@ table.diff_tree span.file_status.mode_ch\n \tcolor: #777777;\n }\n \n+table.diff_tree span.file_status.copied {\n+  color: #70a070;\n+}\n+\n /* age2: 60*60*24*2 <= age */\n table.project_list td.age2, table.blame td.age2 {\n \tfont-style: italic;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 15875a8..ab28caa 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1136,6 +1136,145 @@ sub git_print_page_path {\n ## ......................................................................\n ## functions printing large fragments of HTML\n \n+sub git_difftree_body {\n+\tmy ($difftree, $parent) = @_;\n+\n+\tprint \"<div class=\\\"list_head\\\">\\n\";\n+\tif ($#{$difftree} > 10) {\n+\t\tprint(($#{$difftree} + 1) . \" files changed:\\n\");\n+\t}\n+\tprint \"</div>\\n\";\n+\n+\tprint \"<table class=\\\"diff_tree\\\">\\n\";\n+\tmy $alternate = 0;\n+\tforeach my $line (@{$difftree}) {\n+\t\t# ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M\tls-files.c'\n+\t\t# ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M\trev-tree.c'\n+\t\tif ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\\t(.*)$/) {\n+\t\t\tnext;\n+\t\t}\n+\t\tmy $from_mode = $1;\n+\t\tmy $to_mode = $2;\n+\t\tmy $from_id = $3;\n+\t\tmy $to_id = $4;\n+\t\tmy $status = $5;\n+\t\tmy $similarity = $6; # score\n+\t\tmy $file = validate_input(unquote($7));\n+\n+\t\tif ($alternate) {\n+\t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n+\t\t} else {\n+\t\t\tprint \"<tr class=\\\"light\\\">\\n\";\n+\t\t}\n+\t\t$alternate ^= 1;\n+\n+\t\tif ($status eq \"A\") { # created\n+\t\t\tmy $mode_chng = \"\";\n+\t\t\tif (S_ISREG(oct $to_mode)) {\n+\t\t\t\t$mode_chng = sprintf(\" with mode: %04o\", (oct $to_mode) & 0777);\n+\t\t\t}\n+\t\t\tprint \"<td>\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\"),\n+\t\t\t              -class => \"list\"}, esc_html($file)) .\n+\t\t\t      \"</td>\\n\" .\n+\t\t\t      \"<td><span class=\\\"file_status new\\\">[new \" . file_type($to_mode) . \"$mode_chng]</span></td>\\n\" .\n+\t\t\t      \"<td class=\\\"link\\\">\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\")}, \"blob\") .\n+\t\t\t      \"</td>\\n\";\n+\n+\t\t} elsif ($status eq \"D\") { # deleted\n+\t\t\tprint \"<td>\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$from_id;hb=$parent;f=$file\"),\n+\t\t\t               -class => \"list\"}, esc_html($file)) . \"</td>\\n\" .\n+\t\t\t      \"<td><span class=\\\"file_status deleted\\\">[deleted \" . file_type($from_mode). \"]</span></td>\\n\" .\n+\t\t\t      \"<td class=\\\"link\\\">\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$from_id;hb=$parent;f=$file\")}, \"blob\") . \" | \" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=history;hb=$parent;f=$file\")}, \"history\") .\n+\t\t\t      \"</td>\\n\"\n+\n+\t\t} elsif ($status eq \"M\" || $status eq \"T\") { # modified, or type changed\n+\t\t\tmy $mode_chnge = \"\";\n+\t\t\tif ($from_mode != $to_mode) {\n+\t\t\t\t$mode_chnge = \" <span class=\\\"file_status mode_chnge\\\">[changed\";\n+\t\t\t\tif (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) {\n+\t\t\t\t\t$mode_chnge .= \" from \" . file_type($from_mode) . \" to \" . file_type($to_mode);\n+\t\t\t\t}\n+\t\t\t\tif (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) {\n+\t\t\t\t\tif (S_ISREG($from_mode) && S_ISREG($to_mode)) {\n+\t\t\t\t\t\t$mode_chnge .= sprintf(\" mode: %04o->%04o\", (oct $from_mode) & 0777, (oct $to_mode) & 0777);\n+\t\t\t\t\t} elsif (S_ISREG($to_mode)) {\n+\t\t\t\t\t\t$mode_chnge .= sprintf(\" mode: %04o\", (oct $to_mode) & 0777);\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\t$mode_chnge .= \"]</span>\\n\";\n+\t\t\t}\n+\t\t\tprint \"<td>\";\n+\t\t\tif ($to_id ne $from_id) { # modified\n+\t\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file\"),\n+\t\t\t\t              -class => \"list\"}, esc_html($file));\n+\t\t\t} else { # mode changed\n+\t\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\"),\n+\t\t\t\t              -class => \"list\"}, esc_html($file));\n+\t\t\t}\n+\t\t\tprint \"</td>\\n\" .\n+\t\t\t      \"<td>$mode_chnge</td>\\n\" .\n+\t\t\t      \"<td class=\\\"link\\\">\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\")}, \"blob\");\n+\t\t\tif ($to_id ne $from_id) { # modified\n+\t\t\t\tprint \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file\")}, \"diff\");\n+\t\t\t}\n+\t\t\tprint \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=history;hb=$hash;f=$file\")}, \"history\") . \"\\n\";\n+\t\t\tprint \"</td>\\n\";\n+\n+\t\t} elsif ($status eq \"R\") { # renamed\n+\t\t\tmy ($from_file, $to_file) = split \"\\t\", $file;\n+\t\t\tmy $mode_chng = \"\";\n+\t\t\tif ($from_mode != $to_mode) {\n+\t\t\t\t$mode_chng = sprintf(\", mode: %04o\", (oct $to_mode) & 0777);\n+\t\t\t}\n+\t\t\tprint \"<td>\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file\"),\n+\t\t\t              -class => \"list\"}, esc_html($to_file)) . \"</td>\\n\" .\n+\t\t\t      \"<td><span class=\\\"file_status moved\\\">[moved from \" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file\"),\n+\t\t\t              -class => \"list\"}, esc_html($from_file)) .\n+\t\t\t      \" with \" . (int $similarity) . \"% similarity$mode_chng]</span></td>\\n\" .\n+\t\t\t      \"<td class=\\\"link\\\">\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file\")}, \"blob\");\n+\t\t\tif ($to_id ne $from_id) {\n+\t\t\t\tprint \" | \" .\n+\t\t\t\t      $cgi->a({-href => \"$my_uri?\" .\n+\t\t\t\t              esc_param(\"p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file;fp=$from_file\")}, \"diff\");\n+\t\t\t}\n+\t\t\tprint \"</td>\\n\";\n+\n+\t\t} elsif ($status eq \"C\") { # copied\n+\t\t\tmy ($from_file, $to_file) = split \"\\t\", $file;\n+\t\t\tmy $mode_chng = \"\";\n+\t\t\tif ($from_mode != $to_mode) {\n+\t\t\t\t$mode_chng = sprintf(\", mode: %04o\", (oct $to_mode) & 0777);\n+\t\t\t}\n+\t\t\tprint \"<td>\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file\"),\n+\t\t\t              -class => \"list\"}, esc_html($to_file)) . \"</td>\\n\" .\n+\t\t\t      \"<td><span class=\\\"file_status copied\\\">[copied from \" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file\"),\n+\t\t\t              -class => \"list\"}, esc_html($from_file)) .\n+\t\t\t      \" with \" . (int $similarity) . \"% similarity$mode_chng]</span></td>\\n\" .\n+\t\t\t      \"<td class=\\\"link\\\">\" .\n+\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file\")}, \"blob\");\n+\t\t\tif ($to_id ne $from_id) {\n+\t\t\t\tprint \" | \" .\n+\t\t\t\t      $cgi->a({-href => \"$my_uri?\" .\n+\t\t\t\t              esc_param(\"p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file;fp=$from_file\")}, \"diff\");\n+\t\t\t}\n+\t\t\tprint \"</td>\\n\";\n+\t\t} # we should not encounter Unmerged (U) or Unknown (X) status\n+\t\tprint \"</tr>\\n\";\n+\t}\n+\tprint \"</table>\\n\";\n+}\n+\n sub git_shortlog_body {\n \t# uses global variable $project\n \tmy ($revlist, $from, $to, $refs, $extra) = @_;\n@@ -2089,101 +2228,9 @@ sub git_commit {\n \t\t}\n \t}\n \tprint \"</div>\\n\";\n-\tprint \"<div class=\\\"list_head\\\">\\n\";\n-\tif ($#difftree > 10) {\n-\t\tprint(($#difftree + 1) . \" files changed:\\n\");\n-\t}\n-\tprint \"</div>\\n\";\n-\tprint \"<table class=\\\"diff_tree\\\">\\n\";\n-\tmy $alternate = 0;\n-\tforeach my $line (@difftree) {\n-\t\t# ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M      ls-files.c'\n-\t\t# ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M      rev-tree.c'\n-\t\tif ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\\t(.*)$/) {\n-\t\t\tnext;\n-\t\t}\n-\t\tmy $from_mode = $1;\n-\t\tmy $to_mode = $2;\n-\t\tmy $from_id = $3;\n-\t\tmy $to_id = $4;\n-\t\tmy $status = $5;\n-\t\tmy $similarity = $6;\n-\t\tmy $file = validate_input(unquote($7));\n-\t\tif ($alternate) {\n-\t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n-\t\t} else {\n-\t\t\tprint \"<tr class=\\\"light\\\">\\n\";\n-\t\t}\n-\t\t$alternate ^= 1;\n-\t\tif ($status eq \"A\") {\n-\t\t\tmy $mode_chng = \"\";\n-\t\t\tif (S_ISREG(oct $to_mode)) {\n-\t\t\t\t$mode_chng = sprintf(\" with mode: %04o\", (oct $to_mode) & 0777);\n-\t\t\t}\n-\t\t\tprint \"<td>\" .\n-\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\"), -class => \"list\"}, esc_html($file)) . \"</td>\\n\" .\n-\t\t\t      \"<td><span class=\\\"file_status new\\\">[new \" . file_type($to_mode) . \"$mode_chng]</span></td>\\n\" .\n-\t\t\t      \"<td class=\\\"link\\\">\" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\")}, \"blob\") . \"</td>\\n\";\n-\t\t} elsif ($status eq \"D\") {\n-\t\t\tprint \"<td>\" .\n-\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$from_id;hb=$parent;f=$file\"), -class => \"list\"}, esc_html($file)) . \"</td>\\n\" .\n-\t\t\t      \"<td><span class=\\\"file_status deleted\\\">[deleted \" . file_type($from_mode). \"]</span></td>\\n\" .\n-\t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$from_id;hb=$parent;f=$file\")}, \"blob\") .\n-\t\t\t      \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=history;hb=$parent;f=$file\")}, \"history\") .\n-\t\t\t      \"</td>\\n\"\n-\t\t} elsif ($status eq \"M\" || $status eq \"T\") {\n-\t\t\tmy $mode_chnge = \"\";\n-\t\t\tif ($from_mode != $to_mode) {\n-\t\t\t\t$mode_chnge = \" <span class=\\\"file_status mode_chnge\\\">[changed\";\n-\t\t\t\tif (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) {\n-\t\t\t\t\t$mode_chnge .= \" from \" . file_type($from_mode) . \" to \" . file_type($to_mode);\n-\t\t\t\t}\n-\t\t\t\tif (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) {\n-\t\t\t\t\tif (S_ISREG($from_mode) && S_ISREG($to_mode)) {\n-\t\t\t\t\t\t$mode_chnge .= sprintf(\" mode: %04o->%04o\", (oct $from_mode) & 0777, (oct $to_mode) & 0777);\n-\t\t\t\t\t} elsif (S_ISREG($to_mode)) {\n-\t\t\t\t\t\t$mode_chnge .= sprintf(\" mode: %04o\", (oct $to_mode) & 0777);\n-\t\t\t\t\t}\n-\t\t\t\t}\n-\t\t\t\t$mode_chnge .= \"]</span>\\n\";\n-\t\t\t}\n-\t\t\tprint \"<td>\";\n-\t\t\tif ($to_id ne $from_id) {\n-\t\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file\"), -class => \"list\"}, esc_html($file));\n-\t\t\t} else {\n-\t\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\"), -class => \"list\"}, esc_html($file));\n-\t\t\t}\n-\t\t\tprint \"</td>\\n\" .\n-\t\t\t      \"<td>$mode_chnge</td>\\n\" .\n-\t\t\t      \"<td class=\\\"link\\\">\";\n-\t\t\tprint $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$file\")}, \"blob\");\n-\t\t\tif ($to_id ne $from_id) {\n-\t\t\t\tprint \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$file\")}, \"diff\");\n-\t\t\t}\n-\t\t\tprint \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=history;hb=$hash;f=$file\")}, \"history\") . \"\\n\";\n-\t\t\tprint \"</td>\\n\";\n-\t\t} elsif ($status eq \"R\") {\n-\t\t\tmy ($from_file, $to_file) = split \"\\t\", $file;\n-\t\t\tmy $mode_chng = \"\";\n-\t\t\tif ($from_mode != $to_mode) {\n-\t\t\t\t$mode_chng = sprintf(\", mode: %04o\", (oct $to_mode) & 0777);\n-\t\t\t}\n-\t\t\tprint \"<td>\" .\n-\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file\"), -class => \"list\"}, esc_html($to_file)) . \"</td>\\n\" .\n-\t\t\t      \"<td><span class=\\\"file_status moved\\\">[moved from \" .\n-\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$from_id;hb=$parent;f=$from_file\"), -class => \"list\"}, esc_html($from_file)) .\n-\t\t\t      \" with \" . (int $similarity) . \"% similarity$mode_chng]</span></td>\\n\" .\n-\t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t      $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blob;h=$to_id;hb=$hash;f=$to_file\")}, \"blob\");\n-\t\t\tif ($to_id ne $from_id) {\n-\t\t\t\tprint \" | \" . $cgi->a({-href => \"$my_uri?\" . esc_param(\"p=$project;a=blobdiff;h=$to_id;hp=$from_id;hb=$hash;f=$to_file\")}, \"diff\");\n-\t\t\t}\n-\t\t\tprint \"</td>\\n\";\n-\t\t}\n-\t\tprint \"</tr>\\n\";\n-\t}\n-\tprint \"</table>\\n\";\n+\n+\tgit_difftree_body(\\@difftree, $parent);\n+\n \tgit_footer_html();\n }\n \n-- \n1.4.1.1\n"},{"id":"25243","messageId":"200608141130.04148.jnareb@gmail.com","threadId":"5242","inReplyTo":"200608140214.20450.jnareb@gmail.com","subject":"Re: [PATCH 6/9] gitweb: Change appereance of marker of refs pointing to given object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T09:30:03Z","receivedAt":"2006-08-14T09:30:03Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jakub Narebski wrote:\n> Change git_get_references to include type of ref in the %refs value, which\n> means putting everything after 'refs/' as a ref name, not only last\n> part of the name.  Instead of separating refs pointing to the same\n> object by \" / \" separator, use anonymous array reference to store all\n> refs pointing to given object.\n\nEarlier version of the patch used ':' (instead of ' / ') to concatenate\nmultiple refs pointing to the same object, then split on ':'. Character\n':' was used because it cannot be part of valid ref name (as of\ngit-check-ref-name).\n\nNote that usually there is at most one ref pointing to given object;\nmultiple refs are quite rare (usually when starting new branch, or just\ntagged a branch).\n\n-- \nJakub Narebski\nPoland\n"},{"id":"25247","messageId":"ebpjt8$5ao$1@sea.gmane.org","threadId":"5242","inReplyTo":"200608140202.46160.jnareb@gmail.com","subject":"Re: [PATCH 0/9] gitweb: Great subroutine renaming + task separation into subroutines + improvements","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-14T10:40:20Z","receivedAt":"2006-08-14T10:40:20Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jakub Narebski wrote:\n\n> This series of patches is based on the 'next' branch, commit\n> 10a6653c818f78c6032d45e1d4da544085e1f28b (v1.4.2-g10a6653)\n\nBut it rebases without problem on top of current master\n  460cccd3ba1d38fd64c9e83e40d58bcf3e9d7d2c (v1.4.2-g460cccd)\n('git rebase --onto master next' rebases without errors)\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25323","messageId":"7v8xlqdhis.fsf@assigned-by-dhcp.cox.net","threadId":"5242","inReplyTo":"200608140205.47380.jnareb@gmail.com","subject":"Re: [PATCH 1/9] gitweb: Great subroutines renaming","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-14T23:28:11Z","receivedAt":"2006-08-14T23:28:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> I'm not sure if to add script used to create this commit, and to\n> port changes to be \"post-rename\". Here it is:\n>\n> #!/bin/bash\n> if test -z \"$1\"; then\n> \tFILE=`git rev-parse --show-cdup`gitweb/gitweb.perl\n> else\n> \tFILE=$1\n> fi\n> echo \"Great subroutine renaming: $FILE\"\n> perl -s -p -i.re~ \\\n> \t-e 's/\\bgit_get_referencing\\b/format_ref_marker/;' \\\n\nWill apply, but I suspect all of these need g at the end as in\n\"s/foo/bar/g;\".\n"},{"id":"25326","messageId":"7vy7tqc06u.fsf@assigned-by-dhcp.cox.net","threadId":"5242","inReplyTo":"200608140214.20450.jnareb@gmail.com","subject":"Re: [PATCH 6/9] gitweb: Change appereance of marker of refs pointing to given object","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T00:27:53Z","receivedAt":"2006-08-15T00:27:53Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> Change git_get_references to include type of ref in the %refs value, which\n> means putting everything after 'refs/' as a ref name, not only last\n> part of the name.  Instead of separating refs pointing to the same\n> object by \" / \" separator, use anonymous array reference to store all\n> refs pointing to given object.\n>\n> Use 'git-ls-remote .' if $projectroot/$project/info/refs does not\n> exist.  (Perhaps it should be used always.)\n>\n> Refs are now in separate span elements.  Class is dependent on the ref\n> type: currently known classes are 'tag', 'head', 'remote', and 'ref'\n> (last one for HEAD and other refs in the main directory).  There is\n> encompassing span element of class refs, just in case of unknown ref\n> type.\n\nI do not see definition that matches \"span.refs span.remote\" in\nthe CSS, though.\n\n> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\n> index 6be6c55..4fe3fc7 100755\n> --- a/gitweb/gitweb.perl\n> +++ b/gitweb/gitweb.perl\n> @@ -364,9 +364,26 @@ sub format_log_line_html {\n>  # format marker of refs pointing to given object\n>  sub format_ref_marker {\n>  \tmy ($refs, $id) = @_;\n> +\tmy $markers = '';\n>  \n>  \tif (defined $refs->{$id}) {\n> -\t\treturn ' <span class=\"tag\">' . esc_html($refs->{$id}) . '</span>';\n> +\t\tforeach my $ref (@{$refs->{$id}}) {\n> +\t\t\tmy ($type, $name) = qw();\n\nJust () -- qw() is not needed.\n\n> +\t\t\t# e.g. tags/v2.6.11 or heads/next\n> +\t\t\tif ($ref =~ m!^(.*?)s?/(.*)$!) {\n> +\t\t\t\t$type = $1;\n> +\t\t\t\t$name = $2;\n> +\t\t\t} else {\n> +\t\t\t\t$type = \"ref\";\n> +\t\t\t\t$name = $ref;\n> +\t\t\t}\n\nHmph.  Maybe have a hash that defines the ones you know how to\nhandle, and do something like:\n\n        if ($ref =~ m|^([^/]+)/(.*)$| &&  exists $i_know_this_class{$1}) {\n        \t$type = $1;\n                $name = $2;\n\t}\n        else {\n        \t$type = 'ref';\n                $name = $ref;\n\t}\n\n> @@ -561,18 +578,24 @@ sub git_get_project_owner {\n>...\n> +\t\tif ($line =~ m/^([0-9a-fA-F]{40})\\trefs\\/($type\\/?[^\\^]+)/) {\n>  \t\t\tif (defined $refs{$1}) {\n> -\t\t\t\t$refs{$1} .= \" / $2\";\n> +\t\t\t\tpush @{$refs{$1}}, $2;\n>  \t\t\t} else {\n> -\t\t\t\t$refs{$1} = $2;\n> +\t\t\t\t$refs{$1} = [ $2 ];\n>  \t\t\t}\n>  \t\t}\n\nIt would work as in your patch, but I would have preferred to\nsee \"exists $refs{$1}\" there instead of \"defined\".\n\nOr lose the if() and do it like this, which would be cleaner?\n\n\tif ($line =~ ...) {\n        \tpush @{$refs{$1}}, $2;\n\t}\n"},{"id":"25327","messageId":"7vu04ec04b.fsf@assigned-by-dhcp.cox.net","threadId":"5242","inReplyTo":"200608140207.01108.jnareb@gmail.com","subject":"Re: [PATCH 2/9] gitweb: Separate ref parsing in git_get_refs_list into parse_ref","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T00:29:24Z","receivedAt":"2006-08-15T00:29:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> Note that for each ref there are usually two calls to git subroutines:\n> first to get the type of ref, second to parse ref if ref is of commit\n> or tag type.\n>\n> Signed-off-by: Jakub Narebski <jnareb@gmail.com>\n> ---\n>  gitweb/gitweb.perl |   80 +++++++++++++++++++++++++++++-----------------------\n>  1 files changed, 45 insertions(+), 35 deletions(-)\n>\n> diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\n> index 28df59e..0c4ec92 100755\n> --- a/gitweb/gitweb.perl\n> +++ b/gitweb/gitweb.perl\n> @@ -690,6 +690,49 @@ sub parse_commit {\n>  \treturn %co;\n>  }\n>  \n> +# parse ref from ref_file, given by ref_id, with given type\n> +sub parse_ref {\n> +\tmy $ref_file = shift;\n> +\tmy $ref_id = shift;\n> +\tmy $type = shift || git_get_type($ref_id);\n\nThis git_get_type() is additional from the original.\nFuture-proofing yourself for other new callers?\n"},{"id":"25328","messageId":"7vpsf2c03t.fsf@assigned-by-dhcp.cox.net","threadId":"5242","inReplyTo":"200608140208.27246.jnareb@gmail.com","subject":"Re: [PATCH 3/9] gitweb: Refactor printing shortened title in git_shortlog_body and git_tags_body","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T00:29:42Z","receivedAt":"2006-08-15T00:29:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Beautiful.\n"},{"id":"25329","messageId":"7vlkpqbzxx.fsf@assigned-by-dhcp.cox.net","threadId":"5242","inReplyTo":"200608140216.34150.jnareb@gmail.com","subject":"Re: [PATCH 8/9] gitweb: True fix: Support for the standard mime.types map in gitweb","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T00:33:14Z","receivedAt":"2006-08-15T00:33:14Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> True fix for error in mimetype_guess, error introduced in original commit\n> 2d00737489b8c61ed616b261c7c9bd314e2b0b41 and later fixed temporarily\n> by commenting out the line that caused error in commit\n> 57bd4d3523efecf60197040cad34154aff4ddf80.\n>\n> Gitweb now supports mime.types map $mimetypes_file relative to project.\n\nCare to explain what that commenting out was about?\n\n>  \tif ($mimetypes_file) {\n>  \t\tmy $file = $mimetypes_file;\n> -\t\t#$file =~ m#^/# or $file = \"$projectroot/$path/$file\";\n> +\t\tif ($file !~ m!^/!) { # if it is relative path\n> +\t\t\t# it is relative to project\n> +\t\t\t$file = \"$projectroot/$project/$file\";\n> +\t\t}\n>  \t\t$mime = mimetype_guess_file($filename, $file);\n\nAre $project and $file always defined when we take this new\ncodepath?\n"},{"id":"25330","messageId":"7vfyfybzlf.fsf@assigned-by-dhcp.cox.net","threadId":"5242","inReplyTo":"200608140218.33872.jnareb@gmail.com","subject":"Re: [PATCH 9/9] gitweb: Separate printing difftree in git_commit into git_difftree_body","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T00:40:44Z","receivedAt":"2006-08-15T00:40:44Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> +\t\tif ($status eq \"A\") { # created\n>...\n> +\t\t} elsif ($status eq \"D\") { # deleted\n>...\n> +\t\t} elsif ($status eq \"M\" || $status eq \"T\") { # modified, or type changed\n>...\n> +\t\t} elsif ($status eq \"R\") { # renamed\n>...\n> +\t\t} elsif ($status eq \"C\") { # copied\n>...\n> +\t\t} # we should not encounter Unmerged (U) or Unknown (X) status\n\nThe body of these still seem to have quite a lot of\nsimilarities.  Maybe further refactoring is in the works?\n"},{"id":"25331","messageId":"7vbqqmbzj1.fsf@assigned-by-dhcp.cox.net","threadId":"5242","inReplyTo":"ebpjt8$5ao$1@sea.gmane.org","subject":"Re: [PATCH 0/9] gitweb: Great subroutine renaming + task separation into subroutines + improvements","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-15T00:42:10Z","receivedAt":"2006-08-15T00:42:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jakub Narebski <jnareb@gmail.com> writes:\n\n> Jakub Narebski wrote:\n>\n>> This series of patches is based on the 'next' branch, commit\n>> 10a6653c818f78c6032d45e1d4da544085e1f28b (v1.4.2-g10a6653)\n>\n> But it rebases without problem on top of current master\n>   460cccd3ba1d38fd64c9e83e40d58bcf3e9d7d2c (v1.4.2-g460cccd)\n> ('git rebase --onto master next' rebases without errors)\n\nI sent a few comments, some suggesting further improvements and\nothers expressing my puzzlement, but I'll be applying all of\nthem, so please base your further work on all of the 9 series.\n"},{"id":"25361","messageId":"ebss3h$tgq$2@sea.gmane.org","threadId":"5242","inReplyTo":"7vu04ec04b.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 2/9] gitweb: Separate ref parsing in git_get_refs_list into parse_ref","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-15T16:18:43Z","receivedAt":"2006-08-15T16:18:43Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n>> Note that for each ref there are usually two calls to git subroutines:\n>> first to get the type of ref, second to parse ref if ref is of commit\n>> or tag type.\n\n[...]  \n>> +# parse ref from ref_file, given by ref_id, with given type\n>> +sub parse_ref {\n>> +    my $ref_file = shift;\n>> +    my $ref_id = shift;\n>> +    my $type = shift || git_get_type($ref_id);\n> \n> This git_get_type() is additional from the original.\n> Future-proofing yourself for other new callers?\n\nYes, just in case.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25363","messageId":"ebst0v$3gt$1@sea.gmane.org","threadId":"5242","inReplyTo":"7vy7tqc06u.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 6/9] gitweb: Change appereance of marker of refs pointing to given object","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-15T16:34:17Z","receivedAt":"2006-08-15T16:34:17Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n>> Change git_get_references to include type of ref in the %refs value, which\n>> means putting everything after 'refs/' as a ref name, not only last\n>> part of the name.  Instead of separating refs pointing to the same\n>> object by \" / \" separator, use anonymous array reference to store all\n>> refs pointing to given object.\n>>\n>> Use 'git-ls-remote .' if $projectroot/$project/info/refs does not\n>> exist.  (Perhaps it should be used always.)\n>>\n>> Refs are now in separate span elements.  Class is dependent on the ref\n>> type: currently known classes are 'tag', 'head', 'remote', and 'ref'\n>> (last one for HEAD and other refs in the main directory).  There is\n>> encompassing span element of class refs, just in case of unknown ref\n>> type.\n> \n> I do not see definition that matches \"span.refs span.remote\" in\n> the CSS, though.\n\nIt get's default style \"span.refs span\" (and fefault colors).\n\n>> +                    # e.g. tags/v2.6.11 or heads/next\n>> +                    if ($ref =~ m!^(.*?)s?/(.*)$!) {\n>> +                            $type = $1;\n>> +                            $name = $2;\n>> +                    } else {\n>> +                            $type = \"ref\";\n>> +                            $name = $ref;\n>> +                    }\n> \n> Hmph.  Maybe have a hash that defines the ones you know how to\n> handle, and do something like:\n> \n>         if ($ref =~ m|^([^/]+)/(.*)$| &&  exists $i_know_this_class{$1}) {\n>               $type = $1;\n>               $name = $2;\n>       }\n>         else {\n>               $type = 'ref';\n>               $name = $ref;\n>       }\n\nBut what types are known is defined in CSS, not in gitweb.perl. The rule\nis that type is defined by first component of the ref name, in singular form\n(so with optional final s removed, refs -> ref, tags -> tag, remotes -> remote).\nAll unknown types get default \"span.refs span\" format, thanks to encompassing\nspan element.\n\n\"ref\" class is for refs directly in $GIT_DIR, like HEAD or ORIG_HEAD (as of now\nyou cannot get such a ref due to the regexp used in git_get_references, and\nthe fact that you have no such refs in $GIT_DIR/info/refs file, and \n'git-ls-remote .' gives only HEAD; but we could add them 'by hand').\n\n>> @@ -561,18 +578,24 @@ sub git_get_project_owner {\n>>...\n>> +            if ($line =~ m/^([0-9a-fA-F]{40})\\trefs\\/($type\\/?[^\\^]+)/) {\n>>                      if (defined $refs{$1}) {\n>> -                            $refs{$1} .= \" / $2\";\n>> +                            push @{$refs{$1}}, $2;\n>>                      } else {\n>> -                            $refs{$1} = $2;\n>> +                            $refs{$1} = [ $2 ];\n>>                      }\n>>              }\n> \n> It would work as in your patch, but I would have preferred to\n> see \"exists $refs{$1}\" there instead of \"defined\".\n> \n> Or lose the if() and do it like this, which would be cleaner?\n> \n>       if ($line =~ ...) {\n>               push @{$refs{$1}}, $2;\n>       }\n\nThat's even better.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25364","messageId":"ebsthv$3gt$2@sea.gmane.org","threadId":"5242","inReplyTo":"7vlkpqbzxx.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 8/9] gitweb: True fix: Support for the standard mime.types map in gitweb","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-15T16:43:29Z","receivedAt":"2006-08-15T16:43:29Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n>> True fix for error in mimetype_guess, error introduced in original commit\n>> 2d00737489b8c61ed616b261c7c9bd314e2b0b41 and later fixed temporarily\n>> by commenting out the line that caused error in commit\n>> 57bd4d3523efecf60197040cad34154aff4ddf80.\n>>\n>> Gitweb now supports mime.types map $mimetypes_file relative to project.\n> \n> Care to explain what that commenting out was about?\n> \n>>      if ($mimetypes_file) {\n>>              my $file = $mimetypes_file;\n>> -            #$file =~ m#^/# or $file = \"$projectroot/$path/$file\";\n>> +            if ($file !~ m!^/!) { # if it is relative path\n>> +                    # it is relative to project\n>> +                    $file = \"$projectroot/$project/$file\";\n>> +            }\n>>              $mime = mimetype_guess_file($filename, $file);\n> \n> Are $project and $file always defined when we take this new\n> codepath?\n \n$project is defined always in the \"input validation and dispatch\" part.\n\n\"my $file = $mimetypes_file;\", and only if $mimetypes_file is true\n(so it must be defined). $mimetypes_file is undef by default, and it\nis one of the configuration variables which are not set from Makefile\nin \"make gitweb/gitweb.cgi\".\n\n$path was never defined; I guess that was copy'n'paste error, copying\nfrom other subroutine that used $path as one of arguments.\n\n\nI don't know why I didn't fix this error correctly, only patched it up\nthe first time...\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25365","messageId":"ebstls$3gt$3@sea.gmane.org","threadId":"5242","inReplyTo":"7vfyfybzlf.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 9/9] gitweb: Separate printing difftree in git_commit into git_difftree_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-15T16:45:35Z","receivedAt":"2006-08-15T16:45:35Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n>> +            if ($status eq \"A\") { # created\n>>...\n>> +            } elsif ($status eq \"D\") { # deleted\n>>...\n>> +            } elsif ($status eq \"M\" || $status eq \"T\") { # modified, or type changed\n>>...\n>> +            } elsif ($status eq \"R\") { # renamed\n>>...\n>> +            } elsif ($status eq \"C\") { # copied\n>>...\n>> +            } # we should not encounter Unmerged (U) or Unknown (X) status\n> \n> The body of these still seem to have quite a lot of\n> similarities.  Maybe further refactoring is in the works?\n\nProbably. For now I only separated the difftree printing part into separate \nsubroutine, and added $status eq \"C\" case (I don't know if we might encounter\nit at all, due to current set of options to diff-tree).\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"}]}