On Wed, Nov 02, 2016 at 06:11:14PM -0400, Jeff King wrote: > > Being able to discard hunks (reset working copy to index contents) > > during add-p would alleviate the (quite broad) hard reset. > > As Konstantin pointed out, you can already discard interactively with > "git checkout -p". It might be nice to be able to do both in the same > run, and turn the "yes/no" decision into "yes/no/discard". > > In theory it should be easy, as the same code drives the hunk selector > for both commands. It's just a matter of which command we feed the > selected hunks to. I don't know if there would be corner cases around > hunk-editing and splitting, though. The "add" phase should never touch > the working tree file itself, so any hunks present from the initial list > should still apply cleanly during the "discard" phase. The patch is something like the one below, which worked for me in a very trivial test. I won't be surprised if there are some corner cases it's missing. At the very least, coalesce_overlapping_hunks() needs to learn about the differences between "apply" and "discard" hunks (and not coalesce them!). I don't have immediate plans for this, so if somebody wants to pick it up and run with it, be my guest. -Peff diff --git a/git-add--interactive.perl b/git-add--interactive.perl index ee3d81269..43651435a 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -109,6 +109,7 @@ my %patch_modes = ( PARTICIPLE => 'staging', FILTER => 'file-only', IS_REVERSE => 0, + DISCARD => sub { apply_patch 'apply -R', @_; }, }, 'stash' => { DIFF => 'diff-index -p HEAD', @@ -1325,6 +1326,11 @@ sub patch_update_file { my ($prev, $next, $other, $undecided, $i); $other = ''; + my $discard = exists $patch_mode_flavour{DISCARD}; + if ($discard) { + $other .= ',D'; + } + if ($num <= $ix) { $ix = 0; } @@ -1384,6 +1390,9 @@ sub patch_update_file { elsif ($line =~ /^n/i) { $hunk[$ix]{USE} = 0; } + elsif ($discard && $line =~ /^D/) { + $hunk[$ix]{USE} = -1; + } elsif ($line =~ /^a/i) { while ($ix < $num) { if (!defined $hunk[$ix]{USE}) { @@ -1539,9 +1548,12 @@ sub patch_update_file { my $n_lofs = 0; my @result = (); + my @discard = (); for (@hunk) { - if ($_->{USE}) { + if ($_->{USE} > 0) { push @result, @{$_->{TEXT}}; + } elsif ($_->{USE} < 0) { + push @discard, @{$_->{TEXT}}; } } @@ -1552,6 +1564,13 @@ sub patch_update_file { refresh(); } + if (@discard) { + my @patch = reassemble_patch($head->{TEXT}, @discard); + my $apply_routine = $patch_mode_flavour{DISCARD}; + &$apply_routine(@patch); + refresh(); + } + print "\n"; return $quit; }