Skip to content

Commit

Permalink
add-interactive: refactor mode hunk handling
Browse files Browse the repository at this point in the history
The original implementation considered the mode separately
from the rest of the hunks, asking about it outside the main
hunk-selection loop. This patch instead places a mode change
as the first hunk in the loop. This has two advantages:

  1. less duplicated code (since we use the main selection
     loop). This also cleans up an inconsistency, which is
     that the main selection loop separates options with a
     comma, whereas the mode prompt used slashes.

  2. users can now skip the mode change and come back to it,
     search for it (via "/mode"), etc, as they can with other
     hunks.

To facilitate this, each hunk is now marked with a "type".
Mode hunks are not considered for splitting (which would
make no sense, and also confuses the split_hunk function),
nor are they editable. In theory, one could edit the mode
lines and change to a new mode. In practice, there are only
two modes that git cares about (0644 and 0755), so either
you want to move from one to the other or not (and you can
do that by staging or not staging).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Apr 16, 2009
1 parent 9a7a1e0 commit 0392513
Showing 1 changed file with 21 additions and 43 deletions.
64 changes: 21 additions & 43 deletions git-add--interactive.perl
Original file line number Diff line number Diff line change
Expand Up @@ -620,11 +620,12 @@ sub parse_diff {
if ($diff_use_color) {
@colored = run_cmd_pipe(qw(git diff-files -p --color --), $path);
}
my (@hunk) = { TEXT => [], DISPLAY => [] };
my (@hunk) = { TEXT => [], DISPLAY => [], TYPE => 'header' };

for (my $i = 0; $i < @diff; $i++) {
if ($diff[$i] =~ /^@@ /) {
push @hunk, { TEXT => [], DISPLAY => [] };
push @hunk, { TEXT => [], DISPLAY => [],
TYPE => 'hunk' };
}
push @{$hunk[-1]{TEXT}}, $diff[$i];
push @{$hunk[-1]{DISPLAY}},
Expand All @@ -636,8 +637,8 @@ sub parse_diff {
sub parse_diff_header {
my $src = shift;

my $head = { TEXT => [], DISPLAY => [] };
my $mode = { TEXT => [], DISPLAY => [] };
my $head = { TEXT => [], DISPLAY => [], TYPE => 'header' };
my $mode = { TEXT => [], DISPLAY => [], TYPE => 'mode' };

for (my $i = 0; $i < @{$src->{TEXT}}; $i++) {
my $dest = $src->{TEXT}->[$i] =~ /^(old|new) mode (\d+)$/ ?
Expand Down Expand Up @@ -684,6 +685,7 @@ sub split_hunk {
my $this = +{
TEXT => [],
DISPLAY => [],
TYPE => 'hunk',
OLD => $o_ofs,
NEW => $n_ofs,
OCNT => 0,
Expand Down Expand Up @@ -873,7 +875,11 @@ sub edit_hunk_loop {
if (!defined $text) {
return undef;
}
my $newhunk = { TEXT => $text, USE => 1 };
my $newhunk = {
TEXT => $text,
TYPE => $hunk->[$ix]->{TYPE},
USE => 1
};
if (diff_applies($head,
@{$hunk}[0..$ix-1],
$newhunk,
Expand Down Expand Up @@ -987,37 +993,7 @@ sub patch_update_file {
}

if (@{$mode->{TEXT}}) {
while (1) {
print @{$mode->{DISPLAY}};
print colored $prompt_color,
"Stage mode change [y/n/a/d/?]? ";
my $line = prompt_single_character;
if ($line =~ /^y/i) {
$mode->{USE} = 1;
last;
}
elsif ($line =~ /^n/i) {
$mode->{USE} = 0;
last;
}
elsif ($line =~ /^a/i) {
$_->{USE} = 1 foreach ($mode, @hunk);
last;
}
elsif ($line =~ /^d/i) {
$_->{USE} = 0 foreach ($mode, @hunk);
last;
}
elsif ($line =~ /^q/i) {
$_->{USE} = 0 foreach ($mode, @hunk);
$quit = 1;
last;
}
else {
help_patch_cmd('');
next;
}
}
unshift @hunk, $mode;
}

$num = scalar @hunk;
Expand Down Expand Up @@ -1061,14 +1037,19 @@ sub patch_update_file {
}
last if (!$undecided);

if (hunk_splittable($hunk[$ix]{TEXT})) {
if ($hunk[$ix]{TYPE} eq 'hunk' &&
hunk_splittable($hunk[$ix]{TEXT})) {
$other .= ',s';
}
$other .= ',e';
if ($hunk[$ix]{TYPE} eq 'hunk') {
$other .= ',e';
}
for (@{$hunk[$ix]{DISPLAY}}) {
print;
}
print colored $prompt_color, "Stage this hunk [y,n,a,d,/$other,?]? ";
print colored $prompt_color, 'Stage ',
($hunk[$ix]{TYPE} eq 'mode' ? 'mode change' : 'this hunk'),
" [y,n,a,d,/$other,?]? ";
my $line = prompt_single_character;
if ($line) {
if ($line =~ /^y/i) {
Expand Down Expand Up @@ -1210,7 +1191,7 @@ sub patch_update_file {
$num = scalar @hunk;
next;
}
elsif ($line =~ /^e/) {
elsif ($other =~ /e/ && $line =~ /^e/) {
my $newhunk = edit_hunk_loop($head, \@hunk, $ix);
if (defined $newhunk) {
splice @hunk, $ix, 1, $newhunk;
Expand All @@ -1231,9 +1212,6 @@ sub patch_update_file {

my $n_lofs = 0;
my @result = ();
if ($mode->{USE}) {
push @result, @{$mode->{TEXT}};
}
for (@hunk) {
if ($_->{USE}) {
push @result, @{$_->{TEXT}};
Expand Down

0 comments on commit 0392513

Please sign in to comment.