|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2006 Junio C Hamano
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='Binary diff and apply
|
|
|
|
'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success 'prepare repository' \
|
|
|
|
'echo AIT >a && echo BIT >b && echo CIT >c && echo DIT >d &&
|
|
|
|
git update-index --add a b c d &&
|
|
|
|
echo git >a &&
|
|
|
|
cat "$TEST_DIRECTORY"/test4012.png >b &&
|
|
|
|
echo git >c &&
|
|
|
|
cat b b >d'
|
|
|
|
|
|
|
|
cat > expected <<\EOF
|
|
|
|
a | 2 +-
|
|
|
|
b | Bin
|
|
|
|
c | 2 +-
|
|
|
|
d | Bin
|
|
|
|
4 files changed, 2 insertions(+), 2 deletions(-)
|
|
|
|
EOF
|
|
|
|
test_expect_success 'diff without --binary' \
|
|
|
|
'git diff | git apply --stat --summary >current &&
|
|
|
|
test_cmp expected current'
|
|
|
|
|
|
|
|
test_expect_success 'diff with --binary' \
|
|
|
|
'git diff --binary | git apply --stat --summary >current &&
|
|
|
|
test_cmp expected current'
|
|
|
|
|
|
|
|
# apply needs to be able to skip the binary material correctly
|
|
|
|
# in order to report the line number of a corrupt patch.
|
|
|
|
test_expect_success 'apply detecting corrupt patch correctly' \
|
|
|
|
'git diff | sed -e 's/-CIT/xCIT/' >broken &&
|
|
|
|
if git apply --stat --summary broken 2>detected
|
|
|
|
then
|
|
|
|
echo unhappy - should have detected an error
|
|
|
|
(exit 1)
|
|
|
|
else
|
|
|
|
echo happy
|
|
|
|
fi &&
|
|
|
|
detected=`cat detected` &&
|
|
|
|
detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
|
|
|
|
detected=`sed -ne "${detected}p" broken` &&
|
|
|
|
test "$detected" = xCIT'
|
|
|
|
|
|
|
|
test_expect_success 'apply detecting corrupt patch correctly' \
|
|
|
|
'git diff --binary | sed -e 's/-CIT/xCIT/' >broken &&
|
|
|
|
if git apply --stat --summary broken 2>detected
|
|
|
|
then
|
|
|
|
echo unhappy - should have detected an error
|
|
|
|
(exit 1)
|
|
|
|
else
|
|
|
|
echo happy
|
|
|
|
fi &&
|
|
|
|
detected=`cat detected` &&
|
|
|
|
detected=`expr "$detected" : "fatal.*at line \\([0-9]*\\)\$"` &&
|
|
|
|
detected=`sed -ne "${detected}p" broken` &&
|
|
|
|
test "$detected" = xCIT'
|
|
|
|
|
|
|
|
test_expect_success 'initial commit' 'git commit -a -m initial'
|
|
|
|
|
|
|
|
# Try removal (b), modification (d), and creation (e).
|
|
|
|
test_expect_success 'diff-index with --binary' \
|
|
|
|
'echo AIT >a && mv b e && echo CIT >c && cat e >d &&
|
|
|
|
git update-index --add --remove a b c d e &&
|
|
|
|
tree0=`git write-tree` &&
|
|
|
|
git diff --cached --binary >current &&
|
|
|
|
git apply --stat --summary current'
|
|
|
|
|
|
|
|
test_expect_success 'apply binary patch' \
|
|
|
|
'git reset --hard &&
|
|
|
|
git apply --binary --index <current &&
|
|
|
|
tree1=`git write-tree` &&
|
|
|
|
test "$tree1" = "$tree0"'
|
|
|
|
|
fix bogus "diff --git" header from "diff --no-index"
When "git diff --no-index" is given an absolute pathname, it
would generate a diff header with the absolute path
prepended by the prefix, like:
diff --git a/dev/null b/foo
Not only is this nonsensical, and not only does it violate
the description of diffs given in git-diff(1), but it would
produce broken binary diffs. Unlike text diffs, the binary
diffs don't contain the filenames anywhere else, and so "git
apply" relies on this header to figure out the filename.
This patch just refuses to use an invalid name for anything
visible in the diff.
Now, this fixes the "git diff --no-index --binary a
/dev/null" kind of case (and we'll end up using "a" as the
basename), but some other insane cases are impossible to
handle. If you do
git diff --no-index --binary a /bin/echo
you'll still get a patch like
diff --git a/a b/bin/echo
old mode 100644
new mode 100755
index ...
and "git apply" will refuse to apply it for a couple of
reasons, and the diff is simply bogus.
And that, btw, is no longer a bug, I think. It's impossible
to know whethe the user meant for the patch to be a rename
or not. And as such, refusing to apply it because you don't
know what name you should use is probably _exactly_ the
right thing to do!
Original problem reported by Imre Deak. Test script and problem
description by Jeff King.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
16 years ago
|
|
|
nul_to_q() {
|
|
|
|
perl -pe 'y/\000/Q/'
|
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'diff --no-index with binary creation' '
|
|
|
|
echo Q | q_to_nul >binary &&
|
|
|
|
(: hide error code from diff, which just indicates differences
|
fix bogus "diff --git" header from "diff --no-index"
When "git diff --no-index" is given an absolute pathname, it
would generate a diff header with the absolute path
prepended by the prefix, like:
diff --git a/dev/null b/foo
Not only is this nonsensical, and not only does it violate
the description of diffs given in git-diff(1), but it would
produce broken binary diffs. Unlike text diffs, the binary
diffs don't contain the filenames anywhere else, and so "git
apply" relies on this header to figure out the filename.
This patch just refuses to use an invalid name for anything
visible in the diff.
Now, this fixes the "git diff --no-index --binary a
/dev/null" kind of case (and we'll end up using "a" as the
basename), but some other insane cases are impossible to
handle. If you do
git diff --no-index --binary a /bin/echo
you'll still get a patch like
diff --git a/a b/bin/echo
old mode 100644
new mode 100755
index ...
and "git apply" will refuse to apply it for a couple of
reasons, and the diff is simply bogus.
And that, btw, is no longer a bug, I think. It's impossible
to know whethe the user meant for the patch to be a rename
or not. And as such, refusing to apply it because you don't
know what name you should use is probably _exactly_ the
right thing to do!
Original problem reported by Imre Deak. Test script and problem
description by Jeff King.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
16 years ago
|
|
|
git diff --binary --no-index /dev/null binary >current ||
|
|
|
|
true
|
|
|
|
) &&
|
|
|
|
rm binary &&
|
|
|
|
git apply --binary <current &&
|
|
|
|
echo Q >expected &&
|
|
|
|
nul_to_q <binary >actual &&
|
|
|
|
test_cmp expected actual
|
|
|
|
'
|
|
|
|
|
|
|
|
test_done
|