From: Jakub Narebski <jnareb@gmail.com>
To: Kato Kazuyoshi <kato.kazuyoshi@gmail.com>
Cc: git@vger.kernel.org, Jakub Narebski <jnareb@gmail.com>
Subject: Re: [PATCH 2/2] gitweb: add a feature to show side-by-side diff
Date: Tue, 18 Oct 2011 03:36:02 -0700 (PDT) [thread overview]
Message-ID: <m3zkgy6103.fsf@localhost.localdomain> (raw)
In-Reply-To: <m34nz771mj.fsf@localhost.localdomain>
Jakub Narebski <jnareb@gmail.com> writes:
> Kato Kazuyoshi <kato.kazuyoshi@gmail.com> writes:
>
> > gitweb currently has a feature to show diff but it doesn't support
> > "side-by-side" style. This modification introduces:
> >
> > * The "ds" query parameter to specify the style of diff.
> > * The format_diff_chunk() to reorganize an output of diff.
> > * The diff_nav() for form.
>
> I would state it a bit differently.
>
> I would say that this patch introduces support for side-by-side diff
> in git_patchset_body, and that style of diff is controlled by newly
> introduces 'diff_style' ("ds") parameter.
>
> I would say a bit later that navigation bar got extended to make it
> easy to switch between 'inline' and 'sidebyside' diff.
I think it would be good idea to explain algorithm here, and perhaps
also layout used.
When I was thinking about implementing side-by-side diff in gitweb, I
was always stopped by the problem of aligning changes. In your
solution changes are always aligned to top, which is a simple
solution.
> > +sub format_diff_chunk {
> > + my @chunk = @_;
> > +
> > + my $first_class = $chunk[0]->[0];
> > + my @partial = map { $_->[1] } grep { $_->[0] eq $first_class } @chunk;
> > +
> > + if (scalar @partial < scalar @chunk) {
> > + return join '', ("<div class='chunk'><div class='old'>",
> > + @partial,
> > + "</div>",
> > + "<div class='new'>",
> > + (map {
> > + $_->[1];
> > + } @chunk[scalar @partial..scalar @chunk-1]),
> > + "</div></div>");
> > + } else {
> > + return join '', ("<div class='chunk'><div class='",
> > + ($first_class eq 'add' ? 'new' : 'old'),
> > + "'>",
> > + @partial,
> > + "</div></div>");
> > + }
> > +}
This is I think unnecessary complicated. What you do here is
separating removed and added lines (either can be empty), and putting
removed on left (as "old"), and added on right (as "new").
It means that the following unified diff:
--- a/foo
+++ b/foo
@@ -1,5 +1,4 @@
-foo
-FOO
bar
-baz
+b
+baZ
quux
would be turned into following side by side diff:
foo |
FOO |
bar | bar
baz | b
| baZ
quux | quux
It's a bit strange that context is put line by line, and changed lines
are put in "blocks".
> > @@ -4940,12 +4967,31 @@ sub git_patchset_body {
> >
> > # the patch itself
> > LINE:
> > + my @chunk;
> > while ($patch_line = <$fd>) {
> > chomp $patch_line;
> >
> > next PATCH if ($patch_line =~ m/^diff /);
> >
> > - print format_diff_line($patch_line, \%from, \%to);
> > + my ($class, $line) = format_diff_line($patch_line, \%from, \%to);
> > + if ($is_inline) {
> > + print $line;
> > + } elsif ($class eq 'add' || $class eq 'rem') {
> > + push @chunk, [ $class, $line ];
> > + } else {
> > + if (@chunk) {
> > + print format_diff_chunk(@chunk);
> > + @chunk = ();
> > + } elsif ($class eq 'chunk_header') {
> > + print $line;
> > + } else {
> > + print '<div class="chunk"><div class="old">',
> > + $line,
> > + '</div><div class="new">',
> > + $line,
> > + '</div></div>';
> > + }
> > + }
Note that your side by side diff wouldn't work for combined diff,
which gitweb supports. You should show 'unified' / 'inline' format
for combined diff (more than one parent / from).
--
Jakub Narębski
next prev parent reply other threads:[~2011-10-18 10:36 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-10-17 7:00 [PATCH 2/2] gitweb: add a feature to show side-by-side diff Kato Kazuyoshi
2011-10-17 19:37 ` Junio C Hamano
2011-10-17 21:24 ` Jakub Narebski
2011-10-18 10:36 ` Jakub Narebski [this message]
2011-10-30 18:56 ` 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=m3zkgy6103.fsf@localhost.localdomain \
--to=jnareb@gmail.com \
--cc=git@vger.kernel.org \
--cc=kato.kazuyoshi@gmail.com \
/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).