From: Jeff King <peff@peff.net>
To: Nguyen Thai Ngoc Duy <pclouds@gmail.com>
Cc: Git Mailing List <git@vger.kernel.org>
Subject: Re: feature request: git add--interactive --patch on regex-matched hunks only
Date: Mon, 25 Jul 2011 15:55:55 -0600 [thread overview]
Message-ID: <20110725215553.GA23145@sigill.intra.peff.net> (raw)
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.
> 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 "--";
next prev parent reply other threads:[~2011-07-25 21:56 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-07-24 5:11 feature request: git add--interactive --patch on regex-matched hunks only Nguyen Thai Ngoc Duy
2011-07-25 21:55 ` Jeff King [this message]
2011-07-25 23:44 ` Junio C Hamano
2011-07-26 5:03 ` Jeff King
2011-07-26 3:03 ` Nguyen Thai Ngoc Duy
2011-07-26 5:14 ` Jeff King
2011-07-26 5:57 ` Nguyen Thai Ngoc Duy
2011-07-26 6:09 ` Jeff King
2011-07-26 12:44 ` Nguyen Thai Ngoc Duy
2011-07-26 13:03 ` Nguyen Thai Ngoc Duy
2011-07-27 8:10 ` Jeff King
2011-07-27 9:02 ` Nguyen Thai Ngoc Duy
2011-07-27 17:24 ` Jeff King
2011-07-27 8:03 ` Jeff King
2011-07-27 8:05 ` [PATCH 1/5] add--interactive: refactor patch mode argument processing Jeff King
2011-07-27 8:05 ` [PATCH 2/5] add--interactive: factor out regex error handling Jeff King
2011-07-27 8:05 ` [PATCH 3/5] add--interactive: allow hunk filtering on command line Jeff King
2011-07-27 8:05 ` [PATCH 4/5] add--interactive: allow negatation of hunk filters Jeff King
2011-07-27 8:06 ` [PATCH 5/5] add--interactive: add option to autosplit hunks Jeff King
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110725215553.GA23145@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=pclouds@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).