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

1  2 
builtin/apply.c
t/t3701-add-interactive.sh
diff --combined builtin/apply.c
index 36e150768ba88e427e6257900d7ec4c67c8303c1,8be1ce539c7282db2376925a0bb6be7bad5fcfe4..530d4bb7e76da8e402f78ab7f981a080d25d6e78
@@@ -43,6 -43,7 +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,15 -2431,14 +2431,15 @@@ static void update_image(struct image *
        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;
  }
  
  static int apply_one_fragment(struct image *img, struct fragment *frag,
 -                            int inaccurate_eof, unsigned ws_rule)
 +                            int inaccurate_eof, unsigned ws_rule,
 +                            int nth_fragment)
  {
        int match_beginning, match_end;
        const char *patch = frag->patch;
                                apply = 0;
                }
  
 +              if (apply_verbosely && applied_pos != pos) {
 +                      int offset = applied_pos - pos;
 +                      if (apply_in_reverse)
 +                              offset = 0 - offset;
 +                      fprintf(stderr,
 +                              "Hunk #%d succeeded at %d (offset %d lines).\n",
 +                              nth_fragment, applied_pos + 1, offset);
 +              }
 +
                /*
                 * Warn if it was necessary to reduce the number
                 * of context lines.
@@@ -2800,14 -2791,12 +2801,14 @@@ static int apply_fragments(struct imag
        const char *name = patch->old_name ? patch->old_name : patch->new_name;
        unsigned ws_rule = patch->ws_rule;
        unsigned inaccurate_eof = patch->inaccurate_eof;
 +      int nth = 0;
  
        if (patch->is_binary)
                return apply_binary(img, patch);
  
        while (frag) {
 -              if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule)) {
 +              nth++;
 +              if (apply_one_fragment(img, frag, inaccurate_eof, ws_rule, nth)) {
                        error("patch failed: %s:%ld", name, frag->oldpos);
                        if (!apply_with_reject)
                                return -1;
@@@ -3889,6 -3878,8 +3890,8 @@@ int cmd_apply(int argc, const char **ar
                        "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 fdcbe2e73629fe16bb0d62621b97c624cef5f77c,7f61a1803038201150549aacbed82286cb49bf19..9e236f9cc0bf43155d377c1706c8142d843c417d
@@@ -82,9 -82,10 +82,9 @@@ EO
  '
  
  test_expect_success PERL 'setup fake editor' '
 -      cat >fake_editor.sh <<EOF
 -      EOF
 +      >fake_editor.sh &&
        chmod a+x fake_editor.sh &&
 -      test_set_editor "$(pwd)/fake_editor.sh" &&
 +      test_set_editor "$(pwd)/fake_editor.sh"
  '
  
  test_expect_success PERL 'dummy edit works' '
@@@ -294,4 -295,40 +294,40 @@@ test_expect_success PERL 'deleting an e
        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