[PATCH 3/5] add--interactive: allow hunk filtering on command line

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

 



If you have a lot of uninteresting hunks (e.g., because you
have a file with boilerplate that changed, but you want to
add only the interesting bits and discard the rest), it can
be cumbersome to sift through the boring hunks.

This patch provides an option to match hunks by regular
expression, pretending as if the non-matching changes do not
exist at all (similar to how path-limiting ignores
non-matching paths entirely).

There are two special case pseudo-hunks to consider in the
code: mode hunks and deletion hunks.

  - If a filter is given, this patch will never include mode
    hunks, since the user has asked for a specific subset of
    hunks, and the mode has no text to match.

  - Deletion hunks actually require no special care. In a
    deletion there will be only a single giant diff hunk of
    deleted content. If it matches the filter, then the
    deletion can be presented as normal. If it doesn't
    match, then we exit early from patch_update_file and
    never consider showing the deletion at all (since there
    is nothing to delete).

This patch provides only the perl portion; it is up to
individual callers of add--interactive to pass the option
through to the perl code.

Signed-off-by: Jeff King <peff@xxxxxxxx>
---
 git-add--interactive.perl |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 3e4c8a4..bb16f71 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -86,6 +86,7 @@ sub colored {
 # command line options
 my $patch_mode;
 my $patch_mode_revision;
+my @patch_mode_hunk_filter;
 
 sub apply_patch;
 sub apply_patch_for_checkout_commit;
@@ -1273,17 +1274,33 @@ sub trim_error {
 	return $_;
 }
 
+sub want_hunk {
+	my $hunk = shift;
+	my $text = join('', @{$hunk->{TEXT}});
+
+	foreach my $re (@patch_mode_hunk_filter) {
+		return 1 if $text =~ $re;
+	}
+	return 0;
+}
+
 sub patch_update_file {
 	my $quit = 0;
 	my ($ix, $num);
 	my $path = shift;
 	my ($head, @hunk) = parse_diff($path);
+
+	if (@patch_mode_hunk_filter) {
+		@hunk = grep { want_hunk($_) } @hunk;
+		return unless @hunk;
+	}
+
 	($head, my $mode, my $deletion) = parse_diff_header($head);
 	for (@{$head->{DISPLAY}}) {
 		print;
 	}
 
-	if (@{$mode->{TEXT}}) {
+	if (@{$mode->{TEXT}} && !@patch_mode_hunk_filter) {
 		unshift @hunk, $mode;
 	}
 	if (@{$deletion->{TEXT}}) {
@@ -1568,6 +1585,11 @@ sub process_args {
 		if ($ARGV[0] =~ /--patch(?:=(.*))?/) {
 			$patch_mode = defined $1 ? $1 : 'stage';
 		}
+		elsif ($ARGV[0] =~ /--hunk-filter=(.*)/) {
+			my $re = eval { qr{$1}m }
+				or die "malformed hunk filter $1: " . trim_error($@);
+			push @patch_mode_hunk_filter, $re;
+		}
 		else {
 			last;
 		}
-- 
1.7.5.4.31.ge4d5e

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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]