git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: feature request: git add--interactive --patch on regex-matched hunks only

From
Jeff King <peff@peff.net>
Date
Jul 25, 2011, 21:55 UTC
Message-ID
<20110725215553.GA23145@sigill.intra.peff.net>
In-Reply-To
<CACsJy8B1B25DZ1yrzHq69vwgzQyM2ouTXCHb8oPRpb_cAX+JZQ@mail.gmail.com>
On Sun, Jul 24, 2011 at 12:11:29PM +0700, Nguyen Thai Ngoc Duy wrote:
> Can we have "git add--interactive --patch --match=regex" where only
> (splitted if possible) hunks that match regex are shown?

The patch below does this, but there are a lot of unanswered questions. Such as:

  1. What does it mean to be "shown"? My patch auto-marks non-matching
     hunks as "do not stage". That means you can still switch back to
     them in the hunk list and enable them if you want. Another option
     would be to omit them entirely, and pretend that those hunks don't
     exist.
  2. What should we do with non-text changes, like mode changes are
     full-file deletion?
  3. What should be shown for a file with no matching hunks? Probably
     nothing (i.e., as if it had been limited away by pathname)? My
     patch shows the header, but that is easy to fix.

I think those depend on the intended use case. For me, it seems useful to do something like:

  $ hack hack hack
  [oops, I need to refactor foo() and its callers first]
  $ refactor refactor refactor
  $ git add -p --match=foo
  $ git commit -m 'refactor foo'
  [resume initial hacking]

However, I'm not sure I would trust my regex to actually get all of the changes needed for the refactoring (e.g., there might be nearby hunks related to the refactoring that are not specifically in the same hunk as the word "foo"). So I tend to just "git add -p" and flip through the changes manually.

Show 6 quoted lines
> I've been reviewing a .po file and adding translations that I approve,
> leaving the rest to be determined later. The problem with .po files is
> that a lot of comment lines are changes because some translations are
> moved in source code. I don't care about those comment changes and
> would like to completely ignore them (even destroy them with git
> checkout -p).

You can already skip around in the hunk list using "/regex". Might that be enough for you? I think you're stuck typing "/yoursearch" over and over, though. It would be nice if doing just "/" would search again for the previous regex.

Anyway, here's the patch. It's just the perl bits. You'd need to write the scaffolding to add an option to "git add", "git checkout", etc.

---
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 2ee0908..07896d4 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_match;
 
 sub apply_patch;
 sub apply_patch_for_checkout_commit;
@@ -1277,6 +1278,17 @@ sub display_hunks {
 	return $i;
 }
 
+sub want_hunk {
+	my ($re, $hunk) = @_;
+
+	return 1 if $hunk->{TYPE} ne 'hunk';
+
+	foreach my $line (@{$hunk->{TEXT}}) {
+		return 1 if $line =~ $re;
+	}
+	return 0;
+}
+
 sub patch_update_file {
 	my $quit = 0;
 	my ($ix, $num);
@@ -1301,6 +1313,20 @@ sub patch_update_file {
 	$num = scalar @hunk;
 	$ix = 0;
 
+	if ($patch_match) {
+		# mark non-matching text hunks as "do not want"
+		foreach my $hunk (@hunk) {
+			if (!want_hunk($patch_match, $hunk)) {
+				$hunk->{USE} = 0;
+			}
+		}
+		# and then advance us to the first undecided hunk
+		while ($ix < $num) {
+			last unless defined $hunk[$ix]{USE};
+			$ix++;
+		}
+	}
+
 	while (1) {
 		my ($prev, $next, $other, $undecided, $i);
 		$other = '';
@@ -1606,6 +1632,10 @@ sub process_args {
 		} else {
 			$patch_mode = 'stage';
 			$arg = shift @ARGV or die "missing --";
+			if ($arg =~ /--match=(.*)/) {
+				$patch_match = qr/$1/;
+				$arg = shift @ARGV or die "missing --";
+			}
 		}
 		die "invalid argument $arg, expecting --"
 		    unless $arg eq "--";
Previous: Nguyen Thai Ngoc DuyNext: Junio C Hamano
Message 2 of 19 in “feature request: git add--interactive --patch on regex-matched hunks only”
  1. Nguyen Thai Ngoc DuyJul 24, 2011
  2. Jeff KingJul 25, 2011
  3. Junio C HamanoJul 25, 2011
  4. Jeff KingJul 26, 2011
  5. Nguyen Thai Ngoc DuyJul 26, 2011
  6. Jeff KingJul 26, 2011
  7. Nguyen Thai Ngoc DuyJul 26, 2011
  8. Jeff KingJul 26, 2011
  9. Nguyen Thai Ngoc DuyJul 26, 2011
  10. Nguyen Thai Ngoc DuyJul 26, 2011
  11. Jeff KingJul 27, 2011
  12. Nguyen Thai Ngoc DuyJul 27, 2011
  13. Jeff KingJul 27, 2011
  14. Jeff KingJul 27, 2011
  15. 1/5 add--interactive: refactor patch mode argument processingJeff King, Jul 27, 2011
  16. 2/5 add--interactive: factor out regex error handlingJeff King, Jul 27, 2011
  17. 3/5 add--interactive: allow hunk filtering on command lineJeff King, Jul 27, 2011
  18. 4/5 add--interactive: allow negatation of hunk filtersJeff King, Jul 27, 2011
  19. 5/5 add--interactive: add option to autosplit hunksJeff King, Jul 27, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.