Re: RFE: Discard hunks during `git add -p`

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]