All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pierre Habouzit <madcoder@debian.org>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>, Thomas Rast <trast@student.ethz.ch>
Subject: [PATCH] git-add -p: be able to undo a given hunk
Date: Thu, 23 Jul 2009 09:41:04 +0200	[thread overview]
Message-ID: <20090723074104.GI4750@laphroaig.corp> (raw)

One of my most frequent use case for git-add -p is when I had an intense
debug session with quite a lot of debug() traces added. I then want only
to select the hunks corresponding to the bugfixes and throw away the debug
ones.

With this new operation, instead of not staging hunks I don't want and
will eventually undo, I can just undo them.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---

    I reckon this is a tad late given we're already at -rc2, but that's
    an itch that has scratched me for quite some time already, and I had
    to scratch it today...

    the change looks pretty safe to me though.

    The only think that looks odd in the patch is the removal of the
    if ($_->{USE}) clause from the TEXT copying loops, but
    coalesce_overlapping_hunks already ensures that only ->{USE}d hunks
    remain. I just have modified it to deal with ->{UNDO}ed hunks the
    same way.

 Documentation/git-add.txt |    1 +
 git-add--interactive.perl |   38 ++++++++++++++++++++++++++++++--------
 2 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index ab1943c..7b173dc 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -254,6 +254,7 @@ patch::
 
        y - stage this hunk
        n - do not stage this hunk
+       u - do not stage this hunk and revert it
        q - quit, do not stage this hunk nor any of the remaining ones
        a - stage this and all the remaining hunks in the file
        d - do not stage this hunk nor any of the remaining hunks in the file
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index df9f231..945de9d 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -693,6 +693,7 @@ sub split_hunk {
 			ADDDEL => 0,
 			POSTCTX => 0,
 			USE => undef,
+			UNDO => undef,
 		};
 
 		while (++$i < @$text) {
@@ -835,12 +836,13 @@ sub merge_hunk {
 }
 
 sub coalesce_overlapping_hunks {
+	my $field = shift;
 	my (@in) = @_;
 	my @out = ();
 
 	my ($last_o_ctx, $last_was_dirty);
 
-	for (grep { $_->{USE} } @in) {
+	for (grep { $_->{$field} } @in) {
 		my $text = $_->{TEXT};
 		my ($o_ofs) = parse_hunk_header($text->[0]);
 		if (defined $last_o_ctx &&
@@ -991,6 +993,7 @@ sub help_patch_cmd {
 	print colored $help_color, <<\EOF ;
 y - stage this hunk
 n - do not stage this hunk
+u - do not stage this hunk and revert it
 q - quit, do not stage this hunk nor any of the remaining ones
 a - stage this and all the remaining hunks in the file
 d - do not stage this hunk nor any of the remaining hunks in the file
@@ -1140,7 +1143,7 @@ sub patch_update_file {
 		}
 		print colored $prompt_color, 'Stage ',
 		  ($hunk[$ix]{TYPE} eq 'mode' ? 'mode change' : 'this hunk'),
-		  " [y,n,q,a,d,/$other,?]? ";
+		  " [y,n,u,q,a,d,/$other,?]? ";
 		my $line = prompt_single_character;
 		if ($line) {
 			if ($line =~ /^y/i) {
@@ -1149,6 +1152,10 @@ sub patch_update_file {
 			elsif ($line =~ /^n/i) {
 				$hunk[$ix]{USE} = 0;
 			}
+			elsif ($line =~ /^u/) {
+				$hunk[$ix]{USE} = 0;
+				$hunk[$ix]{UNDO} = 1;
+			}
 			elsif ($line =~ /^a/i) {
 				while ($ix < $num) {
 					if (!defined $hunk[$ix]{USE}) {
@@ -1301,14 +1308,14 @@ sub patch_update_file {
 		}
 	}
 
-	@hunk = coalesce_overlapping_hunks(@hunk);
-
 	my $n_lofs = 0;
 	my @result = ();
-	for (@hunk) {
-		if ($_->{USE}) {
-			push @result, @{$_->{TEXT}};
-		}
+	my @undo = ();
+	for (coalesce_overlapping_hunks("USE", @hunk)) {
+		push @result, @{$_->{TEXT}};
+	}
+	for (coalesce_overlapping_hunks("UNDO", @hunk)) {
+		push @undo, @{$_->{TEXT}};
 	}
 
 	if (@result) {
@@ -1326,6 +1333,21 @@ sub patch_update_file {
 		refresh();
 	}
 
+	if (@undo) {
+		my $fh;
+
+		open $fh, '| git apply -R';
+		for (@{$head->{TEXT}}, @undo) {
+			print $fh $_;
+		}
+		if (!close $fh) {
+			for (@{$head->{TEXT}}, @undo) {
+				print STDERR $_;
+			}
+		}
+		refresh();
+	}
+
 	print "\n";
 	return $quit;
 }
-- 
1.6.4.rc1.189.g9f628.dirty

             reply	other threads:[~2009-07-23  7:41 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-07-23  7:41 Pierre Habouzit [this message]
2009-07-23  8:41 ` [PATCH] git-add -p: be able to undo a given hunk Thomas Rast
2009-07-23  8:50   ` Pierre Habouzit
2009-07-24  9:15   ` [RFC PATCH] Implement unstage and reset modes for git-add--interactive Thomas Rast
2009-07-24 16:24     ` [RFC PATCH v2 1/3] Introduce git-unstage Thomas Rast
2009-07-24 17:59       ` Bert Wesarg
2009-07-24 18:02         ` Bert Wesarg
2009-07-24 18:23       ` Elijah Newren
2009-07-24 16:24     ` [RFC PATCH v2 2/3] Introduce git-discard Thomas Rast
2009-07-24 18:02       ` Elijah Newren
2009-07-24 18:12         ` Bert Wesarg
2009-07-24 18:24           ` Elijah Newren
2009-07-25 14:58       ` Pierre Habouzit
2009-07-24 16:24     ` [RFC PATCH v2 3/3] Implement unstage --patch and discard --patch Thomas Rast
2009-07-24 16:40       ` Matthias Kestenholz
2009-07-24 18:08       ` Bert Wesarg
2009-07-24 16:39     ` [RFC PATCH] Implement unstage and reset modes for git-add--interactive Junio C Hamano
2009-07-24 21:58       ` Nanako Shiraishi
2009-07-24 23:17         ` Thomas Rast
2009-07-24 23:25         ` Junio C Hamano
2009-07-25 21:29           ` [RFC PATCH v3 0/5] {checkout,reset,stash} --patch Thomas Rast
2009-07-25 21:29             ` [RFC PATCH v3 1/5] git-apply--interactive: Refactor patch mode code Thomas Rast
2009-07-25 21:29             ` [RFC PATCH v3 2/5] builtin-add: refactor the meat of interactive_add() Thomas Rast
2009-07-25 21:29             ` [RFC PATCH v3 3/5] Implement 'git reset --patch' Thomas Rast
2009-07-25 21:29             ` [RFC PATCH v3 4/5] Implement 'git checkout --patch' Thomas Rast
2009-07-25 21:29             ` [RFC PATCH v3 5/5] Implement 'git stash save --patch' Thomas Rast
2009-07-26  6:03               ` Sverre Rabbelier
2009-07-26  8:45                 ` Thomas Rast
2009-07-27 10:10             ` [RFC PATCH v3 0/5] {checkout,reset,stash} --patch Thomas Rast
2009-07-28 21:20               ` [PATCH v4 " Thomas Rast
2009-07-28 21:20                 ` [PATCH v4 1/5] git-apply--interactive: Refactor patch mode code Thomas Rast
2009-07-28 21:20                 ` [PATCH v4 2/5] builtin-add: refactor the meat of interactive_add() Thomas Rast
2009-07-28 21:20                 ` [PATCH v4 3/5] Implement 'git reset --patch' Thomas Rast
2009-07-28 21:20                 ` [PATCH v4 4/5] Implement 'git checkout --patch' Thomas Rast
2009-07-28 21:20                 ` [PATCH v4 5/5] Implement 'git stash save --patch' Thomas Rast
2009-07-28 21:20                 ` [PATCH v4 6/5] DWIM 'git stash save -p' for 'git stash -p' Thomas Rast
2009-08-09  6:52                 ` [PATCH v4 0/5] {checkout,reset,stash} --patch Jeff King
2009-08-09  9:17                   ` Thomas Rast
2009-08-09 16:32                     ` [PATCH v4 0/5] " Nicolas Sebrecht
2009-08-09 16:44                       ` Thomas Rast
2009-08-09 21:28                         ` Nicolas Sebrecht
2009-08-09 21:42                           ` Thomas Rast
2009-08-09 22:26                             ` Nicolas Sebrecht
2009-08-10  9:36                               ` Thomas Rast
2009-08-13 12:29                                 ` [PATCH v5 0/6] " Thomas Rast
2009-08-13 12:29                                   ` [PATCH v5 1/6] git-apply--interactive: Refactor patch mode code Thomas Rast
2009-08-13 12:29                                   ` [PATCH v5 2/6] Add a small patch-mode testing library Thomas Rast
2009-08-13 12:29                                   ` [PATCH v5 3/6] builtin-add: refactor the meat of interactive_add() Thomas Rast
2009-08-13 12:29                                   ` [PATCH v5 4/6] Implement 'git reset --patch' Thomas Rast
2009-08-15 11:48                                     ` [PATCH v5.1 " Thomas Rast
2009-08-13 12:29                                   ` [PATCH v5 5/6] Implement 'git checkout --patch' Thomas Rast
2009-08-15 11:48                                     ` [PATCH v5.1 " Thomas Rast
2009-08-13 12:29                                   ` [PATCH v5 6/6] Implement 'git stash save --patch' Thomas Rast
2009-08-13 12:29                                   ` [PATCH v5 7/6] DWIM 'git stash save -p' for 'git stash -p' Thomas Rast
2009-08-14 20:57                                   ` [PATCH v5 0/6] Re: {checkout,reset,stash} --patch Nicolas Sebrecht
2009-08-15  6:51                                   ` [PATCH v5 0/6] " Jeff King
2009-08-15  7:57                                     ` Junio C Hamano
2009-08-15 10:14                                       ` Thomas Rast
2009-08-15 10:04                                     ` Thomas Rast
2009-08-18 16:48                                       ` Jeff King
2009-08-19  9:40                                         ` Thomas Rast
2009-08-19 10:11                                           ` Jeff King
2009-07-23 19:58 ` [PATCH] git-add -p: be able to undo a given hunk Junio C Hamano
2009-07-24 10:32   ` Nanako Shiraishi
2009-07-24 16:06     ` Junio C Hamano
2009-07-24 17:06       ` Jeff King
2009-07-25  0:54         ` Junio C Hamano
2009-07-25  9:35           ` Thomas Rast
2009-07-25 14:48         ` Pierre Habouzit
2009-07-25 14:52       ` Pierre Habouzit
2009-07-26 15:39         ` Jeff King
2009-07-27  8:26           ` Pierre Habouzit
2009-07-27 10:30             ` Jeff King
2009-07-27 10:06           ` Thomas Rast
2009-07-27 10:36             ` Jeff King
2009-07-24 14:58   ` Pierre Habouzit

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=20090723074104.GI4750@laphroaig.corp \
    --to=madcoder@debian.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=trast@student.ethz.ch \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.