apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2005 Junio C Hamano
|
|
|
|
#
|
|
|
|
|
2007-07-03 13:52:14 +08:00
|
|
|
test_description='git apply boundary tests
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
|
|
|
|
'
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
L="c d e f g h i j k l m n o p q r s t u v w x"
|
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
for i in b '"$L"' y
|
|
|
|
do
|
|
|
|
echo $i
|
|
|
|
done >victim &&
|
|
|
|
cat victim >original &&
|
|
|
|
git update-index --add victim &&
|
|
|
|
|
|
|
|
: add to the head
|
|
|
|
for i in a b '"$L"' y
|
|
|
|
do
|
|
|
|
echo $i
|
|
|
|
done >victim &&
|
|
|
|
cat victim >add-a-expect &&
|
|
|
|
git diff victim >add-a-patch.with &&
|
|
|
|
git diff --unified=0 >add-a-patch.without &&
|
|
|
|
|
2008-08-31 04:20:31 +08:00
|
|
|
: 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 &&
|
|
|
|
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
: modify at the head
|
|
|
|
for i in a '"$L"' y
|
|
|
|
do
|
|
|
|
echo $i
|
|
|
|
done >victim &&
|
|
|
|
cat victim >mod-a-expect &&
|
|
|
|
git diff victim >mod-a-patch.with &&
|
|
|
|
git diff --unified=0 >mod-a-patch.without &&
|
|
|
|
|
|
|
|
: remove from the head
|
|
|
|
for i in '"$L"' y
|
|
|
|
do
|
|
|
|
echo $i
|
|
|
|
done >victim &&
|
|
|
|
cat victim >del-a-expect &&
|
|
|
|
git diff victim >del-a-patch.with
|
|
|
|
git diff --unified=0 >del-a-patch.without &&
|
|
|
|
|
|
|
|
: add to the tail
|
|
|
|
for i in b '"$L"' y z
|
|
|
|
do
|
|
|
|
echo $i
|
|
|
|
done >victim &&
|
|
|
|
cat victim >add-z-expect &&
|
|
|
|
git diff victim >add-z-patch.with &&
|
|
|
|
git diff --unified=0 >add-z-patch.without &&
|
|
|
|
|
|
|
|
: modify at the tail
|
2008-08-31 04:20:31 +08:00
|
|
|
for i in b '"$L"' z
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
do
|
|
|
|
echo $i
|
|
|
|
done >victim &&
|
|
|
|
cat victim >mod-z-expect &&
|
|
|
|
git diff victim >mod-z-patch.with &&
|
|
|
|
git diff --unified=0 >mod-z-patch.without &&
|
|
|
|
|
|
|
|
: remove from the tail
|
|
|
|
for i in b '"$L"'
|
|
|
|
do
|
|
|
|
echo $i
|
|
|
|
done >victim &&
|
|
|
|
cat victim >del-z-expect &&
|
|
|
|
git diff victim >del-z-patch.with
|
|
|
|
git diff --unified=0 >del-z-patch.without &&
|
|
|
|
|
|
|
|
: done
|
|
|
|
'
|
|
|
|
|
|
|
|
for with in with without
|
|
|
|
do
|
|
|
|
case "$with" in
|
|
|
|
with) u= ;;
|
|
|
|
without) u='--unidiff-zero ' ;;
|
|
|
|
esac
|
2008-08-31 04:20:31 +08:00
|
|
|
for kind in add-a add-z insert-a mod-a mod-z del-a del-z
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
do
|
|
|
|
test_expect_success "apply $kind-patch $with context" '
|
|
|
|
cat original >victim &&
|
|
|
|
git update-index victim &&
|
|
|
|
git apply --index '"$u$kind-patch.$with"' || {
|
|
|
|
cat '"$kind-patch.$with"'
|
|
|
|
(exit 1)
|
|
|
|
} &&
|
2008-05-24 13:28:56 +08:00
|
|
|
test_cmp '"$kind"'-expect victim
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
'
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
2008-08-31 04:20:31 +08:00
|
|
|
for kind in add-a add-z insert-a mod-a mod-z del-a del-z
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
do
|
|
|
|
rm -f $kind-ng.without
|
|
|
|
sed -e "s/^diff --git /diff /" \
|
|
|
|
-e '/^index /d' \
|
|
|
|
<$kind-patch.without >$kind-ng.without
|
|
|
|
test_expect_success "apply non-git $kind-patch without context" '
|
|
|
|
cat original >victim &&
|
|
|
|
git update-index victim &&
|
|
|
|
git apply --unidiff-zero --index '"$kind-ng.without"' || {
|
|
|
|
cat '"$kind-ng.without"'
|
|
|
|
(exit 1)
|
|
|
|
} &&
|
2008-05-24 13:28:56 +08:00
|
|
|
test_cmp '"$kind"'-expect victim
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
'
|
|
|
|
done
|
|
|
|
|
2008-04-07 10:21:45 +08:00
|
|
|
test_expect_success 'two lines' '
|
|
|
|
|
|
|
|
>file &&
|
|
|
|
git add file &&
|
|
|
|
echo aaa >file &&
|
|
|
|
git diff >patch &&
|
|
|
|
git add file &&
|
|
|
|
echo bbb >file &&
|
|
|
|
git add file &&
|
|
|
|
test_must_fail git apply --check patch
|
|
|
|
|
|
|
|
'
|
|
|
|
|
apply: Remove the quick rejection test
In the next commit, we will make it possible for blank context
lines to match beyond the end of the file. That means that a hunk
with a preimage that has more lines than present in the file may
be possible to successfully apply. Therefore, we must remove
the quick rejection test in find_pos().
find_pos() will already work correctly without the quick
rejection test, but that might not be obvious. Therefore,
comment the test for handling out-of-range line numbers in
find_pos() and cast the "line" variable to the same (unsigned)
type as img->nr.
What are performance implications of removing the quick
rejection test?
It can only help "git apply" to reject a patch faster. For example,
if I have a file with one million lines and a patch that removes
slightly more than 50 percent of the lines and try to apply that
patch twice, the second attempt will fail slightly faster
with the test than without (based on actual measurements).
However, there is the pathological case of a patch with many
more context lines than the default three, and applying that patch
using "git apply -C1". Without the rejection test, the running
time will be roughly proportional to the number of context lines
times the size of the file. That could be handled by writing
a more complicated rejection test (it would have to count the
number of blanks at the end of the preimage), but I don't find
that worth doing until there is a real-world use case that
would benfit from it.
It would be possible to keep the quick rejection test if
--whitespace=fix is not given, but I don't like that from
a testing point of view.
Signed-off-by: Björn Gustavsson <bgustavsson@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2010-03-06 22:30:29 +08:00
|
|
|
test_expect_success 'apply patch with 3 context lines matching at end' '
|
|
|
|
{ echo a; echo b; echo c; echo d; } >file &&
|
|
|
|
git add file &&
|
|
|
|
echo e >>file &&
|
|
|
|
git diff >patch &&
|
|
|
|
>file &&
|
|
|
|
test_must_fail git apply patch
|
|
|
|
'
|
|
|
|
|
apply --unidiff-zero: loosen sanity checks for --unidiff=0 patches
In "git-apply", we have a few sanity checks and heuristics that
expects that the patch fed to us is a unified diff with at least
one line of context.
* When there is no leading context line in a hunk, the hunk
must apply at the beginning of the preimage. Similarly, no
trailing context means that the hunk is anchored at the end.
* We learn a patch deletes the file from a hunk that has no
resulting line (i.e. all lines are prefixed with '-') if it
has not otherwise been known if the patch deletes the file.
Similarly, no old line means the file is being created.
And we declare an error condition when the file created by a
creation patch already exists, and/or when a deletion patch
still leaves content in the file.
These sanity checks are good safety measures, but breaks down
when people feed a diff generated with --unified=0. This was
recently noticed first by Matthew Wilcox and Gerrit Pape.
This adds a new flag, --unified-zero, to allow bypassing these
checks. If you are in control of the patch generation process,
you should not use --unified=0 patch and fix it up with this
flag; rather you should try work with a patch with context. But
if all you have to work with is a patch without context, this
flag may come handy as the last resort.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2006-09-17 16:04:24 +08:00
|
|
|
test_done
|