{"thread":{"id":"8338","subject":"[PATCH] gitweb: Split git_patchset_body into separate subroutines","startedAt":"2007-05-27T23:16:15Z","lastAt":"2007-05-28T14:22:06Z","messageCount":8,"participants":["Jakub Narebski","Junio C Hamano","Petr Baudis"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"43467","messageId":"11803077771867-git-send-email-jnareb@gmail.com","threadId":"8338","inReplyTo":null,"subject":"[PATCH] gitweb: Split git_patchset_body into separate subroutines","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-27T23:16:15Z","receivedAt":"2007-05-27T23:16:15Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Separate formatting \"git diff\" header into format_git_diff_header_line.\nWhile at it fix it so it always escapes pathname. It would be even more\nuseful if we decide to use `--cc' for merges, and need to generate by\nhand empty patches for anchors.\n\nSeparate formatting extended (git) diff header lines into\nformat_extended_diff_header_line. This one is copied without changes.\n\nSeparate formatting two-lines from-file/to-file diff header into\nformat_diff_from_to_header subroutine. While at it fix it so it always\nescapes pathname. Beware calling convention: it takes _two_ lines.\n\nSeparate generating %from and %to hashes (with info used among others to\ngenerate hyperlinks) into parse_from_to_diffinfo subroutine. This one is\ncopied without changes.\n\nSeparate checking if file was deleted (and among others therefore does\nnot have link to the result file) into is_deleted subroutine. This would\nallow us to easily change the algotithm to find if file is_deleted in\nthe result.\n\n\nThis commit makes git_patchset_body easier to read, and reduces level of\nnesting and indent level. It adds more lines that it removes because of\nextra parameter passing in subroutines, and subroutine calls in\ngit_patchset_body. Also because there are few added comments.\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |  313 +++++++++++++++++++++++++++++++++------------------\n 1 files changed, 202 insertions(+), 111 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 999353d..795af92 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -933,7 +933,149 @@ sub format_subject_html {\n \t}\n }\n \n-# format patch (diff) line (rather not to be used for diff headers)\n+# format git diff header line, i.e. \"diff --(git|combined|cc) ...\"\n+sub format_git_diff_header_line {\n+\tmy $line = shift;\n+\tmy $diffinfo = shift;\n+\tmy ($from, $to) = @_;\n+\n+\tif ($diffinfo->{'nparents'}) {\n+\t\t# combined diff\n+\t\t$line =~ s!^(diff (.*?) )\"?.*$!$1!;\n+\t\tif ($to->{'href'}) {\n+\t\t\t$line .= $cgi->a({-href => $to->{'href'}, -class => \"path\"},\n+\t\t\t                 esc_path($to->{'file'}));\n+\t\t} else { # file was deleted (no href)\n+\t\t\t$line .= esc_path($to->{'file'});\n+\t\t}\n+\t} else {\n+\t\t# \"ordinary\" diff\n+\t\t$line =~ s!^(diff (.*?) )\"?a/.*$!$1!;\n+\t\tif ($from->{'href'}) {\n+\t\t\t$line .= $cgi->a({-href => $from->{'href'}, -class => \"path\"},\n+\t\t\t                 'a/' . esc_path($from->{'file'}));\n+\t\t} else { # file was added (no href)\n+\t\t\t$line .= 'a/' . esc_path($from->{'file'});\n+\t\t}\n+\t\t$line .= ' ';\n+\t\tif ($to->{'href'}) {\n+\t\t\t$line .= $cgi->a({-href => $to->{'href'}, -class => \"path\"},\n+\t\t\t                 'b/' . esc_path($to->{'file'}));\n+\t\t} else { # file was deleted\n+\t\t\t$line .= 'b/' . esc_path($to->{'file'});\n+\t\t}\n+\t}\n+\n+\treturn \"<div class=\\\"diff header\\\">$line</div>\\n\";\n+}\n+\n+# format extended diff header line, before patch itself\n+sub format_extended_diff_header_line {\n+\tmy $line = shift;\n+\tmy $diffinfo = shift;\n+\tmy ($from, $to) = @_;\n+\n+\t# match <path>\n+\tif ($line =~ s!^((copy|rename) from ).*$!$1! && $from->{'href'}) {\n+\t\t$line .= $cgi->a({-href=>$from->{'href'}, -class=>\"path\"},\n+\t\t                       esc_path($from->{'file'}));\n+\t}\n+\tif ($line =~ s!^((copy|rename) to ).*$!$1! && $to->{'href'}) {\n+\t\t$line .= $cgi->a({-href=>$to->{'href'}, -class=>\"path\"},\n+\t\t                 esc_path($to->{'file'}));\n+\t}\n+\t# match single <mode>\n+\tif ($line =~ m/\\s(\\d{6})$/) {\n+\t\t$line .= '<span class=\"info\"> (' .\n+\t\t         file_type_long($1) .\n+\t\t         ')</span>';\n+\t}\n+\t# match <hash>\n+\tif ($line =~ m/^index [0-9a-fA-F]{40},[0-9a-fA-F]{40}/) {\n+\t\t# can match only for combined diff\n+\t\t$line = 'index ';\n+\t\tfor (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) {\n+\t\t\tif ($from->{'href'}[$i]) {\n+\t\t\t\t$line .= $cgi->a({-href=>$from->{'href'}[$i],\n+\t\t\t\t                  -class=>\"hash\"},\n+\t\t\t\t                 substr($diffinfo->{'from_id'}[$i],0,7));\n+\t\t\t} else {\n+\t\t\t\t$line .= '0' x 7;\n+\t\t\t}\n+\t\t\t# separator\n+\t\t\t$line .= ',' if ($i < $diffinfo->{'nparents'} - 1);\n+\t\t}\n+\t\t$line .= '..';\n+\t\tif ($to->{'href'}) {\n+\t\t\t$line .= $cgi->a({-href=>$to->{'href'}, -class=>\"hash\"},\n+\t\t\t                 substr($diffinfo->{'to_id'},0,7));\n+\t\t} else {\n+\t\t\t$line .= '0' x 7;\n+\t\t}\n+\n+\t} elsif ($line =~ m/^index [0-9a-fA-F]{40}..[0-9a-fA-F]{40}/) {\n+\t\t# can match only for ordinary diff\n+\t\tmy ($from_link, $to_link);\n+\t\tif ($from->{'href'}) {\n+\t\t\t$from_link = $cgi->a({-href=>$from->{'href'}, -class=>\"hash\"},\n+\t\t\t                     substr($diffinfo->{'from_id'},0,7));\n+\t\t} else {\n+\t\t\t$from_link = '0' x 7;\n+\t\t}\n+\t\tif ($to->{'href'}) {\n+\t\t\t$to_link = $cgi->a({-href=>$to->{'href'}, -class=>\"hash\"},\n+\t\t\t                   substr($diffinfo->{'to_id'},0,7));\n+\t\t} else {\n+\t\t\t$to_link = '0' x 7;\n+\t\t}\n+\t\tmy ($from_id, $to_id) = ($diffinfo->{'from_id'}, $diffinfo->{'to_id'});\n+\t\t$line =~ s!$from_id\\.\\.$to_id!$from_link..$to_link!;\n+\t}\n+\n+\treturn $line . \"<br/>\\n\";\n+}\n+\n+# format from-file/to-file diff header\n+sub format_diff_from_to_header {\n+\tmy ($from_line, $to_line, $diffinfo, $from, $to) = @_;\n+\tmy $line;\n+\tmy $result = '';\n+\n+\t$line = $from_line;\n+\t#assert($line =~ m/^---/) if DEBUG;\n+\t# no extra formatting \"^--- /dev/null\"\n+\tif ($line =~ m!^--- \"?a/!) {\n+\t\tif (!$diffinfo->{'nparents'} && # multiple 'from'\n+\t\t    $from->{'href'}) {\n+\t\t\t$line = '--- a/' .\n+\t\t\t        $cgi->a({-href=>$from->{'href'}, -class=>\"path\"},\n+\t\t\t                esc_path($from->{'file'}));\n+\t\t} else {\n+\t\t\t$line = '--- a/' .\n+\t\t\t        esc_path($from->{'file'});\n+\t\t}\n+\t}\n+\t$result .= qq!<div class=\"diff from_file\">$line</div>\\n!;\n+\n+\t$line = $to_line;\n+\t#assert($line =~ m/^\\+\\+\\+/) if DEBUG;\n+\t# no extra formatting for \"^+++ /dev/null\"\n+\tif ($line =~ m!^\\+\\+\\+ \"?b/!) {\n+\t\tif ($to->{'href'}) {\n+\t\t\t$line = '+++ b/' .\n+\t\t\t        $cgi->a({-href=>$to->{'href'}, -class=>\"path\"},\n+\t\t\t                esc_path($to->{'file'}));\n+\t\t} else {\n+\t\t\t$line = '+++ b/' .\n+\t\t\t        esc_path($to->{'file'});\n+\t\t}\n+\t}\n+\t$result .= qq!<div class=\"diff to_file\">$line</div>\\n!;\n+\n+\treturn $result;\n+}\n+\n+# format patch (diff) line (not to be used for diff headers)\n sub format_diff_line {\n \tmy $line = shift;\n \tmy ($from, $to) = @_;\n@@ -1659,6 +1801,48 @@ sub parse_ls_tree_line ($;%) {\n \treturn wantarray ? %res : \\%res;\n }\n \n+# generates _two_ hashes, references to which are passed as 2 and 3 argument\n+sub parse_from_to_diffinfo {\n+\tmy ($diffinfo, $from, $to, @parents) = @_;\n+\n+\tif ($diffinfo->{'nparents'}) {\n+\t\t# combined diff\n+\t\t$from->{'file'} = [];\n+\t\t$from->{'href'} = [];\n+\t\tfill_from_file_info($diffinfo, @parents)\n+\t\t\tunless exists $diffinfo->{'from_file'};\n+\t\tfor (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) {\n+\t\t\t$from->{'file'}[$i] = $diffinfo->{'from_file'}[$i] || $diffinfo->{'to_file'};\n+\t\t\tif ($diffinfo->{'status'}[$i] ne \"A\") { # not new (added) file\n+\t\t\t\t$from->{'href'}[$i] = href(action=>\"blob\",\n+\t\t\t\t                           hash_base=>$parents[$i],\n+\t\t\t\t                           hash=>$diffinfo->{'from_id'}[$i],\n+\t\t\t\t                           file_name=>$from->{'file'}[$i]);\n+\t\t\t} else {\n+\t\t\t\t$from->{'href'}[$i] = undef;\n+\t\t\t}\n+\t\t}\n+\t} else {\n+\t\t$from->{'file'} = $diffinfo->{'from_file'} || $diffinfo->{'file'};\n+\t\tif ($diffinfo->{'status'} ne \"A\") { # not new (added) file\n+\t\t\t$from->{'href'} = href(action=>\"blob\", hash_base=>$hash_parent,\n+\t\t\t                       hash=>$diffinfo->{'from_id'},\n+\t\t\t                       file_name=>$from->{'file'});\n+\t\t} else {\n+\t\t\tdelete $from->{'href'};\n+\t\t}\n+\t}\n+\n+\t$to->{'file'} = $diffinfo->{'to_file'} || $diffinfo->{'file'};\n+\tif (!is_deleted($diffinfo)) { # file exists in result\n+\t\t$to->{'href'} = href(action=>\"blob\", hash_base=>$hash,\n+\t\t                     hash=>$diffinfo->{'to_id'},\n+\t\t                     file_name=>$to->{'file'});\n+\t} else {\n+\t\tdelete $to->{'href'};\n+\t}\n+}\n+\n ## ......................................................................\n ## parse to array of hashes functions\n \n@@ -2366,6 +2550,11 @@ sub from_ids_eq {\n \t}\n }\n \n+sub is_deleted {\n+\tmy $diffinfo = shift;\n+\n+\treturn $diffinfo->{'to_id'} eq ('0' x 40);\n+}\n \n sub git_difftree_body {\n \tmy ($difftree, $hash, @parents) = @_;\n@@ -2422,7 +2611,7 @@ sub git_difftree_body {\n \t\t\tfill_from_file_info($diff, @parents)\n \t\t\t\tunless exists $diff->{'from_file'};\n \n-\t\t\tif ($diff->{'to_id'} ne ('0' x 40)) {\n+\t\t\tif (!is_deleted($diff)) {\n \t\t\t\t# file exists in the result (child) commit\n \t\t\t\tprint \"<td>\" .\n \t\t\t\t      $cgi->a({-href => href(action=>\"blob\", hash=>$diff->{'to_id'},\n@@ -2742,6 +2931,8 @@ sub git_patchset_body {\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# modifies %from, %to hashes\n+\t\t\tparse_from_to_diffinfo($diffinfo, \\%from, \\%to, @hash_parents);\n \t\t\tif ($diffinfo->{'nparents'}) {\n \t\t\t\t# combined diff\n \t\t\t\t$from{'file'} = [];\n@@ -2771,7 +2962,7 @@ sub git_patchset_body {\n \t\t\t}\n \n \t\t\t$to{'file'} = $diffinfo->{'to_file'} || $diffinfo->{'file'};\n-\t\t\tif ($diffinfo->{'to_id'} ne ('0' x 40)) { # file exists in result\n+\t\t\tif (!is_deleted($diffinfo)) { # file exists in result\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@@ -2785,105 +2976,15 @@ sub git_patchset_body {\n \n \t\t# print \"git diff\" header\n \t\t$patch_line = shift @diff_header;\n-\t\tif ($diffinfo->{'nparents'}) {\n-\n-\t\t\t# combined diff\n-\t\t\t$patch_line =~ s!^(diff (.*?) )\"?.*$!$1!;\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                       esc_path($to{'file'}));\n-\t\t\t} else { # file was deleted\n-\t\t\t\t$patch_line .= esc_path($to{'file'});\n-\t\t\t}\n-\n-\t\t} else {\n-\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}\n-\t\tprint \"<div class=\\\"diff header\\\">$patch_line</div>\\n\";\n+\t\tprint format_git_diff_header_line($patch_line, $diffinfo,\n+\t\t                                  \\%from, \\%to);\n \n \t\t# print extended diff header\n \t\tprint \"<div class=\\\"diff extended_header\\\">\\n\" if (@diff_header > 0);\n \tEXTENDED_HEADER:\n \t\tforeach $patch_line (@diff_header) {\n-\t\t\t# match <path>\n-\t\t\tif ($patch_line =~ s!^((copy|rename) from ).*$!$1! && $from{'href'}) {\n-\t\t\t\t$patch_line .= $cgi->a({-href=>$from{'href'}, -class=>\"path\"},\n-\t\t\t\t                       esc_path($from{'file'}));\n-\t\t\t}\n-\t\t\tif ($patch_line =~ s!^((copy|rename) to ).*$!$1! && $to{'href'}) {\n-\t\t\t\t$patch_line .= $cgi->a({-href=>$to{'href'}, -class=>\"path\"},\n-\t\t\t\t                       esc_path($to{'file'}));\n-\t\t\t}\n-\t\t\t# match single <mode>\n-\t\t\tif ($patch_line =~ m/\\s(\\d{6})$/) {\n-\t\t\t\t$patch_line .= '<span class=\"info\"> (' .\n-\t\t\t\t               file_type_long($1) .\n-\t\t\t\t               ')</span>';\n-\t\t\t}\n-\t\t\t# match <hash>\n-\t\t\tif ($patch_line =~ m/^index [0-9a-fA-F]{40},[0-9a-fA-F]{40}/) {\n-\t\t\t\t# can match only for combined diff\n-\t\t\t\t$patch_line = 'index ';\n-\t\t\t\tfor (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) {\n-\t\t\t\t\tif ($from{'href'}[$i]) {\n-\t\t\t\t\t\t$patch_line .= $cgi->a({-href=>$from{'href'}[$i],\n-\t\t\t\t\t\t                        -class=>\"hash\"},\n-\t\t\t\t\t\t                       substr($diffinfo->{'from_id'}[$i],0,7));\n-\t\t\t\t\t} else {\n-\t\t\t\t\t\t$patch_line .= '0' x 7;\n-\t\t\t\t\t}\n-\t\t\t\t\t# separator\n-\t\t\t\t\t$patch_line .= ',' if ($i < $diffinfo->{'nparents'} - 1);\n-\t\t\t\t}\n-\t\t\t\t$patch_line .= '..';\n-\t\t\t\tif ($to{'href'}) {\n-\t\t\t\t\t$patch_line .= $cgi->a({-href=>$to{'href'}, -class=>\"hash\"},\n-\t\t\t\t\t                       substr($diffinfo->{'to_id'},0,7));\n-\t\t\t\t} else {\n-\t\t\t\t\t$patch_line .= '0' x 7;\n-\t\t\t\t}\n-\n-\t\t\t} elsif ($patch_line =~ m/^index [0-9a-fA-F]{40}..[0-9a-fA-F]{40}/) {\n-\t\t\t\t# can match only for ordinary diff\n-\t\t\t\tmy ($from_link, $to_link);\n-\t\t\t\tif ($from{'href'}) {\n-\t\t\t\t\t$from_link = $cgi->a({-href=>$from{'href'}, -class=>\"hash\"},\n-\t\t\t\t\t                     substr($diffinfo->{'from_id'},0,7));\n-\t\t\t\t} else {\n-\t\t\t\t\t$from_link = '0' x 7;\n-\t\t\t\t}\n-\t\t\t\tif ($to{'href'}) {\n-\t\t\t\t\t$to_link = $cgi->a({-href=>$to{'href'}, -class=>\"hash\"},\n-\t\t\t\t\t                   substr($diffinfo->{'to_id'},0,7));\n-\t\t\t\t} else {\n-\t\t\t\t\t$to_link = '0' x 7;\n-\t\t\t\t}\n-\t\t\t\t#affirm {\n-\t\t\t\t#\tmy ($from_hash, $to_hash) =\n-\t\t\t\t#\t\t($patch_line =~ m/^index ([0-9a-fA-F]{40})..([0-9a-fA-F]{40})/);\n-\t\t\t\t#\tmy ($from_id, $to_id) =\n-\t\t\t\t#\t\t($diffinfo->{'from_id'}, $diffinfo->{'to_id'});\n-\t\t\t\t#\t($from_hash eq $from_id) && ($to_hash eq $to_id);\n-\t\t\t\t#} if DEBUG;\n-\t\t\t\tmy ($from_id, $to_id) = ($diffinfo->{'from_id'}, $diffinfo->{'to_id'});\n-\t\t\t\t$patch_line =~ s!$from_id\\.\\.$to_id!$from_link..$to_link!;\n-\t\t\t}\n-\t\t\tprint $patch_line . \"<br/>\\n\";\n+\t\t\tprint format_extended_diff_header_line($patch_line, $diffinfo,\n+\t\t\t                                       \\%from, \\%to);\n \t\t}\n \t\tprint \"</div>\\n\"  if (@diff_header > 0); # class=\"diff extended_header\"\n \n@@ -2895,24 +2996,14 @@ sub git_patchset_body {\n \t\t}\n \t\tnext PATCH if ($patch_line =~ m/^diff /);\n \t\t#assert($patch_line =~ m/^---/) if DEBUG;\n-\t\tif (!$diffinfo->{'nparents'} && # not from-file line for combined diff\n-\t\t    $from{'href'} && $patch_line =~ m!^--- \"?a/!) {\n-\t\t\t$patch_line = '--- a/' .\n-\t\t\t              $cgi->a({-href=>$from{'href'}, -class=>\"path\"},\n-\t\t\t                      esc_path($from{'file'}));\n-\t\t}\n-\t\tprint \"<div class=\\\"diff from_file\\\">$patch_line</div>\\n\";\n+\t\t#assert($patch_line eq $last_patch_line) if DEBUG;\n \n \t\t$patch_line = <$fd>;\n \t\tchomp $patch_line;\n+\t\t#assert($patch_line =~ m/^\\+\\+\\+/) if DEBUG;\n \n-\t\t#assert($patch_line =~ m/^+++/) if DEBUG;\n-\t\tif ($to{'href'} && $patch_line =~ m!^\\+\\+\\+ \"?b/!) {\n-\t\t\t$patch_line = '+++ b/' .\n-\t\t\t              $cgi->a({-href=>$to{'href'}, -class=>\"path\"},\n-\t\t\t                      esc_path($to{'file'}));\n-\t\t}\n-\t\tprint \"<div class=\\\"diff to_file\\\">$patch_line</div>\\n\";\n+\t\tprint format_diff_from_to_header($last_patch_line, $patch_line,\n+\t\t                                 $diffinfo, \\%from, \\%to);\n \n \t\t# the patch itself\n \tLINE:\n-- \n1.5.2\n"},{"id":"43468","messageId":"11803077792064-git-send-email-jnareb@gmail.com","threadId":"8338","inReplyTo":"11803077771867-git-send-email-jnareb@gmail.com","subject":"[RFC/PATCH] gitweb: Create special from-file/to-file header for combined diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-27T23:16:16Z","receivedAt":"2007-05-27T23:16:16Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Instead of using default, diff(1) like from-file/to-file header for\ncombined diff (for a merge commit), which looks like:\n\n  --- a/git-gui/git-gui.sh\n  +++ b/_git-gui/git-gui.sh_\n\n(where _link_ denotes [hidden] hyperlink), create from-file(n)/to-file\nheader, using n/file for each or parents, e.g.:\n\n  --- 1/_git-gui/git-gui.sh_\n  --- 2/_git-gui.sh_\n  +++ b/_git-gui/git-gui.sh_\n\nTest it on one of merge commits involving rename, e.g.\n  95f97567c1887d77f3a46b42d8622c76414d964d (rename at top)\n  5bac4a671907604b5fb4e24ff682d5b0e8431931 (file from one branch)\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\nThis is just an idea, not seriously meant to be applied... unless of\ncourse you think that this is great. What do you think about it?\n\nThis patch depends on my earlier patch\n  \"gitweb: Split git_patchset_body into separate subroutines\"\n\n gitweb/gitweb.perl |   32 ++++++++++++++++++++++++--------\n 1 files changed, 24 insertions(+), 8 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 795af92..f73f184 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1045,17 +1045,33 @@ sub format_diff_from_to_header {\n \t#assert($line =~ m/^---/) if DEBUG;\n \t# no extra formatting \"^--- /dev/null\"\n \tif ($line =~ m!^--- \"?a/!) {\n-\t\tif (!$diffinfo->{'nparents'} && # multiple 'from'\n-\t\t    $from->{'href'}) {\n-\t\t\t$line = '--- a/' .\n-\t\t\t        $cgi->a({-href=>$from->{'href'}, -class=>\"path\"},\n-\t\t\t                esc_path($from->{'file'}));\n+\t\tif (!$diffinfo->{'nparents'}) {\n+\t\t\tif ($from->{'href'}) {\n+\t\t\t\t$line = '--- a/' .\n+\t\t\t\t        $cgi->a({-href=>$from->{'href'}, -class=>\"path\"},\n+\t\t\t\t                esc_path($from->{'file'}));\n+\t\t\t} else {\n+\t\t\t\t$line = '--- a/' .\n+\t\t\t\t        esc_path($from->{'file'});\n+\t\t\t}\n+\t\t\t$result .= qq!<div class=\"diff from_file\">$line</div>\\n!;\n \t\t} else {\n-\t\t\t$line = '--- a/' .\n-\t\t\t        esc_path($from->{'file'});\n+\t\t\tfor (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) {\n+\t\t\t\tif ($from->{'href'}[$i]) {\n+\t\t\t\t\t$result .= qq!<div class=\"diff from_file\">--- ! .\n+\t\t\t\t\t           ($i+1) . \"/\" .\n+\t\t\t\t\t           $cgi->a({-href=>$from->{'href'}[$i], -class=>\"path\"},\n+\t\t\t\t\t                   esc_path($from->{'file'}[$i])) .\n+\t\t\t\t\t           qq!</div>\\n!;\n+\t\t\t\t} else {\n+\t\t\t\t\t$result .= qq!<div class=\"diff from_file\">--- /dev/null</div>\\n!;\n+\t\t\t\t}\n+\t\t\t}\n \t\t}\n+\t} else {\n+\t\t$result .= qq!<div class=\"diff from_file\">$line</div>\\n!;\n \t}\n-\t$result .= qq!<div class=\"diff from_file\">$line</div>\\n!;\n+\n \n \t$line = $to_line;\n \t#assert($line =~ m/^\\+\\+\\+/) if DEBUG;\n-- \n1.5.2\n"},{"id":"43469","messageId":"11803077803470-git-send-email-jnareb@gmail.com","threadId":"8338","inReplyTo":"11803077792064-git-send-email-jnareb@gmail.com","subject":"[PATCH] gitweb: Create special from-file/to-file header for combined diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-27T23:16:17Z","receivedAt":"2007-05-27T23:16:17Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Instead of using default, diff(1) like from-file/to-file header for\ncombined diff (for a merge commit), which looks like:\n\n  --- a/git-gui/git-gui.sh\n  +++ b/_git-gui/git-gui.sh_\n\n(where _link_ denotes [hidden] hyperlink), create from-file(n)/to-file\nheader, using n/file for each or parents, e.g.:\n\n  --- 1/_git-gui/git-gui.sh_\n  --- 2/_git-gui.sh_\n  +++ b/_git-gui/git-gui.sh_\n\nTest it on one of merge commits involving rename, e.g.\n  95f97567c1887d77f3a46b42d8622c76414d964d (rename at top)\n  5bac4a671907604b5fb4e24ff682d5b0e8431931 (file from one branch)\n\nSigned-off-by: Jakub Narebski <jnareb@gmail.com>\n---\n gitweb/gitweb.perl |   32 ++++++++++++++++++++++++--------\n 1 files changed, 24 insertions(+), 8 deletions(-)\n\ndiff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl\nindex 795af92..f73f184 100755\n--- a/gitweb/gitweb.perl\n+++ b/gitweb/gitweb.perl\n@@ -1045,17 +1045,33 @@ sub format_diff_from_to_header {\n \t#assert($line =~ m/^---/) if DEBUG;\n \t# no extra formatting \"^--- /dev/null\"\n \tif ($line =~ m!^--- \"?a/!) {\n-\t\tif (!$diffinfo->{'nparents'} && # multiple 'from'\n-\t\t    $from->{'href'}) {\n-\t\t\t$line = '--- a/' .\n-\t\t\t        $cgi->a({-href=>$from->{'href'}, -class=>\"path\"},\n-\t\t\t                esc_path($from->{'file'}));\n+\t\tif (!$diffinfo->{'nparents'}) {\n+\t\t\tif ($from->{'href'}) {\n+\t\t\t\t$line = '--- a/' .\n+\t\t\t\t        $cgi->a({-href=>$from->{'href'}, -class=>\"path\"},\n+\t\t\t\t                esc_path($from->{'file'}));\n+\t\t\t} else {\n+\t\t\t\t$line = '--- a/' .\n+\t\t\t\t        esc_path($from->{'file'});\n+\t\t\t}\n+\t\t\t$result .= qq!<div class=\"diff from_file\">$line</div>\\n!;\n \t\t} else {\n-\t\t\t$line = '--- a/' .\n-\t\t\t        esc_path($from->{'file'});\n+\t\t\tfor (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) {\n+\t\t\t\tif ($from->{'href'}[$i]) {\n+\t\t\t\t\t$result .= qq!<div class=\"diff from_file\">--- ! .\n+\t\t\t\t\t           ($i+1) . \"/\" .\n+\t\t\t\t\t           $cgi->a({-href=>$from->{'href'}[$i], -class=>\"path\"},\n+\t\t\t\t\t                   esc_path($from->{'file'}[$i])) .\n+\t\t\t\t\t           qq!</div>\\n!;\n+\t\t\t\t} else {\n+\t\t\t\t\t$result .= qq!<div class=\"diff from_file\">--- /dev/null</div>\\n!;\n+\t\t\t\t}\n+\t\t\t}\n \t\t}\n+\t} else {\n+\t\t$result .= qq!<div class=\"diff from_file\">$line</div>\\n!;\n \t}\n-\t$result .= qq!<div class=\"diff from_file\">$line</div>\\n!;\n+\n \n \t$line = $to_line;\n \t#assert($line =~ m/^\\+\\+\\+/) if DEBUG;\n-- \n1.5.2\n"},{"id":"43472","messageId":"f3d460$gsv$1@sea.gmane.org","threadId":"8338","inReplyTo":"11803077803470-git-send-email-jnareb@gmail.com","subject":"Re: [PATCH] gitweb: Create special from-file/to-file header for combined diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-27T23:33:09Z","receivedAt":"2007-05-27T23:33:09Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Ooops\n\n-- \nJakub Narebski\nWarsaw, Poland\nShadeHawk on #git\n"},{"id":"43481","messageId":"7v1wh1en8k.fsf@assigned-by-dhcp.cox.net","threadId":"8338","inReplyTo":"11803077792064-git-send-email-jnareb@gmail.com","subject":"Re: [RFC/PATCH] gitweb: Create special from-file/to-file header for combined diff","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2007-05-28T01:43:55Z","receivedAt":"2007-05-28T01:43:55Z","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 using default, diff(1) like from-file/to-file header for\n> combined diff (for a merge commit), which looks like:\n>\n>   --- a/git-gui/git-gui.sh\n>   +++ b/_git-gui/git-gui.sh_\n>\n> (where _link_ denotes [hidden] hyperlink), create from-file(n)/to-file\n> header, using n/file for each or parents, e.g.:\n>\n>   --- 1/_git-gui/git-gui.sh_\n>   --- 2/_git-gui.sh_\n>   +++ b/_git-gui/git-gui.sh_\n\nSounds quite straightforward to implement, and diff with 1/\nwould be useful to recreate what the person who did the merge\npulled in, for most of the time.  I suspect diff with 2/ is\nalmost always uninteresting, though.\n"},{"id":"43485","messageId":"200705280850.52323.jnareb@gmail.com","threadId":"8338","inReplyTo":"7v1wh1en8k.fsf@assigned-by-dhcp.cox.net","subject":"Re: [RFC/PATCH] gitweb: Create special from-file/to-file header for combined diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-28T06:50:51Z","receivedAt":"2007-05-28T06:50:51Z","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 using default, diff(1) like from-file/to-file header for\n>> combined diff (for a merge commit), which looks like:\n>>\n>>   --- a/git-gui/git-gui.sh\n>>   +++ b/_git-gui/git-gui.sh_\n>>\n>> (where _link_ denotes [hidden] hyperlink), create from-file(n)/to-file\n>> header, using n/file for each or parents, e.g.:\n>>\n>>   --- 1/_git-gui/git-gui.sh_\n>>   --- 2/_git-gui.sh_\n>>   +++ b/_git-gui/git-gui.sh_\n> \n> Sounds quite straightforward to implement, and diff with 1/\n> would be useful to recreate what the person who did the merge\n> pulled in, for most of the time.  I suspect diff with 2/ is\n> almost always uninteresting, though.\n\nErrr... it _is_ implemented in this patch, although code is not perfect\nand has some unnecessary repetitions. But I thought before improving\ncode would it make sense to do this... and perhaps even add generated\nextended diff headers for renames:\n\n  rename at _2_ parent from _git-gui.sh_\n  rename to _git-gui/git-gui.sh_\n\nwhere as before _link_ denotes hyperlinked part. Hmmm?\n\n-- \nJakub Narebski\nPoland\n"},{"id":"43493","messageId":"20070528132959.GT4489@pasky.or.cz","threadId":"8338","inReplyTo":"200705280850.52323.jnareb@gmail.com","subject":"Re: [RFC/PATCH] gitweb: Create special from-file/to-file header for combined diff","fromName":"Petr Baudis","fromEmail":"pasky@suse.cz","sentAt":"2007-05-28T13:29:59Z","receivedAt":"2007-05-28T13:29:59Z","isPatch":true,"sender":{"key":"pasky@ucw.cz","avatar":"https://avatars.githubusercontent.com/u/18439?v=4"},"body":"On Mon, May 28, 2007 at 08:50:51AM CEST, Jakub Narebski wrote:\n> Junio C Hamano wrote:\n> > Jakub Narebski <jnareb@gmail.com> writes:\n> > \n> >> Instead of using default, diff(1) like from-file/to-file header for\n> >> combined diff (for a merge commit), which looks like:\n> >>\n> >>   --- a/git-gui/git-gui.sh\n> >>   +++ b/_git-gui/git-gui.sh_\n> >>\n> >> (where _link_ denotes [hidden] hyperlink), create from-file(n)/to-file\n> >> header, using n/file for each or parents, e.g.:\n> >>\n> >>   --- 1/_git-gui/git-gui.sh_\n> >>   --- 2/_git-gui.sh_\n> >>   +++ b/_git-gui/git-gui.sh_\n> > \n> > Sounds quite straightforward to implement, and diff with 1/\n> > would be useful to recreate what the person who did the merge\n> > pulled in, for most of the time.  I suspect diff with 2/ is\n> > almost always uninteresting, though.\n\nI like it too.\n\n> Errr... it _is_ implemented in this patch, although code is not perfect\n> and has some unnecessary repetitions.\n\nIt just shows links to older versions of the blob, doesn't it? Links to\ndiffs themselves would be useful too.\n\n-- \n\t\t\t\tPetr \"Pasky\" Baudis\nStuff: http://pasky.or.cz/\nEver try. Ever fail. No matter. // Try again. Fail again. Fail better.\n\t\t-- Samuel Beckett\n"},{"id":"43494","messageId":"200705281622.07313.jnareb@gmail.com","threadId":"8338","inReplyTo":"20070528132959.GT4489@pasky.or.cz","subject":"Re: [RFC/PATCH] gitweb: Create special from-file/to-file header for combined diff","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2007-05-28T14:22:06Z","receivedAt":"2007-05-28T14:22:06Z","isPatch":true,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Mon, 28 May 2007, Petr Baudis wrote:\n> On Mon, May 28, 2007 at 08:50:51AM CEST, Jakub Narebski wrote:\n>> Junio C Hamano wrote:\n>>> Jakub Narebski <jnareb@gmail.com> writes:\n>>> \n>>>> Instead of using default, diff(1) like from-file/to-file header for\n>>>> combined diff (for a merge commit), which looks like:\n>>>>\n>>>>   --- a/git-gui/git-gui.sh\n>>>>   +++ b/_git-gui/git-gui.sh_\n>>>>\n>>>> (where _link_ denotes [hidden] hyperlink), create from-file(n)/to-file\n>>>> header, using n/file for each or parents, e.g.:\n>>>>\n>>>>   --- 1/_git-gui/git-gui.sh_\n>>>>   --- 2/_git-gui.sh_\n>>>>   +++ b/_git-gui/git-gui.sh_\n>>> \n>>> Sounds quite straightforward to implement, and diff with 1/\n>>> would be useful to recreate what the person who did the merge\n>>> pulled in, for most of the time.  I suspect diff with 2/ is\n>>> almost always uninteresting, though.\n> \n> I like it too.\n> \n>> Errr... it _is_ implemented in this patch, although code is not perfect\n>> and has some unnecessary repetitions.\n> \n> It just shows links to older versions of the blob, doesn't it? Links to\n> diffs themselves would be useful too.\n\nFor me most important were those from names (or /dev/null) in the case\nof rename or copying (or file which was not present in some branches).\n\nThe link is to older version of blob; the links to appropriate blobdiffs\n(and with earlier PATCH/RFC \"gitweb: Provide links to individual\ncommitdiffs in difftree for merges\" also to appropriate commitdiffs)\nare in the difftree / whatchanged table.\n\n\nWhere to put link to diff? Should name be link to diff instead of\nlink to blob (to version at parent)?\n\n-- \nJakub Narebski\nPoland\n"}]}