git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jeff King <peff@peff.net>
To: Johan Herland <johan@herland.net>
Cc: git@vger.kernel.org,
	Johannes Schindelin <Johannes.Schindelin@gmx.de>,
	Thomas Rast <trast@student.ethz.ch>,
	Junio C Hamano <gitster@pobox.com>
Subject: Re: [PATCH v3] git-add--interactive: manual hunk editing mode
Date: Tue, 10 Jun 2008 07:05:53 -0400	[thread overview]
Message-ID: <20080610110553.GA13655@sigill.intra.peff.net> (raw)
In-Reply-To: <200806092319.23906.johan@herland.net>

On Mon, Jun 09, 2008 at 11:19:23PM +0200, Johan Herland wrote:

> On Monday 09 June 2008, Jeff King wrote:
> > But honestly, I don't really see a use case that isn't covered by
> > "manually edit the diff and apply the hunk". And the rationale in your
> > "side note" indicates that you think the same way.

Below is a simple patch to build interactive edit support on top of
Dscho's "git apply --recount" patch. Rather than create new hunks, the
action is just "edit and apply": if the apply is successful, the hunk is
removed from further consideration. This is just for playing with, and
not for commit:

  - it's not very well tested :)

  - I think the recount stuff may have flaws; I didn't follow the thread
    too closely, but Junio seemed to have a lot of comments (I am
    working under the assumption that Dscho will get that part right,
    and we can just build on top of it)

  - I tried one or two simple tests where I edited and applied an early
    hunk, and then resumed the loop for later hunks. Everything seemed
    to work, but I am not convinced that it isn't possible to make the
    rest of the hunk selection loop useless by applying early and
    invalidating all of the other hunks. That might be a flaw with this
    approach. A more sane interface might be to simply jump from the
    hunk selection loop into manually editing _all_ hunks and then
    applying, ending the hunk selection loop.

This should be applied on top of "allow git-apply to ignore the hunk
headers" (v3) which can be found on the list.  Obviously significant
portions of the patch below are based on Thomas' version.

-- >8 --
git-add--interactive: manual hunk editing mode

Adds a new option 'e' to the 'add -p' command loop that lets you
edit the current hunk in your favourite editor, applying the
result.
---
 git-add--interactive.perl |   81 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 903953e..62b5aed 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -2,6 +2,7 @@
 
 use strict;
 use Git;
+use File::Temp;
 
 my $repo = Git->repository();
 
@@ -770,6 +771,76 @@ sub coalesce_overlapping_hunks {
 	return @out;
 }
 
+sub edit_hunk_manually {
+	my ($oldtext) = @_;
+
+	my $t = File::Temp->new(
+		TEMPLATE => $repo->repo_path . "/git-hunk-edit.XXXXXX",
+		SUFFIX => '.diff'
+	);
+	print $t "# Manual hunk edit mode -- see bottom for a quick guide\n";
+	print $t @$oldtext;
+	print $t <<EOF;
+# ---
+# To remove '-' lines, make them ' ' lines (context).
+# To remove '+' lines, delete them.
+# Empty lines and lines starting with # will be removed.
+#
+# Lines starting with @ start a new hunk. Line counts will be adjusted
+# according to contents. If the line numbers are missing altogether,
+# they will be inferred from the previous hunk.
+#
+# You can change the hunk to your heart's content, but it will be
+# refused if the end result (the entire patch including your edited
+# hunk) does not apply cleanly.
+EOF
+	close $t;
+
+	my $editor = $ENV{GIT_EDITOR} || $repo->config("core.editor")
+		|| $ENV{VISUAL} || $ENV{EDITOR} || "vi";
+	system('sh', '-c', $editor.' "$@"', $editor, $t);
+
+	open my $fh, '<', $t
+		or die "failed to open hunk edit file for reading: " . $!;
+	my @newtext = grep { !/^#/ } <$fh>;
+	close $fh;
+
+	# Reinsert the first hunk header if the user accidentally deleted it
+	if ($newtext[0] !~ /^@/) {
+		unshift @newtext, $oldtext->[0];
+	}
+	return \@newtext;
+}
+
+sub apply_diff {
+	open(my $fh, '|-', qw(git apply --cached --recount));
+	print $fh map { @$_ } @_;
+	return close $fh;
+}
+
+sub prompt_yesno {
+	my ($prompt) = @_;
+	while (1) {
+		print colored $prompt_color, $prompt;
+		my $line = <STDIN>;
+		return 0 if $line =~ /^n/i;
+		return 1 if $line =~ /^y/i;
+	}
+}
+
+sub edit_hunk_loop {
+	my ($head, $text) = @_;
+
+	while (1) {
+		$text = edit_hunk_manually($text);
+		apply_diff($head, $text) and return 1;
+		prompt_yesno(
+			'Your edited hunk does not apply. Edit again '
+			. '(saying "no" discards!) [y/n]? '
+		) or return 0;
+	}
+}
+
 sub help_patch_cmd {
 	print colored $help_color, <<\EOF ;
 y - stage this hunk
@@ -781,6 +852,7 @@ J - leave this hunk undecided, see next hunk
 k - leave this hunk undecided, see previous undecided hunk
 K - leave this hunk undecided, see previous hunk
 s - split the current hunk into smaller hunks
+e - manually edit the current hunk
 ? - print help
 EOF
 }
@@ -885,6 +957,7 @@ sub patch_update_file {
 		if (hunk_splittable($hunk[$ix]{TEXT})) {
 			$other .= '/s';
 		}
+		$other .= '/e';
 		for (@{$hunk[$ix]{DISPLAY}}) {
 			print;
 		}
@@ -949,6 +1022,14 @@ sub patch_update_file {
 				$num = scalar @hunk;
 				next;
 			}
+			elsif ($line =~ /^e/) {
+				if (edit_hunk_loop($head->{TEXT},
+						   $hunk[$ix]{TEXT})) {
+					splice @hunk, $ix, 1;
+					$num = @hunk;
+				}
+				next;
+			}
 			else {
 				help_patch_cmd($other);
 				next;
-- 
1.5.6.rc2.26.gda075.dirty

  reply	other threads:[~2008-06-10 11:07 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-05-23 20:21 [PATCH] git-add--interactive: manual hunk editing mode Thomas Rast
2008-05-24  1:24 ` Ping Yin
2008-05-29 15:37 ` Thomas Rast
2008-05-29 16:12   ` Johannes Schindelin
2008-05-29 19:10     ` Thomas Rast
2008-05-29 19:16       ` Thomas Rast
2008-05-29 18:58   ` Jeff King
2008-05-30  9:49     ` Johannes Schindelin
2008-05-30 10:46       ` Jakub Narebski
2008-05-30 12:21     ` Thomas Rast
2008-05-30 21:35       ` Junio C Hamano
2008-06-01  0:41     ` [RFC PATCH] git-add--interactive: manual hunk editing mode v2 Thomas Rast
2008-06-01 14:50       ` [RFC PATCH] git-add--interactive: manual hunk editing mode v2.1 Thomas Rast
2008-06-01 15:14         ` Jeff King
2008-06-05  1:46       ` [RFC PATCH] git-add--interactive: manual hunk editing mode v2 Jeff King
2008-06-05  7:53         ` Thomas Rast
2008-06-05  8:11           ` Jeff King
2008-06-05  9:04             ` Thomas Rast
2008-06-05  9:20               ` Jeff King
2008-06-05  9:38                 ` Thomas Rast
2008-06-05  9:46                   ` Jeff King
2008-06-05  8:16         ` Junio C Hamano
2008-06-05  8:56           ` Jeff King
2008-06-05 10:28             ` Johannes Schindelin
2008-06-06  5:10               ` Jeff King
2008-06-06  6:03                 ` Jeff King
2008-06-08 22:33                   ` Thomas Rast
2008-06-08 23:06                     ` Johannes Schindelin
2008-06-06 14:31                 ` Johannes Schindelin
2008-06-08 22:18                   ` Thomas Rast
2008-06-08 23:02                     ` Johannes Schindelin
2008-06-05 12:38         ` [WIP PATCH v2] git-add--interactive: manual hunk editing mode Thomas Rast
2008-06-08 22:32           ` [PATCH v3] " Thomas Rast
2008-06-08 23:19             ` Johannes Schindelin
2008-06-09  5:46               ` Johan Herland
2008-06-09 12:29                 ` Jeff King
2008-06-09 16:13                   ` Johannes Schindelin
2008-06-09 19:59                     ` Junio C Hamano
2008-06-09 17:31                   ` Johan Herland
2008-06-09 20:17                     ` Jeff King
2008-06-09 21:19                       ` Johan Herland
2008-06-10 11:05                         ` Jeff King [this message]
2008-06-11  9:02                           ` Thomas Rast
2008-06-12  4:49                             ` Jeff King
2008-06-12  6:55                               ` Thomas Rast
2008-06-12  7:13                                 ` Jeff King
2008-06-13 15:48                                   ` [PATCH v4] " Thomas Rast
2008-06-23 18:38                                     ` Jeff King
2008-06-23 18:54                                       ` Johannes Schindelin
2008-06-23 19:57                                         ` Jeff King
2008-06-23 21:16                                           ` apply --recount, was " Johannes Schindelin
2008-06-24  5:09                                             ` Jeff King
2008-06-24 19:07                                               ` [PATCH 0/3] Manual editing for 'add' and 'add -p' Thomas Rast
2008-06-24 19:53                                                 ` Miklos Vajna
2008-06-24 19:08                                               ` [PATCH 1/3] Allow git-apply to ignore the hunk headers (AKA recountdiff) Thomas Rast
2008-06-24 23:35                                                 ` Junio C Hamano
2008-06-25  5:45                                                   ` Jeff King
2008-06-27 17:43                                                   ` Johannes Schindelin
2008-06-24 19:08                                               ` [PATCH 2/3] git-add: introduce --edit (to edit the diff vs. the index) Thomas Rast
2008-06-24 19:08                                               ` [PATCH 3/3] git-add--interactive: manual hunk editing mode Thomas Rast
2008-06-10 11:19                       ` [PATCH v3] " Andreas Ericsson
2008-06-05  9:02     ` [PATCH] " Thomas Rast

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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080610110553.GA13655@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=Johannes.Schindelin@gmx.de \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johan@herland.net \
    --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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).