{"thread":{"id":"5346","subject":"[PATCH 2/2] gitweb: Use parse_difftree_raw_line in git_difftree_body","startedAt":"2006-08-21T21:07:00Z","lastAt":"2006-08-21T21:08:52Z","messageCount":2,"participants":["Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"25714","messageId":"200608212307.00712.jnareb@gmail.com","threadId":"5346","inReplyTo":null,"subject":"[PATCH 1/2] gitweb: Added parse_difftree_raw_line function for later use","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-21T21:07:00Z","receivedAt":"2006-08-21T21:07:00Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Adds parse_difftree_raw_line function which parses one line of \"raw\"\nformat diff-tree output into a hash.\n\nFor later use in git_difftree_body, git_commitdiff and\ngit_commitdiff_plain, git_search.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nBased on 'next' branch, commit v1.4.2-gfec6879\n\n>From the four functions which parse git-diff-tree raw format, \ngit_commitdiff and git_commitdiff_plain are to be rewriten to\nuse patch (or patch + raw) format of git-diff-tree, and\ngit_search is to be split into git_search_commit and \ngit_search_pickaxe.\n\nPatch introducing parse_difftree_raw_line to git_difftree_body\nis next.\n\n gitweb/gitweb.perl |   27 +++++++++++++++++++++++++++\n 1 files changed, 27 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 063735d..824fc53 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -918,6 +918,33 @@ sub parse_ref {\n \treturn %ref_item;\n }\n \n+sub parse_difftree_raw_line {\n+\tmy $line = shift;\n+\tmy %res;\n+\n+\t# ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M\tls-files.c'\n+\t# ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M\trev-tree.c'\n+\tif ($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\\t(.*)$/) {\n+\t\t$res{'from_mode'} = $1;\n+\t\t$res{'to_mode'} = $2;\n+\t\t$res{'from_id'} = $3;\n+\t\t$res{'to_id'} = $4;\n+\t\t$res{'status'} = $5;\n+\t\t$res{'similarity'} = $6;\n+\t\tif ($res{'status'} eq 'R' || $res{'status'} eq 'C') { # renamed or copied\n+\t\t\t($res{'from_file'}, $res{'to_file'}) = map(unquote, split(\"\\t\", $7));\n+\t\t} else {\n+\t\t\t$res{'file'} = unquote($7);\n+\t\t}\n+\t}\n+\t# 'c512b523472485aef4fff9e57b229d9d243c967f'\n+\t#elsif ($line =~ m/^([0-9a-fA-F]{40})$/) {\n+\t#\t$res{'commit'} = $1;\n+\t#}\n+\n+\treturn wantarray ? %res : \\%res;\n+}\n+\n ## ......................................................................\n ## parse to array of hashes functions\n \n-- \n1.4.1.1\n"},{"id":"25713","messageId":"200608212308.53231.jnareb@gmail.com","threadId":"5346","inReplyTo":"200608212307.00712.jnareb@gmail.com","subject":"[PATCH 2/2] gitweb: Use parse_difftree_raw_line in git_difftree_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-08-21T21:08:52Z","receivedAt":"2006-08-21T21:08:52Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Use newly introduced parse_difftree_raw_line function in the\ngit_difftree_body subroutine.  While at it correct error in\nparse_difftree_raw_line (unquote is unprototyped function), and\nadd comment explaining this function.\n\nIt also refactors git_difftree_body somewhat, and tries to fit\nit in 80 columns.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nThese two patches probably could be collapsed into one commit.\n\n gitweb/gitweb.perl |  178 ++++++++++++++++++++++++++++------------------------\n 1 files changed, 97 insertions(+), 81 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 824fc53..31a1824 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -918,6 +918,7 @@ sub parse_ref {\n \treturn %ref_item;\n }\n \n+# parse line of git-diff-tree \"raw\" output\n sub parse_difftree_raw_line {\n \tmy $line = shift;\n \tmy %res;\n@@ -932,7 +933,7 @@ sub parse_difftree_raw_line {\n \t\t$res{'status'} = $5;\n \t\t$res{'similarity'} = $6;\n \t\tif ($res{'status'} eq 'R' || $res{'status'} eq 'C') { # renamed or copied\n-\t\t\t($res{'from_file'}, $res{'to_file'}) = map(unquote, split(\"\\t\", $7));\n+\t\t\t($res{'from_file'}, $res{'to_file'}) = map { unquote($_) } split(\"\\t\", $7);\n \t\t} else {\n \t\t\t$res{'file'} = unquote($7);\n \t\t}\n@@ -1355,18 +1356,7 @@ sub git_difftree_body {\n \tprint \"<table class=\\\"diff_tree\\\">\\n\";\n \tmy $alternate = 0;\n \tforeach my $line (@{$difftree}) {\n-\t\t# ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M\tls-files.c'\n-\t\t# ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M\trev-tree.c'\n-\t\tif ($line !~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\\t(.*)$/) {\n-\t\t\tnext;\n-\t\t}\n-\t\tmy $from_mode = $1;\n-\t\tmy $to_mode = $2;\n-\t\tmy $from_id = $3;\n-\t\tmy $to_id = $4;\n-\t\tmy $status = $5;\n-\t\tmy $similarity = $6; # score\n-\t\tmy $file = validate_input(unquote($7));\n+\t\tmy %diff = parse_difftree_raw_line($line);\n \n \t\tif ($alternate) {\n \t\t\tprint \"<tr class=\\\"dark\\\">\\n\";\n@@ -1375,105 +1365,131 @@ sub git_difftree_body {\n \t\t}\n \t\t$alternate ^= 1;\n \n-\t\tif ($status eq \"A\") { # created\n-\t\t\tmy $mode_chng = \"\";\n-\t\t\tif (S_ISREG(oct $to_mode)) {\n-\t\t\t\t$mode_chng = sprintf(\" with mode: %04o\", (oct $to_mode) & 0777);\n+\t\tmy ($to_mode_oct, $to_mode_str, $to_file_type);\n+\t\tmy ($from_mode_oct, $from_mode_str, $from_file_type);\n+\t\tif ($diff{'to_mode'} ne ('0' x 6)) {\n+\t\t\t$to_mode_oct = oct $diff{'to_mode'};\n+\t\t\tif (S_ISREG($to_mode_oct)) { # only for regular file\n+\t\t\t\t$to_mode_str = sprintf(\"%04o\", $to_mode_oct & 0777); # permission bits\n \t\t\t}\n+\t\t\t$to_file_type = file_type($diff{'to_mode'});\n+\t\t}\n+\t\tif ($diff{'from_mode'} ne ('0' x 6)) {\n+\t\t\t$from_mode_oct = oct $diff{'from_mode'};\n+\t\t\tif (S_ISREG($to_mode_oct)) { # only for regular file\n+\t\t\t\t$from_mode_str = sprintf(\"%04o\", $from_mode_oct & 0777); # permission bits\n+\t\t\t}\n+\t\t\t$from_file_type = file_type($diff{'from_mode'});\n+\t\t}\n+\n+\t\tif ($diff{'status'} eq \"A\") { # created\n+\t\t\tmy $mode_chng = \"<span class=\\\"file_status new\\\">[new $to_file_type\";\n+\t\t\t$mode_chng   .= \" with mode: $to_mode_str\" if $to_mode_str;\n+\t\t\t$mode_chng   .= \"]</span>\";\n \t\t\tprint \"<td>\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$file),\n-\t\t\t              -class => \"list\"}, esc_html($file)) .\n+\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$diff{'to_id'},\n+\t\t\t                             hash_base=>$hash, file_name=>$diff{'file'}),\n+\t\t\t              -class => \"list\"}, esc_html($diff{'file'})) .\n \t\t\t      \"</td>\\n\" .\n-\t\t\t      \"<td><span class=\\\"file_status new\\\">[new \" . file_type($to_mode) . \"$mode_chng]</span></td>\\n\" .\n+\t\t\t      \"<td>$mode_chng</td>\\n\" .\n \t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$file)}, \"blob\") .\n+\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$diff{'to_id'},\n+\t\t\t                             hash_base=>$hash, file_name=>$diff{'file'})},\n+\t\t\t              \"blob\") .\n \t\t\t      \"</td>\\n\";\n \n-\t\t} elsif ($status eq \"D\") { # deleted\n+\t\t} elsif ($diff{'status'} eq \"D\") { # deleted\n+\t\t\tmy $mode_chng = \"<span class=\\\"file_status deleted\\\">[deleted $from_file_type]</span>\";\n \t\t\tprint \"<td>\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$from_id, hash_base=>$parent, file_name=>$file),\n-\t\t\t               -class => \"list\"}, esc_html($file)) . \"</td>\\n\" .\n-\t\t\t      \"<td><span class=\\\"file_status deleted\\\">[deleted \" . file_type($from_mode). \"]</span></td>\\n\" .\n+\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$diff{'from_id'},\n+\t\t\t                             hash_base=>$parent, file_name=>$diff{'file'}),\n+\t\t\t               -class => \"list\"}, esc_html($diff{'file'})) .\n+\t\t\t      \"</td>\\n\" .\n+\t\t\t      \"<td>$mode_chng</td>\\n\" .\n \t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$from_id, hash_base=>$parent, file_name=>$file)}, \"blob\") . \" | \" .\n-\t\t\t      $cgi->a({-href => href(action=>\"history\", hash_base=>$parent, file_name=>$file)}, \"history\") .\n-\t\t\t      \"</td>\\n\"\n+\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$diff{'from_id'},\n+\t\t\t                             hash_base=>$parent, file_name=>$diff{'file'})},\n+\t\t\t              \"blob\") .\n+\t\t\t      \" | \" .\n+\t\t\t      $cgi->a({-href => href(action=>\"history\", hash_base=>$parent,\n+\t\t\t                             file_name=>$diff{'file'})},\\\n+\t\t\t              \"history\") .\n+\t\t\t      \"</td>\\n\";\n \n-\t\t} elsif ($status eq \"M\" || $status eq \"T\") { # modified, or type changed\n+\t\t} elsif ($diff{'status'} eq \"M\" || $diff{'status'} eq \"T\") { # modified, or type changed\n \t\t\tmy $mode_chnge = \"\";\n-\t\t\tif ($from_mode != $to_mode) {\n-\t\t\t\t$mode_chnge = \" <span class=\\\"file_status mode_chnge\\\">[changed\";\n-\t\t\t\tif (((oct $from_mode) & S_IFMT) != ((oct $to_mode) & S_IFMT)) {\n-\t\t\t\t\t$mode_chnge .= \" from \" . file_type($from_mode) . \" to \" . file_type($to_mode);\n+\t\t\tif ($diff{'from_mode'} != $diff{'to_mode'}) {\n+\t\t\t\t$mode_chnge = \"<span class=\\\"file_status mode_chnge\\\">[changed\";\n+\t\t\t\tif ($from_file_type != $to_file_type) {\n+\t\t\t\t\t$mode_chnge .= \" from $from_file_type to $to_file_type\";\n \t\t\t\t}\n-\t\t\t\tif (((oct $from_mode) & 0777) != ((oct $to_mode) & 0777)) {\n-\t\t\t\t\tif (S_ISREG($from_mode) && S_ISREG($to_mode)) {\n-\t\t\t\t\t\t$mode_chnge .= sprintf(\" mode: %04o->%04o\", (oct $from_mode) & 0777, (oct $to_mode) & 0777);\n-\t\t\t\t\t} elsif (S_ISREG($to_mode)) {\n-\t\t\t\t\t\t$mode_chnge .= sprintf(\" mode: %04o\", (oct $to_mode) & 0777);\n+\t\t\t\tif (($from_mode_oct & 0777) != ($to_mode_oct & 0777)) {\n+\t\t\t\t\tif ($from_mode_str && $to_mode_str) {\n+\t\t\t\t\t\t$mode_chnge .= \" mode: $from_mode_str->$to_mode_str\";\n+\t\t\t\t\t} elsif ($to_mode_str) {\n+\t\t\t\t\t\t$mode_chnge .= \" mode: $to_mode_str\";\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\t$mode_chnge .= \"]</span>\\n\";\n \t\t\t}\n \t\t\tprint \"<td>\";\n-\t\t\tif ($to_id ne $from_id) { # modified\n-\t\t\t\tprint $cgi->a({-href => href(action=>\"blobdiff\", hash=>$to_id, hash_parent=>$from_id, hash_base=>$hash, file_name=>$file),\n-\t\t\t\t              -class => \"list\"}, esc_html($file));\n-\t\t\t} else { # mode changed\n-\t\t\t\tprint $cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$file),\n-\t\t\t\t              -class => \"list\"}, esc_html($file));\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\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+\t\t\t\t                             hash_base=>$hash, file_name=>$diff{'file'}),\n+\t\t\t\t              -class => \"list\"}, esc_html($diff{'file'}));\n \t\t\t}\n \t\t\tprint \"</td>\\n\" .\n \t\t\t      \"<td>$mode_chnge</td>\\n\" .\n \t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t\t$cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$file)}, \"blob\");\n-\t\t\tif ($to_id ne $from_id) { # modified\n-\t\t\t\tprint \" | \" . $cgi->a({-href => href(action=>\"blobdiff\", hash=>$to_id, hash_parent=>$from_id, hash_base=>$hash, file_name=>$file)}, \"diff\");\n-\t\t\t}\n-\t\t\tprint \" | \" . $cgi->a({-href => href(action=>\"history\", hash_base=>$hash, file_name=>$file)}, \"history\") . \"\\n\";\n-\t\t\tprint \"</td>\\n\";\n-\n-\t\t} elsif ($status eq \"R\") { # renamed\n-\t\t\tmy ($from_file, $to_file) = split \"\\t\", $file;\n-\t\t\tmy $mode_chng = \"\";\n-\t\t\tif ($from_mode != $to_mode) {\n-\t\t\t\t$mode_chng = sprintf(\", mode: %04o\", (oct $to_mode) & 0777);\n-\t\t\t}\n-\t\t\tprint \"<td>\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$to_file),\n-\t\t\t              -class => \"list\"}, esc_html($to_file)) . \"</td>\\n\" .\n-\t\t\t      \"<td><span class=\\\"file_status moved\\\">[moved from \" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$from_id, hash_base=>$parent, file_name=>$from_file),\n-\t\t\t              -class => \"list\"}, esc_html($from_file)) .\n-\t\t\t      \" with \" . (int $similarity) . \"% similarity$mode_chng]</span></td>\\n\" .\n-\t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$to_file)}, \"blob\");\n-\t\t\tif ($to_id ne $from_id) {\n+\t\t\t\t$cgi->a({-href => href(action=>\"blob\", hash=>$diff{'to_id'},\n+\t\t\t\t                       hash_base=>$hash, file_name=>$diff{'file'})},\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      $cgi->a({-href => href(action=>\"blobdiff\", hash=>$to_id, hash_parent=>$from_id, hash_base=>$hash, file_name=>$to_file, file_parent=>$from_file)}, \"diff\");\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        \"diff\");\n \t\t\t}\n+\t\t\tprint \" | \" .\n+\t\t\t\t$cgi->a({-href => href(action=>\"history\",\n+\t\t\t\t                       hash_base=>$hash, file_name=>$diff{'file'})},\n+\t\t\t\t        \"history\");\n \t\t\tprint \"</td>\\n\";\n \n-\t\t} elsif ($status eq \"C\") { # copied\n-\t\t\tmy ($from_file, $to_file) = split \"\\t\", $file;\n+\t\t} elsif ($diff{'status'} eq \"R\" || $diff{'status'} eq \"C\") { # renamed or copied\n+\t\t\tmy %status_name = ('R' => 'moved', 'C' => 'copied');\n+\t\t\tmy $nstatus = $status_name{$diff{'status'}};\n \t\t\tmy $mode_chng = \"\";\n-\t\t\tif ($from_mode != $to_mode) {\n-\t\t\t\t$mode_chng = sprintf(\", mode: %04o\", (oct $to_mode) & 0777);\n+\t\t\tif ($diff{'from_mode'} != $diff{'to_mode'}) {\n+\t\t\t\t# mode also for directories, so we cannot use $to_mode_str\n+\t\t\t\t$mode_chng = sprintf(\", mode: %04o\", $to_mode_oct & 0777);\n \t\t\t}\n \t\t\tprint \"<td>\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$to_file),\n-\t\t\t              -class => \"list\"}, esc_html($to_file)) . \"</td>\\n\" .\n-\t\t\t      \"<td><span class=\\\"file_status copied\\\">[copied from \" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$from_id, hash_base=>$parent, file_name=>$from_file),\n-\t\t\t              -class => \"list\"}, esc_html($from_file)) .\n-\t\t\t      \" with \" . (int $similarity) . \"% similarity$mode_chng]</span></td>\\n\" .\n+\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n+\t\t\t                             hash=>$diff{'to_id'}, file_name=>$diff{'to_file'}),\n+\t\t\t              -class => \"list\"}, esc_html($diff{'to_file'})) . \"</td>\\n\" .\n+\t\t\t      \"<td><span class=\\\"file_status $nstatus\\\">[$nstatus from \" .\n+\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$parent,\n+\t\t\t                             hash=>$diff{'from_id'}, file_name=>$diff{'from_file'}),\n+\t\t\t              -class => \"list\"}, esc_html($diff{'from_file'})) .\n+\t\t\t      \" with \" . (int $diff{'similarity'}) . \"% similarity$mode_chng]</span></td>\\n\" .\n \t\t\t      \"<td class=\\\"link\\\">\" .\n-\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$to_id, hash_base=>$hash, file_name=>$to_file)}, \"blob\");\n-\t\t\tif ($to_id ne $from_id) {\n+\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n+\t\t\t                             hash=>$diff{'to_id'}, file_name=>$diff{'to_file'})},\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      $cgi->a({-href => href(action=>\"blobdiff\", hash=>$to_id, hash_parent=>$from_id, hash_base=>$hash, file_name=>$to_file, file_parent=>$from_file)}, \"diff\");\n+\t\t\t\t\t$cgi->a({-href => href(action=>\"blobdiff\", hash_base=>$hash,\n+\t\t\t\t\t                       hash=>$diff{'to_id'}, hash_parent=>$diff{'from_id'},\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 \t\t\tprint \"</td>\\n\";\n+\n \t\t} # we should not encounter Unmerged (U) or Unknown (X) status\n \t\tprint \"</tr>\\n\";\n \t}\n-- \n1.4.1.1\n"}]}