{"thread":{"id":"43254","subject":"Re: [PATCH 2/2] gitweb: New improved formatting of chunk header in diff","startedAt":"2006-11-08T10:47:52Z","lastAt":"2006-11-08T21:55:03Z","messageCount":16,"participants":["Junio C Hamano","Jakub Narebski"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"296008","messageId":"200611081147.52952.jnareb@gmail.com","threadId":"43254","inReplyTo":null,"subject":"[PATCH 0/2] Better unquoting of git quoted filenames; esc_path to escape pathnames for display","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T10:47:52Z","receivedAt":"2006-11-08T10:47:52Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This series fixes unquote so that it can deal with alphabetic escape\nsequences like '\\n' and '\\t', and escaped literal characters like '\\\"'\nand '\\\\', and adds esc_path do deal with the fact that unquoted \nfilenames can now contain control characters, not suitable for HTML.\nPrevious version of unquote was broken in that it did only octal\nescape sequence unquoting, and could leave filename only partially\nunquoted.\n\nFirst patch adds minimal esc_path, second improves esc_path to final\nversion.\n\nShortlog:\n [PATCH 1/2] gitweb: Better git-unquoting and gitweb-quoting of pathnames\n [PATCH 2/2] gitweb: Use character or octal escape codes (and add span.cntrl) in esc_path\n\nDiffstat:\n gitweb/gitweb.css  |    7 ++++\n gitweb/gitweb.perl |   95 +++++++++++++++++++++++++++++++++++++++++----------\n 2 files changed, 83 insertions(+), 19 deletions(-)\n\n-- \nJakub Narebski\n"},{"id":"295604","messageId":"200611081148.57243.jnareb@gmail.com","threadId":"43254","inReplyTo":"200611081147.52952.jnareb@gmail.com","subject":"[PATCH 1/2] gitweb: Better git-unquoting and gitweb-quoting of pathnames","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T10:48:56Z","receivedAt":"2006-11-08T10:48:56Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Extend unquote subroutine, which unquotes quoted and escaped filenames\nwhich git may return, to deal not only with octal char sequence\nquoting, but also quoting ordinary characters including '\\\"' and '\\\\'\nwhich are respectively quoted '\"' and '\\', and to deal also with\nC escape sequences including '\\t' for TAB and '\\n' for LF.\n\nAdd esc_path subroutine for gitweb quoting and HTML escaping filenames\n(currently it does equivalent of ls' --hide-control-chars, which means\nshowing undisplayable characters (including '\\n' and '\\t') as '?'\n(question mark) character.  Convert gitweb to use esc_path instead of\nsimply esc_html to print pathnames.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nI hope I catched all the places where esc_html should be replaced by\nesc_path.\n\n gitweb/gitweb.perl |   72 ++++++++++++++++++++++++++++++++++++++-------------\n 1 files changed, 53 insertions(+), 19 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c46629f..32926f9 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -584,12 +584,46 @@ sub esc_html ($;%) {\n \treturn $str;\n }\n \n+# quote control characters and escape filename to HTML\n+sub esc_path {\n+\tmy $str = shift;\n+\t$str = esc_html($str);\n+\t$str =~ s/[[:cntrl:]]/?/g; # like --hide-control-chars in ls\n+\treturn $str;\n+}\n+\n # git may return quoted and escaped filenames\n sub unquote {\n \tmy $str = shift;\n+\n+\tsub unq {\n+\t\tmy $seq = shift;\n+\t\tmy %es = ( # character escape codes, aka escape sequences\n+\t\t\t't' => \"\\t\",   # tab            (HT, TAB)\n+\t\t\t'n' => \"\\n\",   # newline        (NL)\n+\t\t\t'r' => \"\\r\",   # return         (CR)\n+\t\t\t'f' => \"\\f\",   # form feed      (FF)\n+\t\t\t'b' => \"\\b\",   # backspace      (BS)\n+\t\t\t'a' => \"\\a\",   # alarm (bell)   (BEL)\n+\t\t\t'e' => \"\\e\",   # escape         (ESC)\n+\t\t\t'v' => \"\\013\", # vertical tab   (VT)\n+\t\t);\n+\n+\t\tif ($seq =~ m/^[0-7]{1,3}$/) {\n+\t\t\t# octal char sequence\n+\t\t\treturn chr(oct($seq));\n+\t\t} elsif (exists $es{$seq}) {\n+\t\t\t# C escape sequence, aka character escape code\n+\t\t\treturn $es{$seq}\n+\t\t}\n+\t\t# quoted ordinary character\n+\t\treturn $seq;\n+\t}\n+\n \tif ($str =~ m/^\"(.*)\"$/) {\n+\t\t# needs unquoting\n \t\t$str = $1;\n-\t\t$str =~ s/\\\\([0-7]{1,3})/chr(oct($1))/eg;\n+\t\t$str =~ s/\\\\([^0-7]|[0-7]{1,3})/unq($1)/eg;\n \t}\n \treturn $str;\n }\n@@ -1520,7 +1554,7 @@ sub git_header_html {\n \t\tif (defined $action) {\n \t\t\t$title .= \"/$action\";\n \t\t\tif (defined $file_name) {\n-\t\t\t\t$title .= \" - \" . esc_html($file_name);\n+\t\t\t\t$title .= \" - \" . esc_path($file_name);\n \t\t\t\tif ($action eq \"tree\" && $file_name !~ m|/$|) {\n \t\t\t\t\t$title .= \"/\";\n \t\t\t\t}\n@@ -1791,20 +1825,20 @@ sub git_print_page_path {\n \t\t\t$fullname .= ($fullname ? '/' : '') . $dir;\n \t\t\tprint $cgi->a({-href => href(action=>\"tree\", file_name=>$fullname,\n \t\t\t                             hash_base=>$hb),\n-\t\t\t              -title => $fullname}, esc_html($dir));\n+\t\t\t              -title => $fullname}, esc_path($dir));\n \t\t\tprint \" / \";\n \t\t}\n \t\tif (defined $type && $type eq 'blob') {\n \t\t\tprint $cgi->a({-href => href(action=>\"blob_plain\", file_name=>$file_name,\n \t\t\t                             hash_base=>$hb),\n-\t\t\t              -title => $name}, esc_html($basename));\n+\t\t\t              -title => $name}, esc_path($basename));\n \t\t} elsif (defined $type && $type eq 'tree') {\n \t\t\tprint $cgi->a({-href => href(action=>\"tree\", file_name=>$file_name,\n \t\t\t                             hash_base=>$hb),\n-\t\t\t              -title => $name}, esc_html($basename));\n+\t\t\t              -title => $name}, esc_path($basename));\n \t\t\tprint \" / \";\n \t\t} else {\n-\t\t\tprint esc_html($basename);\n+\t\t\tprint esc_path($basename);\n \t\t}\n \t}\n \tprint \"<br/></div>\\n\";\n@@ -1876,7 +1910,7 @@ sub git_print_tree_entry {\n \t\tprint \"<td class=\\\"list\\\">\" .\n \t\t\t$cgi->a({-href => href(action=>\"blob\", hash=>$t->{'hash'},\n \t\t\t                       file_name=>\"$basedir$t->{'name'}\", %base_key),\n-\t\t\t        -class => \"list\"}, esc_html($t->{'name'})) . \"</td>\\n\";\n+\t\t\t        -class => \"list\"}, esc_path($t->{'name'})) . \"</td>\\n\";\n \t\tprint \"<td class=\\\"link\\\">\";\n \t\tprint $cgi->a({-href => href(action=>\"blob\", hash=>$t->{'hash'},\n \t\t\t\t\t     file_name=>\"$basedir$t->{'name'}\", %base_key)},\n@@ -1903,7 +1937,7 @@ sub git_print_tree_entry {\n \t\tprint \"<td class=\\\"list\\\">\";\n \t\tprint $cgi->a({-href => href(action=>\"tree\", hash=>$t->{'hash'},\n \t\t                             file_name=>\"$basedir$t->{'name'}\", %base_key)},\n-\t\t              esc_html($t->{'name'}));\n+\t\t              esc_path($t->{'name'}));\n \t\tprint \"</td>\\n\";\n \t\tprint \"<td class=\\\"link\\\">\";\n \t\tprint $cgi->a({-href => href(action=>\"tree\", hash=>$t->{'hash'},\n@@ -1968,7 +2002,7 @@ sub git_difftree_body {\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              -class => \"list\"}, esc_html($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 \t\t\tprint \"<td class=\\\"link\\\">\";\n@@ -1984,7 +2018,7 @@ sub git_difftree_body {\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               -class => \"list\"}, esc_html($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 \t\t\tprint \"<td class=\\\"link\\\">\";\n@@ -2024,7 +2058,7 @@ sub git_difftree_body {\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              -class => \"list\"}, esc_html($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 \t\t\tprint \"<td class=\\\"link\\\">\";\n@@ -2064,11 +2098,11 @@ sub git_difftree_body {\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              -class => \"list\"}, esc_html($diff{'to_file'})) . \"</td>\\n\" .\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              -class => \"list\"}, esc_html($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 \t\t\tif ($action eq 'commitdiff') {\n@@ -2191,7 +2225,7 @@ sub git_patchset_body {\n \t\t\t$file  ||= $diffinfo->{'file'};\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                -class => \"list\"}, esc_path($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@@ -2203,7 +2237,7 @@ sub git_patchset_body {\n \t\t\t$file  ||= $diffinfo->{'file'};\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                -class => \"list\"}, esc_path($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@@ -3521,8 +3555,8 @@ sub git_blobdiff {\n \n \t} else {\n \t\twhile (my $line = <$fd>) {\n-\t\t\t$line =~ s!a/($hash|$hash_parent)!'a/'.esc_html($diffinfo{'from_file'})!eg;\n-\t\t\t$line =~ s!b/($hash|$hash_parent)!'b/'.esc_html($diffinfo{'to_file'})!eg;\n+\t\t\t$line =~ s!a/($hash|$hash_parent)!'a/'.esc_path($diffinfo{'from_file'})!eg;\n+\t\t\t$line =~ s!b/($hash|$hash_parent)!'b/'.esc_path($diffinfo{'to_file'})!eg;\n \n \t\t\tprint $line;\n \n@@ -3879,7 +3913,7 @@ sub git_search {\n \t\t\t\t\t\tprint $cgi->a({-href => href(action=>\"blob\", hash_base=>$co{'id'},\n \t\t\t\t\t\t                             hash=>$set{'id'}, file_name=>$set{'file'}),\n \t\t\t\t\t\t              -class => \"list\"},\n-\t\t\t\t\t\t              \"<span class=\\\"match\\\">\" . esc_html($set{'file'}) . \"</span>\") .\n+\t\t\t\t\t\t              \"<span class=\\\"match\\\">\" . esc_path($set{'file'}) . \"</span>\") .\n \t\t\t\t\t\t      \"<br/>\\n\";\n \t\t\t\t\t}\n \t\t\t\t\tprint \"</td>\\n\" .\n@@ -4014,7 +4048,7 @@ XML\n \t\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\t\tnext;\n \t\t\t}\n-\t\t\tmy $file = esc_html(unquote($7));\n+\t\t\tmy $file = esc_path(unquote($7));\n \t\t\t$file = to_utf8($file);\n \t\t\tprint \"$file<br/>\\n\";\n \t\t}\n-- \n1.4.3.4\n"},{"id":"297057","messageId":"200611081150.07469.jnareb@gmail.com","threadId":"43254","inReplyTo":"200611081147.52952.jnareb@gmail.com","subject":"[PATCH 2/2] gitweb: Use character or octal escape codes (and add span.cntrl) in esc_path","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T10:50:07Z","receivedAt":"2006-11-08T10:50:07Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Instead of simply hiding control characters in esc_path by replacing\nthem with '?', use Character Escape Codes (CEC) i.e. alphabetic\nbackslash sequences like those found in C programming language and\nmany other languages influenced by it, such as Java and Perl.  If\ncontrol characted doesn't have corresponding character escape code,\nuse octal char sequence to escape it.\n\nAdditionally use 'span' element with 'cntrl' attribute to mark escaped\ncontrol characters. Add style for span.cntrl in the CSS.\n\nBelow there is alternative quoting using Unicode Printable\nRepresentation (PR), i.e. replace control characters with appropriate\nUnicode Control Pictures U+2400 - U+243F (9216 - 9279), the Unicode\ncharacters reserved for representing control characters when it is\nnecessary to print or display them:\n\nsub esc_path {\n\tmy $str = shift;\n\t$str = esc_html($str);\n\t$str =~ s!([[:cntrl:]])!sprintf('<span class=\"cntrl\">&#%04d;</span>', 0x2400+ord($1))!eg;\n\treturn $str;\n}\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nThe styling (span.cntrl style) isn't best, I agree.\n\n gitweb/gitweb.css  |    7 +++++++\n gitweb/gitweb.perl |   25 ++++++++++++++++++++++++-\n 2 files changed, 31 insertions(+), 1 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 0eda982..e19e6bc 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -16,6 +16,13 @@ a:hover, a:visited, a:active {\n \tcolor: #880000;\n }\n \n+span.cntrl {\n+\tborder: dashed #aaaaaa;\n+\tborder-width: 1px;\n+\tpadding: 0px 2px 0px 2px;\n+\tmargin:  0px 2px 0px 2px;\n+}\n+\n img.logo {\n \tfloat: right;\n \tborder-width: 0px;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 32926f9..c9b16b5 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -587,8 +587,31 @@ sub esc_html ($;%) {\n # quote control characters and escape filename to HTML\n sub esc_path {\n \tmy $str = shift;\n+\n+\tsub quot {\n+\t\tmy $seq = shift;\n+\t\tmy %es = ( # character escape codes, aka escape sequences\n+\t\t\t\"\\t\" => '\\t',   # tab            (HT, TAB)\n+\t\t\t\"\\n\" => '\\n',   # newline        (NL)\n+\t\t\t\"\\r\" => '\\r',   # return         (CR)\n+\t\t\t\"\\f\" => '\\f',   # form feed      (FF)\n+\t\t\t\"\\b\" => '\\b',   # backspace      (BS)\n+\t\t\t\"\\a\" => '\\a',   # alarm (bell)   (BEL)\n+\t\t\t\"\\e\" => '\\e',   # escape         (ESC)\n+\t\t\t\"\\013\" => '\\v', # vertical tab   (VT)\n+\t\t\t\"\\000\" => '\\0', # null character (NUL)\n+\t\t);\n+\n+\t\tif (exists $es{$seq}) {\n+\t\t\t# C escape sequence, aka character escape code\n+\t\t\treturn $es{$seq};\n+\t\t}\n+\t\t# octal char sequence\n+\t\treturn sprintf('\\%03o', ord($seq));\n+\t}\n+\n \t$str = esc_html($str);\n-\t$str =~ s/[[:cntrl:]]/?/g; # like --hide-control-chars in ls\n+\t$str =~ s!([[:cntrl:]])!'<span class=\"cntrl\">' . quot($1) . '</span>'!eg;\n \treturn $str;\n }\n \n-- \n1.4.3.4\n"},{"id":"298459","messageId":"200611081758.57597.jnareb@gmail.com","threadId":"43254","inReplyTo":"200611081150.07469.jnareb@gmail.com","subject":"[PATCH 0/2] gitweb: New improved patchset view","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T16:58:57Z","receivedAt":"2006-11-08T16:58:57Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"This series of patches is based on previous \"[PATCH 0/2] Better unquoting\nof git quoted filenames; esc_path to escape pathnames for display\" series;\nactually previous series was send because it is prerequisite of this series.\n\nThis series introduces new \"feature\", namely new commitdiff and blobdiff\nview (new patchset view in short) BUT without this feature the accepted\n\"gitweb: Output also empty patches in \"commitdiff\" view\" is of dubious value,\nas it has not much sense without new patchset view.\n\nWithout \"new improved patchset view\" the empty patches are just that:\ntotally empty. It is new header and especially outputting extended header\ninformation which makes outputting \"empty\" patches (with no diff)\nin \"commitdiff\" view usefull. By \"empty\" patches I mean pure type change,\npure rename, pure copy, and type change with rename.\n\n\nShortlog:\n [PATCH 1/2] gitweb: New improved patchset view\n [PATCH 2/2] gitweb: New improved formatting of chunk header in diff\n\nDiffstat:\n gitweb/gitweb.css  |   79 +++++++++++++++++---\n gitweb/gitweb.perl |  201 +++++++++++++++++++++++++++++++++++-----------------\n 2 files changed, 203 insertions(+), 77 deletions(-)\n\n-- \nJakub Narebski\nShadeHawk on #git\n"},{"id":"298210","messageId":"200611081759.41498.jnareb@gmail.com","threadId":"43254","inReplyTo":"200611081758.57597.jnareb@gmail.com","subject":"[PATCH 1/2] gitweb: New improved patchset view","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T16:59:41Z","receivedAt":"2006-11-08T16:59:41Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Replace \"gitweb diff header\" with its full sha1 of blobs and replace\nit by \"git diff\" header and extended diff header. Change also somewhat\nhighlighting of diffs.\n\nAdded `file_type_long' subroutine to convert file mode in octal to\nfile type description (only for file modes which used by git).\n\nChanges:\n* \"gitweb diff header\" which looked for example like below:\n    file:_<sha1 before>_ -> file:_<sha1 after>_\n  where 'file' is file type and '<sha1>' is full sha1 of blob is\n  changed to\n    diff --git _a/<file before>_ _b/<file after>_\n  In both cases links are visible and use default link style. If file\n  is added, a/<file> is not hyperlinked. If file is deleted, b/<file>\n  is not hyperlinked.\n* there is added \"extended diff header\", with <path> and <hash>\n  hyperlinked (and <hash> shortened to 7 characters), and <mode>\n  explained: '<mode>' is extended to '<mode> (<file type description>)',\n  where added text is slightly lighter to easy distinguish that it\n  was added (and it is difference from git-diff output).\n* from-file/to-file two-line header lines have slightly darker color\n  than removed/added lines.\n* chunk header has now delicate line above for easier finding chunk\n  boundary, and top margin of 2px, both barely visible.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.css  |   66 +++++++++++++++----\n gitweb/gitweb.perl |  183 \n++++++++++++++++++++++++++++++++++------------------\n 2 files changed, 173 insertions(+), 76 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex e19e6bc..974b47f 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -298,40 +298,82 @@ td.mode {\n \tfont-family: monospace;\n }\n \n-div.diff a.list {\n+/* styling of diffs (patchsets): commitdiff and blobdiff views */\n+div.diff.header,\n+div.diff.extended_header {\n+\twhite-space: normal;\n+}\n+\n+div.diff.header {\n+\tfont-weight: bold;\n+\n+\tbackground-color: #edece6;\n+\n+\tmargin-top: 4px;\n+\tpadding: 4px 0px 2px 0px;\n+\tborder: solid #d9d8d1;\n+\tborder-width: 1px 0px 1px 0px;\n+}\n+\n+div.diff.header a.path {\n+\ttext-decoration: underline;\n+}\n+\n+div.diff.extended_header,\n+div.diff.extended_header a.path,\n+div.diff.extended_header a.hash {\n+\tcolor: #777777;\n+}\n+\n+div.diff.extended_header .info {\n+\tcolor: #b0b0b0;\n+}\n+\n+div.diff.extended_header {\n+\tbackground-color: #f6f5ee;\n+\tpadding: 2px 0px 2px 0px;\n+}\n+\n+div.diff a.path,\n+div.diff a.hash {\n \ttext-decoration: none;\n }\n \n-div.diff a.list:hover {\n+div.diff a.path:hover,\n+div.diff a.hash:hover {\n \ttext-decoration: underline;\n }\n \n-div.diff.to_file a.list,\n-div.diff.to_file,\n+div.diff.to_file a.path,\n+div.diff.to_file {\n+\tcolor: #007000;\n+}\n+\n div.diff.add {\n \tcolor: #008800;\n }\n \n-div.diff.from_file a.list,\n-div.diff.from_file,\n+div.diff.from_file a.path,\n+div.diff.from_file {\n+\tcolor: #aa0000;\n+}\n+\n div.diff.rem {\n \tcolor: #cc0000;\n }\n \n div.diff.chunk_header {\n \tcolor: #990099;\n+\n+\tborder: dotted #ffe0ff;\n+\tborder-width: 1px 0px 0px 0px;\n+\tmargin-top: 2px;\n }\n \n div.diff.incomplete {\n \tcolor: #cccccc;\n }\n \n-div.diff_info {\n-\tfont-family: monospace;\n-\tcolor: #000099;\n-\tbackground-color: #edece6;\n-\tfont-style: italic;\n-}\n \n div.index_include {\n \tborder: solid #d9d8d1;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c9b16b5..2cf8e60 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -780,6 +780,32 @@ sub file_type {\n \t}\n }\n \n+# convert file mode in octal to file type description string\n+sub file_type_long {\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+\t} elsif (S_ISLNK($mode)) {\n+\t\treturn \"symlink\";\n+\t} elsif (S_ISREG($mode)) {\n+\t\tif ($mode & S_IXUSR) {\n+\t\t\treturn \"executable\";\n+\t\t} else {\n+\t\t\treturn \"file\";\n+\t\t};\n+\t} else {\n+\t\treturn \"unknown\";\n+\t}\n+}\n+\n+\n ## \n----------------------------------------------------------------------\n ## functions returning short HTML fragments, or transforming HTML \nfragments\n ## which don't beling to other sections\n@@ -2166,6 +2192,7 @@ sub git_patchset_body {\n \tmy $in_header = 0;\n \tmy $patch_found = 0;\n \tmy $diffinfo;\n+\tmy (%from, %to);\n \n \tprint \"<div class=\\\"patchset\\\">\\n\";\n \n@@ -2176,6 +2203,10 @@ sub git_patchset_body {\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 extended header for previous empty patch\n+\t\t\t\tif ($in_header) {\n+\t\t\t\t\tprint \"</div>\\n\" # class=\"diff extended_header\"\n+\t\t\t\t}\n \t\t\t\t# close previous patch\n \t\t\t\tprint \"</div>\\n\"; # class=\"patch\"\n \t\t\t} else {\n@@ -2184,89 +2215,113 @@ sub git_patchset_body {\n \t\t\t}\n \t\t\tprint \"<div class=\\\"patch\\\" id=\\\"patch\". ($patch_idx+1) .\"\\\">\\n\";\n \n+\t\t\t# read and prepare patch information\n \t\t\tif (ref($difftree->[$patch_idx]) eq \"HASH\") {\n+\t\t\t\t# pre-parsed (or generated by hand)\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$from{'file'} = $diffinfo->{'from_file'} || $diffinfo->{'file'};\n+\t\t\t$to{'file'}   = $diffinfo->{'to_file'}   || $diffinfo->{'file'};\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}\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}\n \t\t\t$patch_idx++;\n \n-\t\t\tif ($diffinfo->{'status'} eq \"A\") { # added\n-\t\t\t\tprint \"<div class=\\\"diff_info\\\">\" . \nfile_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'}, \nfile_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\\\">\" . \nfile_type($diffinfo->{'from_mode'}) . \":\" .\n-\t\t\t\t      $cgi->a({-href => href(action=>\"blob\", \nhash_base=>$hash_parent,\n-\t\t\t\t                             hash=>$diffinfo->{'from_id'}, \nfile_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         $diffinfo->{'status'} eq \"2\") { # with two filenames (from \ngit_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\", \nhash_base=>$hash_parent,\n-\t\t\t\t                             hash=>$diffinfo->{'from_id'}, \nfile_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'}, \nfile_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\", \nhash_base=>$hash_parent,\n-\t\t\t\t                             hash=>$diffinfo->{'from_id'}, \nfile_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'}, \nfile_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# print \"git diff\" header\n+\t\t\t$patch_line =~ s!^(diff (.*?) )\"?a/.*$!$1!;\n+\t\t\tif ($from{'href'}) {\n+\t\t\t\t$patch_line .= $cgi->a({-href => $from{'href'}, -class => \"path\"},\n+\t\t\t\t                       'a/' . esc_path($from{'file'}));\n+\t\t\t} else { # file was added\n+\t\t\t\t$patch_line .= 'a/' . esc_path($from{'file'});\n+\t\t\t}\n+\t\t\t$patch_line .= ' ';\n+\t\t\tif ($to{'href'}) {\n+\t\t\t\t$patch_line .= $cgi->a({-href => $to{'href'}, -class => \"path\"},\n+\t\t\t\t                       'b/' . esc_path($to{'file'}));\n+\t\t\t} else { # file was deleted\n+\t\t\t\t$patch_line .= 'b/' . esc_path($to{'file'});\n \t\t\t}\n \n-\t\t\t#print \"<div class=\\\"diff extended_header\\\">\\n\";\n+\t\t\tprint \"<div class=\\\"diff header\\\">$patch_line</div>\\n\";\n+\t\t\tprint \"<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+\t\t}\n \n+\t\tif ($in_header) {\n+\t\t\tif ($patch_line !~ m/^---/) {\n+\t\t\t\t# match <path>\n+\t\t\t\tif ($patch_line =~ s!^((copy|rename) from ).*$!$1! && \n$from{'href'}) {\n+\t\t\t\t\t$patch_line .= $cgi->a({-href=>$from{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                        esc_path($from{'file'}));\n+\t\t\t\t}\n+\t\t\t\tif ($patch_line =~ s!^((copy|rename) to ).*$!$1! && $to{'href'}) {\n+\t\t\t\t\t$patch_line = $cgi->a({-href=>$to{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                      esc_path($to{'file'}));\n+\t\t\t\t}\n+\t\t\t\t# match <mode>\n+\t\t\t\tif ($patch_line =~ m/\\s(\\d{6})$/) {\n+\t\t\t\t\t$patch_line .= '<span class=\"info\"> (' .\n+\t\t\t\t\t               file_type_long($1) .\n+\t\t\t\t\t               ')</span>';\n+\t\t\t\t}\n+\t\t\t\t# match <hash>\n+\t\t\t\tif ($patch_line =~ m/^index/) {\n+\t\t\t\t\tmy ($from_link, $to_link);\n+\t\t\t\t\tif ($from{'href'}) {\n+\t\t\t\t\t\t$from_link = $cgi->a({-href=>$from{'href'}, -class=>\"hash\"},\n+\t\t\t\t\t\t                     substr($diffinfo->{'from_id'},0,7));\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\t$from_link = '0' x 7;\n+\t\t\t\t\t}\n+\t\t\t\t\tif ($to{'href'}) {\n+\t\t\t\t\t\t$to_link = $cgi->a({-href=>$to{'href'}, -class=>\"hash\"},\n+\t\t\t\t\t\t                   substr($diffinfo->{'to_id'},0,7));\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\t$to_link = '0' x 7;\n+\t\t\t\t\t}\n+\t\t\t\t\tmy ($from_id, $to_id) = ($diffinfo->{'from_id'}, \n$diffinfo->{'to_id'});\n+\t\t\t\t\t$patch_line =~ s!$from_id\\.\\.$to_id!$from_link..$to_link!;\n+\t\t\t\t}\n+\t\t\t\tprint $patch_line . \"<br/>\\n\";\n \n-\t\tif ($in_header && $patch_line =~ m/^---/) {\n-\t\t\t#print \"</div>\\n\"; # class=\"diff extended_header\"\n-\t\t\t$in_header = 0;\n+\t\t\t} else {\n+\t\t\t\t#$in_header && $patch_line =~ m/^---/;\n+\t\t\t\tprint \"</div>\\n\"; # class=\"diff extended_header\"\n+\t\t\t\t$in_header = 0;\n+\n+\t\t\t\tif ($from{'href'}) {\n+\t\t\t\t\t$patch_line = '--- a/' .\n+\t\t\t\t\t              $cgi->a({-href=>$from{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                      esc_path($from{'file'}));\n+\t\t\t\t}\n+\t\t\t\tprint \"<div class=\\\"diff from_file\\\">$patch_line</div>\\n\";\n \n-\t\t\tmy $file = $diffinfo->{'from_file'};\n-\t\t\t$file  ||= $diffinfo->{'file'};\n-\t\t\t$file = $cgi->a({-href => href(action=>\"blob\", \nhash_base=>$hash_parent,\n-\t\t\t                               hash=>$diffinfo->{'from_id'}, \nfile_name=>$file),\n-\t\t\t                -class => \"list\"}, esc_path($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+\t\t\t\t$patch_line = <$fd>;\n+\t\t\t\tchomp $patch_line;\n \n-\t\t\t$patch_line = <$fd>;\n-\t\t\tchomp $patch_line;\n+\t\t\t\t#$patch_line =~ m/^+++/;\n+\t\t\t\tif ($to{'href'}) {\n+\t\t\t\t\t$patch_line = '+++ b/' .\n+\t\t\t\t\t              $cgi->a({-href=>$to{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                      esc_path($to{'file'}));\n+\t\t\t\t}\n+\t\t\t\tprint \"<div class=\\\"diff to_file\\\">$patch_line</div>\\n\";\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$file = $cgi->a({-href => href(action=>\"blob\", hash_base=>$hash,\n-\t\t\t                               hash=>$diffinfo->{'to_id'}, \nfile_name=>$file),\n-\t\t\t                -class => \"list\"}, esc_path($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+\t\t\t}\n \n \t\t\tnext LINE;\n \t\t}\n-\t\tnext LINE if $in_header;\n \n \t\tprint format_diff_line($patch_line);\n \t}\n-- \n1.4.3.4\n"},{"id":"298638","messageId":"200611081800.16001.jnareb@gmail.com","threadId":"43254","inReplyTo":"200611081758.57597.jnareb@gmail.com","subject":"[PATCH 2/2] gitweb: New improved formatting of chunk header in diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T17:00:15Z","receivedAt":"2006-11-08T17:00:15Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"If we have provided enough info, and diff is not combined diff,\nand if provided diff line is chunk header, then:\n* split chunk header into .chunk_info and .section span elements,\n  first containing proper chunk header, second section heading\n  (aka. which function), for separate styling: the proper chunk\n  header is on non-white background, section heading part uses\n  slightly lighter color.\n* hyperlink from-file-range to starting line of from-file, if file\n  was not created.\n* hyperlink to-file-range to starting line of to-file, if file\n  was not deleted.\nLinks are of invisible variety (and \"list\" class).\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.css  |   13 +++++++++++++\n gitweb/gitweb.perl |   18 +++++++++++++++++-\n 2 files changed, 30 insertions(+), 1 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex 974b47f..7177c6e 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -334,11 +334,13 @@ div.diff.extended_header {\n \tpadding: 2px 0px 2px 0px;\n }\n \n+div.diff a.list,\n div.diff a.path,\n div.diff a.hash {\n \ttext-decoration: none;\n }\n \n+div.diff a.list:hover,\n div.diff a.path:hover,\n div.diff a.hash:hover {\n \ttext-decoration: underline;\n@@ -362,14 +364,25 @@ div.diff.rem {\n \tcolor: #cc0000;\n }\n \n+div.diff.chunk_header a,\n div.diff.chunk_header {\n \tcolor: #990099;\n+}\n \n+div.diff.chunk_header {\n \tborder: dotted #ffe0ff;\n \tborder-width: 1px 0px 0px 0px;\n \tmargin-top: 2px;\n }\n \n+div.diff.chunk_header span.chunk_info {\n+\tbackground-color: #ffeeff;\n+}\n+\n+div.diff.chunk_header span.section {\n+\tcolor: #aa22aa;\n+}\n+\n div.diff.incomplete {\n \tcolor: #cccccc;\n }\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 2cf8e60..3118cb0 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -873,6 +873,7 @@ sub format_subject_html {\n \n sub format_diff_line {\n \tmy $line = shift;\n+\tmy ($from, $to) = @_;\n \tmy $char = substr($line, 0, 1);\n \tmy $diff_class = \"\";\n \n@@ -888,6 +889,21 @@ sub format_diff_line {\n \t\t$diff_class = \" incomplete\";\n \t}\n \t$line = untabify($line);\n+\tif ($from && $to && $line =~ m/^\\@{2} /) {\n+\t\tmy ($from_text, $from_start, $from_lines, $to_text, $to_start, $to_lines, $section) =\n+\t\t\t$line =~ m/^\\@{2} (-(\\d+),(\\d+)) (\\+(\\d+),(\\d+)) \\@{2}(.*)$/;\n+\t\tif ($from->{'href'}) {\n+\t\t\t$from_text = $cgi->a({-href=>\"$from->{'href'}#l$from_start\",\n+\t\t\t                     -class=>\"list\"}, $from_text);\n+\t\t}\n+\t\tif ($to->{'href'}) {\n+\t\t\t$to_text   = $cgi->a({-href=>\"$to->{'href'}#l$to_start\",\n+\t\t\t                     -class=>\"list\"}, $to_text);\n+\t\t}\n+\t\t$line = \"<span class=\\\"chunk_info\\\">@@ $from_text $to_text @@</span>\" .\n+\t\t        \"<span class=\\\"section\\\">\" . esc_html($section, -nbsp=>1) . \"</span>\";\n+\t\treturn \"<div class=\\\"diff$diff_class\\\">$line</div>\\n\";\n+\t}\n \treturn \"<div class=\\\"diff$diff_class\\\">\" . esc_html($line, -nbsp=>1) . \"</div>\\n\";\n }\n \n@@ -2323,7 +2339,7 @@ sub git_patchset_body {\n \t\t\tnext LINE;\n \t\t}\n \n-\t\tprint format_diff_line($patch_line);\n+\t\tprint format_diff_line($patch_line, \\%from, \\%to);\n \t}\n \tprint \"</div>\\n\" if $patch_found; # class=\"patch\"\n \n-- \n1.4.3.4\n"},{"id":"298471","messageId":"7vmz71u787.fsf@assigned-by-dhcp.cox.net","threadId":"43254","inReplyTo":"200611081150.07469.jnareb@gmail.com","subject":"Re: [PATCH 2/2] gitweb: Use character or octal escape codes (and add span.cntrl) in esc_path","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-08T18:24:40Z","receivedAt":"2006-11-08T18:24: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> Instead of simply hiding control characters in esc_path by replacing\n> them with '?', use Character Escape Codes (CEC) i.e. alphabetic\n> backslash sequences like those found in C programming language and\n> many other languages influenced by it, such as Java and Perl.  If\n> control characted doesn't have corresponding character escape code,\n> use octal char sequence to escape it.\n>\n> Additionally use 'span' element with 'cntrl' attribute to mark escaped\n> control characters. Add style for span.cntrl in the CSS.\n\nWould have preferred the 'span' thing to be part of [1/2]...\n\nDidn't I ask quot to be freestanding sub, not nested?  That\nwould make UPR vs CEC experiments easier and more pleasant.\n"},{"id":"295902","messageId":"7virhpu73w.fsf@assigned-by-dhcp.cox.net","threadId":"43254","inReplyTo":"200611081759.41498.jnareb@gmail.com","subject":"Re: [PATCH 1/2] gitweb: New improved patchset view","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-08T18:27:15Z","receivedAt":"2006-11-08T18:27:15Z","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> ---\n>  gitweb/gitweb.css  |   66 +++++++++++++++----\n>  gitweb/gitweb.perl |  183 \n> ++++++++++++++++++++++++++++++++++------------------\n>  2 files changed, 173 insertions(+), 76 deletions(-)\n\nLinewrap?\n\n> ----------------------------------------------------------------------\n>  ## functions returning short HTML fragments, or transforming HTML \n> fragments\n\n...\n"},{"id":"298003","messageId":"200611081941.30330.jnareb@gmail.com","threadId":"43254","inReplyTo":"200611081759.41498.jnareb@gmail.com","subject":"[PATCH 1/2 (amend)] gitweb: New improved patchset view","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T18:41:29Z","receivedAt":"2006-11-08T18:41:29Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Replace \"gitweb diff header\" with its full sha1 of blobs and replace\nit by \"git diff\" header and extended diff header. Change also somewhat\nhighlighting of diffs.\n\nAdded `file_type_long' subroutine to convert file mode in octal to\nfile type description (only for file modes which used by git).\n\nChanges:\n* \"gitweb diff header\" which looked for example like below:\n    file:_<sha1 before>_ -> file:_<sha1 after>_\n  where 'file' is file type and '<sha1>' is full sha1 of blob is\n  changed to\n    diff --git _a/<file before>_ _b/<file after>_\n  In both cases links are visible and use default link style. If file\n  is added, a/<file> is not hyperlinked. If file is deleted, b/<file>\n  is not hyperlinked.\n* there is added \"extended diff header\", with <path> and <hash>\n  hyperlinked (and <hash> shortened to 7 characters), and <mode>\n  explained: '<mode>' is extended to '<mode> (<file type description>)',\n  where added text is slightly lighter to easy distinguish that it\n  was added (and it is difference from git-diff output).\n* from-file/to-file two-line header lines have slightly darker color\n  than removed/added lines.\n* chunk header has now delicate line above for easier finding chunk\n  boundary, and top margin of 2px, both barely visible.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nI'm sorry for previous version with linewrap.\n\n gitweb/gitweb.css  |   66 +++++++++++++++----\n gitweb/gitweb.perl |  183 ++++++++++++++++++++++++++++++++++------------------\n 2 files changed, 173 insertions(+), 76 deletions(-)\n\ndiff --git a/gitweb/gitweb.css b/gitweb/gitweb.css\nindex e19e6bc..974b47f 100644\n--- a/gitweb/gitweb.css\n+++ b/gitweb/gitweb.css\n@@ -298,40 +298,82 @@ td.mode {\n \tfont-family: monospace;\n }\n \n-div.diff a.list {\n+/* styling of diffs (patchsets): commitdiff and blobdiff views */\n+div.diff.header,\n+div.diff.extended_header {\n+\twhite-space: normal;\n+}\n+\n+div.diff.header {\n+\tfont-weight: bold;\n+\n+\tbackground-color: #edece6;\n+\n+\tmargin-top: 4px;\n+\tpadding: 4px 0px 2px 0px;\n+\tborder: solid #d9d8d1;\n+\tborder-width: 1px 0px 1px 0px;\n+}\n+\n+div.diff.header a.path {\n+\ttext-decoration: underline;\n+}\n+\n+div.diff.extended_header,\n+div.diff.extended_header a.path,\n+div.diff.extended_header a.hash {\n+\tcolor: #777777;\n+}\n+\n+div.diff.extended_header .info {\n+\tcolor: #b0b0b0;\n+}\n+\n+div.diff.extended_header {\n+\tbackground-color: #f6f5ee;\n+\tpadding: 2px 0px 2px 0px;\n+}\n+\n+div.diff a.path,\n+div.diff a.hash {\n \ttext-decoration: none;\n }\n \n-div.diff a.list:hover {\n+div.diff a.path:hover,\n+div.diff a.hash:hover {\n \ttext-decoration: underline;\n }\n \n-div.diff.to_file a.list,\n-div.diff.to_file,\n+div.diff.to_file a.path,\n+div.diff.to_file {\n+\tcolor: #007000;\n+}\n+\n div.diff.add {\n \tcolor: #008800;\n }\n \n-div.diff.from_file a.list,\n-div.diff.from_file,\n+div.diff.from_file a.path,\n+div.diff.from_file {\n+\tcolor: #aa0000;\n+}\n+\n div.diff.rem {\n \tcolor: #cc0000;\n }\n \n div.diff.chunk_header {\n \tcolor: #990099;\n+\n+\tborder: dotted #ffe0ff;\n+\tborder-width: 1px 0px 0px 0px;\n+\tmargin-top: 2px;\n }\n \n div.diff.incomplete {\n \tcolor: #cccccc;\n }\n \n-div.diff_info {\n-\tfont-family: monospace;\n-\tcolor: #000099;\n-\tbackground-color: #edece6;\n-\tfont-style: italic;\n-}\n \n div.index_include {\n \tborder: solid #d9d8d1;\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex c9b16b5..2cf8e60 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -780,6 +780,32 @@ sub file_type {\n \t}\n }\n \n+# convert file mode in octal to file type description string\n+sub file_type_long {\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+\t} elsif (S_ISLNK($mode)) {\n+\t\treturn \"symlink\";\n+\t} elsif (S_ISREG($mode)) {\n+\t\tif ($mode & S_IXUSR) {\n+\t\t\treturn \"executable\";\n+\t\t} else {\n+\t\t\treturn \"file\";\n+\t\t};\n+\t} else {\n+\t\treturn \"unknown\";\n+\t}\n+}\n+\n+\n ## ----------------------------------------------------------------------\n ## functions returning short HTML fragments, or transforming HTML fragments\n ## which don't beling to other sections\n@@ -2166,6 +2192,7 @@ sub git_patchset_body {\n \tmy $in_header = 0;\n \tmy $patch_found = 0;\n \tmy $diffinfo;\n+\tmy (%from, %to);\n \n \tprint \"<div class=\\\"patchset\\\">\\n\";\n \n@@ -2176,6 +2203,10 @@ sub git_patchset_body {\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 extended header for previous empty patch\n+\t\t\t\tif ($in_header) {\n+\t\t\t\t\tprint \"</div>\\n\" # class=\"diff extended_header\"\n+\t\t\t\t}\n \t\t\t\t# close previous patch\n \t\t\t\tprint \"</div>\\n\"; # class=\"patch\"\n \t\t\t} else {\n@@ -2184,89 +2215,113 @@ sub git_patchset_body {\n \t\t\t}\n \t\t\tprint \"<div class=\\\"patch\\\" id=\\\"patch\". ($patch_idx+1) .\"\\\">\\n\";\n \n+\t\t\t# read and prepare patch information\n \t\t\tif (ref($difftree->[$patch_idx]) eq \"HASH\") {\n+\t\t\t\t# pre-parsed (or generated by hand)\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$from{'file'} = $diffinfo->{'from_file'} || $diffinfo->{'file'};\n+\t\t\t$to{'file'}   = $diffinfo->{'to_file'}   || $diffinfo->{'file'};\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}\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}\n \t\t\t$patch_idx++;\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         $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-\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# print \"git diff\" header\n+\t\t\t$patch_line =~ s!^(diff (.*?) )\"?a/.*$!$1!;\n+\t\t\tif ($from{'href'}) {\n+\t\t\t\t$patch_line .= $cgi->a({-href => $from{'href'}, -class => \"path\"},\n+\t\t\t\t                       'a/' . esc_path($from{'file'}));\n+\t\t\t} else { # file was added\n+\t\t\t\t$patch_line .= 'a/' . esc_path($from{'file'});\n+\t\t\t}\n+\t\t\t$patch_line .= ' ';\n+\t\t\tif ($to{'href'}) {\n+\t\t\t\t$patch_line .= $cgi->a({-href => $to{'href'}, -class => \"path\"},\n+\t\t\t\t                       'b/' . esc_path($to{'file'}));\n+\t\t\t} else { # file was deleted\n+\t\t\t\t$patch_line .= 'b/' . esc_path($to{'file'});\n \t\t\t}\n \n-\t\t\t#print \"<div class=\\\"diff extended_header\\\">\\n\";\n+\t\t\tprint \"<div class=\\\"diff header\\\">$patch_line</div>\\n\";\n+\t\t\tprint \"<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+\t\t}\n \n+\t\tif ($in_header) {\n+\t\t\tif ($patch_line !~ m/^---/) {\n+\t\t\t\t# match <path>\n+\t\t\t\tif ($patch_line =~ s!^((copy|rename) from ).*$!$1! && $from{'href'}) {\n+\t\t\t\t\t$patch_line .= $cgi->a({-href=>$from{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                        esc_path($from{'file'}));\n+\t\t\t\t}\n+\t\t\t\tif ($patch_line =~ s!^((copy|rename) to ).*$!$1! && $to{'href'}) {\n+\t\t\t\t\t$patch_line = $cgi->a({-href=>$to{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                      esc_path($to{'file'}));\n+\t\t\t\t}\n+\t\t\t\t# match <mode>\n+\t\t\t\tif ($patch_line =~ m/\\s(\\d{6})$/) {\n+\t\t\t\t\t$patch_line .= '<span class=\"info\"> (' .\n+\t\t\t\t\t               file_type_long($1) .\n+\t\t\t\t\t               ')</span>';\n+\t\t\t\t}\n+\t\t\t\t# match <hash>\n+\t\t\t\tif ($patch_line =~ m/^index/) {\n+\t\t\t\t\tmy ($from_link, $to_link);\n+\t\t\t\t\tif ($from{'href'}) {\n+\t\t\t\t\t\t$from_link = $cgi->a({-href=>$from{'href'}, -class=>\"hash\"},\n+\t\t\t\t\t\t                     substr($diffinfo->{'from_id'},0,7));\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\t$from_link = '0' x 7;\n+\t\t\t\t\t}\n+\t\t\t\t\tif ($to{'href'}) {\n+\t\t\t\t\t\t$to_link = $cgi->a({-href=>$to{'href'}, -class=>\"hash\"},\n+\t\t\t\t\t\t                   substr($diffinfo->{'to_id'},0,7));\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\t$to_link = '0' x 7;\n+\t\t\t\t\t}\n+\t\t\t\t\tmy ($from_id, $to_id) = ($diffinfo->{'from_id'}, $diffinfo->{'to_id'});\n+\t\t\t\t\t$patch_line =~ s!$from_id\\.\\.$to_id!$from_link..$to_link!;\n+\t\t\t\t}\n+\t\t\t\tprint $patch_line . \"<br/>\\n\";\n \n-\t\tif ($in_header && $patch_line =~ m/^---/) {\n-\t\t\t#print \"</div>\\n\"; # class=\"diff extended_header\"\n-\t\t\t$in_header = 0;\n+\t\t\t} else {\n+\t\t\t\t#$in_header && $patch_line =~ m/^---/;\n+\t\t\t\tprint \"</div>\\n\"; # class=\"diff extended_header\"\n+\t\t\t\t$in_header = 0;\n+\n+\t\t\t\tif ($from{'href'}) {\n+\t\t\t\t\t$patch_line = '--- a/' .\n+\t\t\t\t\t              $cgi->a({-href=>$from{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                      esc_path($from{'file'}));\n+\t\t\t\t}\n+\t\t\t\tprint \"<div class=\\\"diff from_file\\\">$patch_line</div>\\n\";\n \n-\t\t\tmy $file = $diffinfo->{'from_file'};\n-\t\t\t$file  ||= $diffinfo->{'file'};\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_path($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+\t\t\t\t$patch_line = <$fd>;\n+\t\t\t\tchomp $patch_line;\n \n-\t\t\t$patch_line = <$fd>;\n-\t\t\tchomp $patch_line;\n+\t\t\t\t#$patch_line =~ m/^+++/;\n+\t\t\t\tif ($to{'href'}) {\n+\t\t\t\t\t$patch_line = '+++ b/' .\n+\t\t\t\t\t              $cgi->a({-href=>$to{'href'}, -class=>\"path\"},\n+\t\t\t\t\t                      esc_path($to{'file'}));\n+\t\t\t\t}\n+\t\t\t\tprint \"<div class=\\\"diff to_file\\\">$patch_line</div>\\n\";\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$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_path($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+\t\t\t}\n \n \t\t\tnext LINE;\n \t\t}\n-\t\tnext LINE if $in_header;\n \n \t\tprint format_diff_line($patch_line);\n \t}\n-- \n1.4.3.4\n"},{"id":"297609","messageId":"200611081956.20251.jnareb@gmail.com","threadId":"43254","inReplyTo":"7vmz71u787.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 2/2] gitweb: Use character or octal escape codes (and add span.cntrl) in esc_path","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T18:56:19Z","receivedAt":"2006-11-08T18:56:19Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n>> Instead of simply hiding control characters in esc_path by replacing\n>> them with '?', use Character Escape Codes (CEC) i.e. alphabetic\n>> backslash sequences like those found in C programming language and\n>> many other languages influenced by it, such as Java and Perl.  If\n>> control characted doesn't have corresponding character escape code,\n>> use octal char sequence to escape it.\n>>\n>> Additionally use 'span' element with 'cntrl' attribute to mark escaped\n>> control characters. Add style for span.cntrl in the CSS.\n> \n> Would have preferred the 'span' thing to be part of [1/2]...\n\nI've misunderstood you then. I'm sorry.\n\n> Didn't I ask quot to be freestanding sub, not nested?  That\n> would make UPR vs CEC experiments easier and more pleasant.\n\nIn what way having freestanding and not nested sub would \"make\nUPR vs CEC experiments easier and more pleasant\"?\n\nIf it is important, I can send patch moving quot sub outside\nesc_path (and perhaps also unq sub outside unquote), or send\ncorrected patch... or you can correct patch by hand...\n\n-- \nJakub Narebski\n"},{"id":"297757","messageId":"7vejsdu5p5.fsf@assigned-by-dhcp.cox.net","threadId":"43254","inReplyTo":"7virhpu73w.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/2] gitweb: New improved patchset view","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-08T18:57:42Z","receivedAt":"2006-11-08T18:57:42Z","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> Jakub Narebski <jnareb@gmail.com> writes:\n>\n>> ---\n>>  gitweb/gitweb.css  |   66 +++++++++++++++----\n>>  gitweb/gitweb.perl |  183 \n>> ++++++++++++++++++++++++++++++++++------------------\n>>  2 files changed, 173 insertions(+), 76 deletions(-)\n>\n> Linewrap?\n>\n>> ----------------------------------------------------------------------\n>>  ## functions returning short HTML fragments, or transforming HTML \n>> fragments\n>\n> ...\n\nNo need to resend -- will manage.\n"},{"id":"295342","messageId":"200611082004.19918.jnareb@gmail.com","threadId":"43254","inReplyTo":"7vejsdu5p5.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 1/2] gitweb: New improved patchset view","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T19:04:19Z","receivedAt":"2006-11-08T19:04:19Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n> Junio C Hamano <junkio@cox.net> writes:\n> \n> > Jakub Narebski <jnareb@gmail.com> writes:\n> >\n> >> ---\n> >>  gitweb/gitweb.css  |   66 +++++++++++++++----\n> >>  gitweb/gitweb.perl |  183 \n> >> ++++++++++++++++++++++++++++++++++------------------\n> >>  2 files changed, 173 insertions(+), 76 deletions(-)\n> >\n> > Linewrap?\n> >\n> >> \n----------------------------------------------------------------------\n> >>  ## functions returning short HTML fragments, or transforming HTML \n> >> fragments\n> >\n> > ...\n> \n> No need to resend -- will manage.\n\nToo late... ;-)\n\n-- \nJakub Narebski\n"},{"id":"294149","messageId":"7vfyctsmbm.fsf@assigned-by-dhcp.cox.net","threadId":"43254","inReplyTo":"200611081800.16001.jnareb@gmail.com","subject":"Re: [PATCH 2/2] gitweb: New improved formatting of chunk header in diff","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-08T20:41:33Z","receivedAt":"2006-11-08T20:41:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This regresses on hunks of form \"@@ -n +m,l @@\" and friends, so\nI dropped it for now.\n\nI've applied other three patches but with manual tweaks while I\ndemangled the linewrap, so please sanity check the result after\nit mirrors out.  I also noticed that we unconditionally give\nblame link in \"diff-tree --name-status\" part of commitdiff, so\nI've fixed it up as well.\n\nI think you still leak control characters in commit messages and\nhtmlized blob text view; and perhaps others like blame.  I have\nmade quot_cec into a separate sub that is callable from outside\nesc_path, so these places should be able to reuse it to make\ncontrol characters \"visible and safe\" and keep the presentation\nconsistent.  The non-path callers would not feed tabs into the\nfunction (I haven't looked at the code but I suspect you would\nreplace them into runs of spaces to the next tab stop by hand),\nbut other controls need to be quoted.\n\n\n"},{"id":"295894","messageId":"200611082158.43652.jnareb@gmail.com","threadId":"43254","inReplyTo":"7vfyctsmbm.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 2/2] gitweb: New improved formatting of chunk header in diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T20:58:43Z","receivedAt":"2006-11-08T20:58:43Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n> This regresses on hunks of form \"@@ -n +m,l @@\" and friends, so\n> I dropped it for now.\n\nO.K. This one introduced new feature, and wasn't needed for earlier \naccepted patch (output empty patches) to have sense. And it is rc1 \nphase...\n\nBy the way, where I can find proper specifiction of unified diff format? \nDo I understand correctly that bot from and to ranges can be without \nnumber of lines part if it simplifies to 0?\n-- \nJakub Narebski\n"},{"id":"296475","messageId":"7vzmb1r4yu.fsf@assigned-by-dhcp.cox.net","threadId":"43254","inReplyTo":"200611082158.43652.jnareb@gmail.com","subject":"Re: [PATCH 2/2] gitweb: New improved formatting of chunk header in diff","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2006-11-08T21:41:45Z","receivedAt":"2006-11-08T21:41:45Z","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> O.K. This one introduced new feature, and wasn't needed for earlier \n> accepted patch (output empty patches) to have sense. And it is rc1 \n> phase...\n\nI personally do not mind minor gitweb 'feature' updates in -rc\ncycle, just like I am planning to see if there are gitk updates\nI haven't pulled from Paulus (I think there is at least one\npatch from last month or so), unless the changes do not break it\nso badly.\n\n> By the way, where I can find proper specifiction of unified diff format? \n> Do I understand correctly that bot from and to ranges can be without \n> number of lines part if it simplifies to 0?\n\nWhen Linus did apply.c and I did diff.c, we primarily worked off\nof sources to GNU patch.\n\nThere is a POSIX draft proposal now.\n\nhttp://www.opengroup.org/austin/mailarchives/ag-review/msg02077.html\n\nSee also updates about the proposal.\n\nhttp://thread.gmane.org/gmane.comp.version-control.git/29331/focus=29389\n"},{"id":"294590","messageId":"200611082255.03617.jnareb@gmail.com","threadId":"43254","inReplyTo":"7vzmb1r4yu.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH 2/2] gitweb: New improved formatting of chunk header in diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2006-11-08T21:55:03Z","receivedAt":"2006-11-08T21:55:03Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Junio C Hamano wrote:\n> Jakub Narebski <jnareb@gmail.com> writes:\n> \n>> O.K. This one introduced new feature, and wasn't needed for earlier \n>> accepted patch (output empty patches) to have sense. And it is rc1 \n>> phase...\n> \n> I personally do not mind minor gitweb 'feature' updates in -rc\n> cycle, just like I am planning to see if there are gitk updates\n> I haven't pulled from Paulus (I think there is at least one\n> patch from last month or so), unless the changes do not break it\n> so badly.\n\nI'll resend corrected patch then...\n \n>> By the way, where I can find proper specifiction of unified diff format? \n>> Do I understand correctly that bot from and to ranges can be without \n>> number of lines part if it simplifies to 0?\n> \n> When Linus did apply.c and I did diff.c, we primarily worked off\n> of sources to GNU patch.\n> \n> There is a POSIX draft proposal now.\n> \n> http://www.opengroup.org/austin/mailarchives/ag-review/msg02077.html\n> \n> See also updates about the proposal.\n> \n> http://thread.gmane.org/gmane.comp.version-control.git/29331/focus=29389\n\nThanks a lot.\n\nPersonally I think that we should push for git extended headers to be\n(as an option) in POSIX for unifed diff... well, with the exception\nof index and similarity lines. ;-)\n\n-- \nJakub Narebski\n"}]}