Skip to content

Commit

Permalink
git-apply: Loosen "match_beginning" logic
Browse files Browse the repository at this point in the history
Even after a handfle attempts, match_beginning logic still has corner
cases:

    1bf1a85 (apply: treat EOF as proper context., 2006-05-23)
    65aadb9 (apply: force matching at the beginning., 2006-05-24)
    4be6096 (apply --unidiff-zero: loosen sanity checks ..., 2006-09-17)
    ee5a317 (Fix "git apply" to correctly enforce "match ..., 2008-04-06)

This is a tricky piece of code.

We still incorrectly enforce "match_beginning" for -U0 matches.
I noticed this while trying out an example sequence from Clemens Buchacher:

    $ echo a >victim
    $ git add victim
    $ echo b >>victim
    $ git diff -U0 >patch
    $ cat patch
    diff --git i/victim w/victim
    index 7898192..422c2b7 100644
    --- i/victim
    +++ w/victim
    @@ -1,0 +2 @@ a
    +b
    $ git apply --cached --unidiff-zero <patch
    $ git show :victim
    b
    a

The change inserts a new line before the second line, but we insist it to
be applied at the beginning.  As the result, the code refuses to apply it
at the original offset, and we end up adding the line at the beginning.

Updates to the test script are by Clemens Buchacher.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Junio C Hamano committed Aug 30, 2008
1 parent ee83724 commit ed0f47a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
5 changes: 4 additions & 1 deletion builtin-apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -1996,14 +1996,17 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
/*
* A hunk to change lines at the beginning would begin with
* @@ -1,L +N,M @@
* but we need to be careful. -U0 that inserts before the second
* line also has this pattern.
*
* And a hunk to add to an empty file would begin with
* @@ -0,0 +N,M @@
*
* In other words, a hunk that is (frag->oldpos <= 1) with or
* without leading context must match at the beginning.
*/
match_beginning = frag->oldpos <= 1;
match_beginning = (!frag->oldpos ||
(frag->oldpos == 1 && !unidiff_zero));

/*
* A hunk without trailing lines must match at the end.
Expand Down
15 changes: 12 additions & 3 deletions t/t4104-apply-boundary.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ test_expect_success setup '
git diff victim >add-a-patch.with &&
git diff --unified=0 >add-a-patch.without &&
: insert at line two
for i in b a '"$L"' y
do
echo $i
done >victim &&
cat victim >insert-a-expect &&
git diff victim >insert-a-patch.with &&
git diff --unified=0 >insert-a-patch.without &&
: modify at the head
for i in a '"$L"' y
do
Expand Down Expand Up @@ -55,7 +64,7 @@ test_expect_success setup '
git diff --unified=0 >add-z-patch.without &&
: modify at the tail
for i in a '"$L"' y
for i in b '"$L"' z
do
echo $i
done >victim &&
Expand All @@ -81,7 +90,7 @@ do
with) u= ;;
without) u='--unidiff-zero ' ;;
esac
for kind in add-a add-z mod-a mod-z del-a del-z
for kind in add-a add-z insert-a mod-a mod-z del-a del-z
do
test_expect_success "apply $kind-patch $with context" '
cat original >victim &&
Expand All @@ -95,7 +104,7 @@ do
done
done

for kind in add-a add-z mod-a mod-z del-a del-z
for kind in add-a add-z insert-a mod-a mod-z del-a del-z
do
rm -f $kind-ng.without
sed -e "s/^diff --git /diff /" \
Expand Down

0 comments on commit ed0f47a

Please sign in to comment.