diff options
Diffstat (limited to 't')
38 files changed, 1085 insertions, 175 deletions
diff --git a/t/.gitattributes b/t/.gitattributes index 562b12e16e..1b97c5465b 100644 --- a/t/.gitattributes +++ b/t/.gitattributes @@ -1 +1 @@ -* -whitespace +t[0-9][0-9][0-9][0-9]/* -whitespace @@ -54,6 +54,38 @@ You can pass --verbose (or -v), --debug (or -d), and --immediate This causes the test to immediately exit upon the first failed test. +--long-tests:: + This causes additional long-running tests to be run (where + available), for more exhaustive testing. + + +Skipping Tests +-------------- + +In some environments, certain tests have no way of succeeding +due to platform limitation, such as lack of 'unzip' program, or +filesystem that do not allow arbitrary sequence of non-NUL bytes +as pathnames. + +You should be able to say something like + + $ GIT_SKIP_TESTS=t9200.8 sh ./t9200-git-cvsexport-commit.sh + +and even: + + $ GIT_SKIP_TESTS='t[0-4]??? t91?? t9200.8' make + +to omit such tests. The value of the environment variable is a +SP separated list of patterns that tells which tests to skip, +and either can match the "t[0-9]{4}" part to skip the whole +test, or t[0-9]{4} followed by ".$number" to say which +particular test to skip. + +Note that some tests in the existing test suite rely on previous +test item, so you cannot arbitrarily disable one and expect the +remainder of test to check what the test originally was intended +to check. + Naming Tests ------------ diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index c56d2fbaba..3d8e06a20f 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -54,4 +54,39 @@ test_expect_success 'root subdir attribute test' ' ' +test_expect_success 'setup bare' ' + + git clone --bare . bare.git && + cd bare.git + +' + +test_expect_success 'bare repository: check that .gitattribute is ignored' ' + + ( + echo "f test=f" + echo "a/i test=a/i" + ) >.gitattributes && + attr_check f unspecified && + attr_check a/f unspecified && + attr_check a/c/f unspecified && + attr_check a/i unspecified && + attr_check subdir/a/i unspecified + +' + +test_expect_success 'bare repository: test info/attributes' ' + + ( + echo "f test=f" + echo "a/i test=a/i" + ) >info/attributes && + attr_check f f && + attr_check a/f f && + attr_check a/c/f f && + attr_check a/i a/i && + attr_check subdir/a/i unspecified + +' + test_done diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 9965cfa1dc..6309aed451 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -11,23 +11,35 @@ cat > expect.err << EOF usage: test-parse-options <options> -b, --boolean get a boolean + -4, --or4 bitwise-or boolean with ...0100 + -i, --integer <n> get a integer -j <n> get a integer, too + --set23 set integer to 23 + -t <time> get timestamp of <time> + -L, --length <str> get length of <str> -string options +String options -s, --string <string> get a string --string2 <str> get another string --st <st> get another string (pervert ordering) -o <str> get another string + --default-string set string to default -magic arguments +Magic arguments --quux means --quux +Standard options + --abbrev[=<n>] use <n> digits to display SHA-1s + -v, --verbose be verbose + -n, --dry-run dry run + -q, --quiet be quiet + EOF test_expect_success 'test help' ' - ! test-parse-options -h > output 2> output.err && + test_must_fail test-parse-options -h > output 2> output.err && test ! -s output && test_cmp expect.err output.err ' @@ -36,21 +48,31 @@ cat > expect << EOF boolean: 2 integer: 1729 string: 123 +abbrev: 7 +verbose: 2 +quiet: no +dry run: yes EOF test_expect_success 'short options' ' - test-parse-options -s123 -b -i 1729 -b > output 2> output.err && + test-parse-options -s123 -b -i 1729 -b -vv -n > output 2> output.err && test_cmp expect output && test ! -s output.err ' + cat > expect << EOF boolean: 2 integer: 1729 string: 321 +abbrev: 10 +verbose: 2 +quiet: no +dry run: no EOF test_expect_success 'long options' ' test-parse-options --boolean --integer 1729 --boolean --string2=321 \ + --verbose --verbose --no-dry-run --abbrev=10 \ > output 2> output.err && test ! -s output.err && test_cmp expect output @@ -60,6 +82,10 @@ cat > expect << EOF boolean: 1 integer: 13 string: 123 +abbrev: 7 +verbose: 0 +quiet: no +dry run: no arg 00: a1 arg 01: b1 arg 02: --boolean @@ -76,6 +102,10 @@ cat > expect << EOF boolean: 0 integer: 2 string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no EOF test_expect_success 'unambiguously abbreviated option' ' @@ -99,6 +129,10 @@ cat > expect << EOF boolean: 0 integer: 0 string: 123 +abbrev: 7 +verbose: 0 +quiet: no +dry run: no EOF test_expect_success 'non ambiguous option (after two options it abbreviates)' ' @@ -107,20 +141,24 @@ test_expect_success 'non ambiguous option (after two options it abbreviates)' ' test_cmp expect output ' -cat > expect.err << EOF +cat > typo.err << EOF error: did you mean \`--boolean\` (with two dashes ?) EOF test_expect_success 'detect possible typos' ' - ! test-parse-options -boolean > output 2> output.err && + test_must_fail test-parse-options -boolean > output 2> output.err && test ! -s output && - test_cmp expect.err output.err + test_cmp typo.err output.err ' cat > expect <<EOF boolean: 0 integer: 0 string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no arg 00: --quux EOF @@ -130,4 +168,68 @@ test_expect_success 'keep some options as arguments' ' test_cmp expect output ' +cat > expect <<EOF +boolean: 0 +integer: 1 +string: default +abbrev: 7 +verbose: 0 +quiet: yes +dry run: no +arg 00: foo +EOF + +test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' ' + test-parse-options -t "1970-01-01 00:00:01 +0000" --default-string \ + foo -q > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > expect <<EOF +Callback: "four", 0 +boolean: 5 +integer: 4 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +EOF + +test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' ' + test-parse-options --length=four -b -4 > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +cat > expect <<EOF +Callback: "not set", 1 +EOF + +test_expect_success 'OPT_CALLBACK() and callback errors work' ' + test_must_fail test-parse-options --no-length > output 2> output.err && + test_cmp expect output && + test_cmp expect.err output.err +' + +cat > expect <<EOF +boolean: 1 +integer: 23 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: no +dry run: no +EOF + +test_expect_success 'OPT_BIT() and OPT_SET_INT() work' ' + test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err && + test ! -s output.err && + test_cmp expect output +' + +# --or4 +# --no-or4 + test_done diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index cb1fbe5820..d8b7f2ffbc 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -74,7 +74,7 @@ $content" test -z "$content" || test_expect_success "--batch output of $type is correct" ' expect="$(maybe_remove_timestamp "$batch_output" $no_ts)" - actual="$(maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" no_ts)" + actual="$(maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" $no_ts)" if test "z$expect" = "z$actual" then : happy @@ -174,9 +174,27 @@ do ' done -test_expect_success "--batch-check for a non-existent object" ' - test "deadbeef missing" = \ - "$(echo_without_newline deadbeef | git cat-file --batch-check)" +test_expect_success "--batch-check for a non-existent named object" ' + test "foobar42 missing +foobar84 missing" = \ + "$( ( echo foobar42; echo_without_newline foobar84; ) | git cat-file --batch-check)" +' + +test_expect_success "--batch-check for a non-existent hash" ' + test "0000000000000000000000000000000000000042 missing +0000000000000000000000000000000000000084 missing" = \ + "$( ( echo 0000000000000000000000000000000000000042; + echo_without_newline 0000000000000000000000000000000000000084; ) \ + | git cat-file --batch-check)" +' + +test_expect_success "--batch for an existent and a non-existent hash" ' + test "$tag_sha1 tag $tag_size +$tag_content +0000000000000000000000000000000000000000 missing" = \ + "$( ( echo $tag_sha1; + echo_without_newline 0000000000000000000000000000000000000000; ) \ + | git cat-file --batch)" ' test_expect_success "--batch-check for an emtpy line" ' diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh index 5e4252a320..6c78c8bc9b 100755 --- a/t/t1301-shared-repo.sh +++ b/t/t1301-shared-repo.sh @@ -83,4 +83,19 @@ do done +test_expect_success 'git reflog expire honors core.sharedRepository' ' + git config core.sharedRepository group && + git reflog expire --all && + actual="$(ls -l .git/logs/refs/heads/master)" && + case "$actual" in + -rw-rw-*) + : happy + ;; + *) + echo Ooops, .git/logs/refs/heads/master is not 0662 [$actual] + false + ;; + esac +' + test_done diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index b8b7ab4103..f387d46f1a 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -42,6 +42,14 @@ test_expect_success "delete $m" ' ' rm -f .git/$m +test_expect_success "delete $m without oldvalue verification" " + git update-ref $m $A && + test $A = \$(cat .git/$m) && + git update-ref -d $m && + ! test -f .git/$m +" +rm -f .git/$m + test_expect_success \ "fail to create $n" \ "touch .git/$n_dir diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index d24a47d114..997002d4c4 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -5,7 +5,7 @@ test_description='test git rev-parse --parseopt' cat > expect.err <<EOF usage: some-command [options] <args>... - + some-command does foo and bar! -h, --help show the help @@ -13,7 +13,7 @@ usage: some-command [options] <args>... --bar ... some cool option --bar with an argument An option group Header - -C [...] option C with an optional argument + -C[...] option C with an optional argument Extras --extra1 line above used to cause a segfault but no longer does diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index df1fd6f86f..c851db8ca9 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -241,11 +241,11 @@ check_verify_failure 'disallow spaces in tag email' \ ############################################################ # 17. disallow missing tag timestamp -cat >tag.sig <<EOF +tr '_' ' ' >tag.sig <<EOF object $head type commit tag mytag -tagger T A Gger <tagger@example.com> +tagger T A Gger <tagger@example.com>__ EOF diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 2d3ee3b78c..54d99ed0c3 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -41,7 +41,7 @@ test_expect_success 'apply needs clean working directory' ' echo 4 > other-file && git add other-file && echo 5 > other-file && - test_must_fail git stash apply + test_must_fail git stash apply ' test_expect_success 'apply stashed changes' ' diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 3583e68e92..7fe853c20d 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -98,7 +98,7 @@ test_expect_success 'extra headers' ' sed -e "/^$/q" patch2 > hdrs2 && grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs2 && grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs2 - + ' test_expect_success 'extra headers without newlines' ' @@ -109,7 +109,7 @@ test_expect_success 'extra headers without newlines' ' sed -e "/^$/q" patch3 > hdrs3 && grep "^To: R. E. Cipient <rcipient@example.com>$" hdrs3 && grep "^Cc: S. E. Cipient <scipient@example.com>$" hdrs3 - + ' test_expect_success 'extra headers with multiple To:s' ' @@ -170,7 +170,7 @@ test_expect_success 'thread cover-letter' ' git checkout side && git format-patch --cover-letter --thread -o patches/ master && FIRST_MID=$(grep "Message-Id:" patches/0000-* | sed "s/^[^<]*\(<[^>]*>\).*$/\1/") && - for i in patches/0001-* patches/0002-* patches/0003-* + for i in patches/0001-* patches/0002-* patches/0003-* do grep "References: $FIRST_MID" $i && grep "In-Reply-To: $FIRST_MID" $i || break diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index ca0302f41b..b7cc6b28e6 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -62,16 +62,16 @@ EOF git update-index x -cat << EOF > x +tr '_' ' ' << EOF > x whitespace at beginning whitespace change white space in the middle -whitespace at end +whitespace at end__ unchanged line CR at end EOF -tr 'Q' '\015' << EOF > expect +tr 'Q_' '\015 ' << EOF > expect diff --git a/x b/x index d99af23..8b32fb5 100644 --- a/x @@ -84,7 +84,7 @@ index d99af23..8b32fb5 100644 + whitespace at beginning +whitespace change +white space in the middle -+whitespace at end ++whitespace at end__ unchanged line -CR at endQ +CR at end diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh index 0950250c9b..f07035ab7e 100755 --- a/t/t4016-diff-quote.sh +++ b/t/t4016-diff-quote.sh @@ -53,13 +53,13 @@ test_expect_success 'git diff --summary -M HEAD' ' ' cat >expect <<\EOF - pathname.1 => "Rpathname\twith HT.0" | 0 - pathname.3 => "Rpathname\nwith LF.0" | 0 - "pathname\twith HT.3" => "Rpathname\nwith LF.1" | 0 - pathname.2 => Rpathname with SP.0 | 0 - "pathname\twith HT.2" => Rpathname with SP.1 | 0 - pathname.0 => Rpathname.0 | 0 - "pathname\twith HT.0" => Rpathname.1 | 0 + pathname.1 => "Rpathname\twith HT.0" | 0 + pathname.3 => "Rpathname\nwith LF.0" | 0 + "pathname\twith HT.3" => "Rpathname\nwith LF.1" | 0 + pathname.2 => Rpathname with SP.0 | 0 + "pathname\twith HT.2" => Rpathname with SP.1 | 0 + pathname.0 => Rpathname.0 | 0 + "pathname\twith HT.0" => Rpathname.1 | 0 7 files changed, 0 insertions(+), 0 deletions(-) EOF test_expect_success 'git diff --stat -M HEAD' ' diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh index bd40a218cd..ff5fdf35f9 100755 --- a/t/t4109-apply-multifrag.sh +++ b/t/t4109-apply-multifrag.sh @@ -9,134 +9,10 @@ test_description='git apply test patches with multiple fragments. ' . ./test-lib.sh -# setup - -cat > patch1.patch <<\EOF -diff --git a/main.c b/main.c -new file mode 100644 ---- /dev/null -+++ b/main.c -@@ -0,0 +1,23 @@ -+#include <stdio.h> -+ -+int func(int num); -+void print_int(int num); -+ -+int main() { -+ int i; -+ -+ for (i = 0; i < 10; i++) { -+ print_int(func(i)); -+ } -+ -+ return 0; -+} -+ -+int func(int num) { -+ return num * num; -+} -+ -+void print_int(int num) { -+ printf("%d", num); -+} -+ -EOF -cat > patch2.patch <<\EOF -diff --git a/main.c b/main.c ---- a/main.c -+++ b/main.c -@@ -1,7 +1,9 @@ -+#include <stdlib.h> - #include <stdio.h> - - int func(int num); - void print_int(int num); -+void print_ln(); - - int main() { - int i; -@@ -10,6 +12,8 @@ - print_int(func(i)); - } - -+ print_ln(); -+ - return 0; - } - -@@ -21,3 +25,7 @@ - printf("%d", num); - } - -+void print_ln() { -+ printf("\n"); -+} -+ -EOF -cat > patch3.patch <<\EOF -diff --git a/main.c b/main.c ---- a/main.c -+++ b/main.c -@@ -1,9 +1,7 @@ --#include <stdlib.h> - #include <stdio.h> - - int func(int num); - void print_int(int num); --void print_ln(); - - int main() { - int i; -@@ -12,8 +10,6 @@ - print_int(func(i)); - } - -- print_ln(); -- - return 0; - } - -@@ -25,7 +21,3 @@ - printf("%d", num); - } - --void print_ln() { -- printf("\n"); --} -- -EOF -cat > patch4.patch <<\EOF -diff --git a/main.c b/main.c ---- a/main.c -+++ b/main.c -@@ -1,13 +1,14 @@ - #include <stdio.h> - - int func(int num); --void print_int(int num); -+int func2(int num); - - int main() { - int i; - - for (i = 0; i < 10; i++) { -- print_int(func(i)); -+ printf("%d", func(i)); -+ printf("%d", func3(i)); - } - - return 0; -@@ -17,7 +18,7 @@ - return num * num; - } - --void print_int(int num) { -- printf("%d", num); -+int func2(int num) { -+ return num * num * num; - } - -EOF +cp ../t4109/patch1.patch . +cp ../t4109/patch2.patch . +cp ../t4109/patch3.patch . +cp ../t4109/patch4.patch . test_expect_success "S = git apply (1)" \ 'git apply patch1.patch patch2.patch' diff --git a/t/t4109/patch1.patch b/t/t4109/patch1.patch new file mode 100644 index 0000000000..1d411fc3cc --- /dev/null +++ b/t/t4109/patch1.patch @@ -0,0 +1,28 @@ +diff --git a/main.c b/main.c +new file mode 100644 +--- /dev/null ++++ b/main.c +@@ -0,0 +1,23 @@ ++#include <stdio.h> ++ ++int func(int num); ++void print_int(int num); ++ ++int main() { ++ int i; ++ ++ for (i = 0; i < 10; i++) { ++ print_int(func(i)); ++ } ++ ++ return 0; ++} ++ ++int func(int num) { ++ return num * num; ++} ++ ++void print_int(int num) { ++ printf("%d", num); ++} ++ diff --git a/t/t4109/patch2.patch b/t/t4109/patch2.patch new file mode 100644 index 0000000000..8c6b06d536 --- /dev/null +++ b/t/t4109/patch2.patch @@ -0,0 +1,30 @@ +diff --git a/main.c b/main.c +--- a/main.c ++++ b/main.c +@@ -1,7 +1,9 @@ ++#include <stdlib.h> + #include <stdio.h> + + int func(int num); + void print_int(int num); ++void print_ln(); + + int main() { + int i; +@@ -10,6 +12,8 @@ + print_int(func(i)); + } + ++ print_ln(); ++ + return 0; + } + +@@ -21,3 +25,7 @@ + printf("%d", num); + } + ++void print_ln() { ++ printf("\n"); ++} ++ diff --git a/t/t4109/patch3.patch b/t/t4109/patch3.patch new file mode 100644 index 0000000000..d696c55a75 --- /dev/null +++ b/t/t4109/patch3.patch @@ -0,0 +1,31 @@ +cat > patch3.patch <<\EOF +diff --git a/main.c b/main.c +--- a/main.c ++++ b/main.c +@@ -1,9 +1,7 @@ +-#include <stdlib.h> + #include <stdio.h> + + int func(int num); + void print_int(int num); +-void print_ln(); + + int main() { + int i; +@@ -12,8 +10,6 @@ + print_int(func(i)); + } + +- print_ln(); +- + return 0; + } + +@@ -25,7 +21,3 @@ + printf("%d", num); + } + +-void print_ln() { +- printf("\n"); +-} +- diff --git a/t/t4109/patch4.patch b/t/t4109/patch4.patch new file mode 100644 index 0000000000..4b085909b1 --- /dev/null +++ b/t/t4109/patch4.patch @@ -0,0 +1,30 @@ +diff --git a/main.c b/main.c +--- a/main.c ++++ b/main.c +@@ -1,13 +1,14 @@ + #include <stdio.h> + + int func(int num); +-void print_int(int num); ++int func2(int num); + + int main() { + int i; + + for (i = 0; i < 10; i++) { +- print_int(func(i)); ++ printf("%d", func(i)); ++ printf("%d", func3(i)); + } + + return 0; +@@ -17,7 +18,7 @@ + return num * num; + } + +-void print_int(int num) { +- printf("%d", num); ++int func2(int num) { ++ return num * num * num; + } + diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh index b540f7295a..3c73a783a7 100755 --- a/t/t4119-apply-config.sh +++ b/t/t4119-apply-config.sh @@ -19,12 +19,12 @@ test_expect_success setup ' ' # Also handcraft GNU diff output; note this has trailing whitespace. -cat >gpatch.file <<\EOF && +tr '_' ' ' >gpatch.file <<\EOF && --- file1 2007-02-21 01:04:24.000000000 -0800 +++ file1+ 2007-02-21 01:07:44.000000000 -0800 @@ -1 +1 @@ -A -+B ++B_ EOF sed -e 's|file1|sub/&|' gpatch.file >gpatch-sub.file && diff --git a/t/t4126-apply-empty.sh b/t/t4126-apply-empty.sh index 0cfd47cfcf..ceb6a79fe0 100755 --- a/t/t4126-apply-empty.sh +++ b/t/t4126-apply-empty.sh @@ -26,7 +26,6 @@ test_expect_success setup ' test_expect_success 'apply empty' ' git reset --hard && - >empty && rm -f missing && git apply patch0 && test_cmp expect empty @@ -34,7 +33,6 @@ test_expect_success 'apply empty' ' test_expect_success 'apply --index empty' ' git reset --hard && - >empty && rm -f missing && git apply --index patch0 && test_cmp expect empty && @@ -43,7 +41,6 @@ test_expect_success 'apply --index empty' ' test_expect_success 'apply create' ' git reset --hard && - >empty && rm -f missing && git apply patch1 && test_cmp expect missing @@ -51,7 +48,6 @@ test_expect_success 'apply create' ' test_expect_success 'apply --index create' ' git reset --hard && - >empty && rm -f missing && git apply --index patch1 && test_cmp expect missing && diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 722ae96cd5..bc982607d0 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -110,7 +110,7 @@ test_expect_success 'am applies patch correctly' ' GIT_AUTHOR_NAME="Another Thor" GIT_AUTHOR_EMAIL="a.thor@example.com" -GIT_COMMITTER_NAME="Co M Miter" +GIT_COMMITTER_NAME="Co M Miter" GIT_COMMITTER_EMAIL="c.miter@example.com" export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh index 9b0baac8db..3f1e25d921 100755 --- a/t/t5000-tar-tree.sh +++ b/t/t5000-tar-tree.sh @@ -45,6 +45,11 @@ test_expect_success \ (cd a && find .) | sort >a.lst' test_expect_success \ + 'add ignored file' \ + 'echo ignore me >a/ignored && + echo ignored export-ignore >.gitattributes' + +test_expect_success \ 'add files to repository' \ 'find a -type f | xargs git update-index --add && find a -type l | xargs git update-index --add && @@ -54,6 +59,10 @@ test_expect_success \ git commit-tree $treeid </dev/null)' test_expect_success \ + 'remove ignored file' \ + 'rm a/ignored' + +test_expect_success \ 'git archive' \ 'git archive HEAD >b.tar' diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 09fd917672..ecec591634 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -162,4 +162,18 @@ test_expect_success \ '[index v2] 5) pack-objects refuses to reuse corrupted data' \ '! git pack-objects test-5 <obj-list' +test_expect_success \ + '[index v2] 6) verify-pack detects CRC mismatch' \ + 'rm -f .git/objects/pack/* && + git-index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" && + git verify-pack ".git/objects/pack/pack-${pack1}.pack" && + chmod +w ".git/objects/pack/pack-${pack1}.idx" && + dd if=/dev/zero of=".git/objects/pack/pack-${pack1}.idx" conv=notrunc \ + bs=1 count=4 seek=$((8 + 256 * 4 + `wc -l <obj-list` * 20 + 0)) && + ( while read obj + do git cat-file -p $obj >/dev/null || exit 1 + done <obj-list ) && + err=$(! git verify-pack ".git/objects/pack/pack-${pack1}.pack" 2>&1) && + echo "$err" | grep "CRC mismatch"' + test_done diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh new file mode 100755 index 0000000000..b0f5693482 --- /dev/null +++ b/t/t5303-pack-corruption-resilience.sh @@ -0,0 +1,194 @@ +#!/bin/sh +# +# Copyright (c) 2008 Nicolas Pitre +# + +test_description='resilience to pack corruptions with redundant objects' +. ./test-lib.sh + +# Note: the test objects are created with knowledge of their pack encoding +# to ensure good code path coverage, and to facilitate direct alteration +# later on. The assumed characteristics are: +# +# 1) blob_2 is a delta with blob_1 for base and blob_3 is a delta with blob2 +# for base, such that blob_3 delta depth is 2; +# +# 2) the bulk of object data is uncompressible so the text part remains +# visible; +# +# 3) object header is always 2 bytes. + +create_test_files() { + test-genrandom "foo" 2000 > file_1 && + test-genrandom "foo" 1800 > file_2 && + test-genrandom "foo" 1800 > file_3 && + echo " base " >> file_1 && + echo " delta1 " >> file_2 && + echo " delta delta2 " >> file_3 && + test-genrandom "bar" 150 >> file_2 && + test-genrandom "baz" 100 >> file_3 +} + +create_new_pack() { + rm -rf .git && + git init && + blob_1=`git hash-object -t blob -w file_1` && + blob_2=`git hash-object -t blob -w file_2` && + blob_3=`git hash-object -t blob -w file_3` && + pack=`printf "$blob_1\n$blob_2\n$blob_3\n" | + git pack-objects $@ .git/objects/pack/pack` && + pack=".git/objects/pack/pack-${pack}" && + git verify-pack -v ${pack}.pack +} + +do_corrupt_object() { + ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` && + ofs=$(($ofs + $2)) && + chmod +w ${pack}.pack && + dd if=/dev/zero of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs && + test_must_fail git verify-pack ${pack}.pack +} + +test_expect_success \ + 'initial setup validation' \ + 'create_test_files && + create_new_pack && + git prune-packed && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in header of first object' \ + 'do_corrupt_object $blob_1 0 && + test_must_fail git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and loose copy of first delta allows for partial recovery' \ + 'git prune-packed && + test_must_fail git cat-file blob $blob_2 > /dev/null && + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + test_must_fail git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in data of first object' \ + 'create_new_pack && + git prune-packed && + chmod +w ${pack}.pack && + perl -i -pe "s/ base /abcdef/" ${pack}.pack && + test_must_fail git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and loose copy of second object allows for partial recovery' \ + 'git prune-packed && + test_must_fail git cat-file blob $blob_2 > /dev/null && + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + test_must_fail git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in header of first delta' \ + 'create_new_pack && + git prune-packed && + do_corrupt_object $blob_2 0 && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'create corruption in data of first delta' \ + 'create_new_pack && + git prune-packed && + chmod +w ${pack}.pack && + perl -i -pe "s/ delta1 /abcdefgh/" ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \ + 'create_new_pack && + git prune-packed && + do_corrupt_object $blob_2 2 && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + 'corruption in delta base reference of first delta (OBJ_OFS_DELTA)' \ + 'create_new_pack --delta-base-offset && + git prune-packed && + do_corrupt_object $blob_2 2 && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and a redundant pack allows for full recovery too' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + git hash-object -t blob -w file_2 && + printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack && + git prune-packed && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_done diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 0d7ed1f99b..1e192a2207 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -138,6 +138,25 @@ test_expect_success 'show' ' test_cmp expect output) ' +cat > test/expect << EOF +* remote origin + URL: $(pwd)/one/.git + Remote branch merged with 'git pull' while on branch master + master + Tracked remote branches + master side + Local branches pushed with 'git push' + master:upstream +refs/tags/lastbackup +EOF + +test_expect_success 'show -n' ' + (mv one one.unreachable && + cd test && + git remote show -n origin > output && + mv ../one.unreachable ../one && + test_cmp expect output) +' + test_expect_success 'prune' ' (cd one && git branch -m side side2) && @@ -148,6 +167,24 @@ test_expect_success 'prune' ' ! git rev-parse refs/remotes/origin/side) ' +cat > test/expect << EOF +Pruning origin +URL: $(pwd)/one/.git + * [would prune] origin/side2 +EOF + +test_expect_success 'prune --dry-run' ' + (cd one && + git branch -m side2 side) && + (cd test && + git remote prune --dry-run origin > output && + git rev-parse refs/remotes/origin/side2 && + ! git rev-parse refs/remotes/origin/side && + (cd ../one && + git branch -m side side2) && + test_cmp expect output) +' + test_expect_success 'add --mirror && prune' ' (mkdir mirror && cd mirror && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 6946557c67..df7750f7d1 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -37,7 +37,8 @@ test_expect_success "clone and setup child repos" ' echo "Pull: refs/heads/one:refs/heads/one" } >.git/remotes/two && cd .. && - git clone . bundle + git clone . bundle && + git clone . seven ' test_expect_success "fetch test" ' @@ -295,4 +296,11 @@ test_expect_success 'configured fetch updates tracking' ' ) ' +test_expect_success 'pushing nonexistent branch by mistake should not segv' ' + + cd "$D" && + test_must_fail git push seven no:no + +' + test_done diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh index 3def75eeb2..8becbc3f38 100755 --- a/t/t5515-fetch-merge-logic.sh +++ b/t/t5515-fetch-merge-logic.sh @@ -142,9 +142,12 @@ do set x $cmd; shift git symbolic-ref HEAD refs/heads/$1 ; shift rm -f .git/FETCH_HEAD - rm -f .git/refs/heads/* - rm -f .git/refs/remotes/rem/* - rm -f .git/refs/tags/* + git for-each-ref \ + refs/heads refs/remotes/rem refs/tags | + while read val type refname + do + git update-ref -d "$refname" "$val" + done git fetch "$@" >/dev/null cat .git/FETCH_HEAD } >"$actual_f" && diff --git a/t/t5540-http-push.sh b/t/t5540-http-push.sh index 7372439164..f15dd03e4d 100755 --- a/t/t5540-http-push.sh +++ b/t/t5540-http-push.sh @@ -38,7 +38,7 @@ test_expect_success 'setup remote repository' ' cd - && mv test_repo.git $HTTPD_DOCUMENT_ROOT_PATH ' - + test_expect_success 'clone remote repository' ' cd "$ROOT_PATH" && git clone $HTTPD_URL/test_repo.git test_repo_clone diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 593d1a3877..b642fb260b 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -30,4 +30,26 @@ test_expect_success 'clone checks out files' ' ' +test_expect_success 'clone respects GIT_WORK_TREE' ' + + GIT_WORK_TREE=worktree git clone src bare && + test -f bare/config && + test -f worktree/file + +' + +test_expect_success 'clone creates intermediate directories' ' + + git clone src long/path/to/dst && + test -f long/path/to/dst/file + +' + +test_expect_success 'clone creates intermediate directories for bare repo' ' + + git clone --bare src long/path/to/bare/dst && + test -f long/path/to/bare/dst/config + +' + test_done diff --git a/t/t6033-merge-crlf.sh b/t/t6033-merge-crlf.sh new file mode 100755 index 0000000000..75d9602de4 --- /dev/null +++ b/t/t6033-merge-crlf.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +append_cr () { + sed -e 's/$/Q/' | tr Q '\015' +} + +remove_cr () { + tr '\015' Q | sed -e 's/Q$//' +} + +test_description='merge conflict in crlf repo + + b---M + / / + initial---a + +' + +. ./test-lib.sh + +test_expect_success setup ' + git config core.autocrlf true && + echo foo | append_cr >file && + git add file && + git commit -m "Initial" && + git tag initial && + git branch side && + echo line from a | append_cr >file && + git commit -m "add line from a" file && + git tag a && + git checkout side && + echo line from b | append_cr >file && + git commit -m "add line from b" file && + git tag b && + git checkout master +' + +test_expect_success 'Check "ours" is CRLF' ' + git reset --hard initial && + git merge side -s ours && + cat file | remove_cr | append_cr >file.temp && + test_cmp file file.temp +' + +test_expect_success 'Check that conflict file is CRLF' ' + git reset --hard a && + test_must_fail git merge side && + cat file | remove_cr | append_cr >file.temp && + test_cmp file file.temp +' + +test_done diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index ed871a6b4d..c25eff9e46 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -212,7 +212,11 @@ test_expect_success 'do not fire editor in the presence of conflicts' ' # Must fail due to conflict test_must_fail git cherry-pick -n master && echo "editor not started" >.git/result && - test_must_fail GIT_EDITOR="$(pwd)/.git/FAKE_EDITOR" git commit && + ( + GIT_EDITOR="$(pwd)/.git/FAKE_EDITOR" && + export GIT_EDITOR && + test_must_fail git commit + ) && test "$(cat .git/result)" = "editor not started" ' diff --git a/t/t7502-status.sh b/t/t7502-status.sh index 80a438d4d9..38a48b57c7 100755 --- a/t/t7502-status.sh +++ b/t/t7502-status.sh @@ -67,6 +67,104 @@ test_expect_success 'status (2)' ' ' +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files not listed (use -u option to show untracked files) +EOF +test_expect_success 'status -uno' ' + mkdir dir3 && + : > dir3/untracked1 && + : > dir3/untracked2 && + git status -uno >output && + test_cmp expect output +' + +test_expect_success 'status (status.showUntrackedFiles no)' ' + git config status.showuntrackedfiles no + git status >output && + test_cmp expect output +' + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# dir3/ +# expect +# output +# untracked +EOF +test_expect_success 'status -unormal' ' + git status -unormal >output && + test_cmp expect output +' + +test_expect_success 'status (status.showUntrackedFiles normal)' ' + git config status.showuntrackedfiles normal + git status >output && + test_cmp expect output +' + +cat >expect <<EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# dir3/untracked1 +# dir3/untracked2 +# expect +# output +# untracked +EOF +test_expect_success 'status -uall' ' + git status -uall >output && + test_cmp expect output +' +test_expect_success 'status (status.showUntrackedFiles all)' ' + git config status.showuntrackedfiles all + git status >output && + rm -rf dir3 && + git config --unset status.showuntrackedfiles && + test_cmp expect output +' + cat > expect << \EOF # On branch master # Changes to be committed: diff --git a/t/t9122-git-svn-author.sh b/t/t9122-git-svn-author.sh index 8c58f0b8d7..1190576a65 100755 --- a/t/t9122-git-svn-author.sh +++ b/t/t9122-git-svn-author.sh @@ -64,7 +64,21 @@ test_expect_success 'interact with it via git-svn' ' # Make sure --add-author-from with --use-log-author affected # the authorship information - grep "^Author: A U Thor " actual.4 + grep "^Author: A U Thor " actual.4 && + + # Make sure there are no commit messages with excess blank lines + test $(grep "^ " actual.2 | wc -l) = 3 && + test $(grep "^ " actual.3 | wc -l) = 5 && + test $(grep "^ " actual.4 | wc -l) = 5 && + + # Make sure there are no svn commit messages with excess blank lines + ( + cd work.svn && + svn up && + + test $(svn log -r2:2 | wc -l) = 5 && + test $(svn log -r4:4 | wc -l) = 7 + ) ' test_done diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh new file mode 100755 index 0000000000..c18878fad1 --- /dev/null +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Copyright (c) 2008 Jan Krüger +# + +test_description='git-svn respects rewriteRoot during rebuild' + +. ./lib-git-svn.sh + +mkdir import +cd import + touch foo + svn import -m 'import for git-svn' . "$svnrepo" >/dev/null +cd .. +rm -rf import + +test_expect_success 'init, fetch and checkout repository' ' + git svn init --rewrite-root=http://invalid.invalid/ "$svnrepo" && + git svn fetch + git checkout -b mybranch remotes/git-svn + ' + +test_expect_success 'remove rev_map' ' + rm "$GIT_SVN_DIR"/.rev_map.* + ' + +test_expect_success 'rebuild rev_map' ' + git svn rebase >/dev/null + ' + +test_done + diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh index f09bfb1117..f1bc5ceef0 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9301-fast-export.sh @@ -78,6 +78,29 @@ test_expect_success 'iso-8859-1' ' git cat-file commit i18n | grep "Áéí óú") ' +test_expect_success 'import/export-marks' ' + + git checkout -b marks master && + git fast-export --export-marks=tmp-marks HEAD && + test -s tmp-marks && + test $(wc -l < tmp-marks) -eq 3 && + test $( + git fast-export --import-marks=tmp-marks\ + --export-marks=tmp-marks HEAD | + grep ^commit | + wc -l) \ + -eq 0 && + echo change > file && + git commit -m "last commit" file && + test $( + git fast-export --import-marks=tmp-marks \ + --export-marks=tmp-marks HEAD | + grep ^commit\ | + wc -l) \ + -eq 1 && + test $(wc -l < tmp-marks) -eq 4 + +' cat > signed-tag-import << EOF tag sign-your-name diff --git a/t/t9700-perl-git.sh b/t/t9700-perl-git.sh new file mode 100755 index 0000000000..b2fb9ece9c --- /dev/null +++ b/t/t9700-perl-git.sh @@ -0,0 +1,39 @@ +#!/bin/sh +# +# Copyright (c) 2008 Lea Wiemann +# + +test_description='perl interface (Git.pm)' +. ./test-lib.sh + +# set up test repository + +test_expect_success \ + 'set up test repository' \ + 'echo "test file 1" > file1 && + echo "test file 2" > file2 && + mkdir directory1 && + echo "in directory1" >> directory1/file && + mkdir directory2 && + echo "in directory2" >> directory2/file && + git add . && + git commit -m "first commit" && + + echo "changed file 1" > file1 && + git commit -a -m "second commit" && + + git-config --add color.test.slot1 green && + git-config --add test.string value && + git-config --add test.dupstring value1 && + git-config --add test.dupstring value2 && + git-config --add test.booltrue true && + git-config --add test.boolfalse no && + git-config --add test.boolother other && + git-config --add test.int 2k + ' + +test_external_without_stderr \ + 'Perl API' \ + perl ../t9700/test.pl + +test_done diff --git a/t/t9700/test.pl b/t/t9700/test.pl new file mode 100755 index 0000000000..4d2312548a --- /dev/null +++ b/t/t9700/test.pl @@ -0,0 +1,100 @@ +#!/usr/bin/perl +use lib (split(/:/, $ENV{GITPERLLIB})); + +use 5.006002; +use warnings; +use strict; + +use Test::More qw(no_plan); + +use Cwd; +use File::Basename; +use File::Temp; + +BEGIN { use_ok('Git') } + +# set up +our $repo_dir = "trash directory"; +our $abs_repo_dir = Cwd->cwd; +die "this must be run by calling the t/t97* shell script(s)\n" + if basename(Cwd->cwd) ne $repo_dir; +ok(our $r = Git->repository(Directory => "."), "open repository"); + +# config +is($r->config("test.string"), "value", "config scalar: string"); +is_deeply([$r->config("test.dupstring")], ["value1", "value2"], + "config array: string"); +is($r->config("test.nonexistent"), undef, "config scalar: nonexistent"); +is_deeply([$r->config("test.nonexistent")], [], "config array: nonexistent"); +is($r->config_int("test.int"), 2048, "config_int: integer"); +is($r->config_int("test.nonexistent"), undef, "config_int: nonexistent"); +ok($r->config_bool("test.booltrue"), "config_bool: true"); +ok(!$r->config_bool("test.boolfalse"), "config_bool: false"); +our $ansi_green = "\x1b[32m"; +is($r->get_color("color.test.slot1", "red"), $ansi_green, "get_color"); +# Cannot test $r->get_colorbool("color.foo")) because we do not +# control whether our STDOUT is a terminal. + +# Failure cases for config: +# Save and restore STDERR; we will probably extract this into a +# "dies_ok" method and possibly move the STDERR handling to Git.pm. +open our $tmpstderr, ">&", STDERR or die "cannot save STDERR"; close STDERR; +eval { $r->config("test.dupstring") }; +ok($@, "config: duplicate entry in scalar context fails"); +eval { $r->config_bool("test.boolother") }; +ok($@, "config_bool: non-boolean values fail"); +open STDERR, ">&", $tmpstderr or die "cannot restore STDERR"; + +# ident +like($r->ident("aUthor"), qr/^A U Thor <author\@example.com> [0-9]+ \+0000$/, + "ident scalar: author (type)"); +like($r->ident("cOmmitter"), qr/^C O Mitter <committer\@example.com> [0-9]+ \+0000$/, + "ident scalar: committer (type)"); +is($r->ident("invalid"), "invalid", "ident scalar: invalid ident string (no parsing)"); +my ($name, $email, $time_tz) = $r->ident('author'); +is_deeply([$name, $email], ["A U Thor", "author\@example.com"], + "ident array: author"); +like($time_tz, qr/[0-9]+ \+0000/, "ident array: author"); +is_deeply([$r->ident("Name <email> 123 +0000")], ["Name", "email", "123 +0000"], + "ident array: ident string"); +is_deeply([$r->ident("invalid")], [], "ident array: invalid ident string"); + +# ident_person +is($r->ident_person("aUthor"), "A U Thor <author\@example.com>", + "ident_person: author (type)"); +is($r->ident_person("Name <email> 123 +0000"), "Name <email>", + "ident_person: ident string"); +is($r->ident_person("Name", "email", "123 +0000"), "Name <email>", + "ident_person: array"); + +# objects and hashes +ok(our $file1hash = $r->command_oneline('rev-parse', "HEAD:file1"), "(get file hash)"); +our $tmpfile = File::Temp->new; +is($r->cat_blob($file1hash, $tmpfile), 15, "cat_blob: size"); +our $blobcontents; +{ local $/; seek $tmpfile, 0, 0; $blobcontents = <$tmpfile>; } +is($blobcontents, "changed file 1\n", "cat_blob: data"); +seek $tmpfile, 0, 0; +is(Git::hash_object("blob", $tmpfile), $file1hash, "hash_object: roundtrip"); +$tmpfile = File::Temp->new(); +print $tmpfile my $test_text = "test blob, to be inserted\n"; +like(our $newhash = $r->hash_and_insert_object($tmpfile), qr/[0-9a-fA-F]{40}/, + "hash_and_insert_object: returns hash"); +$tmpfile = File::Temp->new; +is($r->cat_blob($newhash, $tmpfile), length $test_text, "cat_blob: roundtrip size"); +{ local $/; seek $tmpfile, 0, 0; $blobcontents = <$tmpfile>; } +is($blobcontents, $test_text, "cat_blob: roundtrip data"); + +# paths +is($r->repo_path, "./.git", "repo_path"); +is($r->wc_path, $abs_repo_dir . "/", "wc_path"); +is($r->wc_subdir, "", "wc_subdir initial"); +$r->wc_chdir("directory1"); +is($r->wc_subdir, "directory1", "wc_subdir after wc_chdir"); +TODO: { + local $TODO = "commands do not work after wc_chdir"; + # Failure output is active even in non-verbose mode and thus + # annoying. Hence we skip these tests as long as they fail. + todo_skip 'config after wc_chdir', 1; + is($r->config("color.string"), "value", "config after wc_chdir"); +} diff --git a/t/test-lib.sh b/t/test-lib.sh index 2ad3f4a126..4010110010 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -80,6 +80,8 @@ do debug=t; shift ;; -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate) immediate=t; shift ;; + -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests) + export GIT_TEST_LONG=t; shift ;; -h|--h|--he|--hel|--help) help=t; shift ;; -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) @@ -169,7 +171,7 @@ trap 'die' exit # environment variables to work around this. # # In particular, quoting isn't enough, as the path may contain the same quote -# that we're using. +# that we're using. test_set_editor () { FAKE_EDITOR="$1" export FAKE_EDITOR @@ -304,6 +306,64 @@ test_expect_code () { echo >&3 "" } +# test_external runs external test scripts that provide continuous +# test output about their progress, and succeeds/fails on +# zero/non-zero exit code. It outputs the test output on stdout even +# in non-verbose mode, and announces the external script with "* run +# <n>: ..." before running it. When providing relative paths, keep in +# mind that all scripts run in "trash directory". +# Usage: test_external description command arguments... +# Example: test_external 'Perl API' perl ../path/to/test.pl +test_external () { + test "$#" -eq 3 || + error >&5 "bug in the test script: not 3 parameters to test_external" + descr="$1" + shift + if ! test_skip "$descr" "$@" + then + # Announce the script to reduce confusion about the + # test output that follows. + say_color "" " run $(expr "$test_count" + 1): $descr ($*)" + # Run command; redirect its stderr to &4 as in + # test_run_, but keep its stdout on our stdout even in + # non-verbose mode. + "$@" 2>&4 + if [ "$?" = 0 ] + then + test_ok_ "$descr" + else + test_failure_ "$descr" "$@" + fi + fi +} + +# Like test_external, but in addition tests that the command generated +# no output on stderr. +test_external_without_stderr () { + # The temporary file has no (and must have no) security + # implications. + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi + stderr="$tmp/git-external-stderr.$$.tmp" + test_external "$@" 4> "$stderr" + [ -f "$stderr" ] || error "Internal error: $stderr disappeared." + descr="no stderr: $1" + shift + say >&3 "expecting no stderr from previous command" + if [ ! -s "$stderr" ]; then + rm "$stderr" + test_ok_ "$descr" + else + if [ "$verbose" = t ]; then + output=`echo; echo Stderr is:; cat "$stderr"` + else + output= + fi + # rm first in case test_failure exits. + rm "$stderr" + test_failure_ "$descr" "$@" "$output" + fi +} + # This is not among top-level (test_expect_success | test_expect_failure) # but is a prefix that can be used in the test script, like: # @@ -398,7 +458,7 @@ test_done () { } # Test the binaries we have just built. The tests are kept in -# t/ subdirectory and are run in trash subdirectory. +# t/ subdirectory and are run in 'trash directory' subdirectory. TEST_DIRECTORY=$(pwd) PATH=$TEST_DIRECTORY/..:$PATH GIT_EXEC_PATH=$(pwd)/.. |