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;
}