* RFE: Discard hunks during `git add -p`
@ 2016-11-02 13:46 Jan Engelhardt
2016-11-02 14:07 ` Konstantin Khomoutov
2016-11-02 22:11 ` Jeff King
0 siblings, 2 replies; 4+ messages in thread
From: Jan Engelhardt @ 2016-11-02 13:46 UTC (permalink / raw)
To: git
Current version: 2.10.2
Example workflow:
* I would do a global substitution across a source tree, e.g. `perl -i
-pe 's{OLD_FOO\(x\)}{NEW_BAR(x, 0)}' *.c`
* Using `git add -p`, I would verify each of the substitutions that they
make sense in their respective locations, and, based on that,
answer "y" or "n" to the interactive prompting to stage good hunks.
* When done with add-p, I would commit the so-staged hunks,
and then use `git reset --hard` to discard all changes that were
not acknowledged during add-p.
Being able to discard hunks (reset working copy to index contents)
during add-p would alleviate the (quite broad) hard reset.
Similar approach:
* global substitution
* Using `git add -p`, some hunks may warrant some more editing, doable
with the "e" command. The index would be updated with the extra
change, but the working copy be left as-is.
* When rerunning `git add -p` in such a state, a difference is shown
again for such edited spots, which I would like to discard (bring
the working copy into sync with index).
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFE: Discard hunks during `git add -p`
2016-11-02 13:46 RFE: Discard hunks during `git add -p` Jan Engelhardt
@ 2016-11-02 14:07 ` Konstantin Khomoutov
2016-11-02 22:11 ` Jeff King
1 sibling, 0 replies; 4+ messages in thread
From: Konstantin Khomoutov @ 2016-11-02 14:07 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: git
On Wed, 2 Nov 2016 14:46:04 +0100 (CET)
Jan Engelhardt <jengelh@inai.de> wrote:
> Current version: 2.10.2
> Example workflow:
>
> * I would do a global substitution across a source tree, e.g. `perl
> -i -pe 's{OLD_FOO\(x\)}{NEW_BAR(x, 0)}' *.c`
> * Using `git add -p`, I would verify each of the substitutions that
> they make sense in their respective locations, and, based on that,
> answer "y" or "n" to the interactive prompting to stage good hunks.
> * When done with add-p, I would commit the so-staged hunks,
> and then use `git reset --hard` to discard all changes that were
> not acknowledged during add-p.
>
> Being able to discard hunks (reset working copy to index contents)
> during add-p would alleviate the (quite broad) hard reset.
Couldn't you just do
git checkout -- .
after staging your approved changes?
To selectively zap uncommitted changes from your working tree, you could
do
git checkout --patch -- .
I'm not sure overloading `git add` with a "reverse" action is a good
idea. I'm actually prefer pragmatism over conceptual purity but I'm
not sure the prospective gain here is clear.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFE: Discard hunks during `git add -p`
2016-11-02 13:46 RFE: Discard hunks during `git add -p` Jan Engelhardt
2016-11-02 14:07 ` Konstantin Khomoutov
@ 2016-11-02 22:11 ` Jeff King
2016-11-02 22:37 ` Jeff King
1 sibling, 1 reply; 4+ messages in thread
From: Jeff King @ 2016-11-02 22:11 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: git
On Wed, Nov 02, 2016 at 02:46:04PM +0100, Jan Engelhardt wrote:
> Current version: 2.10.2
> Example workflow:
>
> * I would do a global substitution across a source tree, e.g. `perl -i
> -pe 's{OLD_FOO\(x\)}{NEW_BAR(x, 0)}' *.c`
> * Using `git add -p`, I would verify each of the substitutions that they
> make sense in their respective locations, and, based on that,
> answer "y" or "n" to the interactive prompting to stage good hunks.
> * When done with add-p, I would commit the so-staged hunks,
> and then use `git reset --hard` to discard all changes that were
> not acknowledged during add-p.
>
> 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.
-Peff
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: RFE: Discard hunks during `git add -p`
2016-11-02 22:11 ` Jeff King
@ 2016-11-02 22:37 ` Jeff King
0 siblings, 0 replies; 4+ messages in thread
From: Jeff King @ 2016-11-02 22:37 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: git
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;
}
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-11-02 22:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-02 13:46 RFE: Discard hunks during `git add -p` Jan Engelhardt
2016-11-02 14:07 ` Konstantin Khomoutov
2016-11-02 22:11 ` Jeff King
2016-11-02 22:37 ` Jeff King
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).