Merge branch 'jc/maint-add-p-overlapping-hunks'
authorJunio C Hamano <gitster@pobox.com>
Wed, 11 May 2011 18:37:46 +0000 (11:37 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 11 May 2011 18:37:46 +0000 (11:37 -0700)
* jc/maint-add-p-overlapping-hunks:
t3701: add-p-fix makes the last test to pass
"add -p": work-around an old laziness that does not coalesce hunks
add--interactive.perl: factor out repeated --recount option
t3701: Editing a split hunk in an "add -p" session
add -p: 'q' should really quit

builtin/apply.c
git-add--interactive.perl
t/t3701-add-interactive.sh
index 36e150768ba88e427e6257900d7ec4c67c8303c1..530d4bb7e76da8e402f78ab7f981a080d25d6e78 100644 (file)
@@ -43,6 +43,7 @@ static int apply = 1;
 static int apply_in_reverse;
 static int apply_with_reject;
 static int apply_verbosely;
+static int allow_overlap;
 static int no_add;
 static const char *fake_ancestor;
 static int line_termination = '\n';
@@ -2430,9 +2431,9 @@ static void update_image(struct image *img,
        memcpy(img->line + applied_pos,
               postimage->line,
               postimage->nr * sizeof(*img->line));
-       for (i = 0; i < postimage->nr; i++)
-               img->line[applied_pos + i].flag |= LINE_PATCHED;
-
+       if (!allow_overlap)
+               for (i = 0; i < postimage->nr; i++)
+                       img->line[applied_pos + i].flag |= LINE_PATCHED;
        img->nr = nr;
 }
 
@@ -3889,6 +3890,8 @@ int cmd_apply(int argc, const char **argv, const char *prefix_)
                        "don't expect at least one line of context"),
                OPT_BOOLEAN(0, "reject", &apply_with_reject,
                        "leave the rejected hunks in corresponding *.rej files"),
+               OPT_BOOLEAN(0, "allow-overlap", &allow_overlap,
+                       "allow overlapping hunks"),
                OPT__VERBOSE(&apply_verbosely, "be verbose"),
                OPT_BIT(0, "inaccurate-eof", &options,
                        "tolerate incorrectly detected missing new-line at the end of file",
index a329c5a1f8c3b63ee6976a8e0e3903a11783324b..4f08fe704bbaff64613ab07630a71da8bf8bbca0 100755 (executable)
@@ -705,7 +705,7 @@ sub add_untracked_cmd {
 sub run_git_apply {
        my $cmd = shift;
        my $fh;
-       open $fh, '| git ' . $cmd;
+       open $fh, '| git ' . $cmd . " --recount --allow-overlap";
        print $fh @_;
        return close $fh;
 }
@@ -1050,7 +1050,7 @@ sub edit_hunk_manually {
 
 sub diff_applies {
        my $fh;
-       return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --recount --check',
+       return run_git_apply($patch_mode_flavour{APPLY_CHECK} . ' --check',
                             map { @{$_->{TEXT}} } @_);
 }
 
@@ -1139,7 +1139,7 @@ sub help_patch_cmd {
 
 sub apply_patch {
        my $cmd = shift;
-       my $ret = run_git_apply $cmd . ' --recount', @_;
+       my $ret = run_git_apply $cmd, @_;
        if (!$ret) {
                print STDERR @_;
        }
@@ -1148,17 +1148,17 @@ sub apply_patch {
 
 sub apply_patch_for_checkout_commit {
        my $reverse = shift;
-       my $applies_index = run_git_apply 'apply '.$reverse.' --cached --recount --check', @_;
-       my $applies_worktree = run_git_apply 'apply '.$reverse.' --recount --check', @_;
+       my $applies_index = run_git_apply 'apply '.$reverse.' --cached --check', @_;
+       my $applies_worktree = run_git_apply 'apply '.$reverse.' --check', @_;
 
        if ($applies_worktree && $applies_index) {
-               run_git_apply 'apply '.$reverse.' --cached --recount', @_;
-               run_git_apply 'apply '.$reverse.' --recount', @_;
+               run_git_apply 'apply '.$reverse.' --cached', @_;
+               run_git_apply 'apply '.$reverse, @_;
                return 1;
        } elsif (!$applies_index) {
                print colored $error_color, "The selected hunks do not apply to the index!\n";
                if (prompt_yesno "Apply them to the worktree anyway? ") {
-                       return run_git_apply 'apply '.$reverse.' --recount', @_;
+                       return run_git_apply 'apply '.$reverse, @_;
                } else {
                        print colored $error_color, "Nothing was applied.\n";
                        return 0;
@@ -1366,14 +1366,13 @@ sub patch_update_file {
                                next;
                        }
                        elsif ($line =~ /^q/i) {
-                               while ($ix < $num) {
-                                       if (!defined $hunk[$ix]{USE}) {
-                                               $hunk[$ix]{USE} = 0;
+                               for ($i = 0; $i < $num; $i++) {
+                                       if (!defined $hunk[$i]{USE}) {
+                                               $hunk[$i]{USE} = 0;
                                        }
-                                       $ix++;
                                }
                                $quit = 1;
-                               next;
+                               last;
                        }
                        elsif ($line =~ m|^/(.*)|) {
                                my $regex = $1;
index fdcbe2e73629fe16bb0d62621b97c624cef5f77c..9e236f9cc0bf43155d377c1706c8142d843c417d 100755 (executable)
@@ -294,4 +294,40 @@ test_expect_success PERL 'deleting an empty file' '
        test_cmp expected diff
 '
 
+test_expect_success PERL 'split hunk setup' '
+       git reset --hard &&
+       for i in 10 20 30 40 50 60
+       do
+               echo $i
+       done >test &&
+       git add test &&
+       test_tick &&
+       git commit -m test &&
+
+       for i in 10 15 20 21 22 23 24 30 40 50 60
+       do
+               echo $i
+       done >test
+'
+
+test_expect_success PERL 'split hunk "add -p (edit)"' '
+       # Split, say Edit and do nothing.  Then:
+       #
+       # 1. Broken version results in a patch that does not apply and
+       # only takes [y/n] (edit again) so the first q is discarded
+       # and then n attempts to discard the edit. Repeat q enough
+       # times to get out.
+       #
+       # 2. Correct version applies the (not)edited version, and asks
+       #    about the next hunk, against wich we say q and program
+       #    exits.
+       for a in s e     q n q q
+       do
+               echo $a
+       done |
+       EDITOR=: git add -p &&
+       git diff >actual &&
+       ! grep "^+15" actual
+'
+
 test_done