From: Jakub Narebski <jnareb@gmail.com>
To: git@vger.kernel.org
Subject: [PATCH/RFC] gitweb: New improved patchset view
Date: Sun, 29 Oct 2006 11:22:30 +0100 [thread overview]
Message-ID: <200610291122.30852.jnareb@gmail.com> (raw)
You should be able to check new commitdiff view at
http://roke_DOT_dyndns_DOT_info/cgi-bin/gitweb/gitweb.cgi
(URL mangling courtesy vger banned words list, aaaarrghhh)
if I didn't screwed something again with firewall, and when my machine
is up; should be for at least an hour. Check for example:
?p=git.git;a=commitdiff;h=origin
?p=git.git;a=commitdiff;h=161332a521fe10c41979bcd493d95e2ac562b7f
?p=git.git;a=commitdiff;h=e12c095aa69d8aca0326eb11960427d9bf9e2db7
?p=git.git;a=commitdiff;h=82560983997c961d9deafe0074b787c8484c2e1d
and compare to (for example)
http://repo.or.cz/w/git.git?a=commitdiff;h=82560983997c961d9deafe0074b787c8484c2e1d
or (even older gitweb)
http://www.kernel.org/git/?p=git/git.git;a=commitdiff;h=887a612fef942dd3e7dae452e2dc582738b0fb41
BTW. this gitweb has also my previous "Slight improvement" patch applied.
Do you like it? What should be changed (code, output, style)?
-- >8 --
Replace "gitweb diff header" with its full sha1 of blobs with
"git diff" header and extended diff header. Change also
highlighting of diffs.
Changes:
* "gitweb diff header" which looked for example like below:
file:_<sha1 before>_ -> file:_<sha1 after>_
where 'file' is file type and '<sha1>' is full sha1 of blob, is link
and uses default link style is changed to
diff --git a/<file before> b/<file after>
where <file> is hidden link (i.e. underline on hover, only)
to appropriate version of file. If file is added, a/<file> is not
hyperlinked, if file is deleted, b/<file> is not hyperlinked.
* there is added "extended diff header", with <path> and <hash>
hyperlinked (and <hash> shortened to 7 characters), and <mode>
explained: '<mode>' is extnded to '<mode>/<symbolic mode> (<file type>)'.
* <file> hyperlinking should work also when <file> is originally
quoted. For now we present filename quoted. This needed changes to
parse_difftree_raw_line subroutine.
* from-file/to-file two-line header lines have slightly darker color
than removed/added lines.
* chunk header has now delicate line above for easier finding chunk
boundary, and top margin of 1px.
Controversial ideas:
* All links in patch header are hidden
* Hashes are shortened to 7 characters
* Filenames are presented quoted
* Marking of chunk beginning
* No hyperlink for renamed from/to header (bug)
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
gitweb/gitweb.css | 46 ++++++++++++---
gitweb/gitweb.perl | 159 ++++++++++++++++++++++++++++++---------------------
2 files changed, 131 insertions(+), 74 deletions(-)
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 83d900d..3aeceed 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -303,6 +303,33 @@ td.mode {
font-family: monospace;
}
+
+div.diff.header,
+div.diff.extended_header {
+ white-space: normal;
+}
+
+div.diff.header {
+ font-weight: bold;
+
+ background-color: #edece6;
+
+ margin-top: 4px;
+ padding: 4px 0px 2px 0px;
+ border: solid #d9d8d1;
+ border-width: 1px 0px 1px 0px;
+}
+
+div.diff.extended_header,
+div.diff.extended_header a.list {
+ color: #777777;
+}
+
+div.diff.extended_header {
+ background-color: #f6f5ee;
+ padding: 2px 0px 2px 0px;
+}
+
div.diff a.list {
text-decoration: none;
}
@@ -312,31 +339,34 @@ div.diff a.list:hover {
}
div.diff.to_file a.list,
-div.diff.to_file,
+div.diff.to_file {
+ color: #007000;
+}
+
div.diff.add {
color: #008800;
}
div.diff.from_file a.list,
-div.diff.from_file,
+div.diff.from_file {
+ color: #aa0000;
+}
+
div.diff.rem {
color: #cc0000;
}
div.diff.chunk_header {
color: #990099;
+ border: dotted #ffbbff;
+ border-width: 1px 0px 0px 0px;
+ margin-top: 1px;
}
div.diff.incomplete {
color: #cccccc;
}
-div.diff_info {
- font-family: monospace;
- color: #000099;
- background-color: #edece6;
- font-style: italic;
-}
div.index_include {
border: solid #d9d8d1;
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index cbab3c9..2d971ac 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -1255,9 +1255,12 @@ sub parse_difftree_raw_line {
$res{'status'} = $5;
$res{'similarity'} = $6;
if ($res{'status'} eq 'R' || $res{'status'} eq 'C') { # renamed or copied
- ($res{'from_file'}, $res{'to_file'}) = map { unquote($_) } split("\t", $7);
+ ($res{'from_file_raw'}, $res{'to_file_raw'}) = split("\t", $7);
+ $res{'from_file'} = unquote($res{'from_file_raw'});
+ $res{'to_file'} = unquote($res{'to_file_raw'});
} else {
- $res{'file'} = unquote($7);
+ $res{'file_raw'} = $7;
+ $res{'file'} = unquote($res{'file_raw'});
}
}
# 'c512b523472485aef4fff9e57b229d9d243c967f'
@@ -2024,6 +2027,7 @@ sub git_patchset_body {
my $in_header = 0;
my $patch_found = 0;
my $diffinfo;
+ my (@from_subst, @to_subst);
print "<div class=\"patchset\">\n";
@@ -2033,6 +2037,7 @@ sub git_patchset_body {
if ($patch_line =~ m/^diff /) { # "git diff" header
# beginning of patch (in patchset)
+
if ($patch_found) {
# close previous patch
print "</div>\n"; # class="patch"
@@ -2042,11 +2047,59 @@ sub git_patchset_body {
}
print "<div class=\"patch\" id=\"patch". ($patch_idx+1) ."\">\n";
+ # read and prepare patch information
if (ref($difftree->[$patch_idx]) eq "HASH") {
+ # pre-parsed (or generated by hand)
$diffinfo = $difftree->[$patch_idx];
} else {
$diffinfo = parse_difftree_raw_line($difftree->[$patch_idx]);
}
+ if ($diffinfo->{'status'} ne "A") { # not new (added) file
+ my $quot = '';
+ my $from_text;
+ my $file_raw = $diffinfo->{'from_file_raw'} || $diffinfo->{'file_raw'};
+ if ($file_raw =~ s/^"(.*)"$/\1/) {
+ $from_text = qq("a/$file_raw");
+ $quot = '"';
+ } else {
+ $from_text = qq(a/$file_raw);
+ }
+ my $file = $diffinfo->{'from_file'} || $diffinfo->{'file'};
+ my $from_link =
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash_base,
+ hash=>$diffinfo->{'from_id'}, file_name=>$file),
+ -class => "list"}, esc_html($file_raw));
+ my $hash_link =
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash_base,
+ hash=>$diffinfo->{'to_id'}, file_name=>$file),
+ -class => "list"}, substr($diffinfo->{'from_id'},0,7));
+ @from_subst =
+ ($from_text, "${quot}a/$from_link${quot}",
+ $diffinfo->{'from_id'} . '\.\.', "$hash_link..");
+ }
+ if ($diffinfo->{'status'} ne "D") { # not deleted file
+ my $quot = '';
+ my $to_text;
+ my $file_raw = $diffinfo->{'to_file_raw'} || $diffinfo->{'file_raw'};
+ if ($file_raw =~ s/^"(.*)"$/\1/) {
+ $to_text = qq("b/$file_raw");
+ $quot = '"';
+ } else {
+ $to_text = qq(b/$file_raw);
+ }
+ my $file = $diffinfo->{'to_file'} || $diffinfo->{'file'};
+ my $to_link =
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash_base,
+ hash=>$diffinfo->{'to_id'}, file_name=>$file),
+ -class => "list"}, esc_html($file_raw));
+ my $hash_link =
+ $cgi->a({-href => href(action=>"blob", hash_base=>$hash_base,
+ hash=>$diffinfo->{'to_id'}, file_name=>$file),
+ -class => "list"}, substr($diffinfo->{'to_id'},0,7));
+ @to_subst =
+ ($to_text, "${quot}b/$to_link${quot}",
+ '\.\.' . $diffinfo->{'to_id'}, "..$hash_link");
+ }
$patch_idx++;
# for now we skip empty patches
@@ -2056,82 +2109,56 @@ sub git_patchset_body {
next LINE;
}
- if ($diffinfo->{'status'} eq "A") { # added
- print "<div class=\"diff_info\">" . file_type($diffinfo->{'to_mode'}) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
- hash=>$diffinfo->{'to_id'}, file_name=>$diffinfo->{'file'})},
- $diffinfo->{'to_id'}) . " (new)" .
- "</div>\n"; # class="diff_info"
-
- } elsif ($diffinfo->{'status'} eq "D") { # deleted
- print "<div class=\"diff_info\">" . file_type($diffinfo->{'from_mode'}) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
- hash=>$diffinfo->{'from_id'}, file_name=>$diffinfo->{'file'})},
- $diffinfo->{'from_id'}) . " (deleted)" .
- "</div>\n"; # class="diff_info"
-
- } elsif ($diffinfo->{'status'} eq "R" || # renamed
- $diffinfo->{'status'} eq "C" || # copied
- $diffinfo->{'status'} eq "2") { # with two filenames (from git_blobdiff)
- print "<div class=\"diff_info\">" .
- file_type($diffinfo->{'from_mode'}) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
- hash=>$diffinfo->{'from_id'}, file_name=>$diffinfo->{'from_file'})},
- $diffinfo->{'from_id'}) .
- " -> " .
- file_type($diffinfo->{'to_mode'}) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
- hash=>$diffinfo->{'to_id'}, file_name=>$diffinfo->{'to_file'})},
- $diffinfo->{'to_id'});
- print "</div>\n"; # class="diff_info"
-
- } else { # modified, mode changed, ...
- print "<div class=\"diff_info\">" .
- file_type($diffinfo->{'from_mode'}) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
- hash=>$diffinfo->{'from_id'}, file_name=>$diffinfo->{'file'})},
- $diffinfo->{'from_id'}) .
- " -> " .
- file_type($diffinfo->{'to_mode'}) . ":" .
- $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
- hash=>$diffinfo->{'to_id'}, file_name=>$diffinfo->{'file'})},
- $diffinfo->{'to_id'});
- print "</div>\n"; # class="diff_info"
- }
+ # print "git diff" header
+ $patch_line =~ s/$from_subst[0]/$from_subst[1]/ if @from_subst;
+ $patch_line =~ s/$to_subst[0]/$to_subst[1]/ if @to_subst;
+ print "<div class=\"diff header\">$patch_line</div>\n";
- #print "<div class=\"diff extended_header\">\n";
+ print "<div class=\"diff extended_header\">\n";
$in_header = 1;
next LINE;
} # start of patch in patchset
+ if ($in_header) {
+ if ($patch_line !~ m/^---/) {
+ # match <path>
+ if ($patch_line =~ m|a/|) {
+ $patch_line =~ s/$from_subst[0]/$from_subst[1]/ if @from_subst;
+ }
+ if ($patch_line =~ m|b/|) {
+ $patch_line =~ s/$to_subst[0]/$to_subst[1]/ if @to_subst;
+ }
+ # match <mode>
+ if ($patch_line =~ m/\s(\d{6})$/) {
+ $patch_line .= '/' . mode_str($1) . ' (' . file_type($1) . ')';
+ }
+ # match <hash>
+ if ($patch_line =~ m/^index/) {
+ $patch_line =~ s/0{40}/'0' x 7/e;
+ $patch_line =~ s/$from_subst[2]/$from_subst[3]/ if @from_subst;
+ $patch_line =~ s/$to_subst[2]/$to_subst[3]/ if @to_subst;
+ }
+ print $patch_line . "<br/>\n";
- if ($in_header && $patch_line =~ m/^---/) {
- #print "</div>\n"; # class="diff extended_header"
- $in_header = 0;
+ } else {
+ #$patch_line =~ m/^---/;
+ print "</div>\n"; # class="diff extended_header"
+ $in_header = 0;
+
+ $patch_line =~ s/$from_subst[0]/$from_subst[1]/ if @from_subst;
+ print "<div class=\"diff from_file\">$patch_line</div>\n";
- my $file = $diffinfo->{'from_file'};
- $file ||= $diffinfo->{'file'};
- $file = $cgi->a({-href => href(action=>"blob", hash_base=>$hash_parent,
- hash=>$diffinfo->{'from_id'}, file_name=>$file),
- -class => "list"}, esc_html($file));
- $patch_line =~ s|a/.*$|a/$file|g;
- print "<div class=\"diff from_file\">$patch_line</div>\n";
+ $patch_line = <$fd>;
+ chomp $patch_line;
- $patch_line = <$fd>;
- chomp $patch_line;
+ #$patch_line =~ m/^+++/;
+ $patch_line =~ s/$to_subst[0]/$to_subst[1]/ if @to_subst;
+ print "<div class=\"diff to_file\">$patch_line</div>\n";
- #$patch_line =~ m/^+++/;
- $file = $diffinfo->{'to_file'};
- $file ||= $diffinfo->{'file'};
- $file = $cgi->a({-href => href(action=>"blob", hash_base=>$hash,
- hash=>$diffinfo->{'to_id'}, file_name=>$file),
- -class => "list"}, esc_html($file));
- $patch_line =~ s|b/.*|b/$file|g;
- print "<div class=\"diff to_file\">$patch_line</div>\n";
+ }
next LINE;
}
- next LINE if $in_header;
print format_diff_line($patch_line);
}
--
1.4.3.3
-------------------------------------------------------
--
Jakub Narebski
next reply other threads:[~2006-10-29 10:22 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-10-29 10:22 Jakub Narebski [this message]
2006-10-29 11:47 ` [PATCH/RFC] gitweb: New improved patchset view Junio C Hamano
2006-10-29 12:24 ` Jakub Narebski
2006-10-29 12:48 ` Jakub Narebski
2006-10-29 15:35 ` Jakub Narebski
2006-10-29 19:43 ` Luben Tuikov
2006-10-29 20:19 ` Jakub Narebski
2006-10-29 22:05 ` Jakub Narebski
2006-10-29 20:29 ` Junio C Hamano
2006-10-29 19:33 ` Luben Tuikov
2006-10-29 12:44 ` Anand Kumria
2006-10-29 19:38 ` Luben Tuikov
2006-10-29 17:50 ` Jakub Narebski
2006-10-29 18:49 ` Junio C Hamano
2006-10-30 1:43 ` Luben Tuikov
2006-10-29 19:55 ` Luben Tuikov
2006-10-29 20:29 ` Jakub Narebski
2006-10-29 19:31 ` Luben Tuikov
2006-10-29 23:51 ` [PATCH/RFC (take 2)] " Jakub Narebski
2006-10-30 0:34 ` Jakub Narebski
2006-10-30 1:12 ` Junio C Hamano
2006-10-30 1:21 ` Jakub Narebski
2006-10-30 1:59 ` Luben Tuikov
2006-10-30 8:05 ` Jakub Narebski
2006-10-30 8:21 ` Junio C Hamano
2006-10-30 8:51 ` Junio C Hamano
2006-10-30 9:43 ` Jakub Narebski
2006-10-30 13:58 ` Jakub Narebski
2006-10-30 22:59 ` Junio C Hamano
2006-10-30 23:32 ` Jakub Narebski
2006-10-30 23:40 ` Junio C Hamano
2006-10-30 21:34 ` Luben Tuikov
2006-10-30 21:50 ` Jakub Narebski
2006-10-30 22:30 ` Edgar Toernig
2006-10-30 22:39 ` Jakub Narebski
2006-10-31 22:41 ` Edgar Toernig
2006-10-30 22:40 ` Luben Tuikov
2006-10-30 23:00 ` Junio C Hamano
[not found] <200610290100.11731.jnareb@gmail.com>
2006-10-28 23:16 ` [PATCH/RFC] " Jakub Narebski
2006-10-29 10:59 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200610291122.30852.jnareb@gmail.com \
--to=jnareb@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).