{"thread":{"id":"5369","subject":"[PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","startedAt":"2006-08-23T22:15:14Z","lastAt":"2006-08-27T15:37:29Z","messageCount":53,"participants":["Jakub Narebski","Junio C Hamano","Marco Costalba","Josef Weidendorfer","Shawn Pearce","Linus Torvalds","David Miller"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"25819","messageId":"200608240015.15071.jnareb@gmail.com","threadId":"5369","inReplyTo":null,"subject":"[PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-23T22:15:14Z","receivedAt":"2006-08-23T22:15:14Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"As the subject indicates (RFC), I'd like some comments on that patch.\n\n\nThis patch is the first patch in series which tries to remove external\ndiff dependency in gitweb, and the need for temporary files.\n\nConverting \"blobdiff\" and \"blobdiff_plain\" format would be much easier\nif git-diff-tree and friends had -L <label>/--label=<label> option,\nlike GNU diff has.\n\nCurrent patch preserves much of current output; the question is if for\nexample generate if 'plain' format should generate patch which could\nbe appplied by ordinary patch which do not understand git diff\nextensions (including renaming and copying), as it is done in current\nversion, and if 'html' version should detect renames and copying.\n\nAnother question is if to have (as it is currently done) 'html' and\n'plain' format generated by one subroutine, even though they don't\nshare that much code, and how to divide this code (currently invoking\ngit-commit-diff is in one part, generating header and commit message\nis in second part, generating patch/patchset is in third part).\n\n\nFurther patches are planned, including getting rid of\ngit_commitdiff_plain, changing format_diff_line to include incomplete\nlines in output, and converting git_blobdiff and git_blobdiff_plain to\nuse git-diff-tree.\n\nThis patch is based on 'next' (fbf19dd41bb51d5221fac739c5bdb48fd9012412)\n\n\nP.S. Perhaps the below separator should be made standard and\nrecognized by git tools?\n \n-- >8 --\nGet rid of git_diff_print invocation in git_commitdiff and therefore\nexternal diff (/usr/bin/diff) invocation, and use only git-diff-tree\nto generate patch.\n\ngit_commitdiff and git_commitdiff_plain are collapsed into one\nsubroutine git_commitdiff, with format (currently 'html' which is\ndefault format corresponding to git_commitdiff, and 'plain'\ncorresponding to git_commitdiff_plain) specified in argument.\n\nSeparate patch (diff) pretty-printing into git_patchset_body.\nIt is used in git_commitdiff.\n\nSeparate patch (diff) line formatting from git_diff_print into\nformat_diff_line function. It is used in git_patchset_body.\n\nWhile at it, add $hash parameter to git_difftree_body, according to\nrule that inner functions should use parameter passing, and not global\nvariables.\n\nCHANGES TO OUTPUT:\n * \"commitdiff\" now products patches with renaming and copying\n   detection (git-diff-tree is invoked with -M and -C options).\n   Empty patches (mode changes and pure renames and copying)\n   are not written currently. Former version broke renaming and\n   copying, and didn't notice mode changes, like this version.\n\n * \"commitdiff\" output is now divided into several div elements\n   of class \"log\", \"patchset\" and \"patch\".\n\n * \"commitdiff_plain\" now only generates X-Git-Tag: line only if there\n   is tag pointing to the current commit. Former version which wrote\n   first tag following current commit was broken[*1*]; besides we are\n   interested rather in tags _preceding_ the commit, and _heads_\n   following the commit. X-Git-Url: now is current URL; former version\n   tried[*2*] to output URL to HTML version of commitdiff.\n\n * \"commitdiff_plain\" is generated by git-diff-tree, and has therefore\n   has git specific extensions to diff format: \"git diff\" header and\n   optional extended header lines.\n\nFOOTNOTES\n[*1*] First it generated rev-list starting from HEAD even if hash_base\nparameter was set, second it wasn't corrected according to changes\nmade in git_get_references (formerly read_info_ref) output, third even\nfor older version of read_info_ref output it didn't work for multiple\ntags pointing to the current commit (rare).\n\n[*2*] It wrote URL for commitdiff without hash_parent, which produces\ndiff to first parent and is not the same as current diff if it is diff\nof merge commit to non-first parent.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |  323 ++++++++++++++++++++++++++++++++--------------------\n 1 files changed, 201 insertions(+), 122 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 50083e3..9367685 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -524,6 +524,27 @@ sub format_subject_html {\n \t}\n }\n \n+sub format_diff_line {\n+\tmy $line = shift;\n+\tmy $char = substr($line, 0, 1);\n+\tmy $diff_class = \"\";\n+\n+\tchomp $line;\n+\n+\tif ($char eq '+') {\n+\t\t$diff_class = \" add\";\n+\t} elsif ($char eq \"-\") {\n+\t\t$diff_class = \" rem\";\n+\t} elsif ($char eq \"@\") {\n+\t\t$diff_class = \" chunk_header\";\n+\t} elsif ($char eq \"\\\\\") {\n+\t\t# skip errors (incomplete lines)\n+\t\treturn \"\";\n+\t}\n+\t$line = untabify($line);\n+\treturn \"<div class=\\\"diff$diff_class\\\">\" . esc_html($line) . \"</div>\\n\";\n+}\n+\n ## ----------------------------------------------------------------------\n ## git utility subroutines, invoking git commands\n \n@@ -1367,7 +1388,7 @@ ## .....................................\n ## functions printing large fragments of HTML\n \n sub git_difftree_body {\n-\tmy ($difftree, $parent) = @_;\n+\tmy ($difftree, $hash, $parent) = @_;\n \n \tprint \"<div class=\\\"list_head\\\">\\n\";\n \tif ($#{$difftree} > 10) {\n@@ -1518,6 +1539,101 @@ sub git_difftree_body {\n \tprint \"</table>\\n\";\n }\n \n+sub git_patchset_body {\n+\tmy ($patchset, $difftree, $hash, $hash_parent) = @_;\n+\n+\tmy $patch_idx = 0;\n+\tmy $in_header = 0;\n+\tmy $patch_found = 0;\n+\tmy %diffinfo;\n+\n+\tprint \"<div class=\\\"patchset\\\">\\n\";\n+\n+\tLINE: foreach my $patch_line (@$patchset) {\n+\n+\t\tif ($patch_line =~ m/^diff /) { # \"git diff\" header\n+\t\t\t# beginning of patch (in patchset)\n+\t\t\tif ($patch_found) {\n+\t\t\t\t# close previous patch\n+\t\t\t\tprint \"</div>\\n\"; # class=\"patch\"\n+\t\t\t} else {\n+\t\t\t\t# first patch in patchset\n+\t\t\t\t$patch_found = 1;\n+\t\t\t}\n+\t\t\tprint \"<div class=\\\"patch\\\">\\n\";\n+\n+\t\t\t%diffinfo = parse_difftree_raw_line($difftree->[$patch_idx++]);\n+\n+\t\t\t# for now, no extended header, hence we skip empty patches\n+\t\t\t# companion to\tnext LINE if $in_header;\n+\t\t\tif ($diffinfo{'from_id'} eq $diffinfo{'to_id'}) { # no change\n+\t\t\t\t$in_header = 1;\n+\t\t\t\tnext LINE;\n+\t\t\t}\n+\n+\t\t\tif ($diffinfo{'status'} eq \"A\") { # added\n+\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($diffinfo{'to_mode'}) . \":\" .\n+\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n+\t\t\t\t                             hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'file'})},\n+\t\t\t\t              $diffinfo{'to_id'}) . \"(new)\" .\n+\t\t\t\t      \"</div>\\n\"; # class=\"diff_info\"\n+\n+\t\t\t} elsif ($diffinfo{'status'} eq \"D\") { # deleted\n+\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($diffinfo{'from_mode'}) . \":\" .\n+\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n+\t\t\t\t                             hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'file'})},\n+\t\t\t\t              $diffinfo{'from_id'}) . \"(deleted)\" .\n+\t\t\t\t      \"</div>\\n\"; # class=\"diff_info\"\n+\n+\t\t\t} elsif ($diffinfo{'status'} eq \"R\" || # renamed\n+\t\t\t         $diffinfo{'status'} eq \"C\") { # copied\n+\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" .\n+\t\t\t\t      file_type($diffinfo{'from_mode'}) . \":\" .\n+\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n+\t\t\t\t                             hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'from_file'})},\n+\t\t\t\t              $diffinfo{'from_id'}) .\n+\t\t\t\t      \" -> \" .\n+\t\t\t\t      file_type($diffinfo{'to_mode'}) . \":\" .\n+\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n+\t\t\t\t                             hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'to_file'})},\n+\t\t\t\t              $diffinfo{'to_id'});\n+\t\t\t\tprint \"</div>\\n\"; # class=\"diff_info\"\n+\n+\t\t\t} else { # modified, mode changed, ...\n+\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" .\n+\t\t\t\t      file_type($diffinfo{'from_mode'}) . \":\" .\n+\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n+\t\t\t\t                             hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'file'})},\n+\t\t\t\t              $diffinfo{'from_id'}) .\n+\t\t\t\t      \" -> \" .\n+\t\t\t\t      file_type($diffinfo{'to_mode'}) . \":\" .\n+\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n+\t\t\t\t                             hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'file'})},\n+\t\t\t\t              $diffinfo{'to_id'});\n+\t\t\t\tprint \"</div>\\n\"; # class=\"diff_info\"\n+\t\t\t}\n+\n+\t\t\t#print \"<div class=\\\"diff extended_header\\\">\\n\";\n+\t\t\t$in_header = 1;\n+\t\t\tnext LINE;\n+\t\t} # start of patch in patchset\n+\n+\n+\t\tif ($in_header && $patch_line =~ m/^---/) {\n+\t\t\t#print \"</div>\\n\"\n+\t\t\t$in_header = 0;\n+\t\t}\n+\t\tnext LINE if $in_header;\n+\n+\t\tprint format_diff_line($patch_line);\n+\t}\n+\tprint \"</div>\\n\" if $patch_found; # class=\"patch\"\n+\n+\tprint \"</div>\\n\"; # class=\"patchset\"\n+}\n+\n+# . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .\n+\n sub git_shortlog_body {\n \t# uses global variable $project\n \tmy ($revlist, $from, $to, $refs, $extra) = @_;\n@@ -2556,7 +2672,7 @@ sub git_commit {\n \tgit_print_log($co{'comment'});\n \tprint \"</div>\\n\";\n \n-\tgit_difftree_body(\\@difftree, $parent);\n+\tgit_difftree_body(\\@difftree, $hash, $parent);\n \n \tgit_footer_html();\n }\n@@ -2600,7 +2716,7 @@ sub git_blobdiff_plain {\n }\n \n sub git_commitdiff {\n-\tmkdir($git_temp, 0700);\n+\tmy $format = shift || 'html';\n \tmy %co = parse_commit($hash);\n \tif (!%co) {\n \t\tdie_error(undef, \"Unknown commit object\");\n@@ -2608,143 +2724,106 @@ sub git_commitdiff {\n \tif (!defined $hash_parent) {\n \t\t$hash_parent = $co{'parent'} || '--root';\n \t}\n-\topen my $fd, \"-|\", $GIT, \"diff-tree\", '-r', $hash_parent, $hash\n-\t\tor die_error(undef, \"Open git-diff-tree failed\");\n-\tmy @difftree = map { chomp; $_ } <$fd>;\n-\tclose $fd or die_error(undef, \"Reading git-diff-tree failed\");\n+\n+\t# read commitdiff\n+\tmy $fd;\n+\tmy @difftree;\n+\tmy @patchset;\n+\tif ($format eq 'html') {\n+\t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-M', '-C',\n+\t\t\t\"--patch-with-raw\", \"--full-index\", $hash_parent, $hash\n+\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\n+\t\twhile (chomp(my $line = <$fd>)) {\n+\t\t\t# empty line ends raw part of diff-tree output\n+\t\t\tlast unless $line;\n+\t\t\tpush @difftree, $line;\n+\t\t}\n+\t\t@patchset = map { chomp; $_ } <$fd>;\n+\n+\t\tclose $fd\n+\t\t\tor die_error(undef, \"Reading git-diff-tree failed\");\n+\t} elsif ($format eq 'plain') {\n+\t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-p', '-B', $hash_parent, $hash\n+\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\t} else {\n+\t\tdie_error(undef, \"Unknown commitdiff format\");\n+\t}\n \n \t# non-textual hash id's can be cached\n \tmy $expires;\n \tif ($hash =~ m/^[0-9a-fA-F]{40}$/) {\n \t\t$expires = \"+1d\";\n \t}\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 => href(action=>\"commitdiff_plain\", hash=>$hash, hash_parent=>$hash_parent)},\n-\t\t        \"plain\");\n-\tgit_header_html(undef, $expires);\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-\tgit_print_simplified_log($co{'comment'}, 1); # skip title\n-\tprint \"<br/>\\n\";\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}) (.)\\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 $file = validate_input(unquote($6));\n-\t\tif ($status eq \"A\") {\n-\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($to_mode) . \":\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n-\t\t\t                             hash=>$to_id, file_name=>$file)},\n-\t\t\t              $to_id) . \"(new)\" .\n-\t\t\t      \"</div>\\n\";\n-\t\t\tgit_diff_print(undef, \"/dev/null\", $to_id, \"b/$file\");\n-\t\t} elsif ($status eq \"D\") {\n-\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($from_mode) . \":\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n-\t\t\t                             hash=>$from_id, file_name=>$file)},\n-\t\t\t              $from_id) . \"(deleted)\" .\n-\t\t\t      \"</div>\\n\";\n-\t\t\tgit_diff_print($from_id, \"a/$file\", undef, \"/dev/null\");\n-\t\t} elsif ($status eq \"M\") {\n-\t\t\tif ($from_id ne $to_id) {\n-\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" .\n-\t\t\t\t      file_type($from_mode) . \":\" .\n-\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n-\t\t\t\t                             hash=>$from_id, file_name=>$file)},\n-\t\t\t\t              $from_id) .\n-\t\t\t\t      \" -> \" .\n-\t\t\t\t      file_type($to_mode) . \":\" .\n-\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n-\t\t\t\t                             hash=>$to_id, file_name=>$file)},\n-\t\t\t\t              $to_id);\n-\t\t\t\tprint \"</div>\\n\";\n-\t\t\t\tgit_diff_print($from_id, \"a/$file\",  $to_id, \"b/$file\");\n-\t\t\t}\n-\t\t}\n-\t}\n-\tprint \"<br/>\\n\" .\n-\t      \"</div>\";\n-\tgit_footer_html();\n-}\n \n-sub git_commitdiff_plain {\n-\tmkdir($git_temp, 0700);\n-\tmy %co = parse_commit($hash);\n-\tif (!%co) {\n-\t\tdie_error(undef, \"Unknown commit object\");\n-\t}\n-\tif (!defined $hash_parent) {\n-\t\t$hash_parent = $co{'parent'} || '--root';\n-\t}\n-\topen my $fd, \"-|\", $GIT, \"diff-tree\", '-r', $hash_parent, $hash\n-\t\tor die_error(undef, \"Open git-diff-tree failed\");\n-\tmy @difftree = map { chomp; $_ } <$fd>;\n-\tclose $fd or die_error(undef, \"Reading diff-tree failed\");\n-\n-\t# try to figure out the next tag after this commit\n-\tmy $tagname;\n-\tmy $refs = git_get_references(\"tags\");\n-\topen $fd, \"-|\", $GIT, \"rev-list\", \"HEAD\";\n-\tmy @commits = map { chomp; $_ } <$fd>;\n-\tclose $fd;\n-\tforeach my $commit (@commits) {\n-\t\tif (defined $refs->{$commit}) {\n-\t\t\t$tagname = $refs->{$commit}\n-\t\t}\n-\t\tif ($commit eq $hash) {\n-\t\t\tlast;\n-\t\t}\n-\t}\n+\t# write commit message\n+\tif ($format eq 'html') {\n+\t\tmy $refs = git_get_references();\n+\t\tmy $ref = format_ref_marker($refs, $co{'id'});\n+\t\tmy $formats_nav =\n+\t\t\t$cgi->a({-href => href(action=>\"commitdiff_plain\",\n+\t\t\t                       hash=>$hash, hash_parent=>$hash_parent)},\n+\t\t\t        \"plain\");\n \n-\tprint $cgi->header(-type => \"text/plain\",\n-\t                   -charset => 'utf-8',\n-\t                   -content_disposition => \"inline; filename=\\\"git-$hash.patch\\\"\");\n-\tmy %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});\n-\tmy $comment = $co{'comment'};\n-\tprint <<TEXT;\n+\t\tgit_header_html(undef, $expires);\n+\t\tgit_print_page_nav('commitdiff','', $hash,$co{'tree'},$hash, $formats_nav);\n+\t\tgit_print_header_div('commit', esc_html($co{'title'}) . $ref, $hash);\n+\t\tprint \"<div class=\\\"page_body\\\">\\n\";\n+\t\tprint \"<div class=\\\"log\\\">\\n\";\n+\t\tgit_print_simplified_log($co{'comment'}, 1); # skip title\n+\t\tprint \"</div>\\n\"; # class=\"log\"\n+\n+\t} elsif ($format eq 'plain') {\n+\t\tmy $refs = git_get_references(\"tags\");\n+\t\tmy @tagnames;\n+\t\tif (exists $refs->{$hash}) {\n+\t\t\t@tagnames = map { s|^tags/|| } $refs->{$hash};\n+\t\t}\n+\t\tmy $filename = basename($project) . \"-$hash.patch\";\n+\n+\t\tprint $cgi->header(\n+\t\t\t-type => 'text/plain',\n+\t\t\t-charset => 'utf-8',\n+\t\t\t-expires => $expires,\n+\t\t\t-content_disposition => qq(inline; filename=\"$filename\"));\n+\t\tmy %ad = parse_date($co{'author_epoch'}, $co{'author_tz'});\n+\t\tprint <<TEXT;\n From: $co{'author'}\n Date: $ad{'rfc2822'} ($ad{'tz_local'})\n Subject: $co{'title'}\n TEXT\n-\tif (defined $tagname) {\n-\t\tprint \"X-Git-Tag: $tagname\\n\";\n+\t\tforeach my $tag (@tagnames) {\n+\t\t\tprint \"X-Git-Tag: $tag\\n\";\n+\t\t}\n+\t\tprint \"X-Git-Url: \" . $cgi->self_url() . \"\\n\\n\";\n+\t\tforeach my $line (@{$co{'comment'}}) {\n+\t\t\tprint \"$line\\n\";\n+\t\t}\n+\t\tprint \"---\\n\\n\";\n \t}\n-\tprint \"X-Git-Url: $my_url?p=$project;a=commitdiff;h=$hash\\n\" .\n-\t      \"\\n\";\n \n-\tforeach my $line (@$comment) {;\n-\t\tprint \"$line\\n\";\n-\t}\n-\tprint \"---\\n\\n\";\n+\t# write patch\n+\tif ($format eq 'html') {\n+\t\t#git_difftree_body(\\@difftree, $hash, $hash_parent);\n+\t\t#print \"<br/>\\n\";\n \n-\tforeach my $line (@difftree) {\n-\t\tif ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)\\t(.*)$/) {\n-\t\t\tnext;\n-\t\t}\n-\t\tmy $from_id = $3;\n-\t\tmy $to_id = $4;\n-\t\tmy $status = $5;\n-\t\tmy $file = $6;\n-\t\tif ($status eq \"A\") {\n-\t\t\tgit_diff_print(undef, \"/dev/null\", $to_id, \"b/$file\", \"plain\");\n-\t\t} elsif ($status eq \"D\") {\n-\t\t\tgit_diff_print($from_id, \"a/$file\", undef, \"/dev/null\", \"plain\");\n-\t\t} elsif ($status eq \"M\") {\n-\t\t\tgit_diff_print($from_id, \"a/$file\",  $to_id, \"b/$file\", \"plain\");\n-\t\t}\n+\t\tgit_patchset_body(\\@patchset, \\@difftree, $hash, $hash_parent);\n+\n+\t\tprint \"</div>\\n\"; # class=\"page_body\"\n+\t\tgit_footer_html();\n+\n+\t} elsif ($format eq 'plain') {\n+\t\tlocal $/ = undef;\n+\t\tprint <$fd>;\n+\t\tclose $fd\n+\t\t\tor print \"Reading git-diff-tree failed\\n\";\n \t}\n }\n \n+sub git_commitdiff_plain {\n+\tgit_commitdiff('plain');\n+}\n+\n sub git_history {\n \tif (!defined $hash_base) {\n \t\t$hash_base = git_get_head_hash($project);\n-- \n1.4.1.1\n"},{"id":"25825","messageId":"200608240158.14991.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 2] gitweb: Replace git_commitdiff_plain by anonymous subroutine","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-23T23:58:14Z","receivedAt":"2006-08-23T23:58:14Z","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 |    6 +-----\n 1 files changed, 1 insertions(+), 5 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 9367685..c238824 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -234,7 +234,7 @@ my %actions = (\n \t\"blob\" => \\&git_blob,\n \t\"blob_plain\" => \\&git_blob_plain,\n \t\"commitdiff\" => \\&git_commitdiff,\n-\t\"commitdiff_plain\" => \\&git_commitdiff_plain,\n+\t\"commitdiff_plain\" => sub { git_commitdiff('plain'); },\n \t\"commit\" => \\&git_commit,\n \t\"heads\" => \\&git_heads,\n \t\"history\" => \\&git_history,\n@@ -2820,10 +2820,6 @@ TEXT\n \t}\n }\n \n-sub git_commitdiff_plain {\n-\tgit_commitdiff('plain');\n-}\n-\n sub git_history {\n \tif (!defined $hash_base) {\n \t\t$hash_base = git_get_head_hash($project);\n-- \n1.4.1.1\n"},{"id":"25826","messageId":"200608240158.49908.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 3] gitweb: Show information about incomplete lines in commitdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-23T23:58:49Z","receivedAt":"2006-08-23T23:58:49Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"In format_diff_line, instead of skipping errors/incomplete lines,\nfor example\n  \"\\ No newline at end of file\"\nin HTML pretty-printing of diff, use \"incomplete\" class for div.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.css  |    4 ++++\n gitweb/gitweb.perl |    2 +-\n 2 files changed, 5 insertions(+), 1 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 4821022..5eaa24f 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -285,6 +285,10 @@ div.diff.chunk_header {\n \tcolor: #990099;\n }\n \n+div.diff.incomplete {\n+\tcolor: #cccccc;\n+}\n+\n div.diff_info {\n \tfont-family: monospace;\n \tcolor: #000099;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c238824..42b8f93 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -539,7 +539,7 @@ sub format_diff_line {\n \t\t$diff_class = \" chunk_header\";\n \t} elsif ($char eq \"\\\\\") {\n \t\t# skip errors (incomplete lines)\n-\t\treturn \"\";\n+\t\t$diff_class = \" incomplete\";\n \t}\n \t$line = untabify($line);\n \treturn \"<div class=\\\"diff$diff_class\\\">\" . esc_html($line) . \"</div>\\n\";\n-- \n1.4.1.1\n"},{"id":"25829","messageId":"7v3bbmhoa2.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"Re: [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-24T02:15:49Z","receivedAt":"2006-08-24T02:15:49Z","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> Converting \"blobdiff\" and \"blobdiff_plain\" format would be much easier\n> if git-diff-tree and friends had -L <label>/--label=<label> option,\n> like GNU diff has.\n\nI am not sure how that would be useful, given that you would\ndisect the header line-by-line to colorize anyway.\n\n> Current patch preserves much of current output; the question is if for\n> example generate if 'plain' format should generate patch which could\n> be appplied by ordinary patch which do not understand git diff\n> extensions (including renaming and copying), as it is done in current\n> version, and if 'html' version should detect renames and copying.\n\nI would say html is definitely for human consumption; does\nanybody cut&paste html patch and expect to apply that?  Plain\nformat I am easy but probably enabling rename is fine.  You can\nedit the header or tell patch to apply to which file anyway, and\nI think the value of being able to view the real changes outweigh\nthat inconvenience.\n\n>  * \"commitdiff\" now products patches with renaming and copying\n>    detection (git-diff-tree is invoked with -M and -C options).\n\nYou do not have to give -M and -C; a single -C is enough.\nI wonder if -B is also useful as a default (i.e. -B -C).\n\nFor a merge, I often would want to see --cc just like gitk does,\nbut it is probably just me.\n\nI do not know we would want to slurp the entier diff in an\narray before processing.  Is this easy to streamify by passing\nan pipe fd to the formatting sub?\n\n>    Empty patches (mode changes and pure renames and copying)\n>    are not written currently.\n\nThat's quite bad.\n\n>  * \"commitdiff\" output is now divided into several div elements\n>    of class \"log\", \"patchset\" and \"patch\".\n>\n>  * \"commitdiff_plain\" now only generates X-Git-Tag: line only if there\n>    is tag pointing to the current commit.\n\nHmph...\n\n>    ...; besides we are\n>    interested rather in tags _preceding_ the commit, and _heads_\n>    following the commit.\n\nInteresting observation.  When somebody says \"feature X was\nintroduced in such and such commit\", people would want to know (1) the\npoint release they are using has the feature -- which means you\nwould want to know the earliest tag that comes after the commit,\nor (2) if the branch they are working on already has that\nfeature -- which again means if the head follows the commit.  So\nI am not sure when preceding tag is interesting...\n"},{"id":"25830","messageId":"7vy7teg9gz.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"200608240158.49908.jnareb@gmail.com","subject":"Re: [PATCH 3] gitweb: Show information about incomplete lines in commitdiff","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-24T02:21:00Z","receivedAt":"2006-08-24T02:21:00Z","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> In format_diff_line, instead of skipping errors/incomplete lines,\n> for example\n>   \"\\ No newline at end of file\"\n> in HTML pretty-printing of diff, use \"incomplete\" class for div.\n>\n> Signed-off-by: Jakub Narebski <jnareb@gmail.com>\n\nI think this makes sense, while I do not see much point in\nremoval of git_commitdiff_plain.\n"},{"id":"25844","messageId":"eck1em$p8b$1@sea.gmane.org","threadId":"5369","inReplyTo":"7v3bbmhoa2.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T11:10:13Z","receivedAt":"2006-08-24T11:10:13Z","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>> Converting \"blobdiff\" and \"blobdiff_plain\" format would be much easier\n>> if git-diff-tree and friends had -L <label>/--label=<label> option,\n>> like GNU diff has.\n> \n> I am not sure how that would be useful, given that you would\n> disect the header line-by-line to colorize anyway.\n\ngitweb could output patch directly (slurp-print) in blobdiff_plain,\nif there were -L <label>/--label=<label> option to git-diff. As it is now\ngit_blobdiff_plain (or git_blobdiff('plain')) would have to process diff\nheader, replacing hashes by file names.\n\nAnyway to get full information you need commits to diff, not only blobs to\ndiff, otherwise the mode change information is lost, I think. And then we\nwould be able to reus git_patchset_body for git_blobdiff...\n\n>> Current patch preserves much of current output; the question is if for\n>> example generate if 'plain' format should generate patch which could\n>> be appplied by ordinary patch which do not understand git diff\n>> extensions (including renaming and copying), as it is done in current\n>> version, and if 'html' version should detect renames and copying.\n> \n> I would say html is definitely for human consumption; does\n> anybody cut&paste html patch and expect to apply that?  Plain\n> format I am easy but probably enabling rename is fine.  You can\n> edit the header or tell patch to apply to which file anyway, and\n> I think the value of being able to view the real changes outweigh\n> that inconvenience.\n\nOr I we can add another format/option, 'broken' to git_commitdiff\nand friends.\n\n>>  * \"commitdiff\" now products patches with renaming and copying\n>>    detection (git-diff-tree is invoked with -M and -C options).\n> \n> You do not have to give -M and -C; a single -C is enough.\n> I wonder if -B is also useful as a default (i.e. -B -C).\n\nSo -C implies -M?\n\n> For a merge, I often would want to see --cc just like gitk does,\n> but it is probably just me.\n\nPlanned. The problem is that raw format for --cc differs, and parser\nhas to be improved (and similarity is lost)\n\n> I do not know we would want to slurp the entier diff in an\n> array before processing.  Is this easy to streamify by passing\n> an pipe fd to the formatting sub?\n\nThat was one question I meant to ask: slurp entire diff (process\nthen output rule) or streamify (streamify larger output for faster \nresult)?  Will do (quite easy).\n\n>>    Empty patches (mode changes and pure renames and copying)\n>>    are not written currently.\n> \n> That's quite bad.\n\nThis can be easily changed. Question: what format? Current \"gitweb diff\nheader\" (<filetype>:<sha1 link> -> <filetype>:<sha1 link>) has no place for\nthat. Can be easily changed.\n\nAnother question: do output difftree in commitdiff, like in commit view?\nDo write out extended header, perhaps except index line (repeats information\nin \"gitweb diff header\")?\n\n\n>>  * \"commitdiff_plain\" now only generates X-Git-Tag: line only if there\n>>    is tag pointing to the current commit.\n> \n> Hmph...\n> \n>>    ...; besides we are\n>>    interested rather in tags _preceding_ the commit, and _heads_\n>>    following the commit.\n> \n> Interesting observation.  When somebody says \"feature X was\n> introduced in such and such commit\", people would want to know (1) the\n> point release they are using has the feature -- which means you\n> would want to know the earliest tag that comes after the commit,\n> or (2) if the branch they are working on already has that\n> feature -- which again means if the head follows the commit.  So\n> I am not sure when preceding tag is interesting...\n\nQgit and gitk both show \"Follows:\" listing followed = preceding tag(s).\nThis answers question if given commit has given feature.\n\nI have planned separating generation of first/all preceding/following\ntags/heads (from git_get_references) into subroutines anyway.\n\nI will add 'X-Git-Tag-After:' then.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25845","messageId":"eck1is$p8b$2@sea.gmane.org","threadId":"5369","inReplyTo":"7vy7teg9gz.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 3] gitweb: Show information about incomplete lines in commitdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T11:12:28Z","receivedAt":"2006-08-24T11:12:28Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n\n> I do not see much point in\n> removal of git_commitdiff_plain.\n\nSo should I split git_commitdiff into two subroutines,\nor should I left it as it is after\n  gitweb: Use git-diff-tree patch output for commitdiff\ni.e. git_commitdiff('plain') for git_commitdiff_plain?\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25855","messageId":"200608241932.14635.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 4] gitweb: Remove invalid comment in format_diff_line","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T17:32:13Z","receivedAt":"2006-08-24T17:32:13Z","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---\nThis patch and all subsequent patches assumes (although this should\nhave no bearing) that patch\n  [PATCH 2] gitweb: Replace git_commitdiff_plain by anonymous subroutine\nwas not applied. (In my repository this commit had been simply reverted).\n\n gitweb/gitweb.perl |    1 -\n 1 files changed, 0 insertions(+), 1 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex fe9b9ee..1d3d9df 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -538,7 +538,6 @@ sub format_diff_line {\n \t} elsif ($char eq \"@\") {\n \t\t$diff_class = \" chunk_header\";\n \t} elsif ($char eq \"\\\\\") {\n-\t\t# skip errors (incomplete lines)\n \t\t$diff_class = \" incomplete\";\n \t}\n \t$line = untabify($line);\n-- \n1.4.1.1\n"},{"id":"25854","messageId":"200608241934.36684.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 5] gitweb: Streamify patch output in git_commitdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T17:34:36Z","receivedAt":"2006-08-24T17:34:36Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Change output of patch(set) in git_commitdiff from slurping whole diff\nin @patchset array before processing, to passing file descriptor to\ngit_patchset_body.\n\nAdvantages: faster, incremental output, smaller memory footprint.\nDisadvantages: cannot react when there is error during closing file\ndescriptor.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nJunio C Hamano wrote:\n> I do not know we would want to slurp the entier diff in an\n> array before processing.  Is this easy to streamify by passing\n> an pipe fd to the formatting sub?\n\nThis patch adresses that.\n\n gitweb/gitweb.perl |   14 +++++++-------\n 1 files changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 1d3d9df..d72b19a 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1539,7 +1539,7 @@ sub git_difftree_body {\n }\n \n sub git_patchset_body {\n-\tmy ($patchset, $difftree, $hash, $hash_parent) = @_;\n+\tmy ($fd, $difftree, $hash, $hash_parent) = @_;\n \n \tmy $patch_idx = 0;\n \tmy $in_header = 0;\n@@ -1548,7 +1548,9 @@ sub git_patchset_body {\n \n \tprint \"<div class=\\\"patchset\\\">\\n\";\n \n-\tLINE: foreach my $patch_line (@$patchset) {\n+\tLINE:\n+\twhile (my $patch_line = <$fd>) {\n+\t\tchomp $patch_line;\n \n \t\tif ($patch_line =~ m/^diff /) { # \"git diff\" header\n \t\t\t# beginning of patch (in patchset)\n@@ -2727,7 +2729,6 @@ sub git_commitdiff {\n \t# read commitdiff\n \tmy $fd;\n \tmy @difftree;\n-\tmy @patchset;\n \tif ($format eq 'html') {\n \t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-M', '-C',\n \t\t\t\"--patch-with-raw\", \"--full-index\", $hash_parent, $hash\n@@ -2738,13 +2739,11 @@ sub git_commitdiff {\n \t\t\tlast unless $line;\n \t\t\tpush @difftree, $line;\n \t\t}\n-\t\t@patchset = map { chomp; $_ } <$fd>;\n \n-\t\tclose $fd\n-\t\t\tor die_error(undef, \"Reading git-diff-tree failed\");\n \t} elsif ($format eq 'plain') {\n \t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-p', '-B', $hash_parent, $hash\n \t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\n \t} else {\n \t\tdie_error(undef, \"Unknown commitdiff format\");\n \t}\n@@ -2806,7 +2805,8 @@ TEXT\n \t\t#git_difftree_body(\\@difftree, $hash, $hash_parent);\n \t\t#print \"<br/>\\n\";\n \n-\t\tgit_patchset_body(\\@patchset, \\@difftree, $hash, $hash_parent);\n+\t\tgit_patchset_body($fd, \\@difftree, $hash, $hash_parent);\n+\t\tclose $fd;\n \n \t\tprint \"</div>\\n\"; # class=\"page_body\"\n \t\tgit_footer_html();\n-- \n1.4.1.1\n"},{"id":"25853","messageId":"200608241937.04849.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 6] gitweb: Add git_get_{following,preceding}_references functions","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T17:37:04Z","receivedAt":"2006-08-24T17:37:04Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Adds git_get_following_references function, based on code which was\nused in git_commitdiff_plain to generate X-Git-Tag: header,\nand companion git_get_preceding_references function.\n\nBoth functions return array of all references of given type (as\nreturned by git_get_references) following/preceding given commit in\narray (list) context, and last following/first preceding ref in scalar\ncontext.\n\nStripping ref (list of refs) of \"$type/\" (e.g. \"tags/\") is left to\ncaller.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nJunio C Hamano wrote:\n>>  * \"commitdiff_plain\" now only generates X-Git-Tag: line only if\n>> there is tag pointing to the current commit.\n>\n> Hmph...\n>\n>>    ...; besides we are\n>>    interested rather in tags _preceding_ the commit, and _heads_\n>>    following the commit.\n>\n> Interesting observation.  When somebody says \"feature X was\n> introduced in such and such commit\", people would want to know (1)\n> the point release they are using has the feature -- which means you\n> would want to know the earliest tag that comes after the commit, or\n> (2) if the branch they are working on already has that\n> feature -- which again means if the head follows the commit.  So\n> I am not sure when preceding tag is interesting...\n\nActually, the two following patches adresses this, not this patch...\n\n gitweb/gitweb.perl |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 52 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex d72b19a..2d3776a 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -749,6 +749,58 @@ sub git_get_references {\n \treturn \\%refs;\n }\n \n+sub git_get_following_references {\n+\tmy $hash = shift || return undef;\n+\tmy $type = shift;\n+\tmy $base = shift || $hash_base || \"HEAD\";\n+\n+\tmy $refs = git_get_references($type);\n+\topen my $fd, \"-|\", $GIT, \"rev-list\", $base\n+\t\tor return undef;\n+\tmy @commits = map { chomp; $_ } <$fd>;\n+\tclose $fd\n+\t\tor return undef;\n+\n+\tmy @reflist;\n+\tmy $lastref;\n+\n+\tforeach my $commit (@commits) {\n+\t\tforeach my $ref (@{$refs->{$commit}}) {\n+\t\t\t$lastref = $ref;\n+\t\t\tpush @reflist, $lastref;\n+\t\t}\n+\t\tif ($commit eq $hash) {\n+\t\t\tlast;\n+\t\t}\n+\t}\n+\n+\treturn wantarray ? @reflist : $lastref;\n+}\n+\n+sub git_get_preceding_references {\n+\tmy $hash = shift || return undef;\n+\tmy $type = shift;\n+\n+\tmy $refs = git_get_references($type);\n+\topen my $fd, \"-|\", $GIT, \"rev-list\", $hash\n+\t\tor return undef;\n+\tmy @commits = map { chomp; $_ } <$fd>;\n+\tclose $fd\n+\t\tor return undef;\n+\n+\tmy @reflist;\n+\tmy $firstref;\n+\n+\tforeach my $commit (@commits) {\n+\t\tforeach my $ref (@{$refs->{$commit}}) {\n+\t\t\t$firstref = $ref unless $firstref;\n+\t\t\tpush @reflist, $ref;\n+\t\t}\n+\t}\n+\n+\treturn wantarray ? @reflist : $firstref;\n+}\n+\n ## ----------------------------------------------------------------------\n ## parse to hash functions\n \n-- \n1.4.1.1\n"},{"id":"25857","messageId":"200608241939.32535.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 7] gitweb: Faster return from git_get_preceding_references if possible","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T17:39:32Z","receivedAt":"2006-08-24T17:39:32Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Return on first ref found when git_get_preceding_references\nis called in scalar context\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nJakub Narebski wrote:\n> Actually, the two following patches adresses this, not this patch...\n\nThe two following this patch...\n\n gitweb/gitweb.perl |    5 ++---\n 1 files changed, 2 insertions(+), 3 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 2d3776a..a068a81 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -789,16 +789,15 @@ sub git_get_preceding_references {\n \t\tor return undef;\n \n \tmy @reflist;\n-\tmy $firstref;\n \n \tforeach my $commit (@commits) {\n \t\tforeach my $ref (@{$refs->{$commit}}) {\n-\t\t\t$firstref = $ref unless $firstref;\n+\t\t\treturn $ref unless wantarray;\n \t\t\tpush @reflist, $ref;\n \t\t}\n \t}\n \n-\treturn wantarray ? @reflist : $firstref;\n+\treturn @reflist;\n }\n \n ## ----------------------------------------------------------------------\n-- \n1.4.1.1\n"},{"id":"25856","messageId":"200608241941.23804.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 8] gitweb: Add git_get_rev_name_tags function","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T17:41:23Z","receivedAt":"2006-08-24T17:41:23Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Add git_get_rev_name_tags function, for later use in\ngit_commitdiff('plain') for X-Git-Tag: header.\n\nThis function, contrary to the call to\n  git_get_following_references($hash, \"tags\");\n_does_ strip \"tags/\" and returns bare tag name.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nJunio C Hamano wrote:\n>>  * \"commitdiff_plain\" now only generates X-Git-Tag: line only if\n>> there is tag pointing to the current commit.\n>\n> Hmph...\n>\n>>    ...; besides we are\n>>    interested rather in tags _preceding_ the commit, and _heads_\n>>    following the commit.\n>\n> Interesting observation.  When somebody says \"feature X was\n> introduced in such and such commit\", people would want to know (1)\n> the point release they are using has the feature -- which means you\n> would want to know the earliest tag that comes after the commit, or\n> (2) if the branch they are working on already has that\n> feature -- which again means if the head follows the commit.  So\n> I am not sure when preceding tag is interesting...\n\nThis commit introduces function which does job that was intended\nI guess for X-Git-Tag: header... perhaps it should be renamed...\n\n gitweb/gitweb.perl |   16 ++++++++++++++++\n 1 files changed, 16 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex a068a81..3bc3ff3 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -800,6 +800,22 @@ sub git_get_preceding_references {\n \treturn @reflist;\n }\n \n+sub git_get_rev_name_tags {\n+\tmy $hash = shift || return undef;\n+\n+\topen my $fd, \"-|\", $GIT, \"name-rev\", \"--tags\", $hash\n+\t\tor return;\n+\tmy $name_rev = <$fd>;\n+\tclose $fd;\n+\n+\tif ($name_rev =~ m|^$hash tags/(.*)$|) {\n+\t\treturn $1;\n+\t} else {\n+\t\t# catches also '$hash undefined' output\n+\t\treturn undef;\n+\t}\n+}\n+\n ## ----------------------------------------------------------------------\n ## parse to hash functions\n \n-- \n1.4.1.1\n"},{"id":"25858","messageId":"200608241945.30553.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 9] gitweb: Use git_get_name_rev_tags for commitdiff_plain X-Git-Tag: header","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T17:45:30Z","receivedAt":"2006-08-24T17:45:30Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Use git_get_rev_name_tags function for X-Git-Tag: header in\ngit_commitdiff('plain'), i.e. for commitdiff_plain action.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nFor example, commitdiff_plain for 6c7f4cebdb40c0d95c63d59538fd235dcf978029\ncommit -- the following query string:\n   a=commitdiff_plain;p=git.git;h=6c7f4cebdb40c0d95c63d59538fd235dcf978029\noutputs the following X-Git-Tag: header:\n   X-Git-Tag: v1.4.2^0~2\n\n gitweb/gitweb.perl |   10 +++-------\n 1 files changed, 3 insertions(+), 7 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 3bc3ff3..b2e8259 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2840,10 +2840,7 @@ sub git_commitdiff {\n \n \t} elsif ($format eq 'plain') {\n \t\tmy $refs = git_get_references(\"tags\");\n-\t\tmy @tagnames;\n-\t\tif (exists $refs->{$hash}) {\n-\t\t\t@tagnames = map { s|^tags/|| } $refs->{$hash};\n-\t\t}\n+\t\tmy $tagname = git_get_rev_name_tags($hash);\n \t\tmy $filename = basename($project) . \"-$hash.patch\";\n \n \t\tprint $cgi->header(\n@@ -2857,10 +2854,9 @@ From: $co{'author'}\n Date: $ad{'rfc2822'} ($ad{'tz_local'})\n Subject: $co{'title'}\n TEXT\n-\t\tforeach my $tag (@tagnames) {\n-\t\t\tprint \"X-Git-Tag: $tag\\n\";\n-\t\t}\n+\t\tprint \"X-Git-Tag: $tagname\\n\" if $tagname;\n \t\tprint \"X-Git-Url: \" . $cgi->self_url() . \"\\n\\n\";\n+\n \t\tforeach my $line (@{$co{'comment'}}) {\n \t\t\tprint \"$line\\n\";\n \t\t}\n-- \n1.4.1.1\n"},{"id":"25861","messageId":"7vzmdu7z1m.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"eck1em$p8b$1@sea.gmane.org","subject":"Re: [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-24T18:45:41Z","receivedAt":"2006-08-24T18:45:41Z","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> Junio C Hamano wrote:\n>\n>> Jakub Narebski <jnareb@gmail.com> writes:\n>> \n>>> Converting \"blobdiff\" and \"blobdiff_plain\" format would be much easier\n>>> if git-diff-tree and friends had -L <label>/--label=<label> option,\n>>> like GNU diff has.\n>> \n>> I am not sure how that would be useful, given that you would\n>> disect the header line-by-line to colorize anyway.\n>\n> gitweb could output patch directly (slurp-print) in blobdiff_plain,\n> if there were -L <label>/--label=<label> option to git-diff. As it is now\n> git_blobdiff_plain (or git_blobdiff('plain')) would have to process diff\n> header, replacing hashes by file names.\n\nI do not think gitweb does diff between two arbitrary blobs; in\nother words, you only need \"diff-tree treeA treeB -- path\".\n\nI think feeding object names _is_ what's causing you trouble.\n"},{"id":"25862","messageId":"200608242050.34366.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 10] gitweb: Add support for hash_parent_base parameter for blobdiffs","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T18:50:34Z","receivedAt":"2006-08-24T18:50:34Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Add support for hash_parent_base in input validation part and in\nhref() function.  Add proper hash_parent_base to all calls to blobdiff\nand blobdiff_plain action URLs.\n\nTo be used in future rewrite of git_blobdiff and git_blobdiff_plain.\n\nWhile at it, move project before action in ordering CGI parameters in\nhref().\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nSuch an easy commitdiff_plain link wouldn't be possible without\nhref() function, which filters out undefined parameters.\n\n gitweb/gitweb.perl |   35 ++++++++++++++++++++++++++---------\n 1 files changed, 26 insertions(+), 9 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex b2e8259..b236e1a 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -211,6 +211,13 @@ if (defined $hash_base) {\n \t}\n }\n \n+our $hash_parent_base = $cgi->param('hpb');\n+if (defined $hash_parent_base) {\n+\tif (!validate_input($hash_parent_base)) {\n+\t\tdie_error(undef, \"Invalid hash parent base parameter\");\n+\t}\n+}\n+\n our $page = $cgi->param('pg');\n if (defined $page) {\n \tif ($page =~ m/[^0-9]$/) {\n@@ -270,13 +277,14 @@ sub href(%) {\n \tmy %params = @_;\n \n \tmy @mapping = (\n-\t\taction => \"a\",\n \t\tproject => \"p\",\n+\t\taction => \"a\",\n \t\tfile_name => \"f\",\n \t\tfile_parent => \"fp\",\n \t\thash => \"h\",\n \t\thash_parent => \"hp\",\n \t\thash_base => \"hb\",\n+\t\thash_parent_base => \"hpb\",\n \t\tpage => \"pg\",\n \t\tsearchtext => \"s\",\n \t);\n@@ -1543,8 +1551,10 @@ sub git_difftree_body {\n \t\t\t}\n \t\t\tprint \"<td>\";\n \t\t\tif ($diff{'to_id'} ne $diff{'from_id'}) { # modified\n-\t\t\t\tprint $cgi->a({-href => href(action=>\"blobdiff\", hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n-\t\t\t\t                             hash_base=>$hash, file_name=>$diff{'file'}),\n+\t\t\t\tprint $cgi->a({-href => href(action=>\"blobdiff\",\n+\t\t\t\t                             hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n+\t\t\t\t                             hash_base=>$hash, hash_parent_base=>$parent,\n+\t\t\t\t                             file_name=>$diff{'file'}),\n \t\t\t\t              -class => \"list\"}, esc_html($diff{'file'}));\n \t\t\t} else { # only mode changed\n \t\t\t\tprint $cgi->a({-href => href(action=>\"blob\", hash=>$diff{'to_id'},\n@@ -1559,8 +1569,10 @@ sub git_difftree_body {\n \t\t\t\t        \"blob\");\n \t\t\tif ($diff{'to_id'} ne $diff{'from_id'}) { # modified\n \t\t\t\tprint \" | \" .\n-\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\", hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n-\t\t\t\t\t                       hash_base=>$hash, file_name=>$diff{'file'})},\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\",\n+\t\t\t\t\t                       hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n+\t\t\t\t\t                       hash_base=>$hash, hash_parent_base=>$parent,\n+\t\t\t\t\t                       file_name=>$diff{'file'})},\n \t\t\t\t\t        \"diff\");\n \t\t\t}\n \t\t\tprint \" | \" .\n@@ -1592,8 +1604,9 @@ sub git_difftree_body {\n \t\t\t              \"blob\");\n \t\t\tif ($diff{'to_id'} ne $diff{'from_id'}) {\n \t\t\t\tprint \" | \" .\n-\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\", hash_base=>$hash,\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\",\n \t\t\t\t\t                       hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n+\t\t\t\t\t                       hash_base=>$hash, hash_parent_base=>$parent,\n \t\t\t\t\t                       file_name=>$diff{'to_file'}, file_parent=>$diff{'from_file'})},\n \t\t\t\t\t        \"diff\");\n \t\t\t}\n@@ -1793,8 +1806,10 @@ sub git_history_body {\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 => href(action=>\"blobdiff\", hash=>$blob_current, hash_parent=>$blob_parent,\n-\t\t\t\t\t                       hash_base=>$commit, file_name=>$file_name)},\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\",\n+\t\t\t\t\t                       hash=>$blob_current, hash_parent=>$blob_parent,\n+\t\t\t\t\t                       hash_base=>$hash_base, hash_parent_base=>$commit,\n+\t\t\t\t\t                       file_name=>$file_name)},\n \t\t\t\t\t        \"diff to current\");\n \t\t\t}\n \t\t}\n@@ -2751,7 +2766,9 @@ sub git_blobdiff {\n \tif (defined $hash_base && (my %co = parse_commit($hash_base))) {\n \t\tmy $formats_nav =\n \t\t\t$cgi->a({-href => href(action=>\"blobdiff_plain\",\n-\t\t\t                       hash=>$hash, hash_parent=>$hash_parent)},\n+\t\t\t                       hash=>$hash, hash_parent=>$hash_parent,\n+\t\t\t                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n+\t\t\t                       file_name=>$file_name, file_parent=>$file_parent)},\n \t\t\t        \"plain\");\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-- \n1.4.1.1\n"},{"id":"25863","messageId":"eckspe$vuc$1@sea.gmane.org","threadId":"5369","inReplyTo":"7vzmdu7z1m.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T18:56:47Z","receivedAt":"2006-08-24T18:56:47Z","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>> Junio C Hamano wrote:\n>>\n>>> Jakub Narebski <jnareb@gmail.com> writes:\n>>> \n>>>> Converting \"blobdiff\" and \"blobdiff_plain\" format would be much easier\n>>>> if git-diff-tree and friends had -L <label>/--label=<label> option,\n>>>> like GNU diff has.\n>>> \n>>> I am not sure how that would be useful, given that you would\n>>> disect the header line-by-line to colorize anyway.\n>>\n>> gitweb could output patch directly (slurp-print) in blobdiff_plain,\n>> if there were -L <label>/--label=<label> option to git-diff. As it is now\n>> git_blobdiff_plain (or git_blobdiff('plain')) would have to process diff\n>> header, replacing hashes by file names.\n> \n> I do not think gitweb does diff between two arbitrary blobs; in\n> other words, you only need \"diff-tree treeA treeB -- path\".\n\ngitweb didn't pass parent commit (i.e. treeB) information for blobdiff,\nand IIRC passed only blob hashes for blobdiff_plain (and not passed\nfilename aka path).\n\n> I think feeding object names _is_ what's causing you trouble.\n\nAs I said:\n>> Anyway to get full information you need commits to diff, not only blobs to\n>> diff, otherwise the mode change information is lost, I think. And then we\n>> would be able to reuse git_patchset_body for git_blobdiff... \n \nInstead of using hash and hash_parent parameters for tree-ish and \ntree_parent-ish hashes (instead of blob hashes as it is now), I have \nused in patch (in this thread):\n\n  [PATCH 10] gitweb: Add support for hash_parent_base parameter for blobdiffs\n\nhash_base and (newly introduced) hash_parent_base arguments/parameters.\n\nNot used yet, but planned.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25869","messageId":"200608242353.54869.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 10 (amended)] gitweb: Add support for hash_parent_base parameter for blobdiffs","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-24T21:53:54Z","receivedAt":"2006-08-24T21:53:54Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Add support for hash_parent_base in input validation part and in\nhref() function.  Add proper hash_parent_base to all calls to blobdiff\nand blobdiff_plain action URLs. Use hash_parent_base as hash_base for\nblobs of hash_parent.\n\nTo be used in future rewrite of git_blobdiff and git_blobdiff_plain.\n\nWhile at it, move project before action in ordering CGI parameters in\nhref().\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |   37 +++++++++++++++++++++++++++----------\n 1 files changed, 27 insertions(+), 10 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex b2e8259..a3553ad 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -211,6 +211,13 @@ if (defined $hash_base) {\n \t}\n }\n \n+our $hash_parent_base = $cgi->param('hpb');\n+if (defined $hash_parent_base) {\n+\tif (!validate_input($hash_parent_base)) {\n+\t\tdie_error(undef, \"Invalid hash parent base parameter\");\n+\t}\n+}\n+\n our $page = $cgi->param('pg');\n if (defined $page) {\n \tif ($page =~ m/[^0-9]$/) {\n@@ -270,13 +277,14 @@ sub href(%) {\n \tmy %params = @_;\n \n \tmy @mapping = (\n-\t\taction => \"a\",\n \t\tproject => \"p\",\n+\t\taction => \"a\",\n \t\tfile_name => \"f\",\n \t\tfile_parent => \"fp\",\n \t\thash => \"h\",\n \t\thash_parent => \"hp\",\n \t\thash_base => \"hb\",\n+\t\thash_parent_base => \"hpb\",\n \t\tpage => \"pg\",\n \t\tsearchtext => \"s\",\n \t);\n@@ -1543,8 +1551,10 @@ sub git_difftree_body {\n \t\t\t}\n \t\t\tprint \"<td>\";\n \t\t\tif ($diff{'to_id'} ne $diff{'from_id'}) { # modified\n-\t\t\t\tprint $cgi->a({-href => href(action=>\"blobdiff\", hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n-\t\t\t\t                             hash_base=>$hash, file_name=>$diff{'file'}),\n+\t\t\t\tprint $cgi->a({-href => href(action=>\"blobdiff\",\n+\t\t\t\t                             hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n+\t\t\t\t                             hash_base=>$hash, hash_parent_base=>$parent,\n+\t\t\t\t                             file_name=>$diff{'file'}),\n \t\t\t\t              -class => \"list\"}, esc_html($diff{'file'}));\n \t\t\t} else { # only mode changed\n \t\t\t\tprint $cgi->a({-href => href(action=>\"blob\", hash=>$diff{'to_id'},\n@@ -1559,8 +1569,10 @@ sub git_difftree_body {\n \t\t\t\t        \"blob\");\n \t\t\tif ($diff{'to_id'} ne $diff{'from_id'}) { # modified\n \t\t\t\tprint \" | \" .\n-\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\", hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n-\t\t\t\t\t                       hash_base=>$hash, file_name=>$diff{'file'})},\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\",\n+\t\t\t\t\t                       hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n+\t\t\t\t\t                       hash_base=>$hash, hash_parent_base=>$parent,\n+\t\t\t\t\t                       file_name=>$diff{'file'})},\n \t\t\t\t\t        \"diff\");\n \t\t\t}\n \t\t\tprint \" | \" .\n@@ -1592,8 +1604,9 @@ sub git_difftree_body {\n \t\t\t              \"blob\");\n \t\t\tif ($diff{'to_id'} ne $diff{'from_id'}) {\n \t\t\t\tprint \" | \" .\n-\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\", hash_base=>$hash,\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\",\n \t\t\t\t\t                       hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\n+\t\t\t\t\t                       hash_base=>$hash, hash_parent_base=>$parent,\n \t\t\t\t\t                       file_name=>$diff{'to_file'}, file_parent=>$diff{'from_file'})},\n \t\t\t\t\t        \"diff\");\n \t\t\t}\n@@ -1793,8 +1806,10 @@ sub git_history_body {\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 => href(action=>\"blobdiff\", hash=>$blob_current, hash_parent=>$blob_parent,\n-\t\t\t\t\t                       hash_base=>$commit, file_name=>$file_name)},\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\",\n+\t\t\t\t\t                       hash=>$blob_current, hash_parent=>$blob_parent,\n+\t\t\t\t\t                       hash_base=>$hash_base, hash_parent_base=>$commit,\n+\t\t\t\t\t                       file_name=>$file_name)},\n \t\t\t\t\t        \"diff to current\");\n \t\t\t}\n \t\t}\n@@ -2751,7 +2766,9 @@ sub git_blobdiff {\n \tif (defined $hash_base && (my %co = parse_commit($hash_base))) {\n \t\tmy $formats_nav =\n \t\t\t$cgi->a({-href => href(action=>\"blobdiff_plain\",\n-\t\t\t                       hash=>$hash, hash_parent=>$hash_parent)},\n+\t\t\t                       hash=>$hash, hash_parent=>$hash_parent,\n+\t\t\t                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n+\t\t\t                       file_name=>$file_name, file_parent=>$file_parent)},\n \t\t\t        \"plain\");\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@@ -2765,7 +2782,7 @@ HTML\n \tprint \"<div class=\\\"page_body\\\">\\n\" .\n \t      \"<div class=\\\"diff_info\\\">blob:\" .\n \t      $cgi->a({-href => href(action=>\"blob\", hash=>$hash_parent,\n-\t                             hash_base=>$hash_base, file_name=>($file_parent || $file_name))},\n+\t                             hash_base=>$hash_parent_base, file_name=>($file_parent || $file_name))},\n \t              $hash_parent) .\n \t      \" -> blob:\" .\n \t      $cgi->a({-href => href(action=>\"blob\", hash=>$hash,\n-- \n1.4.1.1\n"},{"id":"25890","messageId":"e5bfff550608251032p53ba203fl27af782c765f929f@mail.gmail.com","threadId":"5369","inReplyTo":"eck1em$p8b$1@sea.gmane.org","subject":"Re: [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","fromName":"Marco Costalba","fromEmail":"mcostalba@gmail.com","sentAt":"2006-08-25T17:32:36Z","receivedAt":"2006-08-25T17:32:36Z","isPatch":true,"sender":{"key":"mcostalba@gmail.com","avatar":null},"body":"> >>    Empty patches (mode changes and pure renames and copying)\n> >>    are not written currently.\n> >\n> > That's quite bad.\n>\n> This can be easily changed. Question: what format? Current \"gitweb diff\n\nI don't know if has always been like this, but I don't see on gitweb\n(http://www.kernel.org/git/?p=qgit/qgit.git;a=shortlog) the diff of\nthe patch I've just pushed.\n\nThe patch is \"Fix correct permissions on this excutable script\",\ncurrently the HEAD of qgit repo. The content it's only a file mode\nchange in helpgen.sh, so it' an 'empty' patch.\n\nI've done something wrong or it's gitweb that does not show this info?\n\nThanks\nMarco\n"},{"id":"25891","messageId":"ecnet5$q78$1@sea.gmane.org","threadId":"5369","inReplyTo":"e5bfff550608251032p53ba203fl27af782c765f929f@mail.gmail.com","subject":"Re: [PATCH/RFC 1/x] gitweb: Use git-diff-tree patch output for commitdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T18:18:19Z","receivedAt":"2006-08-25T18:18:19Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Marco Costalba wrote:\n\n>> >>    Empty patches (mode changes and pure renames and copying)\n>> >>    are not written currently.\n>> >\n>> > That's quite bad.\n>>\n>> This can be easily changed. Question: what format? Current \"gitweb diff\n> \n> I don't know if has always been like this, but I don't see on gitweb\n> (http://www.kernel.org/git/?p=qgit/qgit.git;a=shortlog) the diff of\n> the patch I've just pushed.\n> \n> The patch is \"Fix correct permissions on this excutable script\",\n> currently the HEAD of qgit repo. The content it's only a file mode\n> change in helpgen.sh, so it' an 'empty' patch.\n> \n> I've done something wrong or it's gitweb that does not show this info?\n\nIt is visible in \"commit\" view, but is not visible in either \"commitdiff\",\nor \"blobdiff\".\n\nSupport for showing this kind of changes is planned... but of course\nyou would have to wait for kernel.org to update their gitweb.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25895","messageId":"200608252059.39971.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 11/19] gitweb: Allow for pre-parsed difftree info in git_patchset_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T18:59:39Z","receivedAt":"2006-08-25T18:59:39Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Preparation for converting git_blobdiff and git_blobdiff_plain\nto use git-diff-tree patch format to generate patches.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |   55 ++++++++++++++++++++++++++++------------------------\n 1 files changed, 30 insertions(+), 25 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex a3553ad..461ebcd 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1624,7 +1624,7 @@ sub git_patchset_body {\n \tmy $patch_idx = 0;\n \tmy $in_header = 0;\n \tmy $patch_found = 0;\n-\tmy %diffinfo;\n+\tmy $diffinfo;\n \n \tprint \"<div class=\\\"patchset\\\">\\n\";\n \n@@ -1643,54 +1643,59 @@ sub git_patchset_body {\n \t\t\t}\n \t\t\tprint \"<div class=\\\"patch\\\">\\n\";\n \n-\t\t\t%diffinfo = parse_difftree_raw_line($difftree->[$patch_idx++]);\n+\t\t\tif (ref($difftree->[$patch_idx]) eq \"HASH\") {\n+\t\t\t\t$diffinfo = $difftree->[$patch_idx];\n+\t\t\t} else {\n+\t\t\t\t$diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]);\n+\t\t\t}\n+\t\t\t$patch_idx++;\n \n \t\t\t# for now, no extended header, hence we skip empty patches\n \t\t\t# companion to\tnext LINE if $in_header;\n-\t\t\tif ($diffinfo{'from_id'} eq $diffinfo{'to_id'}) { # no change\n+\t\t\tif ($diffinfo->{'from_id'} eq $diffinfo->{'to_id'}) { # no change\n \t\t\t\t$in_header = 1;\n \t\t\t\tnext LINE;\n \t\t\t}\n \n-\t\t\tif ($diffinfo{'status'} eq \"A\") { # added\n-\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($diffinfo{'to_mode'}) . \":\" .\n+\t\t\tif ($diffinfo->{'status'} eq \"A\") { # added\n+\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($diffinfo->{'to_mode'}) . \":\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n-\t\t\t\t                             hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'file'})},\n-\t\t\t\t              $diffinfo{'to_id'}) . \"(new)\" .\n+\t\t\t\t                             hash=>$diffinfo->{'to_id'}, file_name=>$diffinfo->{'file'})},\n+\t\t\t\t              $diffinfo->{'to_id'}) . \"(new)\" .\n \t\t\t\t      \"</div>\\n\"; # class=\"diff_info\"\n \n-\t\t\t} elsif ($diffinfo{'status'} eq \"D\") { # deleted\n-\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($diffinfo{'from_mode'}) . \":\" .\n+\t\t\t} elsif ($diffinfo->{'status'} eq \"D\") { # deleted\n+\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" . file_type($diffinfo->{'from_mode'}) . \":\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n-\t\t\t\t                             hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'file'})},\n-\t\t\t\t              $diffinfo{'from_id'}) . \"(deleted)\" .\n+\t\t\t\t                             hash=>$diffinfo->{'from_id'}, file_name=>$diffinfo->{'file'})},\n+\t\t\t\t              $diffinfo->{'from_id'}) . \"(deleted)\" .\n \t\t\t\t      \"</div>\\n\"; # class=\"diff_info\"\n \n-\t\t\t} elsif ($diffinfo{'status'} eq \"R\" || # renamed\n-\t\t\t         $diffinfo{'status'} eq \"C\") { # copied\n+\t\t\t} elsif ($diffinfo->{'status'} eq \"R\" || # renamed\n+\t\t\t         $diffinfo->{'status'} eq \"C\") { # copied\n \t\t\t\tprint \"<div class=\\\"diff_info\\\">\" .\n-\t\t\t\t      file_type($diffinfo{'from_mode'}) . \":\" .\n+\t\t\t\t      file_type($diffinfo->{'from_mode'}) . \":\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n-\t\t\t\t                             hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'from_file'})},\n-\t\t\t\t              $diffinfo{'from_id'}) .\n+\t\t\t\t                             hash=>$diffinfo->{'from_id'}, file_name=>$diffinfo->{'from_file'})},\n+\t\t\t\t              $diffinfo->{'from_id'}) .\n \t\t\t\t      \" -> \" .\n-\t\t\t\t      file_type($diffinfo{'to_mode'}) . \":\" .\n+\t\t\t\t      file_type($diffinfo->{'to_mode'}) . \":\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n-\t\t\t\t                             hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'to_file'})},\n-\t\t\t\t              $diffinfo{'to_id'});\n+\t\t\t\t                             hash=>$diffinfo->{'to_id'}, file_name=>$diffinfo->{'to_file'})},\n+\t\t\t\t              $diffinfo->{'to_id'});\n \t\t\t\tprint \"</div>\\n\"; # class=\"diff_info\"\n \n \t\t\t} else { # modified, mode changed, ...\n \t\t\t\tprint \"<div class=\\\"diff_info\\\">\" .\n-\t\t\t\t      file_type($diffinfo{'from_mode'}) . \":\" .\n+\t\t\t\t      file_type($diffinfo->{'from_mode'}) . \":\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n-\t\t\t\t                             hash=>$diffinfo{'from_id'}, file_name=>$diffinfo{'file'})},\n-\t\t\t\t              $diffinfo{'from_id'}) .\n+\t\t\t\t                             hash=>$diffinfo->{'from_id'}, file_name=>$diffinfo->{'file'})},\n+\t\t\t\t              $diffinfo->{'from_id'}) .\n \t\t\t\t      \" -> \" .\n-\t\t\t\t      file_type($diffinfo{'to_mode'}) . \":\" .\n+\t\t\t\t      file_type($diffinfo->{'to_mode'}) . \":\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n-\t\t\t\t                             hash=>$diffinfo{'to_id'}, file_name=>$diffinfo{'file'})},\n-\t\t\t\t              $diffinfo{'to_id'});\n+\t\t\t\t                             hash=>$diffinfo->{'to_id'}, file_name=>$diffinfo->{'file'})},\n+\t\t\t\t              $diffinfo->{'to_id'});\n \t\t\t\tprint \"</div>\\n\"; # class=\"diff_info\"\n \t\t\t}\n \n-- \n1.4.1.1\n"},{"id":"25894","messageId":"200608252104.13607.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 12/19] gitweb: Parse two-line from-file/to-file diff header in git_patchset_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:04:13Z","receivedAt":"2006-08-25T19:04:13Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Parse two-line from-file/to-file unified diff header in\ngit_patchset_body directly, instead of leaving pretty-printing to\nformat_diff_line function.  Hashes as from-file/to-file are replaced\nby proper from-file and to-file names (from $diffinfo); in the future\nwe can put hyperlinks there.  This makes possible to do blobdiff with\nonly blobs hashes.\n\nThe lines in two-line unified diff header have now class \"from_file\"\nand \"to_file\"; the style is chosen to match previous output (classes\n\"rem\" and \"add\" because of '-' and '+' as first character of patch\nline).\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.css  |    2 ++\n gitweb/gitweb.perl |   18 +++++++++++++++++-\n 2 files changed, 19 insertions(+), 1 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 5eaa24f..0912361 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -273,10 +273,12 @@ td.mode {\n \tfont-family: monospace;\n }\n \n+div.diff.to_file,\n div.diff.add {\n \tcolor: #008800;\n }\n \n+div.diff.from_file,\n div.diff.rem {\n \tcolor: #cc0000;\n }\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 461ebcd..9222e30 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1706,8 +1706,24 @@ sub git_patchset_body {\n \n \n \t\tif ($in_header && $patch_line =~ m/^---/) {\n-\t\t\t#print \"</div>\\n\"\n+\t\t\t#print \"</div>\\n\"; # class=\"diff extended_header\"\n \t\t\t$in_header = 0;\n+\n+\t\t\tmy $file = $diffinfo->{'from_file'};\n+\t\t\t$file  ||= $diffinfo->{'file'};\n+\t\t\t$patch_line =~ s|a/[0-9a-fA-F]{40}|a/$file|g;\n+\t\t\tprint \"<div class=\\\"diff from_file\\\">\" . esc_html($patch_line) . \"</div>\\n\";\n+\n+\t\t\t$patch_line = <$fd>;\n+\t\t\tchomp $patch_line;\n+\n+\t\t\t#$patch_line =~ m/^+++/;\n+\t\t\t$file    = $diffinfo->{'to_file'};\n+\t\t\t$file  ||= $diffinfo->{'file'};\n+\t\t\t$patch_line =~ s|b/[0-9a-fA-F]{40}|b/$file|g;\n+\t\t\tprint \"<div class=\\\"diff to_file\\\">\" . esc_html($patch_line) . \"</div>\\n\";\n+\n+\t\t\tnext LINE;\n \t\t}\n \t\tnext LINE if $in_header;\n \n-- \n1.4.1.1\n"},{"id":"25896","messageId":"200608252105.07500.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 13/19] gitweb: Add invisible hyperlink to from-file/to-file diff header","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:05:07Z","receivedAt":"2006-08-25T19:05:07Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Change replacing hashes as from-file/to-file with filenames from\ndifftree to adding invisible (except underlining on hover/mouseover)\nhyperlink to from-file/to-file blob.  /dev/null as from-file or\nto-file is not changed (is not hyperlinked).\n\nThis makes two-file from-file/to-file unified diff header parsing in\ngit_patchset_body more generic, and not only for legacy blobdiffs.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.css  |   10 ++++++++++\n gitweb/gitweb.perl |   14 ++++++++++----\n 2 files changed, 20 insertions(+), 4 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 0912361..afd9e8a 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -273,11 +273,21 @@ td.mode {\n \tfont-family: monospace;\n }\n \n+div.diff a.list {\n+\ttext-decoration: none;\n+}\n+\n+div.diff a.list:hover {\n+\ttext-decoration: underline;\n+}\n+\n+div.diff.to_file a.list,\n div.diff.to_file,\n div.diff.add {\n \tcolor: #008800;\n }\n \n+div.diff.from_file a.list,\n div.diff.from_file,\n div.diff.rem {\n \tcolor: #cc0000;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 9222e30..7e68292 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1711,8 +1711,11 @@ sub git_patchset_body {\n \n \t\t\tmy $file = $diffinfo->{'from_file'};\n \t\t\t$file  ||= $diffinfo->{'file'};\n-\t\t\t$patch_line =~ s|a/[0-9a-fA-F]{40}|a/$file|g;\n-\t\t\tprint \"<div class=\\\"diff from_file\\\">\" . esc_html($patch_line) . \"</div>\\n\";\n+\t\t\t$file = $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n+\t\t\t                               hash=>$diffinfo->{'from_id'}, file_name=>$file),\n+\t\t\t                -class => \"list\"}, esc_html($file));\n+\t\t\t$patch_line =~ s|a/.*$|a/$file|g;\n+\t\t\tprint \"<div class=\\\"diff from_file\\\">$patch_line</div>\\n\";\n \n \t\t\t$patch_line = <$fd>;\n \t\t\tchomp $patch_line;\n@@ -1720,8 +1723,11 @@ sub git_patchset_body {\n \t\t\t#$patch_line =~ m/^+++/;\n \t\t\t$file    = $diffinfo->{'to_file'};\n \t\t\t$file  ||= $diffinfo->{'file'};\n-\t\t\t$patch_line =~ s|b/[0-9a-fA-F]{40}|b/$file|g;\n-\t\t\tprint \"<div class=\\\"diff to_file\\\">\" . esc_html($patch_line) . \"</div>\\n\";\n+\t\t\t$file = $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n+\t\t\t                               hash=>$diffinfo->{'to_id'}, file_name=>$file),\n+\t\t\t                -class => \"list\"}, esc_html($file));\n+\t\t\t$patch_line =~ s|b/.*|b/$file|g;\n+\t\t\tprint \"<div class=\\\"diff to_file\\\">$patch_line</div>\\n\";\n \n \t\t\tnext LINE;\n \t\t}\n-- \n1.4.1.1\n"},{"id":"25893","messageId":"200608252105.45448.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 14/19] gitweb: Always display link to blobdiff_plain in git_blobdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:05:45Z","receivedAt":"2006-08-25T19:05:45Z","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 |   14 +++++++-------\n 1 files changed, 7 insertions(+), 7 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 7e68292..ade5d42 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2790,18 +2790,18 @@ sub git_commit {\n sub git_blobdiff {\n \tmkdir($git_temp, 0700);\n \tgit_header_html();\n+\tmy $formats_nav =\n+\t\t$cgi->a({-href => href(action=>\"blobdiff_plain\",\n+\t\t                       hash=>$hash, hash_parent=>$hash_parent,\n+\t\t                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n+\t\t                       file_name=>$file_name, file_parent=>$file_parent)},\n+\t\t        \"plain\");\n \tif (defined $hash_base && (my %co = parse_commit($hash_base))) {\n-\t\tmy $formats_nav =\n-\t\t\t$cgi->a({-href => href(action=>\"blobdiff_plain\",\n-\t\t\t                       hash=>$hash, hash_parent=>$hash_parent,\n-\t\t\t                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n-\t\t\t                       file_name=>$file_name, file_parent=>$file_parent)},\n-\t\t\t        \"plain\");\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 <<HTML;\n-<div class=\"page_nav\"><br/><br/></div>\n+<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n <div class=\"title\">$hash vs $hash_parent</div>\n HTML\n \t}\n-- \n1.4.1.1\n"},{"id":"25892","messageId":"200608252106.50047.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 15/19] gitweb: Change here-doc back for style consistency in git_blobdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:06:49Z","receivedAt":"2006-08-25T19:06:49Z","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---\nNext will be patches which get rid of external diff dependency.\n\n gitweb/gitweb.perl |    6 ++----\n 1 files changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex ade5d42..a866922 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2800,10 +2800,8 @@ sub git_blobdiff {\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 <<HTML;\n-<div class=\"page_nav\"><br/>$formats_nav<br/></div>\n-<div class=\"title\">$hash vs $hash_parent</div>\n-HTML\n+\t\tprint \"<div class=\\\"page_nav\\\"><br/>$formats_nav<br/></div>\\n\";\n+\t\tprint \"<div class=\\\"title\\\">$hash vs $hash_parent</div>\\n\";\n \t}\n \tgit_print_page_path($file_name, \"blob\", $hash_base);\n \tprint \"<div class=\\\"page_body\\\">\\n\" .\n-- \n1.4.1.1\n"},{"id":"25902","messageId":"200608252113.34731.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 16/19] gitweb: Use git-diff-tree or git-diff patch output for blobdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:13:34Z","receivedAt":"2006-08-25T19:13:34Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This is second part of removing gitweb dependency on external\ndiff (used in git_diff_print).\n\nGet rid of git_diff_print invocation in git_blobdiff, and use either\ngit-diff-tree (when both hash_base and hash_parent_base are provided)\npatch format or git-diff patch format (when only hash and hash_parent\nare provided) for output.\n\nSupported URI schemes, and output formats:\n* New URI scheme: both hash_base and hash_parent_base (trees-ish\n  containing blobs versions we want to compare) are provided.\n  Also either filename is provided, or hash (of blob) is provided\n  (we try to find filename then).\n\n  For this scheme we have copying and renames detection, mode changes,\n  file types etc., and information extended diff header is correct.\n\n* Old URI scheme: hash_parent_base is not provided, we use hash and\n  hash_parent to directly compare blobs using git-diff. If no filename\n  is given, blobs hashes are used in place of filenames.\n\n  This scheme has always \"blob\" as file type, it cannot detect mode\n  changes, and we rely on CGI parameters to provide name of the file.\n\nAdded git_to_hash subroutine, which transforms symbolic name or list\nof symbolic name to hash or list of hashes using git-rev-parse.\n\nTo have \"blob\" instead of \"unknown\" (or \"file\" regardless of the type)\nin \"gitweb diff header\" for legacy scheme, file_type function now\nreturns its argument if it is not octal string.\n\nAdded support for fake \"2\" status code in git_patchset_body. Such code\nis generated by git_blobdiff in legacy scheme case.\n\nATTENTION: The order of arguments (operands) to git-diff is reversed\n(sic!) to have correct diff in the legacy (no hash_parent_base) case.\n$hash_parent, $hash ordering is commented out, as it gives reversed\npatch (at least for git version 1.4.1.1) as compared to output in new\nscheme and output of older gitweb version.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nP.S. This is the place to mention that it would be nice to have in \ngitweb/README specification what minimal version of git is needed\nfor some gitweb features; e.g. \"history\" relies on having --full-history\noption to git-rev-list, \"blobdiff\" (and later \"blobdiff_plain\") relies\non git-diff which accepts blob hashes, and relies on bug in git-diff...\n\n gitweb/gitweb.perl |  149 ++++++++++++++++++++++++++++++++++++++++++++++------\n 1 files changed, 132 insertions(+), 17 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex a866922..9be2b2c 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -454,7 +454,13 @@ sub mode_str {\n \n # convert file mode in octal to file type string\n sub file_type {\n-\tmy $mode = oct shift;\n+\tmy $mode = shift;\n+\n+\tif ($mode !~ m/^[0-7]+$/) {\n+\t\treturn $mode;\n+\t} else {\n+\t\t$mode = oct $mode;\n+\t}\n \n \tif (S_ISDIR($mode & S_IFMT)) {\n \t\treturn \"directory\";\n@@ -618,6 +624,26 @@ sub git_get_hash_by_path {\n \treturn $3;\n }\n \n+# converts symbolic name to hash\n+sub git_to_hash {\n+\tmy @params = @_;\n+\treturn undef unless @params;\n+\n+\topen my $fd, \"-|\", $GIT, \"rev-parse\", @params\n+\t\tor return undef;\n+\tmy @hashes = map { chomp; $_ } <$fd>;\n+\tclose $fd;\n+\n+\tif (wantarray) {\n+\t\treturn @hashes;\n+\t} elsif (scalar(@hashes) == 1) {\n+\t\t# single hash\n+\t\treturn $hashes[0];\n+\t} else {\n+\t\treturn \\@hashes;\n+\t}\n+}\n+\n ## ......................................................................\n ## git utility functions, directly accessing git repository\n \n@@ -1672,7 +1698,8 @@ sub git_patchset_body {\n \t\t\t\t      \"</div>\\n\"; # class=\"diff_info\"\n \n \t\t\t} elsif ($diffinfo->{'status'} eq \"R\" || # renamed\n-\t\t\t         $diffinfo->{'status'} eq \"C\") { # copied\n+\t\t\t         $diffinfo->{'status'} eq \"C\" || # copied\n+\t\t\t         $diffinfo->{'status'} eq \"2\") { # with two filenames (from git_blobdiff)\n \t\t\t\tprint \"<div class=\\\"diff_info\\\">\" .\n \t\t\t\t      file_type($diffinfo->{'from_mode'}) . \":\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash_parent,\n@@ -2788,14 +2815,102 @@ sub git_commit {\n }\n \n sub git_blobdiff {\n-\tmkdir($git_temp, 0700);\n-\tgit_header_html();\n+\tmy $fd;\n+\tmy @difftree;\n+\tmy %diffinfo;\n+\n+\t# preparing $fd and %diffinfo for git_patchset_body\n+\t# new style URI\n+\tif (defined $hash_base && defined $hash_parent_base) {\n+\t\tif (defined $file_name) {\n+\t\t\t# read raw output\n+\t\t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-M', '-C', $hash_parent_base, $hash_base,\n+\t\t\t\t\"--\", $file_name\n+\t\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\t\t\t@difftree = map { chomp; $_ } <$fd>;\n+\t\t\tclose $fd\n+\t\t\t\tor die_error(undef, \"Reading git-diff-tree failed\");\n+\t\t\t@difftree\n+\t\t\t\tor die_error('404 Not Found', \"Blob diff not found\");\n+\n+\t\t} elsif (defined $hash) { # try to find filename from $hash\n+\t\t\tif ($hash !~ /[0-9a-fA-F]{40}/) {\n+\t\t\t\t$hash = git_to_hash($hash);\n+\t\t\t}\n+\n+\t\t\t# read filtered raw output\n+\t\t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-M', '-C', $hash_parent_base, $hash_base\n+\t\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\t\t\t@difftree =\n+\t\t\t\t# ':100644 100644 03b21826... 3b93d5e7... M\tls-files.c'\n+\t\t\t\t# $hash == to_id\n+\t\t\t\tgrep { /^:[0-7]{6} [0-7]{6} [0-9a-fA-F]{40} $hash/ }\n+\t\t\t\tmap { chomp; $_ } <$fd>;\n+\t\t\tclose $fd\n+\t\t\t\tor die_error(undef, \"Reading git-diff-tree failed\");\n+\t\t\t@difftree\n+\t\t\t\tor die_error('404 Not Found', \"Blob diff not found\");\n+\n+\t\t} else {\n+\t\t\tdie_error('404 Not Found', \"Missing one of the blob diff parameters\");\n+\t\t}\n+\n+\t\tif (@difftree > 1) {\n+\t\t\tdie_error('404 Not Found', \"Ambiguous blob diff specification\");\n+\t\t}\n+\n+\t\t%diffinfo = parse_difftree_raw_line($difftree[0]);\n+\t\t$file_parent ||= $diffinfo{'from_file'} || $file_name || $diffinfo{'file'};\n+\t\t$file_name   ||= $diffinfo{'to_file'}   || $diffinfo{'file'};\n+\n+\t\t$hash_parent ||= $diffinfo{'from_id'};\n+\t\t$hash        ||= $diffinfo{'to_id'};\n+\n+\t\t# open patch output\n+\t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-p', '-M', '-C', $hash_parent_base, $hash_base,\n+\t\t\t\"--\", $file_name\n+\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\t}\n+\n+\t# old/legacy style URI\n+\tif (!%diffinfo && # if new style URI failed\n+\t    defined $hash && defined $hash_parent) {\n+\t\t# fake git-diff-tree raw output\n+\t\t$diffinfo{'from_mode'} = $diffinfo{'to_mode'} = \"blob\";\n+\t\t$diffinfo{'from_id'} = $hash_parent;\n+\t\t$diffinfo{'to_id'}   = $hash;\n+\t\tif (defined $file_name) {\n+\t\t\tif (defined $file_parent) {\n+\t\t\t\t$diffinfo{'status'} = '2';\n+\t\t\t\t$diffinfo{'from_file'} = $file_parent;\n+\t\t\t\t$diffinfo{'to_file'}   = $file_name;\n+\t\t\t} else { # assume not renamed\n+\t\t\t\t$diffinfo{'status'} = '1';\n+\t\t\t\t$diffinfo{'from_file'} = $file_name;\n+\t\t\t\t$diffinfo{'to_file'}   = $file_name;\n+\t\t\t}\n+\t\t} else { # no filename given\n+\t\t\t$diffinfo{'status'} = '2';\n+\t\t\t$diffinfo{'from_file'} = $hash_parent;\n+\t\t\t$diffinfo{'to_file'}   = $hash;\n+\t\t}\n+\n+\t\t#open $fd, \"-|\", $GIT, \"diff\", '-p', $hash_parent, $hash\n+\t\topen $fd, \"-|\", $GIT, \"diff\", '-p', $hash, $hash_parent\n+\t\t\tor die_error(undef, \"Open git-diff failed\");\n+\t} else  {\n+\t\tdie_error('404 Not Found', \"Missing one of the blob diff parameters\")\n+\t\t\tunless %diffinfo;\n+\t}\n+\n+\t# header\n \tmy $formats_nav =\n \t\t$cgi->a({-href => href(action=>\"blobdiff_plain\",\n \t\t                       hash=>$hash, hash_parent=>$hash_parent,\n \t\t                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n \t\t                       file_name=>$file_name, file_parent=>$file_parent)},\n \t\t        \"plain\");\n+\tgit_header_html();\n \tif (defined $hash_base && (my %co = parse_commit($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@@ -2803,19 +2918,19 @@ sub git_blobdiff {\n \t\tprint \"<div class=\\\"page_nav\\\"><br/>$formats_nav<br/></div>\\n\";\n \t\tprint \"<div class=\\\"title\\\">$hash vs $hash_parent</div>\\n\";\n \t}\n-\tgit_print_page_path($file_name, \"blob\", $hash_base);\n-\tprint \"<div class=\\\"page_body\\\">\\n\" .\n-\t      \"<div class=\\\"diff_info\\\">blob:\" .\n-\t      $cgi->a({-href => href(action=>\"blob\", hash=>$hash_parent,\n-\t                             hash_base=>$hash_parent_base, file_name=>($file_parent || $file_name))},\n-\t              $hash_parent) .\n-\t      \" -> blob:\" .\n-\t      $cgi->a({-href => href(action=>\"blob\", hash=>$hash,\n-\t                             hash_base=>$hash_base, file_name=>$file_name)},\n-\t              $hash) .\n-\t      \"</div>\\n\";\n-\tgit_diff_print($hash_parent, $file_name || $hash_parent, $hash, $file_name || $hash);\n-\tprint \"</div>\"; # page_body\n+\tif (defined $file_name) {\n+\t\tgit_print_page_path($file_name, \"blob\", $hash_base);\n+\t} else {\n+\t\tprint \"<div class=\\\"page_path\\\"></div>\\n\";\n+\t}\n+\n+\t# patch\n+\tprint \"<div class=\\\"page_body\\\">\\n\";\n+\n+\tgit_patchset_body($fd, [ \\%diffinfo ], $hash_base, $hash_parent_base);\n+\tclose $fd;\n+\n+\tprint \"</div>\\n\"; # class=\"page_body\"\n \tgit_footer_html();\n }\n \n-- \n1.4.1.1\n"},{"id":"25901","messageId":"200608252114.50142.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 17/19] gitweb: git_blobdiff_plain is git_blobdiff('plain')","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:14:49Z","receivedAt":"2006-08-25T19:14:49Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"git_blobdiff and git_blobdiff_plain are now collapsed into one\nsubroutine git_blobdiff, with format (currently 'html' which is\ndefault format corresponding to git_blobdiff, and 'plain'\ncorresponding to git_blobdiff_plain) specified in argument.\n\nblobdiff_plain format is now generated either by git-diff-tree\nor by git-diff.  Added X-Git-Url: header.  From-file and to-file name\nin header are corrected.\n\nNote that for now commitdiff_plain does not detect renames \nand copying, while blobdiff_plain does.\n\nWhile at it, set expires to \"+1d\" for non-textual hash ids.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n\n gitweb/gitweb.perl |   95 ++++++++++++++++++++++++++++++++++++++--------------\n 1 files changed, 69 insertions(+), 26 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 9be2b2c..b20640e 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2815,9 +2815,12 @@ sub git_commit {\n }\n \n sub git_blobdiff {\n+\tmy $format = shift || 'html';\n+\n \tmy $fd;\n \tmy @difftree;\n \tmy %diffinfo;\n+\tmy $expires;\n \n \t# preparing $fd and %diffinfo for git_patchset_body\n \t# new style URI\n@@ -2866,6 +2869,12 @@ sub git_blobdiff {\n \t\t$hash_parent ||= $diffinfo{'from_id'};\n \t\t$hash        ||= $diffinfo{'to_id'};\n \n+\t\t# non-textual hash id's can be cached\n+\t\tif ($hash_base =~ m/^[0-9a-fA-F]{40}$/ &&\n+\t\t    $hash_parent_base =~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t\t$expires = '+1d';\n+\t\t}\n+\n \t\t# open patch output\n \t\topen $fd, \"-|\", $GIT, \"diff-tree\", '-r', '-p', '-M', '-C', $hash_parent_base, $hash_base,\n \t\t\t\"--\", $file_name\n@@ -2894,7 +2903,14 @@ sub git_blobdiff {\n \t\t\t$diffinfo{'from_file'} = $hash_parent;\n \t\t\t$diffinfo{'to_file'}   = $hash;\n \t\t}\n \n+\t\t# non-textual hash id's can be cached\n+\t\tif ($hash =~ m/^[0-9a-fA-F]{40}$/ &&\n+\t\t    $hash_parent =~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t\t$expires = '+1d';\n+\t\t}\n+\n+\t\t# open patch output\n \t\t#open $fd, \"-|\", $GIT, \"diff\", '-p', $hash_parent, $hash\n \t\topen $fd, \"-|\", $GIT, \"diff\", '-p', $hash, $hash_parent\n \t\t\tor die_error(undef, \"Open git-diff failed\");\n@@ -2904,40 +2920,67 @@ sub git_blobdiff {\n \t}\n \n \t# header\n-\tmy $formats_nav =\n-\t\t$cgi->a({-href => href(action=>\"blobdiff_plain\",\n-\t\t                       hash=>$hash, hash_parent=>$hash_parent,\n-\t\t                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n-\t\t                       file_name=>$file_name, file_parent=>$file_parent)},\n-\t\t        \"plain\");\n-\tgit_header_html();\n-\tif (defined $hash_base && (my %co = parse_commit($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\\\"><br/>$formats_nav<br/></div>\\n\";\n-\t\tprint \"<div class=\\\"title\\\">$hash vs $hash_parent</div>\\n\";\n-\t}\n-\tif (defined $file_name) {\n-\t\tgit_print_page_path($file_name, \"blob\", $hash_base);\n+\tif ($format eq 'html') {\n+\t\tmy $formats_nav =\n+\t\t\t$cgi->a({-href => href(action=>\"blobdiff_plain\",\n+\t\t\t                       hash=>$hash, hash_parent=>$hash_parent,\n+\t\t\t                       hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n+\t\t\t                       file_name=>$file_name, file_parent=>$file_parent)},\n+\t\t\t        \"plain\");\n+\t\tgit_header_html(undef, $expires);\n+\t\tif (defined $hash_base && (my %co = parse_commit($hash_base))) {\n+\t\t\tgit_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav);\n+\t\t\tgit_print_header_div('commit', esc_html($co{'title'}), $hash_base);\n+\t\t} else {\n+\t\t\tprint \"<div class=\\\"page_nav\\\"><br/>$formats_nav<br/></div>\\n\";\n+\t\t\tprint \"<div class=\\\"title\\\">$hash vs $hash_parent</div>\\n\";\n+\t\t}\n+\t\tif (defined $file_name) {\n+\t\t\tgit_print_page_path($file_name, \"blob\", $hash_base);\n+\t\t} else {\n+\t\t\tprint \"<div class=\\\"page_path\\\"></div>\\n\";\n+\t\t}\n+\n+\t} elsif ($format eq 'plain') {\n+\t\tprint $cgi->header(\n+\t\t\t-type => 'text/plain',\n+\t\t\t-charset => 'utf-8',\n+\t\t\t-expires => $expires,\n+\t\t\t-content_disposition => qq(inline; filename=\"${file_name}.patch\"));\n+\n+\t\tprint \"X-Git-Url: \" . $cgi->self_url() . \"\\n\\n\";\n+\n \t} else {\n-\t\tprint \"<div class=\\\"page_path\\\"></div>\\n\";\n+\t\tdie_error(undef, \"Unknown blobdiff format\");\n \t}\n \n \t# patch\n-\tprint \"<div class=\\\"page_body\\\">\\n\";\n+\tif ($format eq 'html') {\n+\t\tprint \"<div class=\\\"page_body\\\">\\n\";\n \n-\tgit_patchset_body($fd, [ \\%diffinfo ], $hash_base, $hash_parent_base);\n-\tclose $fd;\n+\t\tgit_patchset_body($fd, [ \\%diffinfo ], $hash_base, $hash_parent_base);\n+\t\tclose $fd;\n \n-\tprint \"</div>\\n\"; # class=\"page_body\"\n-\tgit_footer_html();\n+\t\tprint \"</div>\\n\"; # class=\"page_body\"\n+\t\tgit_footer_html();\n+\n+\t} else {\n+\t\twhile (my $line = <$fd>) {\n+\t\t\t$line =~ s!a/($hash|$hash_parent)!a/$diffinfo{'from_file'}!g;\n+\t\t\t$line =~ s!b/($hash|$hash_parent)!b/$diffinfo{'to_file'}!g;\n+\n+\t\t\tprint $line;\n+\n+\t\t\tlast if $line =~ m!^\\+\\+\\+!;\n+\t\t}\n+\t\tlocal $/ = undef;\n+\t\tprint <$fd>;\n+\t\tclose $fd;\n+\t}\n }\n \n sub git_blobdiff_plain {\n-\tmkdir($git_temp, 0700);\n-\tprint $cgi->header(-type => \"text/plain\", -charset => 'utf-8');\n-\tgit_diff_print($hash_parent, $file_name || $hash_parent, $hash, $file_name || $hash, \"plain\");\n+\tgit_blobdiff('plain');\n }\n \n sub git_commitdiff {\n-- \n1.4.1.1\n"},{"id":"25899","messageId":"200608252115.27881.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 18/19] gitweb: Remove git_diff_print subroutine","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:15:27Z","receivedAt":"2006-08-25T19:15:27Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Remove git_diff_print subroutine, used to print diff in previous\nversions of \"diff\" actions, namely git_commitdiff,\ngit_commitdiff_plain, git_blobdiff, git_blobdiff_plain.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |   71 ----------------------------------------------------\n 1 files changed, 0 insertions(+), 71 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex b20640e..2f932f0 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1975,77 +1975,6 @@ sub git_heads_body {\n \tprint \"</table>\\n\";\n }\n \n-## ----------------------------------------------------------------------\n-## functions printing large fragments, format as one of arguments\n-\n-sub git_diff_print {\n-\tmy $from = shift;\n-\tmy $from_name = shift;\n-\tmy $to = shift;\n-\tmy $to_name = shift;\n-\tmy $format = shift || \"html\";\n-\n-\tmy $from_tmp = \"/dev/null\";\n-\tmy $to_tmp = \"/dev/null\";\n-\tmy $pid = $$;\n-\n-\t# create tmp from-file\n-\tif (defined $from) {\n-\t\t$from_tmp = \"$git_temp/gitweb_\" . $$ . \"_from\";\n-\t\topen my $fd2, \"> $from_tmp\";\n-\t\topen my $fd, \"-|\", $GIT, \"cat-file\", \"blob\", $from;\n-\t\tmy @file = <$fd>;\n-\t\tprint $fd2 @file;\n-\t\tclose $fd2;\n-\t\tclose $fd;\n-\t}\n-\n-\t# create tmp to-file\n-\tif (defined $to) {\n-\t\t$to_tmp = \"$git_temp/gitweb_\" . $$ . \"_to\";\n-\t\topen my $fd2, \"> $to_tmp\";\n-\t\topen my $fd, \"-|\", $GIT, \"cat-file\", \"blob\", $to;\n-\t\tmy @file = <$fd>;\n-\t\tprint $fd2 @file;\n-\t\tclose $fd2;\n-\t\tclose $fd;\n-\t}\n-\n-\topen my $fd, \"-|\", \"/usr/bin/diff -u -p -L \\'$from_name\\' -L \\'$to_name\\' $from_tmp $to_tmp\";\n-\tif ($format eq \"plain\") {\n-\t\tundef $/;\n-\t\tprint <$fd>;\n-\t\t$/ = \"\\n\";\n-\t} else {\n-\t\twhile (my $line = <$fd>) {\n-\t\t\tchomp $line;\n-\t\t\tmy $char = substr($line, 0, 1);\n-\t\t\tmy $diff_class = \"\";\n-\t\t\tif ($char eq '+') {\n-\t\t\t\t$diff_class = \" add\";\n-\t\t\t} elsif ($char eq \"-\") {\n-\t\t\t\t$diff_class = \" rem\";\n-\t\t\t} elsif ($char eq \"@\") {\n-\t\t\t\t$diff_class = \" chunk_header\";\n-\t\t\t} elsif ($char eq \"\\\\\") {\n-\t\t\t\t# skip errors\n-\t\t\t\tnext;\n-\t\t\t}\n-\t\t\t$line = untabify($line);\n-\t\t\tprint \"<div class=\\\"diff$diff_class\\\">\" . esc_html($line) . \"</div>\\n\";\n-\t\t}\n-\t}\n-\tclose $fd;\n-\n-\tif (defined $from) {\n-\t\tunlink($from_tmp);\n-\t}\n-\tif (defined $to) {\n-\t\tunlink($to_tmp);\n-\t}\n-}\n-\n-\n ## ======================================================================\n ## ======================================================================\n ## actions\n-- \n1.4.1.1\n"},{"id":"25900","messageId":"200608252135.27894.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T19:35:27Z","receivedAt":"2006-08-25T19:35:27Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Remove $git_temp variable which held location for temporary files\nneeded by git_diff_print, and removed creating $git_temp directory.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nThis is last patch in this (admittedly quite large) series, removing\ndependency on external diff, and the need for temporary files, from\ngitweb.\n\nYou can view new gitweb in work at\n  http://front.fuw.edu.pl/cgi-bin/jnareb/gitweb.cgi\n\nChanges are in branch \"gitweb/web\" in repository available at\n  http://front.fuw.edu.pl/jnareb/scm/git.git/\n\nComments appreciated.\n\n\n gitweb/gitweb.perl |    6 ------\n 1 files changed, 0 insertions(+), 6 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 2f932f0..a6d6637 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -31,9 +31,6 @@ # absolute fs-path which will be prepend\n #our $projectroot = \"/pub/scm\";\n our $projectroot = \"++GITWEB_PROJECTROOT++\";\n \n-# location for temporary files needed for diffs\n-our $git_temp = \"/tmp/gitweb\";\n-\n # target of the home link on top of all pages\n our $home_link = $my_uri || \"/\";\n \n@@ -144,9 +141,6 @@ # version of the core git binary\n our $git_version = qx($GIT --version) =~ m/git version (.*)$/ ? $1 : \"unknown\";\n \n $projects_list ||= $projectroot;\n-if (! -d $git_temp) {\n-\tmkdir($git_temp, 0700) || die_error(undef, \"Couldn't mkdir $git_temp\");\n-}\n \n # ======================================================================\n # input validation and dispatch\n-- \n1.4.1.1\n"},{"id":"25904","messageId":"200608252315.57181.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608240015.15071.jnareb@gmail.com","subject":"[PATCH 00/19] gitweb: Remove dependency on external diff and need for temporary files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T21:15:56Z","receivedAt":"2006-08-25T21:15:56Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This series of patches (now finished) removes dependency on\nexternal diff (/usr/bin/diff) to produce commitdiff and blobdiff\nviews, and the need for temporary files.\n\nComments appreciated.\n\nYou can view new gitweb in work at\n  http://front.fuw.edu.pl/cgi-bin/jnareb/gitweb.cgi\n---\n gitweb/gitweb.css  |   16 +\n gitweb/gitweb.perl |  734 +++++++++++++++++++++++++++++++++++-----------------\n 2 files changed, 515 insertions(+), 235 deletions(-)\n\n\nShortlog:\n\n01/19 gitweb: Use git-diff-tree patch output for commitdiff\n02/19 gitweb: Replace git_commitdiff_plain by anonymous subroutine\n03/19 gitweb: Show information about incomplete lines in commitdiff\n      Revert \"gitweb: Replace git_commitdiff_plain by anonymous\n              subroutine\"\n04/19 gitweb: Remove invalid comment in format_diff_line\n05/19 gitweb: Streamify patch output in git_commitdiff\n06/19 gitweb: Add git_get_{following,preceding}_references functions\n07/19 gitweb: Return on first ref found when\n      git_get_preceding_references is called in scalar context\n08/19 gitweb: Add git_get_rev_name_tags function\n09/19 gitweb: Use git_get_name_rev_tags for commitdiff_plain \n      X-Git-Tag: header\n10/19 gitweb: Add support for hash_parent_base parameter for blobdiffs\n11/19 gitweb: Allow for pre-parsed difftree info in git_patchset_body\n12/19 gitweb: Parse two-line from-file/to-file diff header\n      in git_patchset_body\n13/19 gitweb: Add invisible hyperlink to from-file/to-file diff header\n14/19 gitweb: Always display link to blobdiff_plain in git_blobdiff\n15/19 gitweb: Change here-doc back for consistency in git_blobdiff\n16/19 gitweb: Use git-diff-tree or git-diff patch output for blobdiff\n17/19 gitweb: git_blobdiff_plain is git_blobdiff('plain')\n18/19 gitweb: Remove git_diff_print subroutine\n19/19 gitweb: Remove creating directory for temporary files\n\n-- \nJakub Narebski\nShadeHawk on #git\nPoland\n"},{"id":"25906","messageId":"e5bfff550608251433o36713ee1na5544992320b5845@mail.gmail.com","threadId":"5369","inReplyTo":"200608252135.27894.jnareb@gmail.com","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Marco Costalba","fromEmail":"mcostalba@gmail.com","sentAt":"2006-08-25T21:33:45Z","receivedAt":"2006-08-25T21:33:45Z","isPatch":true,"sender":{"key":"mcostalba@gmail.com","avatar":null},"body":">\n> You can view new gitweb in work at\n>   http://front.fuw.edu.pl/cgi-bin/jnareb/gitweb.cgi\n>\n\nVery nice job!\n\nJust a couple of suggestion regarding blame.\n\n- Instead of commit sha perhaps is more useful to show author name\n(linked to commit) and progressive number of revision.\n\n- Original code lines, ie. imported at the beginning and never\nmodified, perhaps it is better to view without commit number, this\ncould obfuscate the view and in any case is not an accurate info\nbecause the line was not modified during initial patch.\n[Note] Also in qgit there was the annotation of the first initial\ncommit in case of unmodified code lines, then Ingo Molnar suggest me\nto remove that line and leave it blank for the reasons I reported\nabove. I think he was right.\n\nMarco\n"},{"id":"25907","messageId":"ecnr6u$tu$1@sea.gmane.org","threadId":"5369","inReplyTo":"e5bfff550608251433o36713ee1na5544992320b5845@mail.gmail.com","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-25T21:48:21Z","receivedAt":"2006-08-25T21:48:21Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Marco Costalba wrote:\n\n>> You can view new gitweb in work at\n>>   http://front.fuw.edu.pl/cgi-bin/jnareb/gitweb.cgi\n>>\n> \n> Very nice job!\n> \n> Just a couple of suggestion regarding blame.\n\nWell, blame code is not mine. \n\nLuben Tuikov did some work on git_blame2 (using git-blame), original work\nwas by Florian Forster (using git-annotate). At least it is what I found.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25910","messageId":"200608260226.25966.Josef.Weidendorfer@gmx.de","threadId":"5369","inReplyTo":"200608252135.27894.jnareb@gmail.com","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Josef Weidendorfer","fromEmail":"josef.weidendorfer@gmx.de","sentAt":"2006-08-26T00:26:25Z","receivedAt":"2006-08-26T00:26:25Z","isPatch":true,"sender":{"key":"josef.weidendorfer@gmx.de","avatar":null},"body":"On Friday 25 August 2006 21:35, you wrote:\n> You can view new gitweb in work at\n>   http://front.fuw.edu.pl/cgi-bin/jnareb/gitweb.cgi\n\nHmm... history pages seem not to work.\nOtherwise, looks fine.\n\nJosef\n"},{"id":"25912","messageId":"eco5kh$pl3$1@sea.gmane.org","threadId":"5369","inReplyTo":"200608260226.25966.Josef.Weidendorfer@gmx.de","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-26T00:46:18Z","receivedAt":"2006-08-26T00:46:18Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Josef Weidendorfer wrote:\n\n> On Friday 25 August 2006 21:35, you wrote:\n>> You can view new gitweb in work at\n>>   http://front.fuw.edu.pl/cgi-bin/jnareb/gitweb.cgi\n> \n> Hmm... history pages seem not to work.\n> Otherwise, looks fine.\n\nProbably git core on this machine (version 1.3.0) is too old and doesn't\nsupport --full-history option to git-rev-list, needed by git_history.\n\nRelevant changes were made to commitdiff, comitdiff_plain, blobdiff and\nblobdiff_plain views.\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25914","messageId":"7vveog45ff.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"e5bfff550608251433o36713ee1na5544992320b5845@mail.gmail.com","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-26T02:05:56Z","receivedAt":"2006-08-26T02:05:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Marco Costalba\" <mcostalba@gmail.com> writes:\n\n>> You can view new gitweb in work at\n>>   http://front.fuw.edu.pl/cgi-bin/jnareb/gitweb.cgi\n>\n> Very nice job!\n>\n> Just a couple of suggestion regarding blame.\n>\n> - Instead of commit sha perhaps is more useful to show author name\n> (linked to commit) and progressive number of revision.\n\nRemember git history is not linear so progressive number does\nnot make much sense here.  I agree author and commit date would\nbe nice if they were readily available without cluttering.\nA pop-up when hovered, perhaps?\n\n> - Original code lines, ie. imported at the beginning and never\n> modified, perhaps it is better to view without commit number, this\n> could obfuscate the view and in any case is not an accurate info\n> because the line was not modified during initial patch.\n\nThat holds only true for very young projects, or ones that were\nperfect from the beginning and did not see much action ;-).\n"},{"id":"25917","messageId":"e5bfff550608252144p2d234a7cnf2ca2922c98d921b@mail.gmail.com","threadId":"5369","inReplyTo":"7vveog45ff.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Marco Costalba","fromEmail":"mcostalba@gmail.com","sentAt":"2006-08-26T04:44:44Z","receivedAt":"2006-08-26T04:44:44Z","isPatch":true,"sender":{"key":"mcostalba@gmail.com","avatar":null},"body":"> > - Original code lines, ie. imported at the beginning and never\n> > modified, perhaps it is better to view without commit number, this\n> > could obfuscate the view and in any case is not an accurate info\n> > because the line was not modified during initial patch.\n>\n> That holds only true for very young projects, or ones that were\n> perfect from the beginning and did not see much action ;-).\n>\n\nOr also for projects like Linux ;-)\n\nSee blame output of something like kernel/dma.c or also kernel/exit.c,\nnot exactly the most unknown files around.\n"},{"id":"25918","messageId":"7vejv43wq9.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"e5bfff550608252144p2d234a7cnf2ca2922c98d921b@mail.gmail.com","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-26T05:13:50Z","receivedAt":"2006-08-26T05:13:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Marco Costalba\" <mcostalba@gmail.com> writes:\n\n>> > - Original code lines, ie. imported at the beginning and never\n>> > modified, perhaps it is better to view without commit number, this\n>> > could obfuscate the view and in any case is not an accurate info\n>> > because the line was not modified during initial patch.\n>>\n>> That holds only true for very young projects, or ones that were\n>> perfect from the beginning and did not see much action ;-).\n>\n> Or also for projects like Linux ;-)\n>\n> See blame output of something like kernel/dma.c or also kernel/exit.c,\n> not exactly the most unknown files around.\n\nActually Linux git archive _is_ a special, odd-ball case.  Their\ninitial commit (2.6.12-rc2) contains all the fruits from their\n10 years of evolution without git.\n\nPeople with long history stored in some SCM tend to want to\nmigrate their history and then switch, and I expect that to be\nthe norm, especially with the progress Mozilla import team is\nmaking with the CVS interface.\n"},{"id":"25919","messageId":"e5bfff550608252234u6d4e9efax8ca7e2225cef4cef@mail.gmail.com","threadId":"5369","inReplyTo":"7vejv43wq9.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Marco Costalba","fromEmail":"mcostalba@gmail.com","sentAt":"2006-08-26T05:34:34Z","receivedAt":"2006-08-26T05:34:34Z","isPatch":true,"sender":{"key":"mcostalba@gmail.com","avatar":null},"body":"> Actually Linux git archive _is_ a special, odd-ball case.\n\nIt's also our main customer ;-)\n"},{"id":"25920","messageId":"20060826054002.GA22343@spearce.org","threadId":"5369","inReplyTo":"7vejv43wq9.fsf@assigned-by-dhcp.cox.net","subject":"Re: Mozilla import and large history","fromName":"Shawn Pearce","fromEmail":"spearce@spearce.org","sentAt":"2006-08-26T05:40:02Z","receivedAt":"2006-08-26T05:40:02Z","isPatch":false,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> People with long history stored in some SCM tend to want to\n> migrate their history and then switch, and I expect that to be\n> the norm, especially with the progress Mozilla import team is\n> making with the CVS interface.\n\nNot to hijack a thread or anything but we are definately making\nsome progress here.  Jon Smirl is able to import blob revisions,\ncreate trees, commits and tags.  Import for Mozilla is down from\napprox. a week to around 4 hours but right now we are finding that\nthe import isn't always correct.\n\nFortunately we've built a script to compare the result of the import\ninto GIT with the result of the import into SVN, as the cvs2svn\nimport is believed to be correct.  The script is not however very\nfast, as it compares an SVN revision to the corresponding GIT tree\nby checking out the SVN revision to a working directory, loading\nthe GIT tree into an index and using git-diff-files to compare them.\n\nThat simple script has caught a number of errors but has also\nconfirmed a number of cases as working correctly.  We're slowly\nworking through the errors.\n\nWe may also do a CVS checkout based script to verify branch heads\nand labels all match, just as an extra check against what the native\nSVN import had given.\n\n-- \nShawn.\n"},{"id":"25921","messageId":"e5bfff550608252243n61ac8adar78c292f2f1cee50c@mail.gmail.com","threadId":"5369","inReplyTo":"e5bfff550608252234u6d4e9efax8ca7e2225cef4cef@mail.gmail.com","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Marco Costalba","fromEmail":"mcostalba@gmail.com","sentAt":"2006-08-26T05:43:04Z","receivedAt":"2006-08-26T05:43:04Z","isPatch":true,"sender":{"key":"mcostalba@gmail.com","avatar":null},"body":"On 8/26/06, Marco Costalba <mcostalba@gmail.com> wrote:\n> > Actually Linux git archive _is_ a special, odd-ball case.\n>\n> It's also our main customer ;-)\n>\n\nMore seriously, do you foreseen reasons for an SCM to split old\nhistories (more then, say few years and some GB ago) in a separated\nrepository?\n\nNow in Linux we have the historical repo and is splitted because it\nwas borne splitted, but do you think this could be also an acceptable\npolicy for a big project after years of git use: to backup old stuff\nand keep recent one snappy?\n\nWith snappy I mean a long list of things: cloning, getting file\nhistories / blaming, packing, fsck-ing, etc...\n\nThe net effect could be a better browsing/handling experience in the\n99% of cases where you need to check recent work (say last 2 years)\nand in any case the possibility to do some archeologic research when\nneeded.\n\nMarco\n"},{"id":"25930","messageId":"ecp3uq$k1f$1@sea.gmane.org","threadId":"5369","inReplyTo":"200608252113.34731.jnareb@gmail.com","subject":"Re: [PATCH 16/19] gitweb: Use git-diff-tree or git-diff patch output for blobdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-26T09:23:47Z","receivedAt":"2006-08-26T09:23:47Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jakub Narebski wrote:\n\n> ATTENTION: The order of arguments (operands) to git-diff is reversed\n> (sic!) to have correct diff in the legacy (no hash_parent_base) case.\n> $hash_parent, $hash ordering is commented out, as it gives reversed\n> patch (at least for git version 1.4.1.1) as compared to output in new\n> scheme and output of older gitweb version.\n\nBy the way, wa it corrected later? git version 1.4.1.1\n\n\n1010:jnareb@roke:~/git> git diff-tree 599f8d63140^ 599f8d63140 \n:100644 100644 0bd517b2649af37d9980f85e784f9a00c3263922 8213ce240232a1dc8a0a498972323a33e8fcb7a0 M  builtin-grep.c\n\n\n1011:jnareb@roke:~/git> git diff-tree -p 599f8d63140^ 599f8d63140\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex 0bd517b..8213ce2 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -293,9 +293,6 @@ static void compile_patterns(struct grep\n         */\n        p = opt->pattern_list;\n        opt->pattern_expression = compile_pattern_expr(&p);\n-#if DEBUG\n-       dump_pattern_exp(opt->pattern_expression, 0);\n-#endif\n        if (p)\n                die(\"incomplete pattern expression: %s\", p->pattern);\n }\n\n\n1012:jnareb@roke:~/git> git diff 0bd517b2649af37d9980f85e784f9a00c3263922 8213ce240232a1dc8a0a498972323a33e8fcb7a0\ndiff --git a/0bd517b2649af37d9980f85e784f9a00c3263922 b/0bd517b2649af37d9980f85e784f9a00c3263922\nindex 8213ce2..0bd517b 100644\n--- a/0bd517b2649af37d9980f85e784f9a00c3263922\n+++ b/0bd517b2649af37d9980f85e784f9a00c3263922\n@@ -293,6 +293,9 @@ static void compile_patterns(struct grep\n         */\n        p = opt->pattern_list;\n        opt->pattern_expression = compile_pattern_expr(&p);\n+#if DEBUG\n+       dump_pattern_exp(opt->pattern_expression, 0);\n+#endif\n        if (p)\n                die(\"incomplete pattern expression: %s\", p->pattern);\n }\n\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25932","messageId":"7vpsen3itw.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"ecp3uq$k1f$1@sea.gmane.org","subject":"Re: [PATCH 16/19] gitweb: Use git-diff-tree or git-diff patch output for blobdiff","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-26T10:14:03Z","receivedAt":"2006-08-26T10:14:03Z","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>> ATTENTION: The order of arguments (operands) to git-diff is reversed\n>> (sic!) to have correct diff in the legacy (no hash_parent_base) case.\n>> $hash_parent, $hash ordering is commented out, as it gives reversed\n>> patch (at least for git version 1.4.1.1) as compared to output in new\n>> scheme and output of older gitweb version.\n>\n> By the way, wa it corrected later? git version 1.4.1.1\n\nI think you were involved in the thread that resulted in the \nfix...\n\n53dd8a9 Show both blob names from \"git diff blob1 blob2\"\nf82cd3c Fix \"git diff blob1 blob2\" showing the diff in reverse.\n"},{"id":"25933","messageId":"ecp737$qqg$1@sea.gmane.org","threadId":"5369","inReplyTo":"7vpsen3itw.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 16/19] gitweb: Use git-diff-tree or git-diff patch output for blobdiff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-26T10:17:10Z","receivedAt":"2006-08-26T10:17:10Z","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>> Jakub Narebski wrote:\n>>\n>>> ATTENTION: The order of arguments (operands) to git-diff is reversed\n>>> (sic!) to have correct diff in the legacy (no hash_parent_base) case.\n>>> $hash_parent, $hash ordering is commented out, as it gives reversed\n>>> patch (at least for git version 1.4.1.1) as compared to output in new\n>>> scheme and output of older gitweb version.\n>>\n>> By the way, wa it corrected later? git version 1.4.1.1\n> \n> I think you were involved in the thread that resulted in the \n> fix...\n> \n> 53dd8a9 Show both blob names from \"git diff blob1 blob2\"\n> f82cd3c Fix \"git diff blob1 blob2\" showing the diff in reverse.\n\nGaah. So I'd have to fix the gitweb, i.e. remove workaround\n(and update git to 1.4.2). \n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25935","messageId":"200608261233.18337.jnareb@gmail.com","threadId":"5369","inReplyTo":"200608252113.34731.jnareb@gmail.com","subject":"[PATCH 16a/19] gitweb: Remove workaround for git-diff bug fixed in f82cd3c","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-26T10:33:17Z","receivedAt":"2006-08-26T10:33:17Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Remove workaround in git_blobdiff for error in git-diff (showing\nreversed diff for diff of blobs), corrected in commit\n f82cd3c  Fix \"git diff blob1 blob2\" showing the diff in reverse.\nwhich is post 1.4.2-rc2 commit.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |    3 +--\n 1 files changed, 1 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex e5a0db5..36a28a4 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2841,8 +2841,7 @@ sub git_blobdiff {\n \t\t}\n \n \t\t# open patch output\n-\t\t#open $fd, \"-|\", $GIT, \"diff\", '-p', $hash_parent, $hash\n-\t\topen $fd, \"-|\", $GIT, \"diff\", '-p', $hash, $hash_parent\n+\t\topen $fd, \"-|\", $GIT, \"diff\", '-p', $hash_parent, $hash\n \t\t\tor die_error(undef, \"Open git-diff failed\");\n \t} else  {\n \t\tdie_error('404 Not Found', \"Missing one of the blob diff parameters\")\n-- \n1.4.1.1\n"},{"id":"25953","messageId":"7vpsen1eq3.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"200608252135.27894.jnareb@gmail.com","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-26T19:25:40Z","receivedAt":"2006-08-26T19:25:40Z","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> Remove $git_temp variable which held location for temporary files\n> needed by git_diff_print, and removed creating $git_temp directory.\n\nVery good.  Not writing into the filesystem even in the\ntemporary location is a very good thing.\n\nOther things I noticed in this 19 series (note that I've applied\nthem more or less intact already, expecting that any issues will\nbe fixed in-tree):\n\n * Overall\n\n   Your MUA configuration seems to have improved and stabilized\n   quite a bit.  I did not see any corruption this time around.\n\n * 01/19 gitweb: Use git-diff-tree patch output for commitdiff\n\n   This was a bit large for me to review during work-day, and\n   seemed a bit scary.  It initially did not give me a good\n   feeling to see that a large series that followed depended on\n   something that was marked RFC, but it turned out mostly Ok.\n\n * 02/19 gitweb: Replace git_commitdiff_plain by anonymous subroutine\n   03/19 gitweb: Show information about incomplete lines in commitdiff\n         Revert \"gitweb: Replace git_commitdiff_plain by anonymous\n                 subroutine\"\n\n   I've commented on these.\n\n * 06/19 gitweb: Add git_get_{following,preceding}_references functions\n   07/19 gitweb: Return on first ref found when\n         git_get_preceding_references is called in scalar context\n\n   This looks *VERY* expensive.  Does git_get_references()\n   cache and reuse its result?  How many times during a single\n   invocation are these subs called?\n\n   Also I am not sure about the correctness of \"get-following\".\n\n            B------D------F\n           /              base\n\t--A------C------E\n                        hash\n\n   You read from \"rev-list $base\", stop when you see $hash, and\n   grab all the refs that point at the rev you have seen before\n   stopping as \"following\".  But in the above picture, you will\n   follow from F down to the very initial commit without\n   stopping and there actually is _no_ rev that follows E so\n   your result would contain B D A (if they are tagged) but none\n   of them follows E.  There is something wrong here.\n\n   At least you should read from \"rev-list $hash..$base\"; then\n   traversal would go F D B and stop at A; you probably would\n   want --boundary to force showing of A as well, but even then\n   I am not sure how well the result would work.\n\n   \"get-preceding\" also wants to go down to the initial commit.\n\n   \"get-following\" is inherently a very expensive operation, so\n   I would suggest not doing this.  It seems that nobody uses\n   these two subs yet, so probably it is better to yank them\n   before they cause damages.\n\n * 08/19 gitweb: Add git_get_rev_name_tags function\n   09/19 gitweb: Use git_get_name_rev_tags for commitdiff_plain \n         X-Git-Tag: header\n\n   I suspect these make the generation of the header extremely\n   expensive.  I'd suggest reverting them to the original.\n\n * 13/19 gitweb: Add invisible hyperlink to from-file/to-file diff header\n\n   You seem to have forgotten esc_html() on the patch-line\n   before sending it to the browser.  Careful.\n\n * 14/19 gitweb: Always display link to blobdiff_plain in git_blobdiff\n\n   Need justification why this change is needed (or why previous\n   logic to avoid showing it in certain cases is wrong).\n\n * 16/19 gitweb: Use git-diff-tree or git-diff patch output for blobdiff\n\n   Is git_to_hash sub always called with object names and\n   nothing else?  \"git rev-parse no-such\" would die with an\n   error message, and \"git rev-parse Makefile\" in populated\n   working tree would say \"Makefile\" without complaints.\n   Perhaps you want --revs-only --no-flags here.\n\n   I think it is a bad style to return [] or $ in scalar context\n   depending on the number of results.  It forces the caller to\n   do a conditional depending on the type of the stuff returned.\n\n   I would suggest just removing if (wantarray) and always\n   return @hashes.  A caller who is interested in a single\n   element can say \"($it) = your_sub(...)\", a caller who wants\n   the number of elements can say \"$cnt = your_sub(...)\", and a\n   caller who wants to know all can say \"(@them) = your_sub(...)\".\n\n   I think that is the usual thing to do in Perl.  Unless there\n   is a compelling reason that is so important that it is worth\n   to deviate from that norm and confusing the programmer, that\n   is.\n\n   I think \"# try to find filename from $hash\" part would\n   misbehave if $hash returned by git_to_hash($hash) becomes\n   undef.\n\n   You seem to spell out '-M', '-C' everywhere.  I suspect\n   fixing them all to just '-C' (or perhaps '-B', '-C') would be\n   tedious but probably is a good idea.\n\n * 17/19 gitweb: git_blobdiff_plain is git_blobdiff('plain')\n\n   Needs justification why commitdiff and blobdiff plain needs\n   to behave differently.\n"},{"id":"25954","messageId":"ecqaa3$j0u$1@sea.gmane.org","threadId":"5369","inReplyTo":"7vpsen1eq3.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-26T20:18:14Z","receivedAt":"2006-08-26T20:18:14Z","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>> Remove $git_temp variable which held location for temporary files\n>> needed by git_diff_print, and removed creating $git_temp directory.\n> \n> Very good.  Not writing into the filesystem even in the\n> temporary location is a very good thing.\n> \n> Other things I noticed in this 19 series (note that I've applied\n> them more or less intact already, expecting that any issues will\n> be fixed in-tree):\n> \n[...]\n> \n>  * 06/19 gitweb: Add git_get_{following,preceding}_references functions\n>    07/19 gitweb: Return on first ref found when\n>          git_get_preceding_references is called in scalar context\n> \n>    This looks *VERY* expensive.  Does git_get_references()\n>    cache and reuse its result?  How many times during a single\n>    invocation are these subs called?\n> \n>    Also I am not sure about the correctness of \"get-following\".\n> \n>             B------D------F\n>            /              base\n>       --A------C------E\n>                         hash\n> \n>    You read from \"rev-list $base\", stop when you see $hash, and\n>    grab all the refs that point at the rev you have seen before\n>    stopping as \"following\".  But in the above picture, you will\n>    follow from F down to the very initial commit without\n>    stopping and there actually is _no_ rev that follows E so\n>    your result would contain B D A (if they are tagged) but none\n>    of them follows E.  There is something wrong here.\n> \n>    At least you should read from \"rev-list $hash..$base\"; then\n>    traversal would go F D B and stop at A; you probably would\n>    want --boundary to force showing of A as well, but even then\n>    I am not sure how well the result would work.\n> \n>    \"get-preceding\" also wants to go down to the initial commit.\n> \n>    \"get-following\" is inherently a very expensive operation, so\n>    I would suggest not doing this.  It seems that nobody uses\n>    these two subs yet, so probably it is better to yank them\n>    before they cause damages.\n\nI agree.\n    \n>  * 08/19 gitweb: Add git_get_rev_name_tags function\n>    09/19 gitweb: Use git_get_name_rev_tags for commitdiff_plain \n>          X-Git-Tag: header\n> \n>    I suspect these make the generation of the header extremely\n>    expensive.  I'd suggest reverting them to the original.\n\nThe git_get_following_references is copied almost verbatim from the original\n(i.e. before this series) git_commitdiff_plain implementation, modified\nonly to allow for changed output of git_get_references (formerly\nread_info_ref), and with \"HEAD\" changed to $hash_base || \"HEAD\".\n\ngit_get_preceding_references was made to be companion to\ngit_get_following_references, so of course it shares it's warts, errors\nand disadvantages.\n\n\nFirst patch in series changed X-Git-Tag: header to show only the tag that\npoints _directly_ to 'hash' commit, similarly to the ref marker in HTML\noutput (in git_commitdiff for example).\n\nThere was mentioned in discussion that it is nice to know what version you\nneed to have feature introduced by commitdiff. Hence writing code\ngenerating X-Git-Tag: header into subroutine, writing companion\nsubroutine... then deciding that as there is native git command for that,\nnamely 'git name-rev --tags', why not use it? The git_get_following_refs\nand git_get_preceding_refs didn't get used.\n\ngit name-rev is quite fast, perhaps up to half a second, or a second.\nAnd is called only once per commitdiff_plain\n\n\nI guess that generating (properly!) X-Git-Follows:, X-Git-Branch: and\nX-Git-Precedes: (similarly to what gitk and qgit do) should be made into\nfeature, as it is time and resource consuming.\n\n>  * 13/19 gitweb: Add invisible hyperlink to from-file/to-file diff header\n> \n>    You seem to have forgotten esc_html() on the patch-line\n>    before sending it to the browser.  Careful.\n\nCannot esc_html() line with HTML code, namely the hyperlink. I know that the\nline is \"+++ a/<filename>\" or \"--- b/<filename>\", and we replace <filename>\nwith hyperlink, which has esc_html($filename) as contents. There is no need\nto escape \"+++ a/\" or \"--- b/\".\n\nI guess I rely on git-diff/git-diff-tree to have \"+++ /dev/null\" and\n\"--- /dev/null\" (both HTML safe), if there is no \"a/\" and \"b/\" in\nfrom-file/to-file unified diff header.\n\n>  * 14/19 gitweb: Always display link to blobdiff_plain in git_blobdiff\n> \n>    Need justification why this change is needed (or why previous\n>    logic to avoid showing it in certain cases is wrong).\n\nWhy we didn't display it before? I though it was a bug (oversimplification\nin case we don't have $hash_base or it is not a commit). If we can display\n\"blob\" view, we can display \"blob_plain\" view...\n\n>  * 16/19 gitweb: Use git-diff-tree or git-diff patch output for blobdiff\n> \n>    Is git_to_hash sub always called with object names and\n>    nothing else?  \"git rev-parse no-such\" would die with an\n>    error message, and \"git rev-parse Makefile\" in populated\n>    working tree would say \"Makefile\" without complaints.\n>    Perhaps you want --revs-only --no-flags here.\n> \n>    I think it is a bad style to return [] or $ in scalar context\n>    depending on the number of results.  It forces the caller to\n>    do a conditional depending on the type of the stuff returned.\n> \n>    I would suggest just removing if (wantarray) and always\n>    return @hashes.  A caller who is interested in a single\n>    element can say \"($it) = your_sub(...)\", a caller who wants\n>    the number of elements can say \"$cnt = your_sub(...)\", and a\n>    caller who wants to know all can say \"(@them) = your_sub(...)\".\n> \n>    I think that is the usual thing to do in Perl.  Unless there\n>    is a compelling reason that is so important that it is worth\n>    to deviate from that norm and confusing the programmer, that\n>    is.\n> \n>    I think \"# try to find filename from $hash\" part would\n>    misbehave if $hash returned by git_to_hash($hash) becomes\n>    undef.\n\nGaaah, perhaps we should stop to try to be too nice, and just barf or use\nlegacy output if user didn't provide filename, and hash is not sha1 of blob\n(don't try too hard to find filename if it is not provided).\n\nAnd remove git_to_hash function until the correct implementation is written.\n\n>    You seem to spell out '-M', '-C' everywhere.  I suspect\n>    fixing them all to just '-C' (or perhaps '-B', '-C') would be\n>    tedious but probably is a good idea.\n\nDoes '-C' imply '-M'?\n \n>  * 17/19 gitweb: git_blobdiff_plain is git_blobdiff('plain')\n> \n>    Needs justification why commitdiff and blobdiff plain needs\n>    to behave differently.\n\nFirst, if we have blobdiff generated with renames/copying detection (and\n\"commit\" view uses it, and provides link to blobdiffs using it), there not\nalways is single diff (blobdiff) without renames/copying detection. So to\nhave blobdiff and blobdiff_plain equivalent, and blobdiff_plain without\nrenames detection, then blobdiff_plain view would have sometimes _two_\npatches.\n\nThis isn't the case with commitdiff. The diff with and without renames\ndetection are equivalent for diff of whole commit.\n\nOriginally comittdiff and comitdiff_plain both were without renames\ndetection, while blobdiff and blobdiff_plain were called from commit with\nrenames detection, and from history with no need for renames detection.\n\n\nThe idea behind changing comittdiff (HTML version) to including rename\ndetection was that it gives shorter and better to understand patches. The\nidea (perhaps wrong) behind leaving comitdiff_plain output without renames\ndetection was that this output can be applied directly by non-git-aware\ntools. It can be easily changed to include renames/copying detection (put\n'-C' in one place).\n\nThe idea behind having both blobdiff and blobdiff_plain have renames\ndetection was that commit view used rename detection, the two views should\nbe equivalent and one exist always for the other, and that it was easier on\nimplementation ;-)\n\n\nP.S. I have most problems with having legacy blobdiff URL (without 'hpb' \ni.e. hash_parent_base parameter) working correctly without making use of\nexternal diff.\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"25964","messageId":"7vwt8vyqij.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"7vpsen1eq3.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-27T00:24:36Z","receivedAt":"2006-08-27T00:24:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <junkio@cox.net> writes:\n\n>    \"get-following\" is inherently a very expensive operation, so\n>    I would suggest not doing this.  It seems that nobody uses\n>    these two subs yet, so probably it is better to yank them\n>    before they cause damages.\n\nA bit of clarification.  gitk has preceding/following but unlike\ngitweb it has three things that go in favor of having it.\n\n - gitk can afford to use as much CPU as the user throw at it,\n   since it runs locally.\n\n - gitk finds preceding/following in the background so the user\n   does not have to wait, and it is done while it gets the list\n   of commits which it needs to do anyway.\n\n - what gitk reads from rev-list persists while the user keeps\n   it around.  when the user walks around inspecting different\n   commits, the cost for computing preceding/following is\n   amortized.  gitweb cannot do this unless it somehow caches\n   this information, but you just spent significant effort to\n   make it unnecessary for gitweb to write anything on the\n   filesystem, so introducing caching is somewhat going\n   backwards.\n"},{"id":"25965","messageId":"8fe92b430608261738t16cd861brb78c8e78c2c58835@mail.gmail.com","threadId":"5369","inReplyTo":"7vwt8vyqij.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-27T00:38:13Z","receivedAt":"2006-08-27T00:38:13Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On 8/27/06, Junio C Hamano <junkio@cox.net> wrote:\n> Junio C Hamano <junkio@cox.net> writes:\n>\n>>    \"get-following\" is inherently a very expensive operation, so\n>>    I would suggest not doing this.  It seems that nobody uses\n>>    these two subs yet, so probably it is better to yank them\n>>    before they cause damages.\n>\n> A bit of clarification.  gitk has preceding/following but unlike\n> gitweb it has three things that go in favor of having it.\n>\n>  - gitk can afford to use as much CPU as the user throw at it,\n>    since it runs locally.\n>\n>  - gitk finds preceding/following in the background so the user\n>    does not have to wait, and it is done while it gets the list\n>    of commits which it needs to do anyway.\n\nI wonder if we could AJAXize gitweb, and have _browser_ compute\npreceding/following tags using some JavaScript...\n\nThat would be client side, could be in background, and could be cached. :-)\n-- \nJakub Narebski\nShadeHawk on #git\n"},{"id":"25969","messageId":"7v3bbizya1.fsf@assigned-by-dhcp.cox.net","threadId":"5369","inReplyTo":"ecqaa3$j0u$1@sea.gmane.org","subject":"Re: [PATCH 19/19] gitweb: Remove creating directory for temporary files","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-08-27T02:51:34Z","receivedAt":"2006-08-27T02:51:34Z","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> Junio C Hamano wrote:\n>\n>> Jakub Narebski <jnareb@gmail.com> writes:\n>> \n>>  * 13/19 gitweb: Add invisible hyperlink to from-file/to-file diff header\n>> \n>>    You seem to have forgotten esc_html() on the patch-line\n>>    before sending it to the browser.  Careful.\n>\n> Cannot esc_html() line with HTML code, namely the hyperlink.\n\nOK,  I did not notice the lines are already HTMLified with links\nat that point.\n\n>>  * 14/19 gitweb: Always display link to blobdiff_plain in git_blobdiff\n>> \n>>    Need justification why this change is needed (or why previous\n>>    logic to avoid showing it in certain cases is wrong).\n>\n> Why we didn't display it before? I though it was a bug (oversimplification\n> in case we don't have $hash_base or it is not a commit). If we can display\n> \"blob\" view, we can display \"blob_plain\" view...\n\nI take it that you mean that it avoids the case without\n$hash_base even though it can do all the necessary computation\nwithout it.  If so please say that in the commit log message.\n\n>>    You seem to spell out '-M', '-C' everywhere.  I suspect\n>>    fixing them all to just '-C' (or perhaps '-B', '-C') would be\n>>    tedious but probably is a good idea.\n>\n> Does '-C' imply '-M'?\n\nThey are, in this order \"-M\" < \"-C\" < \"--find-copies-harder -C\",\nstrict superset/subset of each other.\n\nHaving said that, I think just -M (or perhaps -B -M) might be a\nbetter default (or \"only choice\" if the UI does not give a\nchoice), for a few reasons:\n\n * -C tends to be far more expensive than -M.  The cost of -M is\n    proportional to (number of removed files) * (number of new\n    files).  The cost of -C is proportional to (number of\n    changed files + number of removed files) * (number of new\n    files).  For -C with --find-copies-harder, the cost is still\n    more expensive: (number of files in the original tree) *\n    (number of new files).\n\n * -C does not detect all copies.  It considers only the\n    pre-image of files changed in the same commit as candidates\n    of copy source.  To make it consider _any_ file that was in\n    the original tree, you would need to give --find-copies-harder\n    as well.  In a way, -C is a cheaper (but still more\n    expensive) compromise, middle ground between -M and -C\n    --find-copies-harder.\n\n>>  * 17/19 gitweb: git_blobdiff_plain is git_blobdiff('plain')\n>> \n>>    Needs justification why commitdiff and blobdiff plain needs\n>>    to behave differently.\n>\n> First, if we have blobdiff generated with renames/copying detection (and\n> \"commit\" view uses it, and provides link to blobdiffs using it), there not\n> always is single diff (blobdiff) without renames/copying detection. So to\n> have blobdiff and blobdiff_plain equivalent, and blobdiff_plain without\n> renames detection, then blobdiff_plain view would have sometimes _two_\n> patches.\n\nSorry, does not parse, but two paragraphs below I think you made\nit clear why.\n\n> The idea behind changing comittdiff (HTML version) to including rename\n> detection was that it gives shorter and better to understand patches. The\n> idea (perhaps wrong) behind leaving comitdiff_plain output without renames\n> detection was that this output can be applied directly by non-git-aware\n> tools. It can be easily changed to include renames/copying detection (put\n> '-C' in one place).\n>\n> The idea behind having both blobdiff and blobdiff_plain have renames\n> detection was that commit view used rename detection, the two views should\n> be equivalent and one exist always for the other, and that it was easier on\n> implementation ;-)\n\nI am not sure about this.  People, especially the ones who do\n_not_ use git and are interested in one single fix, are the ones\nyou are trying to help, because they can just be told about the\nchange (e.g. \"'Fix bar blah' patch in Linus tree last week might\nfix your problems\"), go to gitweb and use it.  But:\n\n (0) If rename/copy is not involved there is no difference so I\n     will not discuss that case further;\n\n (1) If rename/copy is involved, as you say, the patch is far\n     easier to understand in git form; the person who downloaded\n     the patch would have a hard time understanding it before\n     applying the patch if you do not do -M/-C.\n\n (2) The post-image file would not exist in the tree the person\n     who downloaded the patch has for renamed/copied paths, so\n     failure from \"patch -p1\" is immediately noticeable.  The\n     metainformation says what was renamed/copied where, and I\n     do not think it is too much to expect for them to first\n     rename/copy by hand then re-run \"patch -p1\".\n\n (3) If we do not do -M, in situations where the patch has fuzz\n     or conflict when applied to the tree the person who\n     downloaded has, the post-image patch will be applied\n     cleanly and the removal patch will have conflict or fuzz.\n     The local change can easily be lost that way.\n\n> P.S. I have most problems with having legacy blobdiff URL (without 'hpb' \n> i.e. hash_parent_base parameter) working correctly without making use of\n> external diff.\n\nAre people bookmarking such URLs?  How important is the legacy\ncompatibility?\n"},{"id":"25971","messageId":"Pine.LNX.4.64.0608262026230.11811@g5.osdl.org","threadId":"5369","inReplyTo":"200608252315.57181.jnareb@gmail.com","subject":"Re: [PATCH 00/19] gitweb: Remove dependency on external diff and need for temporary files","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-08-27T03:30:49Z","receivedAt":"2006-08-27T03:30:49Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 25 Aug 2006, Jakub Narebski wrote:\n>\n> This series of patches (now finished) removes dependency on\n> external diff (/usr/bin/diff) to produce commitdiff and blobdiff\n> views, and the need for temporary files.\n\nOk, can we now please fix my final annouyance, which is that gitweb from \nthe very beginning has apparently believed that the \"Signed-off-by:\" etc \nlines are not important, and they get stripped away when looking at the \n\"commit-diff\".\n\nAlso, \"commit-diff\" really should have some minimal authorship \ninformation. It's silly to have to go to \"commit\" and then separately ask \nfor \"diff\" to see all these very basic things.\n\nSo I think that \"commit-diff\" should basically show the equivalent of \"git \nshow --pretty\", ie author, date, commit message (including sign-offs) and \nthen the diff.\n\nNo?\n\n\t\t\tLinus\n"},{"id":"25972","messageId":"Pine.LNX.4.64.0608262033000.11811@g5.osdl.org","threadId":"5369","inReplyTo":"200608252105.07500.jnareb@gmail.com","subject":"Re: [PATCH 13/19] gitweb: Add invisible hyperlink to from-file/to-file diff header","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-08-27T03:38:32Z","receivedAt":"2006-08-27T03:38:32Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 25 Aug 2006, Jakub Narebski wrote:\n>\n> Change replacing hashes as from-file/to-file with filenames from\n> difftree to adding invisible (except underlining on hover/mouseover)\n> hyperlink to from-file/to-file blob.  /dev/null as from-file or\n> to-file is not changed (is not hyperlinked).\n\nWouldn't it be even better to have the hyperlink (or a new, separate one) \npoint to the history for that file, too?\n\nThat way, you can go to the commit-diff, and when you see a diff for a \nfile, you can easily just ask for the whole history for that file. As it \nis, you can get that, but only by going to the \"commit\" thing, not from \nthe \"commit-diff\" thing.\n\nAlternatively, maybe commit-diff should have a header with the files it \nchanges (ie it would truly be a superset of the \"commit\" case)? That might \nbe even nicer, since you'd not have to scroll through a potentially big \ndiff for other files in order to get to the one you care about.\n\n(If you do the \"header with changed files\", each file could have the same \nthree buttons as in the \"commit\" view: \"blob\" (pointing to the blob), \n\"diff\" (which just points to _within_ the current window, so that you can \nget to the start of that particular file diff) and \"history\" (which \nobviously does what the \"commit\" case does too - generate a history page).\n\n\t\t\tLinus\n"},{"id":"25973","messageId":"20060826.204208.85688529.davem@davemloft.net","threadId":"5369","inReplyTo":"Pine.LNX.4.64.0608262026230.11811@g5.osdl.org","subject":"Re: [PATCH 00/19] gitweb: Remove dependency on external diff and need for temporary files","fromName":"David Miller","fromEmail":"davem@davemloft.net","sentAt":"2006-08-27T03:42:08Z","receivedAt":"2006-08-27T03:42:08Z","isPatch":true,"sender":{"key":"davem@davemloft.net","avatar":null},"body":"From: Linus Torvalds <torvalds@osdl.org>\nDate: Sat, 26 Aug 2006 20:30:49 -0700 (PDT)\n\n> Ok, can we now please fix my final annouyance, which is that gitweb from \n> the very beginning has apparently believed that the \"Signed-off-by:\" etc \n> lines are not important, and they get stripped away when looking at the \n> \"commit-diff\".\n\nIsn't this to keep the email address from being published on the web\nand thus harvested by spammers?\n\nIf it will obfuscate the email address, that's fine I guess.\n"},{"id":"25974","messageId":"Pine.LNX.4.64.0608262051050.11811@g5.osdl.org","threadId":"5369","inReplyTo":"20060826.204208.85688529.davem@davemloft.net","subject":"Re: [PATCH 00/19] gitweb: Remove dependency on external diff and need for temporary files","fromName":"Linus Torvalds","fromEmail":"torvalds@osdl.org","sentAt":"2006-08-27T03:54:25Z","receivedAt":"2006-08-27T03:54:25Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 26 Aug 2006, David Miller wrote:\n> \n> > Ok, can we now please fix my final annouyance, which is that gitweb from \n> > the very beginning has apparently believed that the \"Signed-off-by:\" etc \n> > lines are not important, and they get stripped away when looking at the \n> > \"commit-diff\".\n> \n> Isn't this to keep the email address from being published on the web\n> and thus harvested by spammers?\n\nWell, since gitweb already exposes all of those in the \"commit\" thing (in \na different color, but they are there), I don't see why \"commit-diff\" \nwouldn't show the same data..\n\nI would certainly _hope_ that every developer has a spam blocker. I don't \nthink not showing email addresses is the answer to _that_ particular \nproblem (and if somebody wants to harvest the email addresses for a git \nproject that is exposed with gitweb, there are more efficient ways to do \nthat ;)\n\n\t\tLinus\n"},{"id":"25990","messageId":"ecse7k$2q3$2@sea.gmane.org","threadId":"5369","inReplyTo":"Pine.LNX.4.64.0608262026230.11811@g5.osdl.org","subject":"Re: [PATCH 00/19] gitweb: Remove dependency on external diff and need for temporary files","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-27T15:37:29Z","receivedAt":"2006-08-27T15:37:29Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Linus Torvalds wrote:\n\n> On Fri, 25 Aug 2006, Jakub Narebski wrote:\n>>\n>> This series of patches (now finished) removes dependency on\n>> external diff (/usr/bin/diff) to produce commitdiff and blobdiff\n>> views, and the need for temporary files.\n> \n> Ok, can we now please fix my final annoyance, which is that gitweb from \n> the very beginning has apparently believed that the \"Signed-off-by:\" etc \n> lines are not important, and they get stripped away when looking at the \n> \"commit-diff\".\n\nThis can be easily fixed.\n\n> Also, \"commit-diff\" really should have some minimal authorship \n> information. It's silly to have to go to \"commit\" and then separately ask \n> for \"diff\" to see all these very basic things.\n\nAnd this need some layout redesign for commitdiff and log views.\nCurrently it is specially formatted subject/first line, simplified\nmessage (with empty lines collapsed), and without signoff.\n\nPerhaps something similar to what \"log\" view uses?\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"}]}