diff options
author | Wincent Colaiuta <win@wincent.com> | 2007-12-07 13:35:10 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-12-08 02:53:19 -0800 |
commit | 4af756f31b0696ed1ca6ad10dc6d7053477edc16 (patch) | |
tree | f95f0781c3090151b73b4d18b3284898c9934492 /git-add--interactive.perl | |
parent | 8e566f24b369836c43d720e4246a152b0e7724c6 (diff) | |
download | git-4af756f31b0696ed1ca6ad10dc6d7053477edc16.tar.gz |
Teach "git add -i" to colorize whitespace errors
Rather than replicating the colorization logic of "git diff-files" we
rely on "git diff-files" itself. This guarantees consistent colorization
in and outside "git add -i".
Seeing as speed is not a concern here (the bottleneck is how fast the
user can read, not how fast "git diff-files" runs) we do this by
actually running it twice, once without color and once with.
In this way as the whitespace colorization provided by "git diff-files"
evolves (per-path attributes, new classes of whitespace error), "git
add -i" will automatically benefit from it and stay in synch.
Also, by working with two sets of diff output (an uncolorized one for
internal processing and a colorized one for display only) we minimize
the risk of regressions because the changes required to implement this
are minimally invasive.
Signed-off-by: Wincent Colaiuta <win@wincent.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'git-add--interactive.perl')
-rwxr-xr-x | git-add--interactive.perl | 73 |
1 files changed, 34 insertions, 39 deletions
diff --git a/git-add--interactive.perl b/git-add--interactive.perl index 1019a72d6c..0cdd80073b 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -525,40 +525,21 @@ sub add_untracked_cmd { sub parse_diff { my ($path) = @_; my @diff = run_cmd_pipe(qw(git diff-files -p --), $path); - my (@hunk) = { TEXT => [] }; - - for (@diff) { - if (/^@@ /) { - push @hunk, { TEXT => [] }; - } - push @{$hunk[-1]{TEXT}}, $_; + my @colored = (); + if ($diff_use_color) { + @colored = run_cmd_pipe(qw(git diff-files -p --color --), $path); } - return @hunk; -} - -sub colored_diff_hunk { - my ($text) = @_; - # return the text, so that it can be passed to print() - my @ret; - for (@$text) { - if (!$diff_use_color) { - push @ret, $_; - next; - } + my (@hunk) = { TEXT => [], DISPLAY => [] }; - if (/^\+/) { - push @ret, colored($new_color, $_); - } elsif (/^\-/) { - push @ret, colored($old_color, $_); - } elsif (/^\@/) { - push @ret, colored($fraginfo_color, $_); - } elsif (/^ /) { - push @ret, colored($normal_color, $_); - } else { - push @ret, colored($metainfo_color, $_); + for (my $i = 0; $i < @diff; $i++) { + if ($diff[$i] =~ /^@@ /) { + push @hunk, { TEXT => [], DISPLAY => [] }; } + push @{$hunk[-1]{TEXT}}, $diff[$i]; + push @{$hunk[-1]{DISPLAY}}, + ($diff_use_color ? $colored[$i] : $diff[$i]); } - return @ret; + return @hunk; } sub hunk_splittable { @@ -578,9 +559,11 @@ sub parse_hunk_header { } sub split_hunk { - my ($text) = @_; + my ($text, $display) = @_; my @split = (); - + if (!defined $display) { + $display = $text; + } # If there are context lines in the middle of a hunk, # it can be split, but we would need to take care of # overlaps later. @@ -594,16 +577,19 @@ sub split_hunk { my $i = $hunk_start - 1; my $this = +{ TEXT => [], + DISPLAY => [], OLD => $o_ofs, NEW => $n_ofs, OCNT => 0, NCNT => 0, ADDDEL => 0, POSTCTX => 0, + USE => undef, }; while (++$i < @$text) { my $line = $text->[$i]; + my $display = $display->[$i]; if ($line =~ /^ /) { if ($this->{ADDDEL} && !defined $next_hunk_start) { @@ -615,6 +601,7 @@ sub split_hunk { $next_hunk_start = $i; } push @{$this->{TEXT}}, $line; + push @{$this->{DISPLAY}}, $display; $this->{OCNT}++; $this->{NCNT}++; if (defined $next_hunk_start) { @@ -637,6 +624,7 @@ sub split_hunk { redo OUTER; } push @{$this->{TEXT}}, $line; + push @{$this->{DISPLAY}}, $display; $this->{ADDDEL}++; if ($line =~ /^-/) { $this->{OCNT}++; @@ -661,9 +649,14 @@ sub split_hunk { " +$n_ofs" . (($n_cnt != 1) ? ",$n_cnt" : '') . " @@\n"); + my $display_head = $head; unshift @{$hunk->{TEXT}}, $head; + if ($diff_use_color) { + $display_head = colored($fraginfo_color, $head); + } + unshift @{$hunk->{DISPLAY}}, $display_head; } - return map { $_->{TEXT} } @split; + return @split; } sub find_last_o_ctx { @@ -794,7 +787,9 @@ sub patch_update_file { my ($ix, $num); my $path = shift; my ($head, @hunk) = parse_diff($path); - print colored_diff_hunk($head->{TEXT}); + for (@{$head->{DISPLAY}}) { + print; + } $num = scalar @hunk; $ix = 0; @@ -836,7 +831,9 @@ sub patch_update_file { if (hunk_splittable($hunk[$ix]{TEXT})) { $other .= '/s'; } - print colored_diff_hunk($hunk[$ix]{TEXT}); + for (@{$hunk[$ix]{DISPLAY}}) { + print; + } print colored $prompt_color, "Stage this hunk [y/n/a/d$other/?]? "; my $line = <STDIN>; if ($line) { @@ -889,14 +886,12 @@ sub patch_update_file { next; } elsif ($other =~ /s/ && $line =~ /^s/) { - my @split = split_hunk($hunk[$ix]{TEXT}); + my @split = split_hunk($hunk[$ix]{TEXT}, $hunk[$ix]{DISPLAY}); if (1 < @split) { print colored $header_color, "Split into ", scalar(@split), " hunks.\n"; } - splice(@hunk, $ix, 1, - map { +{ TEXT => $_, USE => undef } } - @split); + splice (@hunk, $ix, 1, @split); $num = scalar @hunk; next; } |