{"thread":{"id":"7663","subject":"[PATCH 1/7] gitweb: show \"no difference\" message for empty diff","startedAt":"2007-04-15T20:46:04Z","lastAt":"2007-04-28T08:22:33Z","messageCount":14,"participants":["Martin Koegler","Jakub Narebski","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":7},"messages":[{"id":"39395","messageId":"11766699702663-git-send-email-mkoegler@auto.tuwien.ac.at","threadId":"7663","inReplyTo":null,"subject":"[PATCH 1/7] gitweb: show \"no difference\" message for empty diff","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-15T20:46:04Z","receivedAt":"2007-04-15T20:46:04Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"Currently, gitweb shows only header and footer, if no differences are\nfound. This patch adds a \"No differences found\" message for the html\noutput.\n\nSigned-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\n---\n$patch_idx does not work, so I need a new variable.\n\nThe css style for the no difference message is useable. If somebody\ndoes not like, feel free to send a patch with a better layout.\n\n gitweb/gitweb.css  |    7 +++++++\n gitweb/gitweb.perl |    3 +++\n 2 files changed, 10 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 5e40292..fb58bec 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -387,6 +387,13 @@ div.diff.incomplete {\n \tcolor: #cccccc;\n }\n \n+div.diff.nodifferences {\n+\tfont-weight: bold;\n+\tbackground-color: #edece6;\n+\n+\tpadding: 4px;\n+\tborder: 1px solid #d9d8d1;\n+}\n \n div.index_include {\n \tborder: solid #d9d8d1;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c48b35a..cbd8d03 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2398,6 +2398,7 @@ sub git_patchset_body {\n \tmy ($fd, $difftree, $hash, $hash_parent) = @_;\n \n \tmy $patch_idx = 0;\n+\tmy $patch_number = 0;\n \tmy $patch_line;\n \tmy $diffinfo;\n \tmy (%from, %to);\n@@ -2419,6 +2420,7 @@ sub git_patchset_body {\n \t\t# git diff header\n \t\t#assert($patch_line =~ m/^diff /) if DEBUG;\n \t\t#assert($patch_line !~ m!$/$!) if DEBUG; # is chomp-ed\n+\t\t$patch_number++;\n \t\tpush @diff_header, $patch_line;\n \n \t\t# extended diff header\n@@ -2581,6 +2583,7 @@ sub git_patchset_body {\n \t} continue {\n \t\tprint \"</div>\\n\"; # class=\"patch\"\n \t}\n+\tprint \"<div class=\\\"diff nodifferences\\\">No differences found</div>\\n\" if (!$patch_number);\n \n \tprint \"</div>\\n\"; # class=\"patchset\"\n }\n-- \n1.5.1.1.85.gf1888\n"},{"id":"39397","messageId":"11766699701308-git-send-email-mkoegler@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"11766699702663-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"[PATCH 2/7] gitweb: Support comparing blobs with different names","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-15T20:46:05Z","receivedAt":"2007-04-15T20:46:05Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"Currently, blobdiff can only compare blobs with different file\nnames, if no hb/hpb parameters are present.\n\nThis patch adds support for comparing two blobs specified by any\ncombination of hb/f/h and hpb/fp/hp.\n\nSigned-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\n---\n\nI unified all blobdiff variants and added support for comparing blobs\nwith different names.\n\nIf h/hp parameter are missing, I need to generate them with\ngit_get_hash_by_path, as the are needed for the html header, which is\ngenerated before parsing the git-diff output.\n\nI currently ignore all mode changed, as they are part of the tree. I\ndon't think that displaying a mode change message justifes two call to\ngit-ls-tree for each blob diff (Currently it only calls git-ls-tree\nfor each missing h/hp parameter).\n\n gitweb/gitweb.perl |  136 ++++++++++++++++------------------------------------\n 1 files changed, 41 insertions(+), 95 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex cbd8d03..790041c 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -3902,109 +3902,54 @@ sub git_blobdiff {\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-\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_cmd(), \"diff-tree\", '-r', @diff_opts,\n-\t\t\t\t$hash_parent_base, $hash_base,\n-\t\t\t\t\"--\", (defined $file_parent ? $file_parent : ()), $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 &&\n-\t\t         $hash =~ /[0-9a-fA-F]{40}/) {\n-\t\t\t# try to find filename from $hash\n-\n-\t\t\t# read filtered raw output\n-\t\t\topen $fd, \"-|\", git_cmd(), \"diff-tree\", '-r', @diff_opts,\n-\t\t\t\t$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+\tmy $expires = '+1d';\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+\t$file_parent ||= $file_name;\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+\t# non-textual hash id's can be cached\n+\tif (defined $hash && $hash !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t} elsif (defined $hash_parent && $hash_parent !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t} elsif (defined $hash_base && $hash_base !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t} elsif (defined $hash_parent_base && $hash_parent_base !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t}\n \n-\t\t# open patch output\n-\t\topen $fd, \"-|\", git_cmd(), \"diff-tree\", '-r', @diff_opts,\n-\t\t\t'-p', ($format eq 'html' ? \"--full-index\" : ()),\n-\t\t\t$hash_parent_base, $hash_base,\n-\t\t\t\"--\", (defined $file_parent ? $file_parent : ()), $file_name\n-\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\t# if hash parameter is missing, read it from the commit.\n+\tif (defined $hash_base && defined $file_name && !defined $hash) {\n+\t\t$hash = git_get_hash_by_path($hash_base, $file_name);\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+\tif (defined $hash_parent_base && defined $file_parent && !defined $hash_parent) {\n+\t    $hash_parent = git_get_hash_by_path($hash_parent_base, $file_parent);\n+\t}\n+\t\n+\tif (!defined $hash || ! defined $hash_parent) {\n+\t\tdie_error('404 Not Found', \"Missing one of the blob diff parameters\");\n+\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\topen $fd, \"-|\", git_cmd(), \"diff\", @diff_opts,\n-\t\t\t'-p', ($format eq 'html' ? \"--full-index\" : ()),\n-\t\t\t$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-\t\t\tunless %diffinfo;\n+\t# fake git-diff-tree raw output\n+\t$diffinfo{'from_mode'} = $diffinfo{'to_mode'} = \"blob\";\n+\t$diffinfo{'from_id'} = $hash_parent;\n+\t$diffinfo{'to_id'}   = $hash;\n+\tif (defined $file_name) {\n+\t\t$diffinfo{'status'} = '2';\n+\t\t$diffinfo{'from_file'} = $file_parent;\n+\t\t$diffinfo{'to_file'}   = $file_name;\n+\t} else { # no filename given\n+\t\t$diffinfo{'status'} = '2';\n+\t\t$diffinfo{'from_file'} = $hash_parent;\n+\t\t$diffinfo{'to_file'}   = $hash;\n \t}\n \n+\t# open patch output\n+\topen $fd, \"-|\", git_cmd(), \"diff\", @diff_opts,\n+\t$hash_parent, $hash, \"--\"\n+\t\tor die_error(undef, \"Open git-diff failed\");\n+\n \t# header\n \tif ($format eq 'html') {\n \t\tmy $formats_nav =\n@@ -4028,11 +3973,12 @@ sub git_blobdiff {\n \t\t}\n \n \t} elsif ($format eq 'plain') {\n+\t\tmy $patch_file_name = $file_name || $hash;\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 => 'inline; filename=\"' . \"$file_name\" . '.patch\"');\n+\t\t\t-content_disposition => 'inline; filename=\"' . \"$patch_file_name\" . '.patch\"');\n \n \t\tprint \"X-Git-Url: \" . $cgi->self_url() . \"\\n\\n\";\n \n-- \n1.5.1.1.85.gf1888\n"},{"id":"39398","messageId":"11766699713715-git-send-email-mkoegler@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"11766699701308-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"[PATCH 3/7] gitweb: support filename prefix in git_patchset_body/git_difftree_body","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-15T20:46:06Z","receivedAt":"2007-04-15T20:46:06Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"git_treediff supports comparing subdirectories. As the output of\ngit-difftree is missing the path to the compared directories,\nthe links in the output would be wrong.\n\nThe patch adds two new parameters to add the missing path prefix.\n\nSigned-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\n---\n\nI renamed the parameters to to/from_prefix.\n\nModfifing the file name in $diff would require bigger changes and cause new problems:\n* new output rewriter for plain view needed\n* for modfied files only one file name, but possibly two prefixes\n\n gitweb/gitweb.perl |   51 ++++++++++++++++++++++++++++++---------------------\n 1 files changed, 30 insertions(+), 21 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 790041c..1551d95 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2205,8 +2205,12 @@ sub git_print_tree_entry {\n ## functions printing large fragments of HTML\n \n sub git_difftree_body {\n-\tmy ($difftree, $hash, $parent) = @_;\n+\tmy ($difftree, $hash, $parent, $from_prefix, $to_prefix) = @_;\n \tmy ($have_blame) = gitweb_check_feature('blame');\n+\n+\t$from_prefix = !defined $from_prefix ? '' : $from_prefix.'/';\n+\t$to_prefix   = !defined $to_prefix   ? '' : $to_prefix . '/';\n+\n \tprint \"<div class=\\\"list_head\\\">\\n\";\n \tif ($#{$difftree} > 10) {\n \t\tprint(($#{$difftree} + 1) . \" files changed:\\n\");\n@@ -2249,7 +2253,7 @@ sub git_difftree_body {\n \t\t\t$mode_chng   .= \"]</span>\";\n \t\t\tprint \"<td>\";\n \t\t\tprint $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                             hash_base=>$hash, file_name=>$to_prefix.$diff{'file'}),\n \t\t\t              -class => \"list\"}, esc_path($diff{'file'}));\n \t\t\tprint \"</td>\\n\";\n \t\t\tprint \"<td>$mode_chng</td>\\n\";\n@@ -2261,7 +2265,7 @@ sub git_difftree_body {\n \t\t\t\tprint \" | \";\n \t\t\t}\n \t\t\tprint $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                             hash_base=>$hash, file_name=>$to_prefix.$diff{'file'})},\n \t\t\t              \"blob\");\n \t\t\tprint \"</td>\\n\";\n \n@@ -2269,7 +2273,7 @@ sub git_difftree_body {\n \t\t\tmy $mode_chng = \"<span class=\\\"file_status deleted\\\">[deleted $from_file_type]</span>\";\n \t\t\tprint \"<td>\";\n \t\t\tprint $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                             hash_base=>$parent, file_name=>$from_prefix.$diff{'file'}),\n \t\t\t               -class => \"list\"}, esc_path($diff{'file'}));\n \t\t\tprint \"</td>\\n\";\n \t\t\tprint \"<td>$mode_chng</td>\\n\";\n@@ -2281,15 +2285,15 @@ sub git_difftree_body {\n \t\t\t\tprint \" | \";\n \t\t\t}\n \t\t\tprint $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                             hash_base=>$parent, file_name=>$from_prefix.$diff{'file'})},\n \t\t\t              \"blob\") . \" | \";\n \t\t\tif ($have_blame) {\n \t\t\t\tprint $cgi->a({-href => href(action=>\"blame\", hash_base=>$parent,\n-\t\t\t\t                             file_name=>$diff{'file'})},\n+\t\t\t\t                             file_name=>$from_prefix.$diff{'file'})},\n \t\t\t\t              \"blame\") . \" | \";\n \t\t\t}\n \t\t\tprint $cgi->a({-href => href(action=>\"history\", hash_base=>$parent,\n-\t\t\t                             file_name=>$diff{'file'})},\n+\t\t\t                             file_name=>$from_prefix.$diff{'file'})},\n \t\t\t              \"history\");\n \t\t\tprint \"</td>\\n\";\n \n@@ -2311,7 +2315,7 @@ sub git_difftree_body {\n \t\t\t}\n \t\t\tprint \"<td>\";\n \t\t\tprint $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                             hash_base=>$hash, file_name=>$to_prefix.$diff{'file'}),\n \t\t\t              -class => \"list\"}, esc_path($diff{'file'}));\n \t\t\tprint \"</td>\\n\";\n \t\t\tprint \"<td>$mode_chnge</td>\\n\";\n@@ -2326,20 +2330,21 @@ sub git_difftree_body {\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                             file_name=>$to_prefix.$diff{'file'},\n+\t\t\t\t                             file_parent=>$from_prefix.$diff{'file'})},\n \t\t\t\t              \"diff\") .\n \t\t\t\t      \" | \";\n \t\t\t}\n \t\t\tprint $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                             hash_base=>$hash, file_name=>$to_prefix.$diff{'file'})},\n \t\t\t               \"blob\") . \" | \";\n \t\t\tif ($have_blame) {\n \t\t\t\tprint $cgi->a({-href => href(action=>\"blame\", hash_base=>$hash,\n-\t\t\t\t                             file_name=>$diff{'file'})},\n+\t\t\t\t                             file_name=>$to_prefix.$diff{'file'})},\n \t\t\t\t              \"blame\") . \" | \";\n \t\t\t}\n \t\t\tprint $cgi->a({-href => href(action=>\"history\", hash_base=>$hash,\n-\t\t\t                             file_name=>$diff{'file'})},\n+\t\t\t                             file_name=>$to_prefix.$diff{'file'})},\n \t\t\t              \"history\");\n \t\t\tprint \"</td>\\n\";\n \n@@ -2353,11 +2358,11 @@ sub git_difftree_body {\n \t\t\t}\n \t\t\tprint \"<td>\" .\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                             hash=>$diff{'to_id'}, file_name=>$to_prefix.$diff{'to_file'}),\n \t\t\t              -class => \"list\"}, esc_path($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                             hash=>$diff{'from_id'}, file_name=>$from_prefix.$diff{'from_file'}),\n \t\t\t              -class => \"list\"}, esc_path($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@@ -2371,20 +2376,20 @@ sub git_difftree_body {\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{'to_file'}, file_parent=>$diff{'from_file'})},\n+\t\t\t\t                             file_name=>$to_prefix.$diff{'to_file'}, file_parent=>$from_prefix.$diff{'from_file'})},\n \t\t\t\t              \"diff\") .\n \t\t\t\t      \" | \";\n \t\t\t}\n \t\t\tprint $cgi->a({-href => href(action=>\"blob\", hash=>$diff{'to_id'},\n-\t\t\t                             hash_base=>$parent, file_name=>$diff{'to_file'})},\n+\t\t\t                             hash_base=>$hash, file_name=>$to_prefix.$diff{'to_file'})},\n \t\t\t              \"blob\") . \" | \";\n \t\t\tif ($have_blame) {\n \t\t\t\tprint $cgi->a({-href => href(action=>\"blame\", hash_base=>$hash,\n-\t\t\t\t                             file_name=>$diff{'to_file'})},\n+\t\t\t\t                             file_name=>$to_prefix.$diff{'to_file'})},\n \t\t\t\t              \"blame\") . \" | \";\n \t\t\t}\n \t\t\tprint $cgi->a({-href => href(action=>\"history\", hash_base=>$hash,\n-\t\t\t                            file_name=>$diff{'to_file'})},\n+\t\t\t                            file_name=>$to_prefix.$diff{'to_file'})},\n \t\t\t              \"history\");\n \t\t\tprint \"</td>\\n\";\n \n@@ -2395,7 +2400,7 @@ sub git_difftree_body {\n }\n \n sub git_patchset_body {\n-\tmy ($fd, $difftree, $hash, $hash_parent) = @_;\n+\tmy ($fd, $difftree, $hash, $hash_parent, $from_prefix, $to_prefix) = @_;\n \n \tmy $patch_idx = 0;\n \tmy $patch_number = 0;\n@@ -2403,6 +2408,9 @@ sub git_patchset_body {\n \tmy $diffinfo;\n \tmy (%from, %to);\n \n+\t$from_prefix = !defined $from_prefix ? '' : $from_prefix.'/';\n+\t$to_prefix   = !defined $to_prefix   ? '' : $to_prefix . '/';\n+\n \tprint \"<div class=\\\"patchset\\\">\\n\";\n \n \t# skip to first patch\n@@ -2459,17 +2467,18 @@ sub git_patchset_body {\n \t\t\t}\n \t\t\t$from{'file'} = $diffinfo->{'from_file'} || $diffinfo->{'file'};\n \t\t\t$to{'file'}   = $diffinfo->{'to_file'}   || $diffinfo->{'file'};\n+\n \t\t\tif ($diffinfo->{'status'} ne \"A\") { # not new (added) file\n \t\t\t\t$from{'href'} = href(action=>\"blob\", hash_base=>$hash_parent,\n \t\t\t\t                     hash=>$diffinfo->{'from_id'},\n-\t\t\t\t                     file_name=>$from{'file'});\n+\t\t\t\t                     file_name=>$from_prefix.$from{'file'});\n \t\t\t} else {\n \t\t\t\tdelete $from{'href'};\n \t\t\t}\n \t\t\tif ($diffinfo->{'status'} ne \"D\") { # not deleted file\n \t\t\t\t$to{'href'} = href(action=>\"blob\", hash_base=>$hash,\n \t\t\t\t                   hash=>$diffinfo->{'to_id'},\n-\t\t\t\t                   file_name=>$to{'file'});\n+\t\t\t\t                   file_name=>$to_prefix.$to{'file'});\n \t\t\t} else {\n \t\t\t\tdelete $to{'href'};\n \t\t\t}\n-- \n1.5.1.1.85.gf1888\n"},{"id":"39396","messageId":"1176669971694-git-send-email-mkoegler@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"11766699713715-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"[PATCH 4/7] gitweb: Add treediff view","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-15T20:46:07Z","receivedAt":"2007-04-15T20:46:07Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"git_treediff supports comparing different trees. A tree can be specified\neither as hash or as base hash and filename.\n---\n\nI removed the parent links for now, as they require more discussion.\n\nThis patch uses empty fp/f for the root directory and does not propagte f to fp.\nPatch 6 adds this.\n\n gitweb/gitweb.perl |  116 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 116 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 1551d95..c2dc82d 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -450,6 +450,8 @@ my %actions = (\n \t\"tag\" => \\&git_tag,\n \t\"tags\" => \\&git_tags,\n \t\"tree\" => \\&git_tree,\n+\t\"treediff\" => \\&git_treediff,\n+\t\"treediff_plain\" => \\&git_treediff_plain,\n \t\"snapshot\" => \\&git_snapshot,\n \t\"object\" => \\&git_object,\n \t# those below don't need $project\n@@ -4174,6 +4176,120 @@ sub git_commitdiff_plain {\n \tgit_commitdiff('plain');\n }\n \n+sub git_treediff {\n+\tmy $format = shift || 'html';\n+\tmy $expires = '+1d';\n+\n+\t# non-textual hash id's can be cached\n+\tif (defined $hash && $hash !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t} elsif (defined $hash_parent && $hash_parent !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t} elsif (defined $hash_base && $hash_base !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t} elsif (defined $hash_parent_base && $hash_parent_base !=~ m/^[0-9a-fA-F]{40}$/) {\n+\t\t$expires = undef;\n+\t}\n+\n+\t# we need to prepare $formats_nav before any parameter munging\n+\tmy $formats_nav;\n+\tif ($format eq 'html') {\n+\t\t$formats_nav =\n+\t\t\t$cgi->a({-href => href(action=>\"treediff_plain\",\n+\t\t\t\t\t\t\t\t   hash=>$hash, hash_parent=>$hash_parent,\n+\t\t\t\t\t\t\t\t   hash_base=>$hash_base, hash_parent_base=>$hash_parent_base,\n+\t\t\t\t\t\t\t\t   file_name=>$file_name, file_parent=>$file_parent)},\n+\t\t\t\t\t\"raw\");\n+\t}\n+\n+\tif (!defined $hash) {\n+\t\tif (!defined $hash_base) {\n+\t\t\tdie_error(undef,'tree parameter missing');\n+\t\t}\n+\t\t$hash = $hash_base;\n+\t\t$hash .= \":\".$file_name if (defined $file_name);\n+\t}\n+\t\n+\tif (!defined $hash_parent) {\n+\t\tif (!defined $hash_parent_base) {\n+\t\t\tdie_error(undef,'tree parameter missing');\n+\t\t}\n+\t\t$hash_parent = $hash_parent_base;\n+\t\t$hash_parent .= \":\".$file_parent if (defined $file_parent);\n+\t}\n+\n+\t# read treediff\n+\tmy $fd;\n+\tmy @difftree;\n+\tif ($format eq 'html') {\n+\t\topen $fd, \"-|\", git_cmd(), \"diff-tree\", '-r', @diff_opts,\n+\t\t\"--no-commit-id\", \"--patch-with-raw\", \"--full-index\",\n+\t\t$hash_parent, $hash, \"--\"\n+\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\t\t\n+\t\twhile (my $line = <$fd>) {\n+\t\t\tchomp $line;\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\n+\t} elsif ($format eq 'plain') {\n+\t\topen $fd, \"-|\", git_cmd(), \"diff-tree\", '-r', @diff_opts,\n+\t\t'-p', $hash_parent, $hash, \"--\"\n+\t\t\tor die_error(undef, \"Open git-diff-tree failed\");\n+\t\t\n+\t} else {\n+\t\tdie_error(undef, \"Unknown treediff format\");\n+\t}\n+\n+\t# write header\n+\tif ($format eq 'html') {\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\tprint \"<div class=\\\"page_body\\\">\\n\";\n+\t\t\n+\t} elsif ($format eq 'plain') {\n+\t\tmy $filename = basename($project) . \"-$hash-$hash_parent.patch\";\n+\t\t\n+\t\tprint $cgi->header(\n+\t\t\t\t\t\t   -type => 'text/plain',\n+\t\t\t\t\t\t   -charset => 'utf-8',\n+\t\t\t\t\t\t   -expires => $expires,\n+\t\t\t\t\t\t   -content_disposition => 'inline; filename=\"' . \"$filename\" . '\"');\n+\t\t\n+\t\tprint \"X-Git-Url: \" . $cgi->self_url() . \"\\n\\n\";\n+\t\tprint \"---\\n\\n\";\n+\t}\n+\t\n+\t# write patch\n+\tif ($format eq 'html') {\n+\t\tgit_difftree_body(\\@difftree, $hash_base, $hash_parent_base, $file_name, $file_parent);\n+\t\tprint \"<br/>\\n\";\n+\n+\t\tgit_patchset_body($fd, \\@difftree, $hash_base, $hash_parent_base, $file_name, $file_parent);\n+\t\tclose $fd;\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_treediff_plain {\n+\tgit_treediff('plain');\n+}\n+\n sub git_history {\n \tif (!defined $hash_base) {\n \t\t$hash_base = git_get_head_hash($project);\n-- \n1.5.1.1.85.gf1888\n"},{"id":"39401","messageId":"1176669971921-git-send-email-mkoegler@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"1176669971694-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"[PATCH 5/7] gitweb: Prototyp for selecting diffs in JavaScript","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-15T20:46:08Z","receivedAt":"2007-04-15T20:46:08Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"---\nThis patch is only to test the other patches. I'm working on reimplementing it in perl.\n\n gitweb/gitweb.js   |  273 ++++++++++++++++++++++++++++++++++++++++++++++++++++\n gitweb/gitweb.perl |    1 +\n 2 files changed, 274 insertions(+), 0 deletions(-)\n create mode 100644 gitweb/gitweb.js\n\ndiff --git a/gitweb/gitweb.js b/gitweb/gitweb.js\nnew file mode 100644\nindex 0000000..2e1a94d\n--- /dev/null\n+++ b/gitweb/gitweb.js\n@@ -0,0 +1,273 @@\n+function getCookie(name)\n+{\n+  var name=name+\"=\";\n+  var c=document.cookie;\n+  var p=c.indexOf(name);\n+  if(p==-1)\n+    return null;\n+  c=c.substr(p+name.length,c.length);\n+  p=c.indexOf(\";\");\n+  if(p==-1)\n+    return c;\n+  else\n+    return c.substr(0, p);\n+}\n+\n+function insertAfter(elem, node)\n+{\n+  if(node.nextSibling)\n+    node.parentNode.insertBefore(elem, node.nextSibling);\n+  else\n+    node.parentNode.appendChild(elem);\n+}\n+\n+function createLink(href, linktext)\n+{\n+  var l=document.createElement(\"a\");\n+  l.appendChild(document.createTextNode(linktext));\n+  l.href=href;\n+  return l;\n+}\n+\n+function createLinkGroup(href1, basetxt, href2, difftxt)\n+{\n+  var l=document.createElement(\"span\");\n+  l.appendChild(document.createTextNode(\" (\"));\n+  l.appendChild(createLink(href1, basetxt));\n+  l.appendChild(document.createTextNode(\" | \"));\n+  l.appendChild(createLink(href2, difftxt));\n+  l.appendChild(document.createTextNode(\") \"));\n+  return l;\n+}\n+\n+function GitRef()\n+{\n+    this.t=null;\n+    this.h=null;\n+    this.hb=null;\n+    this.f=null;\n+    this.ToRef=ToRef;\n+}\n+\n+function ToRef()\n+{\n+  var parts=new Array();\n+  if(this.f)\n+    parts.push(\"f=\"+this.f);\n+  if(this.h)\n+    parts.push(\"h=\"+this.h);\n+  if(this.hb)\n+    parts.push(\"hb=\"+this.hb);\n+  if(this.t)\n+    parts.push(\"t=\"+this.t);\n+  return parts.join(\"@\");\n+}\n+\n+function splitGitRef(ref)\n+{\n+  var parts=ref.split(\"@\");\n+  var res=new GitRef();\n+  var i;\n+  for(i=0;i<parts.length;i++)\n+  {\n+      var p=parts[i].split(\"=\");\n+      res[p[0]]=p[1];\n+  }\n+  return res;\n+}\n+\n+function GitURL(base)\n+{\n+  this.base=base;\n+  this.p=null;\n+  this.a=null;\n+  this.f=null;\n+  this.fp=null;\n+  this.h=null;\n+  this.hp=null;\n+  this.hb=null;\n+  this.hpb=null;\n+  this.pg=null;\n+  this.o=null;\n+  this.s=null;\n+  this.st=null;\n+  this.ToURL=ToURL;\n+  this.ToRef=UrlToRef;\n+  this.ToDUrl=ToDUrl;\n+}\n+\n+function ToURL()\n+{\n+  var parts=new Array();\n+  if(this.p)\n+    parts.push(\"p=\"+this.p);\n+  if(this.a)\n+    parts.push(\"a=\"+this.a);\n+  if(this.f)\n+    parts.push(\"f=\"+this.f);\n+  if(this.fp)\n+    parts.push(\"fp=\"+this.fp);\n+  if(this.h)\n+    parts.push(\"h=\"+this.h);\n+  if(this.hp)\n+    parts.push(\"hp=\"+this.hp);\n+  if(this.hb)\n+    parts.push(\"hb=\"+this.hb);\n+  if(this.hpb)\n+    parts.push(\"hpb=\"+this.hpb);\n+  if(this.o)\n+    parts.push(\"o=\"+this.o);\n+  if(this.s)\n+    parts.push(\"s=\"+this.s);\n+  if(this.st)\n+    parts.push(\"st=\"+this.st);\n+  return this.base+\"?\"+parts.join(\";\");\n+}\n+\n+function UrlToRef(type)\n+{\n+    var res=new GitRef;\n+    res.f=this.f;\n+    res.h=this.h;\n+    res.hb=this.hb;\n+    res.t=type;\n+    return res.ToRef();\n+}\n+\n+function ToDUrl(type)\n+{\n+    var res=new GitURL(this.base);\n+    res.f=this.f;\n+    res.h=this.h;\n+    res.hb=this.hb;\n+    res.p=this.p;\n+    res.a=type;\n+    return res.ToURL();\n+}\n+\n+function splitGitURL(url)\n+{\n+  var Urls=url.split(\"?\");\n+  var res=new GitURL(Urls[0]);\n+  if(Urls.length>1)\n+    {\n+      var parts=Urls[1].split(\";\");\n+      var i;\n+      for(i=0;i<parts.length;i++)\n+\t{\n+\t  var p=parts[i].split(\"=\");\n+\t  res[p[0]]=p[1];\n+\t}\n+    }\n+  return res;\n+}\n+\n+function GitAddLinks()\n+{\n+  var links=document.getElementsByTagName(\"a\");\n+  var i;\n+  for(i=0;i<links.length;i++)\n+    {\n+      var link=links[i];\n+      if(link.innerHTML=='commit'||link.innerHTML=='tag')\n+\t{\n+\t  var url=splitGitURL(link.href);\n+\t  if(!url.h)\n+\t    continue;\n+\t  var l=createLinkGroup(\"javascript:base('\"+url.ToRef('commit')+\"')\",\"base\",\n+\t\t\t\t\"javascript:diff('\"+url.ToDUrl('commit')+\"')\",\"diff\");\n+\t  insertAfter(l, link);\n+\t}\n+      if(link.innerHTML=='blob')\n+\t{\n+\t  var url=splitGitURL(link.href);\n+\t  if(!url.h&&!(url.hb&&url.f))\n+\t    continue;\n+\t  var l=createLinkGroup(\"javascript:base('\"+url.ToRef('blob')+\"')\",\"base\",\n+\t\t\t\t\"javascript:diff('\"+url.ToDUrl('blob')+\"')\",\"diff\");\n+\t  insertAfter(l, link);\n+\t}\n+      if(link.innerHTML=='tree')\n+\t{\n+\t  var url=splitGitURL(link.href);\n+\t  if(!url.h&&!(url.hb&&url.f))\n+\t    continue;\n+\t  var l=createLinkGroup(\"javascript:base('\"+url.ToRef('tree')+\"')\",\"base\",\n+\t\t\t\t\"javascript:diff('\"+url.ToDUrl('tree')+\"')\",\"diff\");\n+\t  insertAfter(l, link);\n+\t}\n+    }\n+}\n+\n+function base(ref)\n+{\n+  document.cookie=\"basename=\"+ref;\n+}\n+\n+function diff(url)\n+{\n+  var c=getCookie(\"basename\");\n+  if (!c)\n+  {\n+      alert(\"no diff base selected\");\n+      return;\n+  }\n+  c=splitGitRef(c);\n+  url=splitGitURL(url);\n+  \n+  if(c.t=='commit'&&url.a=='commit')\n+  {\n+      url.a='commitdiff';\n+      if(!c.h||!url.h)\n+      {\n+\t  alert(\"commit diff not possible\");\n+\t  return;\n+      }\n+      url.hb=null;\n+      url.f=null;\n+      url.hp=c.h;\n+      document.location.href=url.ToURL();\n+      return;\n+  }\n+  if(c.t=='blob'&&url.a=='blob')\n+  {\n+      url.a='blobdiff';\n+      url.hp=c.h;\n+      url.hpb=c.hb;\n+      url.fp=c.f;\n+      document.location.href=url.ToURL();\n+      return;\n+  }\n+  if(c.t=='tree'&&url.a=='tree')\n+  {\n+      url.a='treediff';\n+      url.hpb=c.hb;\n+      url.hp=c.h;\n+      url.fp=c.f;\n+      document.location.href=url.ToURL();\n+      return;\n+  } \n+  if(c.t=='commit'&&url.a=='tree')\n+  {\n+      url.a='treediff';\n+      url.hpb=c.h;\n+      url.hp=null;\n+      url.fp=null;\n+      document.location.href=url.ToURL();\n+      return;\n+  } \n+  if(c.t=='tree'&&url.a=='commit')\n+  {\n+      url.a='treediff';\n+      url.hpb=c.hb;\n+      url.hp=c.h;\n+      url.fp=c.f;\n+      url.hb=url.h;\n+      url.h=null;\n+      document.location.href=url.ToURL();\n+      return;\n+  } \n+  alert(\"diff not possible\");\n+}\n+\n+GitAddLinks();\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c2dc82d..769e755 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1860,6 +1860,7 @@ sub git_footer_html {\n \t\tclose $fd;\n \t}\n \n+\tprint '<script type=\"text/javascript\" src=\"gitweb.js\"></script>';\n \tprint \"</body>\\n\" .\n \t      \"</html>\";\n }\n-- \n1.5.1.1.85.gf1888\n"},{"id":"39399","messageId":"11766699714077-git-send-email-mkoegler@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"1176669971921-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"[PATCH 6/7] gitweb: pass root directory as empty file parameter","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-15T20:46:09Z","receivedAt":"2007-04-15T20:46:09Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"This patch add the automatic propagation of the file name from f to fp\nfor git_treeview, if fp is undefined. To distinguish it from the root\ndirectory, allow an empty string for this in f/fp.\n\nSigned-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\n---\n\nIt was requested, that git_treediff should propagate f to fp, if the fp\nparameter is missing. So I created this patch.\n\nAs any other path could be a valid blob, I use the empty string for\nthe root directory.\n\nAs I personally don't like this, I have split this change into a\nseperate patch:\n\n* As git_treediff is new code, not propagating f->fp would not break any\n  existing urls. \n\n* The f->fp propagation currently only happens in blobdiff (The only\n  place, where fp is used). Is this enough to make it the standard\n  gitweb parameter convention?\n\n* The root tree is specified in git_tree with an missing f parameter.\n\n* I don't know all security implication, if an empty file name is\n  passed to all existing git function.\n\nSo I would like to drop this patch and pass the root directory as\nmissing f/fp parameter, which does not allow propagating f to fp.\n\nComments from other on this topic?\n\n gitweb/gitweb.perl |    8 ++++++--\n 1 files changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 769e755..e4d3f8f 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -310,14 +310,14 @@ if (defined $project) {\n }\n \n our $file_name = $cgi->param('f');\n-if (defined $file_name) {\n+if (defined $file_name && $file_name ne '') {\n \tif (!validate_pathname($file_name)) {\n \t\tdie_error(undef, \"Invalid file parameter\");\n \t}\n }\n \n our $file_parent = $cgi->param('fp');\n-if (defined $file_parent) {\n+if (defined $file_parent && $file_parent ne '') {\n \tif (!validate_pathname($file_parent)) {\n \t\tdie_error(undef, \"Invalid file parent parameter\");\n \t}\n@@ -4203,6 +4203,10 @@ sub git_treediff {\n \t\t\t\t\t\"raw\");\n \t}\n \n+\t$file_parent = $file_name if (!defined $file_parent);\n+\t$file_name = undef if(defined $file_name && $file_name eq '');\n+\t$file_parent = undef if(defined $file_parent && $file_parent eq '');\n+\n \tif (!defined $hash) {\n \t\tif (!defined $hash_base) {\n \t\t\tdie_error(undef,'tree parameter missing');\n-- \n1.5.1.1.85.gf1888\n"},{"id":"39400","messageId":"117666997124-git-send-email-mkoegler@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"11766699714077-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"[PATCH 7/7] gitweb: Adapt gitweb.js to new git_treeview calling convention","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-15T20:46:10Z","receivedAt":"2007-04-15T20:46:10Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"---\n\nNecessary changes for patch 5, if patch 6 is applied.\n\n gitweb/gitweb.js |    4 ++++\n 1 files changed, 4 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.js b/gitweb/gitweb.js\nindex 2e1a94d..51eeedb 100644\n--- a/gitweb/gitweb.js\n+++ b/gitweb/gitweb.js\n@@ -105,8 +105,12 @@ function ToURL()\n     parts.push(\"a=\"+this.a);\n   if(this.f)\n     parts.push(\"f=\"+this.f);\n+  else if(this.hb)\n+    parts.push(\"f=\");\n   if(this.fp)\n     parts.push(\"fp=\"+this.fp);\n+  else if(this.hpb)\n+    parts.push(\"fp=\");\n   if(this.h)\n     parts.push(\"h=\"+this.h);\n   if(this.hp)\n-- \n1.5.1.1.85.gf1888\n"},{"id":"39842","messageId":"200704181552.48363.jnareb@gmail.com","threadId":"7663","inReplyTo":"11766699702663-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"Re: [PATCH 1/7] gitweb: show \"no difference\" message for empty diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-04-18T13:52:47Z","receivedAt":"2007-04-18T13:52:47Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sun, Apr 15, 2007, Martin Koegler wrote:\n> Currently, gitweb shows only header and footer, if no differences are\n> found. This patch adds a \"No differences found\" message for the html\n> output.\n> \n> Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\n> ---\n> $patch_idx does not work, so I need a new variable.\n\nNice work.\n\n> The css style for the no difference message is useable. If somebody\n> does not like, feel free to send a patch with a better layout.\n\nI like it, although I'd rather have \"quieter\" CSS style for the\n\"No differences found\" message. But it is I think a matter of taste.\n\nBelow your patch with my changes.\n\n-- >8 --\nFrom: Martin Koegler <mkoegler@auto.tuwien.ac.at>\nSubject: [PATCH 1/7] gitweb: Show \"no difference\" message for empty diff\n\nCurrently, gitweb shows only header and footer, if no differences are\nfound. This patch adds a \"No differences found\" message for the html\noutput.\n\nSigned-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.css  |    4 ++++\n gitweb/gitweb.perl |    3 +++\n 2 files changed, 7 insertions(+), 0 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 5e40292..2b023bd 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -387,6 +387,10 @@ div.diff.incomplete {\n \tcolor: #cccccc;\n }\n \n+div.diff.nodifferences {\n+\tfont-weight: bold;\n+\tcolor: #600000;\n+}\n \n div.index_include {\n \tborder: solid #d9d8d1;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c48b35a..cbd8d03 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -2398,6 +2398,7 @@ sub git_patchset_body {\n \tmy ($fd, $difftree, $hash, $hash_parent) = @_;\n \n \tmy $patch_idx = 0;\n+\tmy $patch_number = 0;\n \tmy $patch_line;\n \tmy $diffinfo;\n \tmy (%from, %to);\n@@ -2419,6 +2420,7 @@ sub git_patchset_body {\n \t\t# git diff header\n \t\t#assert($patch_line =~ m/^diff /) if DEBUG;\n \t\t#assert($patch_line !~ m!$/$!) if DEBUG; # is chomp-ed\n+\t\t$patch_number++;\n \t\tpush @diff_header, $patch_line;\n \n \t\t# extended diff header\n@@ -2581,6 +2583,7 @@ sub git_patchset_body {\n \t} continue {\n \t\tprint \"</div>\\n\"; # class=\"patch\"\n \t}\n+\tprint \"<div class=\\\"diff nodifferences\\\">No differences found</div>\\n\" if (!$patch_number);\n \n \tprint \"</div>\\n\"; # class=\"patchset\"\n }\n-- \n1.5.1\n"},{"id":"39962","messageId":"200704201234.50134.jnareb@gmail.com","threadId":"7663","inReplyTo":"11766699701308-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"Re: [PATCH 2/7] gitweb: Support comparing blobs with different names","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-04-20T10:34:49Z","receivedAt":"2007-04-20T10:34:49Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Martin Koegler wrote:\n> Currently, blobdiff can only compare blobs with different file\n> names, if no hb/hpb parameters are present.\n> \n> This patch adds support for comparing two blobs specified by any\n> combination of hb/f/h and hpb/fp/hp.\n> \n> Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\n> ---\n\nShouldn't the comment below be also a part of commit message (perhaps\nchanged to use passive form)?\n \n> I unified all blobdiff variants and added support for comparing blobs\n> with different names.\n> \n> If h/hp parameter are missing, I need to generate them with\n> git_get_hash_by_path, as the are needed for the html header, which is\n> generated before parsing the git-diff output.\n> \n> I currently ignore all mode changes, as they are part of the tree. I\n> don't think that displaying a mode change message justifes two call to\n> git-ls-tree for each blob diff (Currently it only calls git-ls-tree\n> for each missing h/hp parameter).\n\nI have mixed feelings about this. On the one hand side the blobdiff\ngeneration is simplified as we have only one codepath instead of two,\nand removed codepath in rare cases (not generated by gitweb currently)\nmight return incorrect results in the case of requesting diff between\ntwo arbitrary and unrelated files.\n\nOn the other hand side we do loose some information, contained in\nextended diff header, like mode changes, renames and such.\n\nIt's a pity that extended sha-1 syntax to specify blobs, namely the\n<tree-ish>:<path> syntax is opaque, and git-diff machinery sees only the\nresult of it, as if it was called directly with the sha-1 of blob.\nIt would be nice if \"git diff <tree1>:<path1> <tree2>:<path2>\" took\nthe information about file name and mode (permissions) from <tree1>\nand <tree2> and included such information in extended git diff header.\n\nCurrently we have:\n\n  $ git diff -p HEAD^ HEAD -- gitweb/test/hardlink\n  diff --git a/gitweb/test/hardlink b/gitweb/test/hardlink\n  old mode 100644\n  new mode 100755\n\nbut\n\n  $ git diff -p HEAD^:gitweb/test/hardlink HEAD:gitweb/test/hardlink\n\nreturns empty diff.\n\n\nI'd rather have core git support for this first before changing how \ngit_blobdiff is implemented in gitweb...\n\n-- \nJakub Narebski\nPoland\n"},{"id":"39967","messageId":"7vabx3z3tf.fsf@assigned-by-dhcp.cox.net","threadId":"7663","inReplyTo":"200704201234.50134.jnareb@gmail.com","subject":"Re: [PATCH 2/7] gitweb: Support comparing blobs with different names","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-04-20T11:24:28Z","receivedAt":"2007-04-20T11:24:28Z","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> Currently we have:\n>\n>   $ git diff -p HEAD^ HEAD -- gitweb/test/hardlink\n>   diff --git a/gitweb/test/hardlink b/gitweb/test/hardlink\n>   old mode 100644\n>   new mode 100755\n>\n> but\n>\n>   $ git diff -p HEAD^:gitweb/test/hardlink HEAD:gitweb/test/hardlink\n>\n> returns empty diff.\n\nBy \"blobdiff\", I understand you are talking about the \"diff\"\nlink that appears on each path at the bottom of the commit view.\n\nI think the bug is the way gitweb drives the core; it uses the\nlatter form, when it has perfectly good information to run the\nformer.  It's not like you have an UI that says \"pick any path\nfrom any comit first; after you have picked one, pick the other\narbitrary one; now we run compare them\".  The UI says \"Give me\ndiff for this path in this commit\".\n"},{"id":"40013","messageId":"200704202249.08464.jnareb@gmail.com","threadId":"7663","inReplyTo":"7vabx3z3tf.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 2/7] gitweb: Support comparing blobs with different names","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-04-20T20:49:08Z","receivedAt":"2007-04-20T20:49:08Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano <junkio@cox.net> wrote:\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n>> Currently we have:\n>>\n>>   $ git diff -p HEAD^ HEAD -- gitweb/test/hardlink\n>>   diff --git a/gitweb/test/hardlink b/gitweb/test/hardlink\n>>   old mode 100644\n>>   new mode 100755\n>>\n>> but\n>>\n>>   $ git diff -p HEAD^:gitweb/test/hardlink HEAD:gitweb/test/hardlink\n>>\n>> returns empty diff.\n> \n> By \"blobdiff\", I understand you are talking about the \"diff\"\n> link that appears on each path at the bottom of the commit view.\n\nBy \"blobdiff\" I mean \"blobdiff\" action (a=blobdiff), generated by\ngit_blobdiff subroutine.  The \"diff\" link that appears for each\npath at the bottom of the \"commit\" view (in the whatchanged / difftree\npart), and the \"diff to current\" link in the \"history\" view for files\nboth lead to \"blobdiff\" view.\n \n> I think the bug is the way gitweb drives the core; it uses the\n> latter form, when it has perfectly good information to run the\n> former.  It's not like you have an UI that says \"pick any path\n> from any comit first; after you have picked one, pick the other\n> arbitrary one; now we run compare them\".  The UI says \"Give me\n> diff for this path in this commit\".\n\n_Currently_ gitweb uses git-diff-tree with path limiting when there\nis enough information given, which means for all \"blobdiff\" links\ncurrently generated by gitweb.  It uses git-diff for blobs only if\nthere is not enough information, e.g. for legacy URL; before moving\nto generating diffs with git-diff-tree and git-diff, and all patches\nwere generated by external /usr/bin/diff, there were no 'hp' and 'hpb'\nparameters which are needed for git-diff-tree.\n\nBut using git-diff-tree with path limiter to extract diff between\ngiven blobs for \"blobdiff\" view is not without its caveats.  For example\nfor a rename you need both pre and post filenames in path limiter, \notherwise you would get only \"half\" of rename diff, namely appropriate\ncreation diff.  And you can select only between blobs which have changed\nfrom one commit (tree) to other; you cannot for example generate diff\nbetween README at 'master' and INSTALL at 'next'.  Although why one \nwould want such diff are beyond me... well, except for [overrated] \ncompleteness...\n\nMartin wants to have ability to generate diff (blobdiff) between two\narbitrary blobs (two arbitrary files at arbitrary revisions). Earlier\npatch if I remember correctly introduced yet another codepath; this one\ntries to generate everything using one codepath, the git-diff one.\n\"Pick any path from any comit first; after you have picked one, pick the \nother arbitrary one; now we run compare them\".\n\nIt adds new feature to gitweb I think almost nobody would use, namely\ncomparing arbitrary blobs (arbitrary files, with different names), and \nunifies diff generation in git_blobdiff (everything does use git-diff).\nBut it does so [currently] at the loss of information, namely ignoring \nall mode changes.  The mode changes can be done without lost of \nunification at the cost of performance of always having to do \ngit-ls-tree, twice, or at the loss of having git_blobdiff quite \ncomplicated.\n\nSo from me it is slight Nak to this patch, at least unless \"git diff \n<tree1>:<path1> <tree2>:<path2>\" will take the information about file \nname and mode (permissions) from <tree1> and <tree2>, and included such \ninformation in extended git diff header.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"40045","messageId":"20070421122348.GA29174@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"200704202249.08464.jnareb@gmail.com","subject":"[PATCH 0/4] git-diff: use mode for tree:name syntax (was: Re: [PATCH 2/7] gitweb: Support comparing blobs with different names)","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-21T12:23:48Z","receivedAt":"2007-04-21T12:23:48Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"On Fri, Apr 20, 2007 at 10:49:08PM +0200, Jakub Narebski wrote:\n> So from me it is slight Nak to this patch, at least unless \"git diff \n> <tree1>:<path1> <tree2>:<path2>\" will take the information about file \n> name and mode (permissions) from <tree1> and <tree2>, and included such \n> information in extended git diff header.\n\nI created a prototyp implemention:\n\n* Patch 1:\n add a parameter to get_sha1 to store the mode, if it is known.\n If it is not possible to dermine the mode, it stores S_IFINVALID.\n\n* Patch 2:\n add space for the mode in object_array (unknown mode is S_IFINVALID).\n\n* Patch 3:\n stores the mode for <tree>:<filename> syntax\n\n* Patch 4:\n use mode information for comparing two blobs\n\nThe patches are large, as some heavy used functions get a new\nparameter. The changes should not increase the CPU time. Patch 2\nincreases the storage size for each object of object_array by an\nunsigned for the mode.\n\nMy blobdiff patch will need some small adaptations:\n* we need to add --raw -p --full-index as diff arguments\n* we must pass $hash_parent_base.':'.$file_parent and\n  $hash_base.':'.$file_name to git-diff instead of \n  $hash and $hash_parent, if possible.\n\nmfg Martin Kögler\n"},{"id":"40596","messageId":"200704271255.24200.jnareb@gmail.com","threadId":"7663","inReplyTo":"11766699713715-git-send-email-mkoegler@auto.tuwien.ac.at","subject":"Re: [PATCH 3/7] gitweb: support filename prefix in git_patchset_body/git_difftree_body","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-04-27T10:55:22Z","receivedAt":"2007-04-27T10:55:22Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Sunday, 15 April 2007, Martin Koegler wrote:\n> git_treediff supports comparing subdirectories. As the output of\n> git-difftree is missing the path to the compared directories,\n> the links in the output would be wrong.\n\nYou mean that git-diff-tree output for diff between two non-toplevel\ntrees lacks the path to compared tree, e.g.\n  $ git diff-tree <commit1>:<path1> <commit2>:<path2>\nlacks <path1> prefix in the from part, and <path2> prefix in to part,\nand the goal is to add those missing prefixes in the links, without\nchanging the visible output of git_patchset_body/git_difftree_body.\n \n> The patch adds two new parameters to add the missing path prefix.\n\n...and makes use of them while generating links.\n\nAlthough I'm not sure if it wouldn't be better to put e.g.\n$prefix_from.$diff{'file'} in $diff{'file_from_url'} or something\nlike that.\n\n> Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>\n> ---\n> I renamed the parameters to to/from_prefix.\n> \n> Modifying the file name in $diff would require bigger changes\n> and cause new problems: \n> * new output rewriter for plain view needed\n> * for modified files only one file name, but possibly two prefixes\n\nLooks nice, although I think this patch is needed only when we have\n\"treediff\" (and \"treediff_plain\") views, i.e. when we are able to\ncompare not only top level trees (like in \"commitdiff\" view),\nor individual files (in \"blobdiff\" view), but also arbitrary trees.\n\nIt can be usefull to compare for example git-gui/ directory in git.git\nmainline branch with the root directory from git://repo.or.cz/git-gui\nor gitweb/ directory after including gitweb in git repository with the\ngitweb.git commits. Although not that useful in first example: there is\nas far as I know no development of git-gui directly in git.git\nrepository so the only difference is that in mainline git-gui stuff\nresides in git-gui/ and in git://repo.or.cz/git-gui in top directory\n\n-- \nJakub Narebski\nShadeHawk on #git\nPoland\n"},{"id":"40649","messageId":"20070428082233.GA19578@auto.tuwien.ac.at","threadId":"7663","inReplyTo":"200704271255.24200.jnareb@gmail.com","subject":"Re: [PATCH 3/7] gitweb: support filename prefix in git_patchset_body/git_difftree_body","fromName":"Martin Koegler","fromEmail":"mkoegler@auto.tuwien.ac.at","sentAt":"2007-04-28T08:22:33Z","receivedAt":"2007-04-28T08:22:33Z","isPatch":true,"sender":{"key":"mkoegler@auto.tuwien.ac.at","avatar":null},"body":"On Fri, Apr 27, 2007 at 12:55:22PM +0200, Jakub Narebski wrote:\n> On Sunday, 15 April 2007, Martin Koegler wrote:\n> > git_treediff supports comparing subdirectories. As the output of\n> > git-difftree is missing the path to the compared directories,\n> > the links in the output would be wrong.\n> \n> You mean that git-diff-tree output for diff between two non-toplevel\n> trees lacks the path to compared tree, e.g.\n>   $ git diff-tree <commit1>:<path1> <commit2>:<path2>\n> lacks <path1> prefix in the from part, and <path2> prefix in to part,\n> and the goal is to add those missing prefixes in the links, without\n> changing the visible output of git_patchset_body/git_difftree_body.\n\nYes, as I don't want to rewrite the raw view.\n\n> > The patch adds two new parameters to add the missing path prefix.\n> \n> ...and makes use of them while generating links.\n> \n> Although I'm not sure if it wouldn't be better to put e.g.\n> $prefix_from.$diff{'file'} in $diff{'file_from_url'} or something\n> like that.\n\nWould this really simplify the code? \n\nFiguring out, what is stored in $diff and how its elements are used,\nrequries more time. Adding a prefix is easier to understand.\n\n> Looks nice, although I think this patch is needed only when we have\n> \"treediff\" (and \"treediff_plain\") views, i.e. when we are able to\n> compare not only top level trees (like in \"commitdiff\" view),\n> or individual files (in \"blobdiff\" view), but also arbitrary trees.\n\nMy git_treediff patch supports this. My JavaScript prototyp can be used to\nselect such a comparison.\n\nmfg Martin Kögler\n"}]}