diff options
Diffstat (limited to 't')
89 files changed, 3380 insertions, 396 deletions
diff --git a/t/Makefile b/t/Makefile index 25c559bb49..f9de24b4d2 100644 --- a/t/Makefile +++ b/t/Makefile @@ -3,6 +3,7 @@ # Copyright (c) 2005 Junio C Hamano # +-include ../config.mak.autogen -include ../config.mak #GIT_TEST_OPTS=--verbose --debug @@ -35,7 +36,9 @@ aggregate-results-and-cleanup: $(T) $(MAKE) clean aggregate-results: - '$(SHELL_PATH_SQ)' ./aggregate-results.sh test-results/t*-* + for f in test-results/t*-*; do \ + echo "$$f"; \ + done | '$(SHELL_PATH_SQ)' ./aggregate-results.sh # we can test NO_OPTIMIZE_COMMITS independently of LC_ALL full-svn-test: @@ -84,6 +84,12 @@ appropriately before running "make". implied by other options like --valgrind and GIT_TEST_INSTALLED. +--root=<directory>:: + Create "trash" directories used to store all temporary data during + testing under <directory>, instead of the t/ directory. + Using this option with a RAM-based filesystem (such as tmpfs) + can massively speed up the test suite. + You can also set the GIT_TEST_INSTALLED environment variable to the bindir of an existing git installation to test that installation. You still need to have built this git sandbox, from which various diff --git a/t/aggregate-results.sh b/t/aggregate-results.sh index d5bab75d7d..d206b7c4cf 100755 --- a/t/aggregate-results.sh +++ b/t/aggregate-results.sh @@ -6,7 +6,7 @@ failed=0 broken=0 total=0 -for file +while read file do while read type value do diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh index 5a734b1b7b..b70b891b62 100644 --- a/t/gitweb-lib.sh +++ b/t/gitweb-lib.sh @@ -19,9 +19,9 @@ our \$site_name = '[localhost]'; our \$site_header = ''; our \$site_footer = ''; our \$home_text = 'indextext.html'; -our @stylesheets = ('file:///$TEST_DIRECTORY/../gitweb/gitweb.css'); -our \$logo = 'file:///$TEST_DIRECTORY/../gitweb/git-logo.png'; -our \$favicon = 'file:///$TEST_DIRECTORY/../gitweb/git-favicon.png'; +our @stylesheets = ('file:///$TEST_DIRECTORY/../gitweb/static/gitweb.css'); +our \$logo = 'file:///$TEST_DIRECTORY/../gitweb/static/git-logo.png'; +our \$favicon = 'file:///$TEST_DIRECTORY/../gitweb/static/git-favicon.png'; our \$projects_list = ''; our \$export_ok = ''; our \$strict_export = ''; diff --git a/t/t6000lib.sh b/t/lib-t6000.sh index 985d517a1c..ea25dd89e5 100644 --- a/t/t6000lib.sh +++ b/t/lib-t6000.sh @@ -91,7 +91,7 @@ check_output() shift 1 if eval "$*" | entag > $_name.actual then - diff $_name.expected $_name.actual + test_cmp $_name.expected $_name.actual else return 1; fi diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index f4ca4fc85c..f2c73369a5 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -73,6 +73,27 @@ then exit 1 fi +clean=no +test_expect_success 'tests clean up after themselves' ' + test_when_finished clean=yes +' + +cleaner=no +test_expect_code 1 'tests clean up even after a failure' ' + test_when_finished cleaner=yes && + (exit 1) +' + +if test $clean$cleaner != yesyes +then + say "bug in test framework: cleanup commands do not work reliably" + exit 1 +fi + +test_expect_code 2 'failure to clean up causes the test to fail' ' + test_when_finished "(exit 2)" +' + ################################################################ # Basics of the basics @@ -280,7 +301,7 @@ $expectfilter >expected <<\EOF EOF test_expect_success \ 'validate git diff-files output for a know cache/work tree state.' \ - 'git diff-files >current && diff >/dev/null -b current expected' + 'git diff-files >current && test_cmp current expected >/dev/null' test_expect_success \ 'git update-index --refresh should succeed.' \ diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 675773479a..7c0a698b92 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -310,4 +310,18 @@ test_expect_success POSIXPERM 'init notices EPERM' ' ) ' +test_expect_success 'init creates a new bare directory with global --bare' ' + rm -rf newdir && + git --bare init newdir && + test -d newdir/refs +' + +test_expect_success 'init prefers command line to GIT_DIR' ' + rm -rf newdir && + mkdir otherdir && + GIT_DIR=otherdir git --bare init newdir && + test -d newdir/refs && + ! test -d otherdir/refs +' + test_done diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 1c77192eb3..53bd7fcc4a 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -20,8 +20,12 @@ test_expect_success 'setup' ' mkdir -p a/b/d a/c && ( + echo "[attr]notest !test" echo "f test=f" echo "a/i test=a/i" + echo "onoff test -test" + echo "offon -test test" + echo "no notest" ) >.gitattributes && ( echo "g test=a/g" && @@ -30,6 +34,7 @@ test_expect_success 'setup' ' ( echo "h test=a/b/h" && echo "d/* test=a/b/d/*" + echo "d/yes notest" ) >a/b/.gitattributes ' @@ -44,6 +49,11 @@ test_expect_success 'attribute test' ' attr_check b/g unspecified && attr_check a/b/h a/b/h && attr_check a/b/d/g "a/b/d/*" + attr_check onoff unset + attr_check offon set + attr_check no unspecified + attr_check a/b/d/no "a/b/d/*" + attr_check a/b/d/yes unspecified ' @@ -58,6 +68,11 @@ a/b/g: test: a/b/g b/g: test: unspecified a/b/h: test: a/b/h a/b/d/g: test: a/b/d/* +onoff: test: unset +offon: test: set +no: test: unspecified +a/b/d/no: test: a/b/d/* +a/b/d/yes: test: unspecified EOF sed -e "s/:.*//" < expect | git check-attr --stdin test > actual && diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index c3e7e322a8..234a94f3e6 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -453,5 +453,57 @@ test_expect_success 'invalid .gitattributes (must not crash)' ' git diff ' +# Some more tests here to add new autocrlf functionality. +# We want to have a known state here, so start a bit from scratch + +test_expect_success 'setting up for new autocrlf tests' ' + git config core.autocrlf false && + git config core.safecrlf false && + rm -rf .????* * && + for w in I am all LF; do echo $w; done >alllf && + for w in Oh here is CRLFQ in text; do echo $w; done | q_to_cr >mixed && + for w in I am all CRLF; do echo $w; done | append_cr >allcrlf && + git add -A . && + git commit -m "alllf, allcrlf and mixed only" && + git tag -a -m "message" autocrlf-checkpoint +' + +test_expect_success 'report no change after setting autocrlf' ' + git config core.autocrlf true && + touch * && + git diff --exit-code +' + +test_expect_success 'files are clean after checkout' ' + rm * && + git checkout -f && + git diff --exit-code +' + +cr_to_Q_no_NL () { + tr '\015' Q | tr -d '\012' +} + +test_expect_success 'LF only file gets CRLF with autocrlf' ' + test "$(cr_to_Q_no_NL < alllf)" = "IQamQallQLFQ" +' + +test_expect_success 'Mixed file is still mixed with autocrlf' ' + test "$(cr_to_Q_no_NL < mixed)" = "OhhereisCRLFQintext" +' + +test_expect_success 'CRLF only file has CRLF with autocrlf' ' + test "$(cr_to_Q_no_NL < allcrlf)" = "IQamQallQCRLFQ" +' + +test_expect_success 'New CRLF file gets LF in repo' ' + tr -d "\015" < alllf | append_cr > alllf2 && + git add alllf2 && + git commit -m "alllf2 added" && + git config core.autocrlf false && + rm * && + git checkout -f && + test_cmp alllf alllf2 +' test_done diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index 6cb8d60ea2..828e35baf7 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -65,17 +65,21 @@ test_expect_success expanded_in_repo ' echo "\$Id:NoSpaceAtFront \$" echo "\$Id:NoSpaceAtEitherEnd\$" echo "\$Id: NoTerminatingSymbol" + echo "\$Id: Foreign Commit With Spaces \$" + echo "\$Id: NoTerminatingSymbolAtEOF" } > expanded-keywords && { echo "File with expanded keywords" - echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" - echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" - echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" - echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" - echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" - echo "\$Id: 4f21723e7b15065df7de95bd46c8ba6fb1818f4c \$" + echo "\$Id: fd0478f5f1486f3d5177d4c3f6eb2765e8fc56b9 \$" + echo "\$Id: fd0478f5f1486f3d5177d4c3f6eb2765e8fc56b9 \$" + echo "\$Id: fd0478f5f1486f3d5177d4c3f6eb2765e8fc56b9 \$" + echo "\$Id: fd0478f5f1486f3d5177d4c3f6eb2765e8fc56b9 \$" + echo "\$Id: fd0478f5f1486f3d5177d4c3f6eb2765e8fc56b9 \$" + echo "\$Id: fd0478f5f1486f3d5177d4c3f6eb2765e8fc56b9 \$" echo "\$Id: NoTerminatingSymbol" + echo "\$Id: Foreign Commit With Spaces \$" + echo "\$Id: NoTerminatingSymbolAtEOF" } > expected-output && git add expanded-keywords && diff --git a/t/t0025-crlf-auto.sh b/t/t0025-crlf-auto.sh new file mode 100755 index 0000000000..f5f67a6337 --- /dev/null +++ b/t/t0025-crlf-auto.sh @@ -0,0 +1,155 @@ +#!/bin/sh + +test_description='CRLF conversion' + +. ./test-lib.sh + +has_cr() { + tr '\015' Q <"$1" | grep Q >/dev/null +} + +test_expect_success setup ' + + git config core.autocrlf false && + + for w in Hello world how are you; do echo $w; done >one && + for w in I am very very fine thank you; do echo ${w}Q; done | q_to_cr >two && + for w in Oh here is a QNUL byte how alarming; do echo ${w}; done | q_to_nul >three && + git add . && + + git commit -m initial && + + one=`git rev-parse HEAD:one` && + two=`git rev-parse HEAD:two` && + three=`git rev-parse HEAD:three` && + + echo happy. +' + +test_expect_success 'default settings cause no changes' ' + + rm -f .gitattributes tmp one two three && + git read-tree --reset -u HEAD && + + ! has_cr one && + has_cr two && + onediff=`git diff one` && + twodiff=`git diff two` && + threediff=`git diff three` && + test -z "$onediff" -a -z "$twodiff" -a -z "$threediff" +' + +test_expect_success 'crlf=true causes a CRLF file to be normalized' ' + + # Backwards compatibility check + rm -f .gitattributes tmp one two three && + echo "two crlf" > .gitattributes && + git read-tree --reset -u HEAD && + + # Note, "normalized" means that git will normalize it if added + has_cr two && + twodiff=`git diff two` && + test -n "$twodiff" +' + +test_expect_success 'text=true causes a CRLF file to be normalized' ' + + rm -f .gitattributes tmp one two three && + echo "two text" > .gitattributes && + git read-tree --reset -u HEAD && + + # Note, "normalized" means that git will normalize it if added + has_cr two && + twodiff=`git diff two` && + test -n "$twodiff" +' + +test_expect_success 'eol=crlf gives a normalized file CRLFs with autocrlf=false' ' + + rm -f .gitattributes tmp one two three && + git config core.autocrlf false && + echo "one eol=crlf" > .gitattributes && + git read-tree --reset -u HEAD && + + has_cr one && + onediff=`git diff one` && + test -z "$onediff" +' + +test_expect_success 'eol=crlf gives a normalized file CRLFs with autocrlf=input' ' + + rm -f .gitattributes tmp one two three && + git config core.autocrlf input && + echo "one eol=crlf" > .gitattributes && + git read-tree --reset -u HEAD && + + has_cr one && + onediff=`git diff one` && + test -z "$onediff" +' + +test_expect_success 'eol=lf gives a normalized file LFs with autocrlf=true' ' + + rm -f .gitattributes tmp one two three && + git config core.autocrlf true && + echo "one eol=lf" > .gitattributes && + git read-tree --reset -u HEAD && + + ! has_cr one && + onediff=`git diff one` && + test -z "$onediff" +' + +test_expect_success 'autocrlf=true does not normalize CRLF files' ' + + rm -f .gitattributes tmp one two three && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + has_cr one && + has_cr two && + onediff=`git diff one` && + twodiff=`git diff two` && + threediff=`git diff three` && + test -z "$onediff" -a -z "$twodiff" -a -z "$threediff" +' + +test_expect_success 'text=auto, autocrlf=true _does_ normalize CRLF files' ' + + rm -f .gitattributes tmp one two three && + git config core.autocrlf true && + echo "* text=auto" > .gitattributes && + git read-tree --reset -u HEAD && + + has_cr one && + has_cr two && + onediff=`git diff one` && + twodiff=`git diff two` && + threediff=`git diff three` && + test -z "$onediff" -a -n "$twodiff" -a -z "$threediff" +' + +test_expect_success 'text=auto, autocrlf=true does not normalize binary files' ' + + rm -f .gitattributes tmp one two three && + git config core.autocrlf true && + echo "* text=auto" > .gitattributes && + git read-tree --reset -u HEAD && + + ! has_cr three && + threediff=`git diff three` && + test -z "$threediff" +' + +test_expect_success 'eol=crlf _does_ normalize binary files' ' + + rm -f .gitattributes tmp one two three && + echo "three eol=crlf" > .gitattributes && + git read-tree --reset -u HEAD && + + has_cr three && + threediff=`git diff three` && + test -z "$threediff" +' + +test_done diff --git a/t/t0026-eol-config.sh b/t/t0026-eol-config.sh new file mode 100755 index 0000000000..f37ac8fa0b --- /dev/null +++ b/t/t0026-eol-config.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +test_description='CRLF conversion' + +. ./test-lib.sh + +has_cr() { + tr '\015' Q <"$1" | grep Q >/dev/null +} + +test_expect_success setup ' + + git config core.autocrlf false && + + echo "one text" > .gitattributes + + for w in Hello world how are you; do echo $w; done >one && + for w in I am very very fine thank you; do echo $w; done >two && + git add . && + + git commit -m initial && + + one=`git rev-parse HEAD:one` && + two=`git rev-parse HEAD:two` && + + echo happy. +' + +test_expect_success 'eol=lf puts LFs in normalized file' ' + + rm -f .gitattributes tmp one two && + git config core.eol lf && + git read-tree --reset -u HEAD && + + ! has_cr one && + ! has_cr two && + onediff=`git diff one` && + twodiff=`git diff two` && + test -z "$onediff" -a -z "$twodiff" +' + +test_expect_success 'eol=crlf puts CRLFs in normalized file' ' + + rm -f .gitattributes tmp one two && + git config core.eol crlf && + git read-tree --reset -u HEAD && + + has_cr one && + ! has_cr two && + onediff=`git diff one` && + twodiff=`git diff two` && + test -z "$onediff" -a -z "$twodiff" +' + +test_expect_success 'autocrlf=true overrides eol=lf' ' + + rm -f .gitattributes tmp one two && + git config core.eol lf && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + has_cr one && + has_cr two && + onediff=`git diff one` && + twodiff=`git diff two` && + test -z "$onediff" -a -z "$twodiff" +' + +test_expect_success 'autocrlf=true overrides unset eol' ' + + rm -f .gitattributes tmp one two && + git config --unset-all core.eol && + git config core.autocrlf true && + git read-tree --reset -u HEAD && + + has_cr one && + has_cr two && + onediff=`git diff one` && + twodiff=`git diff two` && + test -z "$onediff" -a -z "$twodiff" +' + +test_done diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 3d450ed379..20924506af 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -7,7 +7,7 @@ test_description='our own option parser' . ./test-lib.sh -cat > expect.err << EOF +cat > expect << EOF usage: test-parse-options <options> -b, --boolean get a boolean @@ -46,10 +46,12 @@ EOF test_expect_success 'test help' ' test_must_fail test-parse-options -h > output 2> output.err && - test ! -s output && - test_cmp expect.err output.err + test ! -s output.err && + test_cmp expect output ' +mv expect expect.err + cat > expect << EOF boolean: 2 integer: 1729 diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index f11f98c3ce..64f05080b6 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -824,4 +824,12 @@ test_expect_success 'check split_cmdline return' " test_must_fail git merge master " +test_expect_success 'git -c "key=value" support' ' + test "z$(git -c name=value config name)" = zvalue && + test "z$(git -c core.name=value config core.name)" = zvalue && + test "z$(git -c CamelCase=value config camelcase)" = zvalue && + test "z$(git -c flag config --bool flag)" = ztrue && + test_must_fail git -c core.name=value config name +' + test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 49cae3ed52..759cf12e16 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -5,7 +5,9 @@ test_description='git fsck random collection of tests' . ./test-lib.sh test_expect_success setup ' + git config i18n.commitencoding ISO-8859-1 && test_commit A fileA one && + git config --unset i18n.commitencoding && git checkout HEAD^0 && test_commit B fileB two && git tag -d A B && @@ -28,6 +30,12 @@ test_expect_success 'loose objects borrowed from alternate are not missing' ' ) ' +test_expect_success 'valid objects appear valid' ' + { git fsck 2>out; true; } && + ! grep error out && + ! grep fatal out +' + # Corruption tests follow. Make sure to remove all traces of the # specific corruption you test afterwards, lest a later test trip over # it. @@ -57,6 +65,34 @@ test_expect_success 'branch pointing to non-commit' ' git update-ref -d refs/heads/invalid ' +new=nothing +test_expect_success 'email without @ is okay' ' + git cat-file commit HEAD >basis && + sed "s/@/AT/" basis >okay && + new=$(git hash-object -t commit -w --stdin <okay) && + echo "$new" && + git update-ref refs/heads/bogus "$new" && + git fsck 2>out && + cat out && + ! grep "error in commit $new" out +' +git update-ref -d refs/heads/bogus +rm -f ".git/objects/$new" + +new=nothing +test_expect_success 'email with embedded > is not okay' ' + git cat-file commit HEAD >basis && + sed "s/@[a-z]/&>/" basis >bad-email && + new=$(git hash-object -t commit -w --stdin <bad-email) && + echo "$new" && + git update-ref refs/heads/bogus "$new" && + git fsck 2>out && + cat out && + grep "error in commit $new" out +' +git update-ref -d refs/heads/bogus +rm -f ".git/objects/$new" + cat > invalid-tag <<EOF object ffffffffffffffffffffffffffffffffffffffff type commit diff --git a/t/t1501-worktree.sh b/t/t1501-worktree.sh index 9df301211c..bd8b60732b 100755 --- a/t/t1501-worktree.sh +++ b/t/t1501-worktree.sh @@ -30,6 +30,7 @@ test_rev_parse() { EMPTY_TREE=$(git write-tree) mkdir -p work/sub/dir || exit 1 +mkdir -p work2 || exit 1 mv .git repo.git || exit 1 say "core.worktree = relative path" @@ -54,7 +55,9 @@ GIT_DIR=$(pwd)/repo.git GIT_CONFIG=$GIT_DIR/config git config core.worktree "$(pwd)/work" test_rev_parse 'outside' false false false -cd work || exit 1 +cd work2 +test_rev_parse 'outside2' false false false +cd ../work || exit 1 test_rev_parse 'inside' false false true '' cd sub/dir || exit 1 test_rev_parse 'subdirectory' false false true sub/dir/ @@ -67,7 +70,9 @@ git config core.worktree non-existent GIT_WORK_TREE=work export GIT_WORK_TREE test_rev_parse 'outside' false false false -cd work || exit 1 +cd work2 +test_rev_parse 'outside' false false false +cd ../work || exit 1 GIT_WORK_TREE=. test_rev_parse 'inside' false false true '' cd sub/dir || exit 1 @@ -76,6 +81,7 @@ test_rev_parse 'subdirectory' false false true sub/dir/ cd ../../.. || exit 1 mv work repo.git/work +mv work2 repo.git/work2 say "GIT_WORK_TREE=absolute path, work tree below git dir" GIT_DIR=$(pwd)/repo.git @@ -86,6 +92,8 @@ cd repo.git || exit 1 test_rev_parse 'in repo.git' false true false cd objects || exit 1 test_rev_parse 'in repo.git/objects' false true false +cd ../work2 || exit 1 +test_rev_parse 'in repo.git/work2' false true false cd ../work || exit 1 test_rev_parse 'in repo.git/work' false true true '' cd sub/dir || exit 1 diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index e504058062..4346795855 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -3,7 +3,8 @@ test_description='test git rev-parse --parseopt' . ./test-lib.sh -cat > expect.err <<EOF +cat > expect <<\END_EXPECT +cat <<\EOF usage: some-command [options] <args>... some-command does foo and bar! @@ -19,6 +20,7 @@ Extras --extra1 line above used to cause a segfault but no longer does EOF +END_EXPECT cat > optionspec << EOF some-command [options] <args>... @@ -38,8 +40,8 @@ extra1 line above used to cause a segfault but no longer does EOF test_expect_success 'test --parseopt help output' ' - git rev-parse --parseopt -- -h 2> output.err < optionspec - test_cmp expect.err output.err + git rev-parse --parseopt -- -h > output < optionspec + test_cmp expect output ' cat > expect <<EOF diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh index 20f33436d0..27e2127afe 100755 --- a/t/t2007-checkout-symlink.sh +++ b/t/t2007-checkout-symlink.sh @@ -44,8 +44,10 @@ test_expect_success 'switch from symlink to dir' ' ' -rm -fr frotz xyzzy nitfol && -git checkout -f master || exit +test_expect_success 'Remove temporary directories & switch to master' ' + rm -fr frotz xyzzy nitfol && + git checkout -f master +' test_expect_success 'switch from dir to symlink' ' diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh new file mode 100755 index 0000000000..be88d4b5ee --- /dev/null +++ b/t/t2017-checkout-orphan.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# +# Copyright (c) 2010 Erick Mattos +# + +test_description='git checkout --orphan + +Main Tests for --orphan functionality.' + +. ./test-lib.sh + +TEST_FILE=foo + +test_expect_success 'Setup' ' + echo "Initial" >"$TEST_FILE" && + git add "$TEST_FILE" && + git commit -m "First Commit" + test_tick && + echo "State 1" >>"$TEST_FILE" && + git add "$TEST_FILE" && + test_tick && + git commit -m "Second Commit" +' + +test_expect_success '--orphan creates a new orphan branch from HEAD' ' + git checkout --orphan alpha && + test_must_fail git rev-parse --verify HEAD && + test "refs/heads/alpha" = "$(git symbolic-ref HEAD)" && + test_tick && + git commit -m "Third Commit" && + test_must_fail git rev-parse --verify HEAD^ && + git diff-tree --quiet master alpha +' + +test_expect_success '--orphan creates a new orphan branch from <start_point>' ' + git checkout master && + git checkout --orphan beta master^ && + test_must_fail git rev-parse --verify HEAD && + test "refs/heads/beta" = "$(git symbolic-ref HEAD)" && + test_tick && + git commit -m "Fourth Commit" && + test_must_fail git rev-parse --verify HEAD^ && + git diff-tree --quiet master^ beta +' + +test_expect_success '--orphan must be rejected with -b' ' + git checkout master && + test_must_fail git checkout --orphan new -b newer && + test refs/heads/master = "$(git symbolic-ref HEAD)" +' + +test_expect_success '--orphan must be rejected with -t' ' + git checkout master && + test_must_fail git checkout --orphan new -t master && + test refs/heads/master = "$(git symbolic-ref HEAD)" +' + +test_expect_success '--orphan ignores branch.autosetupmerge' ' + git checkout master && + git config branch.autosetupmerge always && + git checkout --orphan gamma && + test -z "$(git config branch.gamma.merge)" && + test refs/heads/gamma = "$(git symbolic-ref HEAD)" && + test_must_fail git rev-parse --verify HEAD^ +' + +test_expect_success '--orphan makes reflog by default' ' + git checkout master && + git config --unset core.logAllRefUpdates && + git checkout --orphan delta && + ! test -f .git/logs/refs/heads/delta && + test_must_fail PAGER= git reflog show delta && + git commit -m Delta && + test -f .git/logs/refs/heads/delta && + PAGER= git reflog show delta +' + +test_expect_success '--orphan does not make reflog when core.logAllRefUpdates = false' ' + git checkout master && + git config core.logAllRefUpdates false && + git checkout --orphan epsilon && + ! test -f .git/logs/refs/heads/epsilon && + test_must_fail PAGER= git reflog show epsilon && + git commit -m Epsilon && + ! test -f .git/logs/refs/heads/epsilon && + test_must_fail PAGER= git reflog show epsilon +' + +test_expect_success '--orphan with -l makes reflog when core.logAllRefUpdates = false' ' + git checkout master && + git checkout -l --orphan zeta && + test -f .git/logs/refs/heads/zeta && + test_must_fail PAGER= git reflog show zeta && + git commit -m Zeta && + PAGER= git reflog show zeta +' + +test_expect_success 'giving up --orphan not committed when -l and core.logAllRefUpdates = false deletes reflog' ' + git checkout master && + git checkout -l --orphan eta && + test -f .git/logs/refs/heads/eta && + test_must_fail PAGER= git reflog show eta && + git checkout master && + ! test -f .git/logs/refs/heads/eta && + test_must_fail PAGER= git reflog show eta +' + +test_expect_success '--orphan is rejected with an existing name' ' + git checkout master && + test_must_fail git checkout --orphan master && + test refs/heads/master = "$(git symbolic-ref HEAD)" +' + +test_expect_success '--orphan refuses to switch if a merge is needed' ' + git checkout master && + git reset --hard && + echo local >>"$TEST_FILE" && + cat "$TEST_FILE" >"$TEST_FILE.saved" && + test_must_fail git checkout --orphan new master^ && + test refs/heads/master = "$(git symbolic-ref HEAD)" && + test_cmp "$TEST_FILE" "$TEST_FILE.saved" && + git diff-index --quiet --cached HEAD && + git reset --hard +' + +test_done diff --git a/t/t2106-update-index-assume-unchanged.sh b/t/t2106-update-index-assume-unchanged.sh new file mode 100755 index 0000000000..99d858c6b7 --- /dev/null +++ b/t/t2106-update-index-assume-unchanged.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +test_description='git update-index --assume-unchanged test. +' + +. ./test-lib.sh + +test_expect_success 'setup' \ + ': >file && + git add file && + git commit -m initial && + git branch other && + echo upstream >file && + git add file && + git commit -m upstream' + +test_expect_success 'do not switch branches with dirty file' \ + 'git reset --hard && + git checkout other && + echo dirt >file && + git update-index --assume-unchanged file && + test_must_fail git checkout master' + +test_done diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 9929f82021..d541544537 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -22,6 +22,7 @@ test_expect_success 'setup 1' ' git branch df-2 && git branch df-3 && git branch remove && + git branch submod && echo hello >>a && cp a d/e && @@ -236,6 +237,17 @@ test_expect_success 'setup 6' ' test_cmp expected actual ' +test_expect_success 'setup 7' ' + + git checkout submod && + git rm d/e && + test_tick && + git commit -m "remove d/e" && + git update-index --add --cacheinfo 160000 $c1 d && + test_tick && + git commit -m "make d/ a submodule" +' + test_expect_success 'merge-recursive simple' ' rm -fr [abcd] && @@ -551,4 +563,21 @@ test_expect_success 'merge removes empty directories' ' test_must_fail test -d d ' +test_expect_failure 'merge-recursive simple w/submodule' ' + + git checkout submod && + git merge remove +' + +test_expect_failure 'merge-recursive simple w/submodule result' ' + + git ls-files -s >actual && + ( + echo "100644 $o5 0 a" + echo "100644 $o0 0 c" + echo "160000 $c1 0 d" + ) >expected && + test_cmp expected actual +' + test_done diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index e0b760513c..859b99abf1 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -43,7 +43,7 @@ test_expect_success \ git branch -l d/e/f && test -f .git/refs/heads/d/e/f && test -f .git/logs/refs/heads/d/e/f && - diff expect .git/logs/refs/heads/d/e/f' + test_cmp expect .git/logs/refs/heads/d/e/f' test_expect_success \ 'git branch -d d/e/f should delete a branch and a log' \ @@ -222,7 +222,31 @@ test_expect_success \ git checkout -b g/h/i -l master && test -f .git/refs/heads/g/h/i && test -f .git/logs/refs/heads/g/h/i && - diff expect .git/logs/refs/heads/g/h/i' + test_cmp expect .git/logs/refs/heads/g/h/i' + +test_expect_success 'checkout -b makes reflog by default' ' + git checkout master && + git config --unset core.logAllRefUpdates && + git checkout -b alpha && + test -f .git/logs/refs/heads/alpha && + PAGER= git reflog show alpha +' + +test_expect_success 'checkout -b does not make reflog when core.logAllRefUpdates = false' ' + git checkout master && + git config core.logAllRefUpdates false && + git checkout -b beta && + ! test -f .git/logs/refs/heads/beta && + test_must_fail PAGER= git reflog show beta +' + +test_expect_success 'checkout -b with -l makes reflog when core.logAllRefUpdates = false' ' + git checkout master && + git checkout -lb gamma && + git config --unset core.logAllRefUpdates && + test -f .git/logs/refs/heads/gamma && + PAGER= git reflog show gamma +' test_expect_success 'avoid ambiguous track' ' git config branch.autosetupmerge true && diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 413019acaf..525174013c 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -28,7 +28,7 @@ test_expect_success \ SHA1=`cat .git/refs/heads/a` && echo "$SHA1 refs/heads/a" >expect && git show-ref a >result && - diff expect result' + test_cmp expect result' test_expect_success \ 'see if a branch still exists when packed' \ @@ -37,7 +37,7 @@ test_expect_success \ rm -f .git/refs/heads/b && echo "$SHA1 refs/heads/b" >expect && git show-ref b >result && - diff expect result' + test_cmp expect result' test_expect_success 'git branch c/d should barf if branch c exists' ' git branch c && @@ -52,7 +52,7 @@ test_expect_success \ git pack-refs --all --prune && echo "$SHA1 refs/heads/e" >expect && git show-ref e >result && - diff expect result' + test_cmp expect result' test_expect_success 'see if git pack-refs --prune remove ref files' ' git branch f && @@ -109,7 +109,7 @@ test_expect_success 'pack, prune and repack' ' git show-ref >all-of-them && git pack-refs && git show-ref >again && - diff all-of-them again + test_cmp all-of-them again ' test_done diff --git a/t/t3306-notes-prune.sh b/t/t3306-notes-prune.sh index a0ed0353e6..b4554041b4 100755 --- a/t/t3306-notes-prune.sh +++ b/t/t3306-notes-prune.sh @@ -60,7 +60,7 @@ test_expect_success 'verify commits and notes' ' test_expect_success 'remove some commits' ' - git reset --hard HEAD~2 && + git reset --hard HEAD~1 && git reflog expire --expire=now HEAD && git gc --prune=now ' @@ -68,7 +68,7 @@ test_expect_success 'remove some commits' ' test_expect_success 'verify that commits are gone' ' ! git cat-file -p 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && - ! git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 && + git cat-file -p 08341ad9e94faa089d60fd3f523affb25c6da189 && git cat-file -p ab5f302035f2e7aaf04265f08b42034c23256e1f ' @@ -79,6 +79,26 @@ test_expect_success 'verify that notes are still present' ' git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f ' +test_expect_success 'prune -n does not remove notes' ' + + git notes list > expect && + git notes prune -n && + git notes list > actual && + test_cmp expect actual +' + +cat > expect <<EOF +5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 +EOF + +test_expect_success 'prune -n lists prunable notes' ' + + + git notes prune -n > actual && + test_cmp expect actual +' + + test_expect_success 'prune notes' ' git notes prune @@ -87,6 +107,30 @@ test_expect_success 'prune notes' ' test_expect_success 'verify that notes are gone' ' ! git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && + git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 && + git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f +' + +test_expect_success 'remove some commits' ' + + git reset --hard HEAD~1 && + git reflog expire --expire=now HEAD && + git gc --prune=now +' + +cat > expect <<EOF +08341ad9e94faa089d60fd3f523affb25c6da189 +EOF + +test_expect_success 'prune -v notes' ' + + git notes prune -v > actual && + test_cmp expect actual +' + +test_expect_success 'verify that notes are gone' ' + + ! git notes show 5ee1c35e83ea47cd3cc4f8cbee0568915fbbbd29 && ! git notes show 08341ad9e94faa089d60fd3f523affb25c6da189 && git notes show ab5f302035f2e7aaf04265f08b42034c23256e1f ' diff --git a/t/t3307-notes-man.sh b/t/t3307-notes-man.sh new file mode 100755 index 0000000000..3269f2eebd --- /dev/null +++ b/t/t3307-notes-man.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +test_description='Examples from the git-notes man page + +Make sure the manual is not full of lies.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit A && + test_commit B && + test_commit C +' + +test_expect_success 'example 1: notes to add an Acked-by line' ' + cat <<-\EOF >expect && + B + + Notes: + Acked-by: A C Ker <acker@example.com> + EOF + git notes add -m "Acked-by: A C Ker <acker@example.com>" B && + git show -s B^{commit} >log && + tail -n 4 log >actual && + test_cmp expect actual +' + +test_expect_success 'example 2: binary notes' ' + cp "$TEST_DIRECTORY"/test4012.png . + git checkout B && + blob=$(git hash-object -w test4012.png) && + git notes --ref=logo add -C "$blob" && + git notes --ref=logo copy B C && + git notes --ref=logo show C >actual && + test_cmp test4012.png actual +' + +test_done diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index dbf7dfba9b..e5691bc5ed 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -126,9 +126,20 @@ test_expect_success 'Show verbose error when HEAD could not be detached' ' test_must_fail git rebase topic 2> output.err > output.out && grep "Untracked working tree file .B. would be overwritten" output.err ' +rm -f B + +test_expect_success 'dump usage when upstream arg is missing' ' + git checkout -b usage topic && + test_must_fail git rebase 2>error1 && + grep "[Uu]sage" error1 && + test_must_fail git rebase --abort 2>error2 && + grep "No rebase in progress" error2 && + test_must_fail git rebase --onto master 2>error3 && + grep "[Uu]sage" error3 && + ! grep "can.t shift" error3 +' test_expect_success 'rebase -q is quiet' ' - rm B && git checkout -b quiet topic && git rebase -q master > output.out 2>&1 && test ! -s output.out diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index f20ea38411..ee9a1b25e6 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -146,6 +146,16 @@ test_expect_success 'abort' ' ! test -d .git/rebase-merge ' +test_expect_success 'abort with error when new base cannot be checked out' ' + git rm --cached file1 && + git commit -m "remove file in base" && + test_must_fail git rebase -i master > output 2>&1 && + grep "Untracked working tree file .file1. would be overwritten" \ + output && + ! test -d .git/rebase-merge && + git reset --hard HEAD^ +' + test_expect_success 'retain authorship' ' echo A > file7 && git add file7 && @@ -181,6 +191,12 @@ test_expect_success '-p handles "no changes" gracefully' ' test $HEAD = $(git rev-parse HEAD) ' +test_expect_failure 'exchange two commits with -p' ' + FAKE_LINES="2 1" git rebase -i -p HEAD~2 && + test H = $(git cat-file commit HEAD^ | sed -ne \$p) && + test G = $(git cat-file commit HEAD | sed -ne \$p) +' + test_expect_success 'preserve merges with -p' ' git checkout -b to-be-preserved master^ && : > unrelated-file && diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh index dadbbc2a9f..f038f34b7c 100755 --- a/t/t3500-cherry.sh +++ b/t/t3500-cherry.sh @@ -17,17 +17,19 @@ test_expect_success \ 'prepare repository with topic branch, and check cherry finds the 2 patches from there' \ 'echo First > A && git update-index --add A && + test_tick && git commit -m "Add A." && git checkout -b my-topic-branch && echo Second > B && git update-index --add B && + test_tick && git commit -m "Add B." && - sleep 2 && echo AnotherSecond > C && git update-index --add C && + test_tick && git commit -m "Add C." && git checkout -f master && @@ -35,6 +37,7 @@ test_expect_success \ echo Third >> A && git update-index A && + test_tick && git commit -m "Modify A." && expr "$(echo $(git cherry master my-topic-branch) )" : "+ [^ ]* + .*" diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index 7f858151d4..e4fbf7a210 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -47,7 +47,8 @@ test_expect_success 'cherry-pick after renaming branch' ' git cherry-pick added && test $(git rev-parse HEAD^) = $(git rev-parse rename2) && test -f opos && - grep "Add extra line at the end" opos + grep "Add extra line at the end" opos && + git reflog -1 | grep cherry-pick ' @@ -57,7 +58,8 @@ test_expect_success 'revert after renaming branch' ' git revert added && test $(git rev-parse HEAD^) = $(git rev-parse rename1) && test -f spoo && - ! grep "Add extra line at the end" spoo + ! grep "Add extra line at the end" spoo && + git reflog -1 | grep revert ' diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 476e5ec038..62e208aadd 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -81,7 +81,7 @@ test_expect_success 'drop top stash' ' git stash && git stash drop && git stash list > stashlist2 && - diff stashlist1 stashlist2 && + test_cmp stashlist1 stashlist2 && git stash apply && test 3 = $(cat file) && test 1 = $(git show :file) && @@ -228,4 +228,154 @@ test_expect_success 'stash --invalid-option' ' test bar,bar2 = $(cat file),$(cat file2) ' +test_expect_success 'stash an added file' ' + git reset --hard && + echo new >file3 && + git add file3 && + git stash save "added file" && + ! test -r file3 && + git stash apply && + test new = "$(cat file3)" +' + +test_expect_success 'stash rm then recreate' ' + git reset --hard && + git rm file && + echo bar7 >file && + git stash save "rm then recreate" && + test bar = "$(cat file)" && + git stash apply && + test bar7 = "$(cat file)" +' + +test_expect_success 'stash rm and ignore' ' + git reset --hard && + git rm file && + echo file >.gitignore && + git stash save "rm and ignore" && + test bar = "$(cat file)" && + test file = "$(cat .gitignore)" + git stash apply && + ! test -r file && + test file = "$(cat .gitignore)" +' + +test_expect_success 'stash rm and ignore (stage .gitignore)' ' + git reset --hard && + git rm file && + echo file >.gitignore && + git add .gitignore && + git stash save "rm and ignore (stage .gitignore)" && + test bar = "$(cat file)" && + ! test -r .gitignore + git stash apply && + ! test -r file && + test file = "$(cat .gitignore)" +' + +test_expect_success SYMLINKS 'stash file to symlink' ' + git reset --hard && + rm file && + ln -s file2 file && + git stash save "file to symlink" && + test -f file && + test bar = "$(cat file)" && + git stash apply && + case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac +' + +test_expect_success SYMLINKS 'stash file to symlink (stage rm)' ' + git reset --hard && + git rm file && + ln -s file2 file && + git stash save "file to symlink (stage rm)" && + test -f file && + test bar = "$(cat file)" && + git stash apply && + case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac +' + +test_expect_success SYMLINKS 'stash file to symlink (full stage)' ' + git reset --hard && + rm file && + ln -s file2 file && + git add file && + git stash save "file to symlink (full stage)" && + test -f file && + test bar = "$(cat file)" && + git stash apply && + case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac +' + +# This test creates a commit with a symlink used for the following tests + +test_expect_success SYMLINKS 'stash symlink to file' ' + git reset --hard && + ln -s file filelink && + git add filelink && + git commit -m "Add symlink" && + rm filelink && + cp file filelink && + git stash save "symlink to file" && + test -h filelink && + case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac && + git stash apply && + ! test -h filelink && + test bar = "$(cat file)" +' + +test_expect_success SYMLINKS 'stash symlink to file (stage rm)' ' + git reset --hard && + git rm filelink && + cp file filelink && + git stash save "symlink to file (stage rm)" && + test -h filelink && + case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac && + git stash apply && + ! test -h filelink && + test bar = "$(cat file)" +' + +test_expect_success SYMLINKS 'stash symlink to file (full stage)' ' + git reset --hard && + rm filelink && + cp file filelink && + git add filelink && + git stash save "symlink to file (full stage)" && + test -h filelink && + case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac && + git stash apply && + ! test -h filelink && + test bar = "$(cat file)" +' + +test_expect_failure 'stash directory to file' ' + git reset --hard && + mkdir dir && + echo foo >dir/file && + git add dir/file && + git commit -m "Add file in dir" && + rm -fr dir && + echo bar >dir && + git stash save "directory to file" && + test -d dir && + test foo = "$(cat dir/file)" && + test_must_fail git stash apply && + test bar = "$(cat dir)" && + git reset --soft HEAD^ +' + +test_expect_failure 'stash file to directory' ' + git reset --hard && + rm file && + mkdir file && + echo foo >file/file && + git stash save "file to directory" && + test -f file && + test bar = "$(cat file)" && + git stash apply && + test -f file/file && + test foo = "$(cat file/file)" +' + test_done diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index 18695ce821..73441a5165 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -135,7 +135,7 @@ cmp_diff_files_output () { # filesystem. sed <"$2" >.test-tmp \ -e '/^:000000 /d;s/'$x40'\( [MCRNDU][0-9]*\) /'$z40'\1 /' && - diff "$1" .test-tmp + test_cmp "$1" .test-tmp } test_expect_success \ diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index d7e327cc5b..e12fbea1b5 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -54,7 +54,7 @@ EOF test_expect_success \ 'diff removed symlink' \ - 'rm frotz && + 'mv frotz frotz2 && git diff-index -M -p $tree > current && compare_diff_patch current expected' @@ -64,8 +64,7 @@ EOF test_expect_success \ 'diff identical, but newly created symlink' \ - 'sleep 3 && - ln -s xyzzy frotz && + 'ln -s xyzzy frotz && git diff-index -M -p $tree > current && compare_diff_patch current expected' diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 90f3342373..935d101fe8 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -352,6 +352,48 @@ test_expect_success 'check tabs and spaces as indentation (indent-with-non-tab: ' +test_expect_success 'check tabs as indentation (tab-in-indent: off)' ' + + git config core.whitespace "-tab-in-indent" && + echo " foo ();" > x && + git diff --check + +' + +test_expect_success 'check tabs as indentation (tab-in-indent: on)' ' + + git config core.whitespace "tab-in-indent" && + echo " foo ();" > x && + test_must_fail git diff --check + +' + +test_expect_success 'check tabs and spaces as indentation (tab-in-indent: on)' ' + + git config core.whitespace "tab-in-indent" && + echo " foo ();" > x && + test_must_fail git diff --check + +' + +test_expect_success 'check tab-in-indent and indent-with-non-tab conflict' ' + + git config core.whitespace "tab-in-indent,indent-with-non-tab" && + echo "foo ();" > x && + test_must_fail git diff --check + +' + +test_expect_success 'check tab-in-indent excluded from wildcard whitespace attribute' ' + + git config --unset core.whitespace && + echo "x whitespace" > .gitattributes && + echo " foo ();" > x && + git diff --check && + rm -f .gitattributes + +' + test_expect_success 'line numbers in --check output are correct' ' echo "" > x && @@ -396,6 +438,43 @@ test_expect_success 'whitespace-only changes not reported' ' test_cmp expect actual ' +cat <<EOF >expect +diff --git a/x b/z +similarity index NUM% +rename from x +rename to z +index 380c32a..a97b785 100644 +EOF +test_expect_success 'whitespace-only changes reported across renames' ' + git reset --hard && + for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x && + git add x && + git commit -m "base" && + sed -e "5s/^/ /" x >z && + git rm x && + git add z && + git diff -w -M --cached | + sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual && + test_cmp expect actual +' + +cat >expected <<\EOF +diff --git a/empty b/void +similarity index 100% +rename from empty +rename to void +EOF + +test_expect_success 'rename empty' ' + git reset --hard && + >empty && + git add empty && + git commit -m empty && + git mv empty void && + git diff -w --cached -M >current && + test_cmp expected current +' + test_expect_success 'combined diff with autocrlf conversion' ' git reset --hard && diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 2e2e103b31..6f7548c3a1 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -55,6 +55,93 @@ test_expect_success 'word diff with runs of whitespace' ' ' +test_expect_success '--word-diff=color' ' + + word_diff --word-diff=color + +' + +test_expect_success '--color --word-diff=color' ' + + word_diff --color --word-diff=color + +' + +sed 's/#.*$//' > expect <<EOF +diff --git a/pre b/post +index 330b04f..5ed8eff 100644 +--- a/pre ++++ b/post +@@ -1,3 +1,7 @@ +-h(4) ++h(4),hh[44] +~ + # significant space +~ + a = b + c +~ +~ ++aa = a +~ +~ ++aeff = aeff * ( aaa ) +~ +EOF + +test_expect_success '--word-diff=porcelain' ' + + word_diff --word-diff=porcelain + +' + +cat > expect <<EOF +diff --git a/pre b/post +index 330b04f..5ed8eff 100644 +--- a/pre ++++ b/post +@@ -1,3 +1,7 @@ +[-h(4)-]{+h(4),hh[44]+} + +a = b + c + +{+aa = a+} + +{+aeff = aeff * ( aaa )+} +EOF + +test_expect_success '--word-diff=plain' ' + + word_diff --word-diff=plain + +' + +test_expect_success '--word-diff=plain --no-color' ' + + word_diff --word-diff=plain --no-color + +' + +cat > expect <<EOF +<WHITE>diff --git a/pre b/post<RESET> +<WHITE>index 330b04f..5ed8eff 100644<RESET> +<WHITE>--- a/pre<RESET> +<WHITE>+++ b/post<RESET> +<CYAN>@@ -1,3 +1,7 @@<RESET> +<RED>[-h(4)-]<RESET><GREEN>{+h(4),hh[44]+}<RESET> + +a = b + c<RESET> + +<GREEN>{+aa = a+}<RESET> + +<GREEN>{+aeff = aeff * ( aaa )+}<RESET> +EOF + +test_expect_success '--word-diff=plain --color' ' + + word_diff --word-diff=plain --color + +' + cat > expect <<\EOF <WHITE>diff --git a/pre b/post<RESET> <WHITE>index 330b04f..5ed8eff 100644<RESET> @@ -143,6 +230,25 @@ test_expect_success 'command-line overrides config' ' word_diff --color-words="[a-z]+" ' +cat > expect <<\EOF +<WHITE>diff --git a/pre b/post<RESET> +<WHITE>index 330b04f..5ed8eff 100644<RESET> +<WHITE>--- a/pre<RESET> +<WHITE>+++ b/post<RESET> +<CYAN>@@ -1,3 +1,7 @@<RESET> +h(4),<GREEN>{+hh+}<RESET>[44] + +a = b + c<RESET> + +<GREEN>{+aa = a+}<RESET> + +<GREEN>{+aeff = aeff * ( aaa+}<RESET> ) +EOF + +test_expect_success 'command-line overrides config: --word-diff-regex' ' + word_diff --color --word-diff-regex="[a-z]+" +' + cp expect.non-whitespace-is-word expect test_expect_success '.gitattributes override config' ' @@ -209,4 +315,20 @@ test_expect_success 'test when words are only removed at the end' ' ' +cat > expect <<\EOF +diff --git a/pre b/post +index 289cb9d..2d06f37 100644 +--- a/pre ++++ b/post +@@ -1 +1 @@ +-(: ++( +EOF + +test_expect_success '--word-diff=none' ' + + word_diff --word-diff=plain --word-diff=none + +' + test_done diff --git a/t/t4042-diff-textconv-caching.sh b/t/t4042-diff-textconv-caching.sh new file mode 100755 index 0000000000..91f8198f05 --- /dev/null +++ b/t/t4042-diff-textconv-caching.sh @@ -0,0 +1,109 @@ +#!/bin/sh + +test_description='test textconv caching' +. ./test-lib.sh + +cat >helper <<'EOF' +#!/bin/sh +sed 's/^/converted: /' "$@" >helper.out +cat helper.out +EOF +chmod +x helper + +test_expect_success 'setup' ' + echo foo content 1 >foo.bin && + echo bar content 1 >bar.bin && + git add . && + git commit -m one && + echo foo content 2 >foo.bin && + echo bar content 2 >bar.bin && + git commit -a -m two && + echo "*.bin diff=magic" >.gitattributes && + git config diff.magic.textconv ./helper && + git config diff.magic.cachetextconv true +' + +cat >expect <<EOF +diff --git a/bar.bin b/bar.bin +index fcf9166..28283d5 100644 +--- a/bar.bin ++++ b/bar.bin +@@ -1 +1 @@ +-converted: bar content 1 ++converted: bar content 2 +diff --git a/foo.bin b/foo.bin +index d5b9fe3..1345db2 100644 +--- a/foo.bin ++++ b/foo.bin +@@ -1 +1 @@ +-converted: foo content 1 ++converted: foo content 2 +EOF + +test_expect_success 'first textconv works' ' + git diff HEAD^ HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'cached textconv produces same output' ' + git diff HEAD^ HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'cached textconv does not run helper' ' + rm -f helper.out && + git diff HEAD^ HEAD >actual && + test_cmp expect actual && + ! test -r helper.out +' + +cat >expect <<EOF +diff --git a/bar.bin b/bar.bin +index fcf9166..28283d5 100644 +--- a/bar.bin ++++ b/bar.bin +@@ -1,2 +1,2 @@ + converted: other +-converted: bar content 1 ++converted: bar content 2 +diff --git a/foo.bin b/foo.bin +index d5b9fe3..1345db2 100644 +--- a/foo.bin ++++ b/foo.bin +@@ -1,2 +1,2 @@ + converted: other +-converted: foo content 1 ++converted: foo content 2 +EOF +test_expect_success 'changing textconv invalidates cache' ' + echo other >other && + git config diff.magic.textconv "./helper other" && + git diff HEAD^ HEAD >actual && + test_cmp expect actual +' + +cat >expect <<EOF +diff --git a/bar.bin b/bar.bin +index fcf9166..28283d5 100644 +--- a/bar.bin ++++ b/bar.bin +@@ -1,2 +1,2 @@ + converted: other +-converted: bar content 1 ++converted: bar content 2 +diff --git a/foo.bin b/foo.bin +index d5b9fe3..1345db2 100644 +--- a/foo.bin ++++ b/foo.bin +@@ -1 +1 @@ +-converted: foo content 1 ++converted: foo content 2 +EOF +test_expect_success 'switching diff driver produces correct results' ' + git config diff.moremagic.textconv ./helper && + echo foo.bin diff=moremagic >>.gitattributes && + git diff HEAD^ HEAD >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t4043-diff-rename-binary.sh b/t/t4043-diff-rename-binary.sh new file mode 100755 index 0000000000..06012811a1 --- /dev/null +++ b/t/t4043-diff-rename-binary.sh @@ -0,0 +1,45 @@ +#!/bin/sh +# +# Copyright (c) 2010 Jakub Narebski, Christian Couder +# + +test_description='Move a binary file' + +. ./test-lib.sh + + +test_expect_success 'prepare repository' ' + git init && + echo foo > foo && + echo "barQ" | q_to_nul > bar && + git add . && + git commit -m "Initial commit" +' + +test_expect_success 'move the files into a "sub" directory' ' + mkdir sub && + git mv bar foo sub/ && + git commit -m "Moved to sub/" +' + +cat > expected <<\EOF + bar => sub/bar | Bin 5 -> 5 bytes + foo => sub/foo | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) + +diff --git a/bar b/sub/bar +similarity index 100% +rename from bar +rename to sub/bar +diff --git a/foo b/sub/foo +similarity index 100% +rename from foo +rename to sub/foo +EOF + +test_expect_success 'git show -C -C report renames' ' + git show -C -C --raw --binary --stat | tail -n 12 > current && + test_cmp expected current +' + +test_done diff --git a/t/t4044-diff-index-unique-abbrev.sh b/t/t4044-diff-index-unique-abbrev.sh new file mode 100755 index 0000000000..d5ce72be63 --- /dev/null +++ b/t/t4044-diff-index-unique-abbrev.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +test_description='test unique sha1 abbreviation on "index from..to" line' +. ./test-lib.sh + +cat >expect_initial <<EOF +100644 blob 51d2738463ea4ca66f8691c91e33ce64b7d41bb1 foo +EOF + +cat >expect_update <<EOF +100644 blob 51d2738efb4ad8a1e40bed839ab8e116f0a15e47 foo +EOF + +test_expect_success 'setup' ' + echo 4827 > foo && + git add foo && + git commit -m "initial" && + git cat-file -p HEAD: > actual && + test_cmp expect_initial actual && + echo 11742 > foo && + git commit -a -m "update" && + git cat-file -p HEAD: > actual && + test_cmp expect_update actual +' + +cat >expect <<EOF +index 51d27384..51d2738e 100644 +EOF + +test_expect_success 'diff does not produce ambiguous index line' ' + git diff HEAD^..HEAD | grep index > actual && + test_cmp expect actual +' + +test_done diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index fb9ad247bf..8a676a5dcd 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -11,21 +11,22 @@ prepare_test_file () { # ! trailing-space # @ space-before-tab # # indent-with-non-tab + # % tab-in-indent sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF An_SP in an ordinary line>and a HT. - >A HT. - _>A SP and a HT (@). - _>_A SP, a HT and a SP (@). + >A HT (%). + _>A SP and a HT (@%). + _>_A SP, a HT and a SP (@%). _______Seven SP. ________Eight SP (#). - _______>Seven SP and a HT (@). - ________>Eight SP and a HT (@#). - _______>_Seven SP, a HT and a SP (@). - ________>_Eight SP, a HT and a SP (@#). + _______>Seven SP and a HT (@%). + ________>Eight SP and a HT (@#%). + _______>_Seven SP, a HT and a SP (@%). + ________>_Eight SP, a HT and a SP (@#%). _______________Fifteen SP (#). - _______________>Fifteen SP and a HT (@#). + _______________>Fifteen SP and a HT (@#%). ________________Sixteen SP (#). - ________________>Sixteen SP and a HT (@#). + ________________>Sixteen SP and a HT (@#%). _____a__Five SP, a non WS, two SP. A line with a (!) trailing SP_ A line with a (!) trailing HT> @@ -39,12 +40,11 @@ apply_patch () { } test_fix () { - # fix should not barf apply_patch --whitespace=fix || return 1 # find touched lines - diff file target | sed -n -e "s/^> //p" >fixed + $DIFF file target | sed -n -e "s/^> //p" >fixed # the changed lines are all expeced to change fixed_cnt=$(wc -l <fixed) @@ -85,14 +85,14 @@ test_expect_success setup ' test_expect_success 'whitespace=nowarn, default rule' ' apply_patch --whitespace=nowarn && - diff file target + test_cmp file target ' test_expect_success 'whitespace=warn, default rule' ' apply_patch --whitespace=warn && - diff file target + test_cmp file target ' @@ -108,7 +108,7 @@ test_expect_success 'whitespace=error-all, no rule' ' git config core.whitespace -trailing,-space-before,-indent && apply_patch --whitespace=error-all && - diff file target + test_cmp file target ' @@ -117,7 +117,7 @@ test_expect_success 'whitespace=error-all, no rule (attribute)' ' git config --unset core.whitespace && echo "target -whitespace" >.gitattributes && apply_patch --whitespace=error-all && - diff file target + test_cmp file target ' @@ -130,20 +130,25 @@ do for i in - '' do case "$i" in '') ti='#' ;; *) ti= ;; esac - rule=${t}trailing,${s}space,${i}indent - - rm -f .gitattributes - test_expect_success "rule=$rule" ' - git config core.whitespace "$rule" && - test_fix "$tt$ts$ti" - ' - - test_expect_success "rule=$rule (attributes)" ' - git config --unset core.whitespace && - echo "target whitespace=$rule" >.gitattributes && - test_fix "$tt$ts$ti" - ' - + for h in - '' + do + [ -z "$h$i" ] && continue + case "$h" in '') th='%' ;; *) th= ;; esac + rule=${t}trailing,${s}space,${i}indent,${h}tab + + rm -f .gitattributes + test_expect_success "rule=$rule" ' + git config core.whitespace "$rule" && + test_fix "$tt$ts$ti$th" + ' + + test_expect_success "rule=$rule (attributes)" ' + git config --unset core.whitespace && + echo "target whitespace=$rule" >.gitattributes && + test_fix "$tt$ts$ti$th" + ' + + done done done done @@ -325,6 +330,18 @@ test_expect_success 'two missing blank lines at end with --whitespace=fix' ' test_cmp one expect ' +test_expect_success 'missing blank line at end, insert before end, --whitespace=fix' ' + { echo a; echo; } >one && + git add one && + { echo b; echo a; echo; } >one && + cp one expect && + git diff -- one >patch && + echo a >one && + test_must_fail git apply patch && + git apply --whitespace=fix patch && + test_cmp one expect +' + test_expect_success 'shrink file with tons of missing blanks at end of file' ' { echo a; echo b; echo c; } >one && cp one no-blank-lines && diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh index 3a8202ea93..77200c0b2d 100755 --- a/t/t4127-apply-same-fn.sh +++ b/t/t4127-apply-same-fn.sh @@ -27,7 +27,7 @@ test_expect_success 'apply same filename with independent changes' ' cp same_fn same_fn2 && git reset --hard && git apply patch0 && - diff same_fn same_fn2 + test_cmp same_fn same_fn2 ' test_expect_success 'apply same filename with overlapping changes' ' @@ -40,7 +40,7 @@ test_expect_success 'apply same filename with overlapping changes' ' cp same_fn same_fn2 && git reset --hard && git apply patch0 && - diff same_fn same_fn2 + test_cmp same_fn same_fn2 ' test_expect_success 'apply same new filename after rename' ' @@ -54,7 +54,7 @@ test_expect_success 'apply same new filename after rename' ' cp new_fn new_fn2 && git reset --hard && git apply --index patch1 && - diff new_fn new_fn2 + test_cmp new_fn new_fn2 ' test_expect_success 'apply same old filename after rename -- should fail.' ' diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh new file mode 100755 index 0000000000..1b82f93cff --- /dev/null +++ b/t/t4134-apply-submodule.sh @@ -0,0 +1,38 @@ +#!/bin/sh +# +# Copyright (c) 2010 Peter Collingbourne +# + +test_description='git apply submodule tests' + +. ./test-lib.sh + +test_expect_success setup ' + cat > create-sm.patch <<EOF +diff --git a/dir/sm b/dir/sm +new file mode 160000 +index 0000000..0123456 +--- /dev/null ++++ b/dir/sm +@@ -0,0 +1 @@ ++Subproject commit 0123456789abcdef0123456789abcdef01234567 +EOF + cat > remove-sm.patch <<EOF +diff --git a/dir/sm b/dir/sm +deleted file mode 160000 +index 0123456..0000000 +--- a/dir/sm ++++ /dev/null +@@ -1 +0,0 @@ +-Subproject commit 0123456789abcdef0123456789abcdef01234567 +EOF +' + +test_expect_success 'removing a submodule also removes all leading subdirectories' ' + git apply --index create-sm.patch && + test -d dir/sm && + git apply --index remove-sm.patch && + test \! -d dir +' + +test_done diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index a01e55bf6b..cdb70b4b33 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -8,30 +8,93 @@ test_description='git shortlog . ./test-lib.sh -echo 1 > a1 -git add a1 -tree=$(git write-tree) -commit=$( (echo "Test"; echo) | git commit-tree $tree ) -git update-ref HEAD $commit +test_expect_success 'setup' ' + echo 1 >a1 && + git add a1 && + tree=$(git write-tree) && + commit=$(printf "%s\n" "Test" "" | git commit-tree "$tree") && + git update-ref HEAD "$commit" && + + echo 2 >a1 && + git commit --quiet -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1 && + + # test if the wrapping is still valid + # when replacing all is by treble clefs. + echo 3 >a1 && + git commit --quiet -m "$( + echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | + sed "s/i/1234/g" | + tr 1234 "\360\235\204\236")" a1 && + + # now fsck up the utf8 + git config i18n.commitencoding non-utf-8 && + echo 4 >a1 && + git commit --quiet -m "$( + echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | + sed "s/i/1234/g" | + tr 1234 "\370\235\204\236")" a1 && + + echo 5 >a1 && + git commit --quiet -m "a 12 34 56 78" a1 + + echo 6 >a1 && + git commit --quiet -m "Commit by someone else" \ + --author="Someone else <not!me>" a1 && + + cat >expect.template <<-\EOF + A U Thor (5): + SUBJECT + SUBJECT + SUBJECT + SUBJECT + SUBJECT + + Someone else (1): + SUBJECT + + EOF +' -echo 2 > a1 -git commit --quiet -m "This is a very, very long first line for the commit message to see if it is wrapped correctly" a1 +fuzz() { + file=$1 && + sed " + s/$_x40/OBJECT_NAME/g + s/$_x05/OBJID/g + s/^ \{6\}[CTa].*/ SUBJECT/g + s/^ \{8\}[^ ].*/ CONTINUATION/g + " <"$file" >"$file.fuzzy" && + sed "/CONTINUATION/ d" <"$file.fuzzy" +} -# test if the wrapping is still valid when replacing all i's by treble clefs. -echo 3 > a1 -git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\360\235\204\236')" a1 +test_expect_success 'default output format' ' + git shortlog HEAD >log && + fuzz log >log.predictable && + test_cmp expect.template log.predictable +' -# now fsck up the utf8 -git config i18n.commitencoding non-utf-8 -echo 4 > a1 -git commit --quiet -m "$(echo "This is a very, very long first line for the commit message to see if it is wrapped correctly" | sed "s/i/1234/g" | tr 1234 '\370\235\204\236')" a1 +test_expect_success 'pretty format' ' + sed s/SUBJECT/OBJECT_NAME/ expect.template >expect && + git shortlog --format="%H" HEAD >log && + fuzz log >log.predictable && + test_cmp expect log.predictable +' -echo 5 > a1 -git commit --quiet -m "a 12 34 56 78" a1 +test_expect_success '--abbrev' ' + sed s/SUBJECT/OBJID/ expect.template >expect && + git shortlog --format="%h" --abbrev=5 HEAD >log && + fuzz log >log.predictable && + test_cmp expect log.predictable +' -git shortlog -w HEAD > out +test_expect_success 'output from user-defined format is re-wrapped' ' + sed "s/SUBJECT/two lines/" expect.template >expect && + git shortlog --format="two%nlines" HEAD >log && + fuzz log >log.predictable && + test_cmp expect log.predictable +' -cat > expect << EOF +test_expect_success 'shortlog wrapping' ' + cat >expect <<\EOF && A U Thor (5): Test This is a very, very long first line for the commit message to see if @@ -43,14 +106,19 @@ A U Thor (5): a 12 34 56 78 -EOF - -test_expect_success 'shortlog wrapping' 'test_cmp expect out' +Someone else (1): + Commit by someone else -git log HEAD > log -GIT_DIR=non-existing git shortlog -w < log > out +EOF + git shortlog -w HEAD >out && + test_cmp expect out +' -test_expect_success 'shortlog from non-git directory' 'test_cmp expect out' +test_expect_success 'shortlog from non-git directory' ' + git log HEAD >log && + GIT_DIR=non-existing git shortlog -w <log >out && + test_cmp expect out +' iconvfromutf8toiso88591() { printf "%s" "$*" | iconv -f UTF-8 -t ISO8859-1 diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 1dc224f6fb..2230e606ed 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -387,5 +387,54 @@ test_expect_success 'log --graph with merge' ' test_cmp expect actual ' +test_expect_success 'log.decorate configuration' ' + git config --unset-all log.decorate || : + + git log --oneline >expect.none && + git log --oneline --decorate >expect.short && + git log --oneline --decorate=full >expect.full && + + echo "[log] decorate" >>.git/config && + git log --oneline >actual && + test_cmp expect.short actual && + + git config --unset-all log.decorate && + git config log.decorate true && + git log --oneline >actual && + test_cmp expect.short actual && + git log --oneline --decorate=full >actual && + test_cmp expect.full actual && + git log --oneline --decorate=no >actual && + test_cmp expect.none actual && + + git config --unset-all log.decorate && + git config log.decorate no && + git log --oneline >actual && + test_cmp expect.none actual && + git log --oneline --decorate >actual && + test_cmp expect.short actual && + git log --oneline --decorate=full >actual && + test_cmp expect.full actual && + + git config --unset-all log.decorate && + git config log.decorate short && + git log --oneline >actual && + test_cmp expect.short actual && + git log --oneline --no-decorate >actual && + test_cmp expect.none actual && + git log --oneline --decorate=full >actual && + test_cmp expect.full actual && + + git config --unset-all log.decorate && + git config log.decorate full && + git log --oneline >actual && + test_cmp expect.full actual && + git log --oneline --no-decorate >actual && + test_cmp expect.none actual && + git log --oneline --decorate >actual && + test_cmp expect.short actual + +' + test_done diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh index 04f7bae850..68e2652814 100755 --- a/t/t4204-patch-id.sh +++ b/t/t4204-patch-id.sh @@ -18,6 +18,11 @@ test_expect_success 'patch-id output is well-formed' ' grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output ' +calc_patch_id () { + git patch-id | + sed "s# .*##" > patch-id_"$1" +} + get_patch_id () { git log -p -1 "$1" | git patch-id | sed "s# .*##" > patch-id_"$1" @@ -35,4 +40,27 @@ test_expect_success 'patch-id detects inequality' ' ! test_cmp patch-id_master patch-id_notsame ' +test_expect_success 'patch-id supports git-format-patch output' ' + get_patch_id master && + git checkout same && + git format-patch -1 --stdout | calc_patch_id same && + test_cmp patch-id_master patch-id_same && + set `git format-patch -1 --stdout | git patch-id` && + test "$2" = `git rev-parse HEAD` +' + +test_expect_success 'whitespace is irrelevant in footer' ' + get_patch_id master && + git checkout same && + git format-patch -1 --stdout | sed "s/ \$//" | calc_patch_id same && + test_cmp patch-id_master patch-id_same +' + +test_expect_success 'patch-id supports git-format-patch MIME output' ' + get_patch_id master && + git checkout same && + git format-patch -1 --attach --stdout | calc_patch_id same && + test_cmp patch-id_master patch-id_same +' + test_done diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh new file mode 100755 index 0000000000..cb9f2bdd29 --- /dev/null +++ b/t/t4205-log-pretty-formats.sh @@ -0,0 +1,74 @@ +#!/bin/sh +# +# Copyright (c) 2010, Will Palmer +# + +test_description='Test pretty formats' +. ./test-lib.sh + +test_expect_success 'set up basic repos' ' + >foo && + >bar && + git add foo && + test_tick && + git commit -m initial && + git add bar && + test_tick && + git commit -m "add bar" +' + +test_expect_success 'alias builtin format' ' + git log --pretty=oneline >expected && + git config pretty.test-alias oneline && + git log --pretty=test-alias >actual && + test_cmp expected actual +' + +test_expect_success 'alias masking builtin format' ' + git log --pretty=oneline >expected && + git config pretty.oneline "%H" && + git log --pretty=oneline >actual && + test_cmp expected actual +' + +test_expect_success 'alias user-defined format' ' + git log --pretty="format:%h" >expected && + git config pretty.test-alias "format:%h" && + git log --pretty=test-alias >actual && + test_cmp expected actual +' + +test_expect_success 'alias user-defined tformat' ' + git log --pretty="tformat:%h" >expected && + git config pretty.test-alias "tformat:%h" && + git log --pretty=test-alias >actual && + test_cmp expected actual +' + +test_expect_success 'alias non-existant format' ' + git config pretty.test-alias format-that-will-never-exist && + test_must_fail git log --pretty=test-alias +' + +test_expect_success 'alias of an alias' ' + git log --pretty="tformat:%h" >expected && + git config pretty.test-foo "tformat:%h" && + git config pretty.test-bar test-foo && + git log --pretty=test-bar >actual && test_cmp expected actual +' + +test_expect_success 'alias masking an alias' ' + git log --pretty=format:"Two %H" >expected && + git config pretty.duplicate "format:One %H" && + git config --add pretty.duplicate "format:Two %H" && + git log --pretty=duplicate >actual && + test_cmp expected actual +' + +test_expect_success 'alias loop' ' + git config pretty.test-foo test-bar && + git config pretty.test-bar test-foo && + test_must_fail git log --pretty=test-foo +' + +test_done diff --git a/t/t4206-log-follow-harder-copies.sh b/t/t4206-log-follow-harder-copies.sh new file mode 100755 index 0000000000..ad29e65fcb --- /dev/null +++ b/t/t4206-log-follow-harder-copies.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# Copyright (c) 2010 Bo Yang +# + +test_description='Test --follow should always find copies hard in git log. + +' +. ./test-lib.sh +. "$TEST_DIRECTORY"/diff-lib.sh + +echo >path0 'Line 1 +Line 2 +Line 3 +' + +test_expect_success \ + 'add a file path0 and commit.' \ + 'git add path0 && + git commit -m "Add path0"' + +echo >path0 'New line 1 +New line 2 +New line 3 +' +test_expect_success \ + 'Change path0.' \ + 'git add path0 && + git commit -m "Change path0"' + +cat <path0 >path1 +test_expect_success \ + 'copy path0 to path1.' \ + 'git add path1 && + git commit -m "Copy path1 from path0"' + +test_expect_success \ + 'find the copy path0 -> path1 harder' \ + 'git log --follow --name-status --pretty="format:%s" path1 > current' + +cat >expected <<\EOF +Copy path1 from path0 +C100 path0 path1 + +Change path0 +M path0 + +Add path0 +A path0 +EOF + +test_expect_success \ + 'validate the output.' \ + 'compare_diff_patch current expected' + +test_done diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh new file mode 100755 index 0000000000..9cc0a42ea9 --- /dev/null +++ b/t/t5150-request-pull.sh @@ -0,0 +1,228 @@ +#!/bin/sh + +test_description='Test workflows involving pull request.' + +. ./test-lib.sh + +test_expect_success 'setup' ' + + git init --bare upstream.git && + git init --bare downstream.git && + git clone upstream.git upstream-private && + git clone downstream.git local && + + trash_url="file://$TRASH_DIRECTORY" && + downstream_url="$trash_url/downstream.git/" && + upstream_url="$trash_url/upstream.git/" && + + ( + cd upstream-private && + cat <<-\EOT >mnemonic.txt && + Thirtey days hath November, + Aprile, June, and September: + EOT + git add mnemonic.txt && + test_tick && + git commit -m "\"Thirty days\", a reminder of month lengths" && + git tag -m "version 1" -a initial && + git push --tags origin master + ) && + ( + cd local && + git remote add upstream "$trash_url/upstream.git" && + git fetch upstream && + git pull upstream master && + cat <<-\EOT >>mnemonic.txt && + Of twyecescore-eightt is but eine, + And all the remnante be thrycescore-eine. + O’course Leap yare comes an’pynes, + Ev’rie foure yares, gote it ryghth. + An’twyecescore-eight is but twyecescore-nyne. + EOT + git add mnemonic.txt && + test_tick && + git commit -m "More detail" && + git tag -m "version 2" -a full && + git checkout -b simplify HEAD^ && + mv mnemonic.txt mnemonic.standard && + cat <<-\EOT >mnemonic.clarified && + Thirty days has September, + All the rest I can’t remember. + EOT + git add -N mnemonic.standard mnemonic.clarified && + git commit -a -m "Adapt to use modern, simpler English + +But keep the old version, too, in case some people prefer it." && + git checkout master + ) + +' + +test_expect_success 'setup: two scripts for reading pull requests' ' + + downstream_url_for_sed=$( + printf "%s\n" "$downstream_url" | + sed -e '\''s/\\/\\\\/g'\'' -e '\''s/[[/.*^$]/\\&/g'\'' + ) && + + cat <<-\EOT >read-request.sed && + #!/bin/sed -nf + / in the git repository at:$/!d + n + /^$/ n + s/^[ ]*\(.*\) \([^ ]*\)/please pull\ + \1\ + \2/p + q + EOT + + cat <<-EOT >fuzz.sed + #!/bin/sed -nf + s/$_x40/OBJECT_NAME/g + s/A U Thor/AUTHOR/g + s/[-0-9]\{10\} [:0-9]\{8\} [-+][0-9]\{4\}/DATE/g + s/ [^ ].*/ SUBJECT/g + s/ [^ ].* (DATE)/ SUBJECT (DATE)/g + s/$downstream_url_for_sed/URL/g + s/for-upstream/BRANCH/g + s/mnemonic.txt/FILENAME/g + /^ FILENAME | *[0-9]* [-+]*\$/ b diffstat + /^AUTHOR ([0-9]*):\$/ b shortlog + p + b + : diffstat + n + / [0-9]* files changed/ { + a\\ + DIFFSTAT + b + } + b diffstat + : shortlog + /^ [a-zA-Z]/ n + /^[a-zA-Z]* ([0-9]*):\$/ n + /^\$/ N + /^\n[a-zA-Z]* ([0-9]*):\$/!{ + a\\ + SHORTLOG + D + } + n + b shortlog + EOT + +' + +test_expect_success 'pull request when forgot to push' ' + + rm -fr downstream.git && + git init --bare downstream.git && + ( + cd local && + git checkout initial && + git merge --ff-only master && + test_must_fail git request-pull initial "$downstream_url" \ + 2>../err + ) && + grep "No branch of.*is at:\$" err && + grep "Are you sure you pushed" err + +' + +test_expect_success 'pull request after push' ' + + rm -fr downstream.git && + git init --bare downstream.git && + ( + cd local && + git checkout initial && + git merge --ff-only master && + git push origin master:for-upstream && + git request-pull initial origin >../request + ) && + sed -nf read-request.sed <request >digest && + cat digest && + { + read task && + read repository && + read branch + } <digest && + ( + cd upstream-private && + git checkout initial && + git pull --ff-only "$repository" "$branch" + ) && + test "$branch" = for-upstream && + test_cmp local/mnemonic.txt upstream-private/mnemonic.txt + +' + +test_expect_success 'request names an appropriate branch' ' + + rm -fr downstream.git && + git init --bare downstream.git && + ( + cd local && + git checkout initial && + git merge --ff-only master && + git push --tags origin master simplify && + git push origin master:for-upstream && + git request-pull initial "$downstream_url" >../request + ) && + sed -nf read-request.sed <request >digest && + cat digest && + { + read task && + read repository && + read branch + } <digest && + { + test "$branch" = master || + test "$branch" = for-upstream + } + +' + +test_expect_success 'pull request format' ' + + rm -fr downstream.git && + git init --bare downstream.git && + cat <<-\EOT >expect && + The following changes since commit OBJECT_NAME: + + SUBJECT (DATE) + + are available in the git repository at: + URL BRANCH + + SHORTLOG + + DIFFSTAT + EOT + ( + cd local && + git checkout initial && + git merge --ff-only master && + git push origin master:for-upstream && + git request-pull initial "$downstream_url" >../request + ) && + <request sed -nf fuzz.sed >request.fuzzy && + test_cmp expect request.fuzzy + +' + +test_expect_success 'request-pull ignores OPTIONS_KEEPDASHDASH poison' ' + + ( + cd local && + OPTIONS_KEEPDASHDASH=Yes && + export OPTIONS_KEEPDASHDASH && + git checkout initial && + git merge --ff-only master && + git push origin master:for-upstream && + git request-pull -- initial "$downstream_url" >../request + ) + +' + +test_done diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 7649b810b1..bbb9c1251d 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -147,7 +147,7 @@ test_expect_success \ git cat-file $t $object || return 1 done <obj-list } >current && - diff expect current' + test_cmp expect current' test_expect_success \ 'use packed deltified (REF_DELTA) objects' \ @@ -162,7 +162,7 @@ test_expect_success \ git cat-file $t $object || return 1 done <obj-list } >current && - diff expect current' + test_cmp expect current' test_expect_success \ 'use packed deltified (OFS_DELTA) objects' \ @@ -177,7 +177,7 @@ test_expect_success \ git cat-file $t $object || return 1 done <obj-list } >current && - diff expect current' + test_cmp expect current' unset GIT_OBJECT_DIRECTORY diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 230c0cd784..4c498b1902 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -320,6 +320,69 @@ test_expect_success 'add alt && prune' ' git rev-parse --verify refs/remotes/origin/side2) ' +cat >test/expect <<\EOF +some-tag +EOF + +test_expect_success 'add with reachable tags (default)' ' + (cd one && + >foobar && + git add foobar && + git commit -m "Foobar" && + git tag -a -m "Foobar tag" foobar-tag && + git reset --hard HEAD~1 && + git tag -a -m "Some tag" some-tag) && + (mkdir add-tags && + cd add-tags && + git init && + git remote add -f origin ../one && + git tag -l some-tag >../test/output && + git tag -l foobar-tag >>../test/output && + test_must_fail git config remote.origin.tagopt) && + test_cmp test/expect test/output +' + +cat >test/expect <<\EOF +some-tag +foobar-tag +--tags +EOF + +test_expect_success 'add --tags' ' + (rm -rf add-tags && + mkdir add-tags && + cd add-tags && + git init && + git remote add -f --tags origin ../one && + git tag -l some-tag >../test/output && + git tag -l foobar-tag >>../test/output && + git config remote.origin.tagopt >>../test/output) && + test_cmp test/expect test/output +' + +cat >test/expect <<\EOF +--no-tags +EOF + +test_expect_success 'add --no-tags' ' + (rm -rf add-tags && + mkdir add-no-tags && + cd add-no-tags && + git init && + git remote add -f --no-tags origin ../one && + git tag -l some-tag >../test/output && + git tag -l foobar-tag >../test/output && + git config remote.origin.tagopt >>../test/output) && + (cd one && + git tag -d some-tag foobar-tag) && + test_cmp test/expect test/output +' + +test_expect_success 'reject --no-no-tags' ' + (cd add-no-tags && + test_must_fail git remote add -f --no-no-tags neworigin ../one) +' + cat > one/expect << EOF apis/master apis/side @@ -534,6 +597,94 @@ test_expect_success 'show empty remote' ' ) ' +test_expect_success 'remote set-branches requires a remote' ' + test_must_fail git remote set-branches && + test_must_fail git remote set-branches --add +' + +test_expect_success 'remote set-branches' ' + echo "+refs/heads/*:refs/remotes/scratch/*" >expect.initial && + sort <<-\EOF >expect.add && + +refs/heads/*:refs/remotes/scratch/* + +refs/heads/other:refs/remotes/scratch/other + EOF + sort <<-\EOF >expect.replace && + +refs/heads/maint:refs/remotes/scratch/maint + +refs/heads/master:refs/remotes/scratch/master + +refs/heads/next:refs/remotes/scratch/next + EOF + sort <<-\EOF >expect.add-two && + +refs/heads/maint:refs/remotes/scratch/maint + +refs/heads/master:refs/remotes/scratch/master + +refs/heads/next:refs/remotes/scratch/next + +refs/heads/pu:refs/remotes/scratch/pu + +refs/heads/t/topic:refs/remotes/scratch/t/topic + EOF + sort <<-\EOF >expect.setup-ffonly && + refs/heads/master:refs/remotes/scratch/master + +refs/heads/next:refs/remotes/scratch/next + EOF + sort <<-\EOF >expect.respect-ffonly && + refs/heads/master:refs/remotes/scratch/master + +refs/heads/next:refs/remotes/scratch/next + +refs/heads/pu:refs/remotes/scratch/pu + EOF + + git clone .git/ setbranches && + ( + cd setbranches && + git remote rename origin scratch && + git config --get-all remote.scratch.fetch >config-result && + sort <config-result >../actual.initial && + + git remote set-branches scratch --add other && + git config --get-all remote.scratch.fetch >config-result && + sort <config-result >../actual.add && + + git remote set-branches scratch maint master next && + git config --get-all remote.scratch.fetch >config-result && + sort <config-result >../actual.replace && + + git remote set-branches --add scratch pu t/topic && + git config --get-all remote.scratch.fetch >config-result && + sort <config-result >../actual.add-two && + + git config --unset-all remote.scratch.fetch && + git config remote.scratch.fetch \ + refs/heads/master:refs/remotes/scratch/master && + git config --add remote.scratch.fetch \ + +refs/heads/next:refs/remotes/scratch/next && + git config --get-all remote.scratch.fetch >config-result && + sort <config-result >../actual.setup-ffonly && + + git remote set-branches --add scratch pu && + git config --get-all remote.scratch.fetch >config-result && + sort <config-result >../actual.respect-ffonly + ) && + test_cmp expect.initial actual.initial && + test_cmp expect.add actual.add && + test_cmp expect.replace actual.replace && + test_cmp expect.add-two actual.add-two && + test_cmp expect.setup-ffonly actual.setup-ffonly && + test_cmp expect.respect-ffonly actual.respect-ffonly +' + +test_expect_success 'remote set-branches with --mirror' ' + echo "+refs/*:refs/*" >expect.initial && + echo "+refs/heads/master:refs/heads/master" >expect.replace && + git clone --mirror .git/ setbranches-mirror && + ( + cd setbranches-mirror && + git remote rename origin scratch && + git config --get-all remote.scratch.fetch >../actual.initial && + + git remote set-branches scratch heads/master && + git config --get-all remote.scratch.fetch >../actual.replace + ) && + test_cmp expect.initial actual.initial && + test_cmp expect.replace actual.replace +' + test_expect_success 'new remote' ' git remote add someremote foo && echo foo >expect && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 721821ec92..4eb10f602f 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -71,7 +71,7 @@ test_expect_success "fetch test for-merge" ' echo "$one_in_two " } >expected && cut -f -2 .git/FETCH_HEAD >actual && - diff expected actual' + test_cmp expected actual' test_expect_success 'fetch tags when there is no tags' ' diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 1dd8eed5bb..d1912351db 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -49,4 +49,78 @@ test_expect_success 'ls-remote self' ' ' +test_expect_success 'dies when no remote specified and no default remotes found' ' + + test_must_fail git ls-remote + +' + +test_expect_success 'use "origin" when no remote specified' ' + + URL="$(pwd)/.git" && + echo "From $URL" >exp_err && + + git remote add origin "$URL" && + git ls-remote 2>actual_err >actual && + + test_cmp exp_err actual_err && + test_cmp expected.all actual + +' + +test_expect_success 'suppress "From <url>" with -q' ' + + git ls-remote -q 2>actual_err && + test_must_fail test_cmp exp_err actual_err + +' + +test_expect_success 'use branch.<name>.remote if possible' ' + + # + # Test that we are indeed using branch.<name>.remote, not "origin", even + # though the "origin" remote has been set. + # + + # setup a new remote to differentiate from "origin" + git clone . other.git && + ( + cd other.git && + echo "$(git rev-parse HEAD) HEAD" + git show-ref | sed -e "s/ / /" + ) >exp && + + URL="other.git" && + echo "From $URL" >exp_err && + + git remote add other $URL && + git config branch.master.remote other && + + git ls-remote 2>actual_err >actual && + test_cmp exp_err actual_err && + test_cmp exp actual + +' + +cat >exp <<EOF +fatal: 'refs*master' does not appear to be a git repository +fatal: The remote end hung up unexpectedly +EOF +test_expect_success 'confuses pattern as remote when no remote specified' ' + # + # Do not expect "git ls-remote <pattern>" to work; ls-remote, correctly, + # confuses <pattern> for <remote>. Although ugly, this behaviour is akin + # to the confusion of refspecs for remotes by git-fetch and git-push, + # eg: + # + # $ git fetch branch + # + + # We could just as easily have used "master"; the "*" emphasizes its + # role as a pattern. + test_must_fail git ls-remote refs*master >actual 2>&1 && + test_cmp exp actual + +' + test_done diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 2de98e6561..b11da79c9c 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -64,13 +64,13 @@ check_push_result () { test_expect_success setup ' - : >path1 && + >path1 && git add path1 && test_tick && git commit -a -m repo && the_first_commit=$(git show-ref -s --verify refs/heads/master) && - : >path2 && + >path2 && git add path2 && test_tick && git commit -a -m second && @@ -483,8 +483,10 @@ git config --remove-section remote.there test_expect_success 'push with dry-run' ' mk_test heads/master && - (cd testrepo && - old_commit=$(git show-ref -s --verify refs/heads/master)) && + ( + cd testrepo && + old_commit=$(git show-ref -s --verify refs/heads/master) + ) && git push --dry-run testrepo && check_push_result $old_commit heads/master ' @@ -493,10 +495,13 @@ test_expect_success 'push updates local refs' ' mk_test heads/master && mk_child child && - (cd child && + ( + cd child && git pull .. master && git push && - test $(git rev-parse master) = $(git rev-parse remotes/origin/master)) + test $(git rev-parse master) = \ + $(git rev-parse remotes/origin/master) + ) ' @@ -506,10 +511,13 @@ test_expect_success 'push updates up-to-date local refs' ' mk_child child1 && mk_child child2 && (cd child1 && git pull .. master && git push) && - (cd child2 && + ( + cd child2 && git pull ../child1 master && git push && - test $(git rev-parse master) = $(git rev-parse remotes/origin/master)) + test $(git rev-parse master) = \ + $(git rev-parse remotes/origin/master) + ) ' @@ -517,9 +525,11 @@ test_expect_success 'push preserves up-to-date packed refs' ' mk_test heads/master && mk_child child && - (cd child && + ( + cd child && git push && - ! test -f .git/refs/remotes/origin/master) + ! test -f .git/refs/remotes/origin/master + ) ' @@ -528,13 +538,15 @@ test_expect_success 'push does not update local refs on failure' ' mk_test heads/master && mk_child child && mkdir testrepo/.git/hooks && - echo exit 1 >testrepo/.git/hooks/pre-receive && + echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive && chmod +x testrepo/.git/hooks/pre-receive && - (cd child && + ( + cd child && git pull .. master test_must_fail git push && test $(git rev-parse master) != \ - $(git rev-parse remotes/origin/master)) + $(git rev-parse remotes/origin/master) + ) ' @@ -575,34 +587,41 @@ test_expect_success 'push --delete refuses src:dest refspecs' ' test_expect_success 'warn on push to HEAD of non-bare repository' ' mk_test heads/master - (cd testrepo && + ( + cd testrepo && git checkout master && - git config receive.denyCurrentBranch warn) && + git config receive.denyCurrentBranch warn + ) && git push testrepo master 2>stderr && grep "warning: updating the current branch" stderr ' test_expect_success 'deny push to HEAD of non-bare repository' ' mk_test heads/master - (cd testrepo && + ( + cd testrepo && git checkout master && - git config receive.denyCurrentBranch true) && + git config receive.denyCurrentBranch true + ) && test_must_fail git push testrepo master ' test_expect_success 'allow push to HEAD of bare repository (bare)' ' mk_test heads/master - (cd testrepo && + ( + cd testrepo && git checkout master && git config receive.denyCurrentBranch true && - git config core.bare true) && + git config core.bare true + ) && git push testrepo master 2>stderr && ! grep "warning: updating the current branch" stderr ' test_expect_success 'allow push to HEAD of non-bare repository (config)' ' mk_test heads/master - (cd testrepo && + ( + cd testrepo && git checkout master && git config receive.denyCurrentBranch false ) && @@ -615,7 +634,8 @@ test_expect_success 'fetch with branches' ' git branch second $the_first_commit && git checkout second && echo ".." > testrepo/.git/branches/branch1 && - (cd testrepo && + ( + cd testrepo && git fetch branch1 && r=$(git show-ref -s --verify refs/heads/branch1) && test "z$r" = "z$the_commit" && @@ -627,7 +647,8 @@ test_expect_success 'fetch with branches' ' test_expect_success 'fetch with branches containing #' ' mk_empty && echo "..#second" > testrepo/.git/branches/branch2 && - (cd testrepo && + ( + cd testrepo && git fetch branch2 && r=$(git show-ref -s --verify refs/heads/branch2) && test "z$r" = "z$the_first_commit" && @@ -641,7 +662,8 @@ test_expect_success 'push with branches' ' git checkout second && echo "testrepo" > .git/branches/branch1 && git push branch1 && - (cd testrepo && + ( + cd testrepo && r=$(git show-ref -s --verify refs/heads/master) && test "z$r" = "z$the_first_commit" && test 1 = $(git for-each-ref refs/heads | wc -l) @@ -652,7 +674,8 @@ test_expect_success 'push with branches containing #' ' mk_empty && echo "testrepo#branch3" > .git/branches/branch2 && git push branch2 && - (cd testrepo && + ( + cd testrepo && r=$(git show-ref -s --verify refs/heads/branch3) && test "z$r" = "z$the_first_commit" && test 1 = $(git for-each-ref refs/heads | wc -l) @@ -660,6 +683,55 @@ test_expect_success 'push with branches containing #' ' git checkout master ' +test_expect_success 'push into aliased refs (consistent)' ' + mk_test heads/master && + mk_child child1 && + mk_child child2 && + ( + cd child1 && + git branch foo && + git symbolic-ref refs/heads/bar refs/heads/foo + git config receive.denyCurrentBranch false + ) && + ( + cd child2 && + >path2 && + git add path2 && + test_tick && + git commit -a -m child2 && + git branch foo && + git branch bar && + git push ../child1 foo bar + ) +' + +test_expect_success 'push into aliased refs (inconsistent)' ' + mk_test heads/master && + mk_child child1 && + mk_child child2 && + ( + cd child1 && + git branch foo && + git symbolic-ref refs/heads/bar refs/heads/foo + git config receive.denyCurrentBranch false + ) && + ( + cd child2 && + >path2 && + git add path2 && + test_tick && + git commit -a -m child2 && + git branch foo && + >path3 && + git add path3 && + test_tick && + git commit -a -m child2 && + git branch bar && + test_must_fail git push ../child1 foo bar 2>stderr && + grep "refusing inconsistent update" stderr + ) +' + test_expect_success 'push --porcelain' ' mk_empty && echo >.git/foo "To testrepo" && diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index dd2ee842e0..319e389ed0 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -26,7 +26,7 @@ cd "$D" test_expect_success 'checking the results' ' test -f file && test -f cloned/file && - diff file cloned/file + test_cmp file cloned/file ' test_expect_success 'pulling into void using master:master' ' diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index a696b8791b..044603c26e 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -32,9 +32,9 @@ test_expect_success 'fsck fails' ' test_expect_success 'upload-pack fails due to error in pack-objects packing' ' - ! echo "0032want $(git rev-parse HEAD) -00000009done -0000" | git upload-pack . > /dev/null 2> output.err && + printf "0032want %s\n00000009done\n0000" \ + $(git rev-parse HEAD) >input && + test_must_fail git upload-pack . <input >/dev/null 2>output.err && grep "unable to read" output.err && grep "pack-objects died" output.err ' @@ -51,9 +51,9 @@ test_expect_success 'fsck fails' ' ' test_expect_success 'upload-pack fails due to error in rev-list' ' - ! echo "0032want $(git rev-parse HEAD) -0034shallow $(git rev-parse HEAD^)00000009done -0000" | git upload-pack . > /dev/null 2> output.err && + printf "0032want %s\n0034shallow %s00000009done\n0000" \ + $(git rev-parse HEAD) $(git rev-parse HEAD^) >input && + test_must_fail git upload-pack . <input >/dev/null 2>output.err && # pack-objects survived grep "Total.*, reused" output.err && # but there was an error, which must have been in rev-list @@ -62,9 +62,9 @@ test_expect_success 'upload-pack fails due to error in rev-list' ' test_expect_success 'upload-pack fails due to error in pack-objects enumeration' ' - ! echo "0032want $(git rev-parse HEAD) -00000009done -0000" | git upload-pack . > /dev/null 2> output.err && + printf "0032want %s\n00000009done\n0000" \ + $(git rev-parse HEAD) >input && + test_must_fail git upload-pack . <input >/dev/null 2>output.err && grep "bad tree object" output.err && grep "pack-objects died" output.err ' diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh index 795dc2bcdf..17e1bdc5a8 100755 --- a/t/t5541-http-push.sh +++ b/t/t5541-http-push.sh @@ -34,8 +34,34 @@ test_expect_success 'setup remote repository' ' mv test_repo.git "$HTTPD_DOCUMENT_ROOT_PATH" ' -test_expect_success 'clone remote repository' ' +cat >exp <<EOF +GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200 +POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200 +EOF +test_expect_success 'no empty path components' ' + # In the URL, add a trailing slash, and see if git appends yet another + # slash. cd "$ROOT_PATH" && + git clone $HTTPD_URL/smart/test_repo.git/ test_repo_clone && + + sed -e " + s/^.* \"// + s/\"// + s/ [1-9][0-9]*\$// + s/^GET /GET / + " >act <"$HTTPD_ROOT_PATH"/access.log && + + # Clear the log, so that it does not affect the "used receive-pack + # service" test which reads the log too. + # + # We do this before the actual comparison to ensure the log is cleared. + echo > "$HTTPD_ROOT_PATH"/access.log && + + test_cmp exp act +' + +test_expect_success 'clone remote repository' ' + rm -rf test_repo_clone && git clone $HTTPD_URL/smart/test_repo.git test_repo_clone ' @@ -68,6 +94,7 @@ test_expect_success 'create and delete remote branch' ' ' cat >exp <<EOF + GET /smart/test_repo.git/info/refs?service=git-upload-pack HTTP/1.1 200 POST /smart/test_repo.git/git-upload-pack HTTP/1.1 200 GET /smart/test_repo.git/info/refs?service=git-receive-pack HTTP/1.1 200 diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh index 8cfce969bc..fc675b50ad 100755 --- a/t/t5550-http-fetch.sh +++ b/t/t5550-http-fetch.sh @@ -55,12 +55,43 @@ test_expect_success 'http remote detects correct HEAD' ' test_expect_success 'fetch packed objects' ' cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git && - cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git && - git --bare repack && - git --bare prune-packed && + (cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git && + git --bare repack && + git --bare prune-packed + ) && git clone $HTTPD_URL/dumb/repo_pack.git ' +test_expect_success 'fetch notices corrupt pack' ' + cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad1.git && + (cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad1.git && + p=`ls objects/pack/pack-*.pack` && + chmod u+w $p && + printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc + ) && + mkdir repo_bad1.git && + (cd repo_bad1.git && + git --bare init && + test_must_fail git --bare fetch $HTTPD_URL/dumb/repo_bad1.git && + test 0 = `ls objects/pack/pack-*.pack | wc -l` + ) +' + +test_expect_success 'fetch notices corrupt idx' ' + cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad2.git && + (cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad2.git && + p=`ls objects/pack/pack-*.idx` && + chmod u+w $p && + printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc + ) && + mkdir repo_bad2.git && + (cd repo_bad2.git && + git --bare init && + test_must_fail git --bare fetch $HTTPD_URL/dumb/repo_bad2.git && + test 0 = `ls objects/pack | wc -l` + ) +' + test_expect_success 'did not use upload-pack service' ' grep '/git-upload-pack' <"$HTTPD_ROOT_PATH"/access.log >act : >exp diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 214756731b..8abb71afcd 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -34,7 +34,7 @@ test_expect_success 'clone with excess parameters (2)' ' test_expect_success 'output from clone' ' rm -fr dst && git clone -n "file://$(pwd)/src" dst >output && - test $(grep Initialized output | wc -l) = 1 + test $(grep Clon output | wc -l) = 1 ' test_expect_success 'clone does not keep pack' ' @@ -176,4 +176,16 @@ test_expect_success 'clone respects global branch.autosetuprebase' ' ) ' +test_expect_success 'respect url-encoding of file://' ' + git init x+y && + test_must_fail git clone "file://$PWD/x+y" xy-url && + git clone "file://$PWD/x%2By" xy-url +' + +test_expect_success 'do not respect url-encoding of non-url path' ' + git init x+y && + test_must_fail git clone x%2By xy-regular && + git clone x+y xy-regular +' + test_done diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh index 1c10916069..895f5595ae 100755 --- a/t/t5700-clone-reference.sh +++ b/t/t5700-clone-reference.sh @@ -48,7 +48,7 @@ test_expect_success 'that reference gets used' \ 'cd C && echo "0 objects, 0 kilobytes" > expected && git count-objects > current && -diff expected current' +test_cmp expected current' cd "$base_dir" @@ -75,7 +75,7 @@ cd "$base_dir" test_expect_success 'that reference gets used' \ 'cd D && echo "0 objects, 0 kilobytes" > expected && git count-objects > current && -diff expected current' +test_cmp expected current' cd "$base_dir" @@ -100,7 +100,7 @@ test_expect_success 'that alternate to origin gets used' \ 'cd C && echo "2 objects" > expected && git count-objects | cut -d, -f1 > current && -diff expected current' +test_cmp expected current' cd "$base_dir" @@ -116,7 +116,7 @@ test_expect_success 'check objects expected to exist locally' \ 'cd D && echo "5 objects" > expected && git count-objects | cut -d, -f1 > current && -diff expected current' +test_cmp expected current' cd "$base_dir" diff --git a/t/t5704-bundle.sh b/t/t5704-bundle.sh index a8f4419e61..ddc3dc52f4 100755 --- a/t/t5704-bundle.sh +++ b/t/t5704-bundle.sh @@ -30,4 +30,20 @@ test_expect_success 'tags can be excluded by rev-list options' ' ' +test_expect_failure 'bundle --stdin' ' + + echo master | git bundle create stdin-bundle.bdl --stdin && + git ls-remote stdin-bundle.bdl >output && + grep master output + +' + +test_expect_failure 'bundle --stdin <rev-list options>' ' + + echo master | git bundle create hybrid-bundle.bdl --stdin tag && + git ls-remote hybrid-bundle.bdl >output && + grep master output + +' + test_done diff --git a/t/t5705-clone-2gb.sh b/t/t5705-clone-2gb.sh index adfaae8c5b..8afbdd4de2 100755 --- a/t/t5705-clone-2gb.sh +++ b/t/t5705-clone-2gb.sh @@ -12,7 +12,7 @@ test_expect_success 'setup' ' git config pack.compression 0 && git config pack.depth 0 && - blobsize=$((20*1024*1024)) && + blobsize=$((100*1024*1024)) && blobcount=$((2*1024*1024*1024/$blobsize+1)) && i=1 && (while test $i -le $blobcount @@ -36,9 +36,15 @@ test_expect_success 'setup' ' ' -test_expect_success 'clone' ' +test_expect_success 'clone - bare' ' - git clone --bare --no-hardlinks . clone + git clone --bare --no-hardlinks . clone-bare + +' + +test_expect_success 'clone - with worktree, file:// protocol' ' + + git clone file://. clone-wt ' diff --git a/t/t5800-remote-helpers.sh b/t/t5800-remote-helpers.sh new file mode 100755 index 0000000000..4ee7b65ce6 --- /dev/null +++ b/t/t5800-remote-helpers.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# +# Copyright (c) 2010 Sverre Rabbelier +# + +test_description='Test remote-helper import and export commands' + +. ./test-lib.sh + +if test_have_prereq PYTHON && "$PYTHON_PATH" -c ' +import sys +if sys.hexversion < 0x02040000: + sys.exit(1) +' +then + : +else + say 'skipping git remote-testgit tests: requires Python 2.4 or newer' + test_done +fi + +test_expect_success 'setup repository' ' + git init --bare server/.git && + git clone server public && + (cd public && + echo content >file && + git add file && + git commit -m one && + git push origin master) +' + +test_expect_success 'cloning from local repo' ' + git clone "testgit::${PWD}/server" localclone && + test_cmp public/file localclone/file +' + +test_expect_success 'cloning from remote repo' ' + git clone "testgit::file://${PWD}/server" clone && + test_cmp public/file clone/file +' + +test_expect_success 'create new commit on remote' ' + (cd public && + echo content >>file && + git commit -a -m two && + git push) +' + +test_expect_success 'pulling from local repo' ' + (cd localclone && git pull) && + test_cmp public/file localclone/file +' + +test_expect_success 'pulling from remote remote' ' + (cd clone && git pull) && + test_cmp public/file clone/file +' + +test_expect_success 'pushing to local repo' ' + (cd localclone && + echo content >>file && + git commit -a -m three && + git push) && + HEAD=$(git --git-dir=localclone/.git rev-parse --verify HEAD) && + test $HEAD = $(git --git-dir=server/.git rev-parse --verify HEAD) +' + +test_expect_success 'synch with changes from localclone' ' + (cd clone && + git pull) +' + +test_expect_success 'pushing remote local repo' ' + (cd clone && + echo content >>file && + git commit -a -m four && + git push) && + HEAD=$(git --git-dir=clone/.git rev-parse --verify HEAD) && + test $HEAD = $(git --git-dir=server/.git rev-parse --verify HEAD) +' + +test_done diff --git a/t/t6001-rev-list-graft.sh b/t/t6001-rev-list-graft.sh index b2131cdacd..fc57e7d3fd 100755 --- a/t/t6001-rev-list-graft.sh +++ b/t/t6001-rev-list-graft.sh @@ -84,7 +84,7 @@ check () { git rev-list --parents --pretty=raw $arg | sed -n -e 's/^commit //p' >test.actual fi - diff test.expect test.actual + test_cmp test.expect test.actual } for type in basic parents parents-raw diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index b4e8fbaa5e..fb07536a0f 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -5,7 +5,7 @@ test_description='Tests git rev-list --bisect functionality' . ./test-lib.sh -. "$TEST_DIRECTORY"/t6000lib.sh # t6xxx specific functions +. "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions # usage: test_bisection max-diff bisect-option head ^prune... # diff --git a/t/t6003-rev-list-topo-order.sh b/t/t6003-rev-list-topo-order.sh index 2c73f2da7b..e4c52b0214 100755 --- a/t/t6003-rev-list-topo-order.sh +++ b/t/t6003-rev-list-topo-order.sh @@ -6,7 +6,7 @@ test_description='Tests git rev-list --topo-order functionality' . ./test-lib.sh -. "$TEST_DIRECTORY"/t6000lib.sh # t6xxx specific functions +. "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions list_duplicates() { diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index a49b7c5722..9b77073df8 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -101,6 +101,15 @@ commit 131a310eb913d107dd3c09a65d1651175898735d commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 EOF +test_format raw-body %B <<'EOF' +commit 131a310eb913d107dd3c09a65d1651175898735d +changed foo + +commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 +added foo + +EOF + test_format colors %Credfoo%Cgreenbar%Cbluebaz%Cresetxyzzy <<'EOF' commit 131a310eb913d107dd3c09a65d1651175898735d [31mfoo[32mbar[34mbaz[mxyzzy @@ -191,6 +200,31 @@ test_expect_success 'add LF before non-empty (2)' ' grep "^$" actual ' +test_expect_success '--abbrev' ' + echo SHORT SHORT SHORT >expect2 && + echo LONG LONG LONG >expect3 && + git log -1 --format="%h %h %h" HEAD >actual1 && + git log -1 --abbrev=5 --format="%h %h %h" HEAD >actual2 && + git log -1 --abbrev=5 --format="%H %H %H" HEAD >actual3 && + sed -e "s/$_x40/LONG/g" -e "s/$_x05/SHORT/g" <actual2 >fuzzy2 && + sed -e "s/$_x40/LONG/g" -e "s/$_x05/SHORT/g" <actual3 >fuzzy3 && + test_cmp expect2 fuzzy2 && + test_cmp expect3 fuzzy3 && + ! test_cmp actual1 actual2 +' + +test_expect_success '%H is not affected by --abbrev-commit' ' + git log -1 --format=%H --abbrev-commit --abbrev=20 HEAD >actual && + len=$(wc -c <actual) && + test $len = 41 +' + +test_expect_success '%h is not affected by --abbrev-commit' ' + git log -1 --format=%h --abbrev-commit --abbrev=20 HEAD >actual && + len=$(wc -c <actual) && + test $len = 21 +' + test_expect_success '"%h %gD: %gs" is same as git-reflog' ' git reflog >expect && git log -g --format="%h %gD: %gs" >actual && @@ -203,6 +237,12 @@ test_expect_success '"%h %gD: %gs" is same as git-reflog (with date)' ' test_cmp expect actual ' +test_expect_success '"%h %gD: %gs" is same as git-reflog (with --abbrev)' ' + git reflog --abbrev=13 --date=raw >expect && + git log -g --abbrev=13 --format="%h %gD: %gs" --date=raw >actual && + test_cmp expect actual +' + test_expect_success '%gd shortens ref name' ' echo "master@{0}" >expect.gd-short && git log -g -1 --format=%gd refs/heads/master >actual.gd-short && diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index e3f7ae8120..b66544b76d 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -280,7 +280,7 @@ test_expect_success 'updated working tree file should prevent the merge' ' echo "BAD: should have complained" return 1 } - diff M M.saved || { + test_cmp M M.saved || { echo "BAD: should have left M intact" return 1 } @@ -301,7 +301,7 @@ test_expect_success 'updated working tree file should prevent the merge' ' echo "BAD: should have complained" return 1 } - diff M M.saved || { + test_cmp M M.saved || { echo "BAD: should have left M intact" return 1 } diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index f105fab98e..e673c25e94 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -6,7 +6,7 @@ test_description='Test git rev-parse with different parent options' . ./test-lib.sh -. "$TEST_DIRECTORY"/t6000lib.sh # t6xxx specific functions +. "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions date >path0 git update-index --add path0 diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 065deadc29..876d1ab743 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -8,7 +8,7 @@ test_description='test describe o----o----o----o----o----. / \ A c / .------------o---o---o - D e + D,R e ' . ./test-lib.sh @@ -68,6 +68,8 @@ test_expect_success setup ' echo D >another && git add another && git commit -m D && test_tick && git tag -a -m D D && + test_tick && + git tag -a -m R R && test_tick && echo DD >another && git commit -a -m another && @@ -89,10 +91,10 @@ test_expect_success setup ' check_describe A-* HEAD check_describe A-* HEAD^ -check_describe D-* HEAD^^ +check_describe R-* HEAD^^ check_describe A-* HEAD^^2 check_describe B HEAD^^2^ -check_describe D-* HEAD^^^ +check_describe R-* HEAD^^^ check_describe c-* --tags HEAD check_describe c-* --tags HEAD^ diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 8052c86ad3..7dc8a510c7 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -295,6 +295,15 @@ test_expect_success 'Check short upstream format' ' test_cmp expected actual ' +cat >expected <<EOF +67a36f1 +EOF + +test_expect_success 'Check short objectname format' ' + git for-each-ref --format="%(objectname:short)" refs/heads >actual && + test_cmp expected actual +' + test_expect_success 'Check for invalid refname format' ' test_must_fail git for-each-ref --format="%(refname:INVALID)" ' diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh index e249c3ed41..8a6322765c 100755 --- a/t/t7002-grep.sh +++ b/t/t7002-grep.sh @@ -60,7 +60,7 @@ do echo ${HC}file:5:foo_mmap bar mmap baz } >expected && git grep -n -w -e mmap $H >actual && - diff expected actual + test_cmp expected actual ' test_expect_success "grep -w $L (w)" ' @@ -74,7 +74,7 @@ do echo ${HC}x:1:x x xx x } >expected && git grep -n -w -e "x xx* x" $H >actual && - diff expected actual + test_cmp expected actual ' test_expect_success "grep -w $L (y-1)" ' @@ -82,7 +82,7 @@ do echo ${HC}y:1:y yy } >expected && git grep -n -w -e "^y" $H >actual && - diff expected actual + test_cmp expected actual ' test_expect_success "grep -w $L (y-2)" ' @@ -93,7 +93,7 @@ do cat actual false else - diff expected actual + test_cmp expected actual fi ' @@ -105,14 +105,14 @@ do cat actual false else - diff expected actual + test_cmp expected actual fi ' test_expect_success "grep $L (t-1)" ' echo "${HC}t/t:1:test" >expected && git grep -n -e test $H >actual && - diff expected actual + test_cmp expected actual ' test_expect_success "grep $L (t-2)" ' @@ -121,7 +121,7 @@ do cd t && git grep -n -e test $H ) >actual && - diff expected actual + test_cmp expected actual ' test_expect_success "grep $L (t-3)" ' @@ -130,7 +130,7 @@ do cd t && git grep --full-name -n -e test $H ) >actual && - diff expected actual + test_cmp expected actual ' test_expect_success "grep -c $L (no /dev/null)" ' diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh index 5257f4d261..fe60d699a3 100755 --- a/t/t7005-editor.sh +++ b/t/t7005-editor.sh @@ -13,7 +13,7 @@ test_expect_success 'determine default editor' ' ' -if ! expr "$vi" : '^[a-z]*$' >/dev/null +if ! expr "$vi" : '[a-z]*$' >/dev/null then vi= fi @@ -38,7 +38,7 @@ test_expect_success setup ' test_commit "$msg" && echo "$msg" >expect && git show -s --format=%s > actual && - diff actual expect + test_cmp actual expect ' @@ -85,7 +85,7 @@ do git --exec-path=. commit --amend && git show -s --pretty=oneline | sed -e "s/^[0-9a-f]* //" >actual && - diff actual expect + test_cmp actual expect ' done @@ -107,7 +107,7 @@ do git --exec-path=. commit --amend && git show -s --pretty=oneline | sed -e "s/^[0-9a-f]* //" >actual && - diff actual expect + test_cmp actual expect ' done diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index d9202d5af5..9a83241c94 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -4,17 +4,24 @@ test_description='Test automatic use of a pager.' . ./test-lib.sh -rm -f stdout_is_tty +cleanup_fail() { + echo >&2 cleanup failed + (exit 1) +} + test_expect_success 'set up terminal for tests' ' + rm -f stdout_is_tty || + cleanup_fail && + if test -t 1 then - : > stdout_is_tty + >stdout_is_tty elif test_have_prereq PERL && "$PERL_PATH" "$TEST_DIRECTORY"/t7006/test-terminal.perl \ sh -c "test -t 1" then - : > test_terminal_works + >test_terminal_works fi ' @@ -32,53 +39,68 @@ else say no usable terminal, so skipping some tests fi -unset GIT_PAGER GIT_PAGER_IN_USE -git config --unset core.pager -PAGER='cat > paginated.out' -export PAGER - test_expect_success 'setup' ' + unset GIT_PAGER GIT_PAGER_IN_USE; + test_might_fail git config --unset core.pager && + + PAGER="cat >paginated.out" && + export PAGER && + test_commit initial ' -rm -f paginated.out test_expect_success TTY 'some commands use a pager' ' + rm -f paginated.out || + cleanup_fail && + test_terminal git log && test -e paginated.out ' -rm -f paginated.out test_expect_success TTY 'some commands do not use a pager' ' + rm -f paginated.out || + cleanup_fail && + test_terminal git rev-list HEAD && ! test -e paginated.out ' -rm -f paginated.out test_expect_success 'no pager when stdout is a pipe' ' + rm -f paginated.out || + cleanup_fail && + git log | cat && ! test -e paginated.out ' -rm -f paginated.out test_expect_success 'no pager when stdout is a regular file' ' - git log > file && + rm -f paginated.out || + cleanup_fail && + + git log >file && ! test -e paginated.out ' -rm -f paginated.out test_expect_success TTY 'git --paginate rev-list uses a pager' ' + rm -f paginated.out || + cleanup_fail && + test_terminal git --paginate rev-list HEAD && test -e paginated.out ' -rm -f file paginated.out test_expect_success 'no pager even with --paginate when stdout is a pipe' ' + rm -f file paginated.out || + cleanup_fail && + git --paginate log | cat && ! test -e paginated.out ' -rm -f paginated.out test_expect_success TTY 'no pager with --no-pager' ' + rm -f paginated.out || + cleanup_fail && + test_terminal git --no-pager log && ! test -e paginated.out ' @@ -86,88 +108,119 @@ test_expect_success TTY 'no pager with --no-pager' ' # A colored commit log will begin with an appropriate ANSI escape # for the first color; the text "commit" comes later. colorful() { - read firstline < $1 - ! expr "$firstline" : "^[a-zA-Z]" >/dev/null + read firstline <$1 + ! expr "$firstline" : "[a-zA-Z]" >/dev/null } -rm -f colorful.log colorless.log test_expect_success 'tests can detect color' ' - git log --no-color > colorless.log && - git log --color > colorful.log && + rm -f colorful.log colorless.log || + cleanup_fail && + + git log --no-color >colorless.log && + git log --color >colorful.log && ! colorful colorless.log && colorful colorful.log ' -rm -f colorless.log -git config color.ui auto test_expect_success 'no color when stdout is a regular file' ' - git log > colorless.log && + rm -f colorless.log && + git config color.ui auto || + cleanup_fail && + + git log >colorless.log && ! colorful colorless.log ' -rm -f paginated.out -git config color.ui auto test_expect_success TTY 'color when writing to a pager' ' - TERM=vt100 test_terminal git log && + rm -f paginated.out && + git config color.ui auto || + cleanup_fail && + + ( + TERM=vt100 && + export TERM && + test_terminal git log + ) && colorful paginated.out ' -rm -f colorful.log -git config color.ui auto test_expect_success 'color when writing to a file intended for a pager' ' - TERM=vt100 GIT_PAGER_IN_USE=true git log > colorful.log && + rm -f colorful.log && + git config color.ui auto || + cleanup_fail && + + ( + TERM=vt100 && + GIT_PAGER_IN_USE=true && + export TERM GIT_PAGER_IN_USE && + git log >colorful.log + ) && colorful colorful.log ' -unset PAGER GIT_PAGER -git config --unset core.pager test_expect_success 'determine default pager' ' + unset PAGER GIT_PAGER; + test_might_fail git config --unset core.pager || + cleanup_fail && + less=$(git var GIT_PAGER) && test -n "$less" ' -if expr "$less" : '^[a-z]*$' > /dev/null && test_have_prereq TTY +if expr "$less" : '[a-z][a-z]*$' >/dev/null && test_have_prereq TTY then test_set_prereq SIMPLEPAGER fi -unset PAGER GIT_PAGER -git config --unset core.pager -rm -f default_pager_used test_expect_success SIMPLEPAGER 'default pager is used by default' ' - cat > $less <<-EOF && - #!$SHELL_PATH - wc > default_pager_used + unset PAGER GIT_PAGER; + test_might_fail git config --unset core.pager && + rm -f default_pager_used || + cleanup_fail && + + cat >$less <<-\EOF && + #!/bin/sh + wc >default_pager_used EOF chmod +x $less && - PATH=.:$PATH test_terminal git log && + ( + PATH=.:$PATH && + export PATH && + test_terminal git log + ) && test -e default_pager_used ' -unset GIT_PAGER -git config --unset core.pager -rm -f PAGER_used test_expect_success TTY 'PAGER overrides default pager' ' - PAGER="wc > PAGER_used" && + unset GIT_PAGER; + test_might_fail git config --unset core.pager && + rm -f PAGER_used || + cleanup_fail && + + PAGER="wc >PAGER_used" && export PAGER && test_terminal git log && test -e PAGER_used ' -unset GIT_PAGER -rm -f core.pager_used test_expect_success TTY 'core.pager overrides PAGER' ' + unset GIT_PAGER; + rm -f core.pager_used || + cleanup_fail && + PAGER=wc && export PAGER && - git config core.pager "wc > core.pager_used" && + git config core.pager "wc >core.pager_used" && test_terminal git log && test -e core.pager_used ' -rm -f GIT_PAGER_used test_expect_success TTY 'GIT_PAGER overrides core.pager' ' + rm -f GIT_PAGER_used || + cleanup_fail && + git config core.pager wc && - GIT_PAGER="wc > GIT_PAGER_used" && + GIT_PAGER="wc >GIT_PAGER_used" && export GIT_PAGER && test_terminal git log && test -e GIT_PAGER_used diff --git a/t/t7008-grep-binary.sh b/t/t7008-grep-binary.sh new file mode 100755 index 0000000000..eb8ca88cce --- /dev/null +++ b/t/t7008-grep-binary.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +test_description='git grep in binary files' + +. ./test-lib.sh + +test_expect_success 'setup' " + printf 'binary\000file\n' >a && + git add a && + git commit -m. +" + +test_expect_success 'git grep ina a' ' + echo Binary file a matches >expect && + git grep ina a >actual && + test_cmp expect actual +' + +test_expect_success 'git grep -ah ina a' ' + git grep -ah ina a >actual && + test_cmp a actual +' + +test_expect_success 'git grep -I ina a' ' + : >expect && + test_must_fail git grep -I ina a >actual && + test_cmp expect actual +' + +test_expect_success 'git grep -c ina a' ' + echo a:1 >expect && + git grep -c ina a >actual && + test_cmp expect actual +' + +test_expect_success 'git grep -l ina a' ' + echo a >expect && + git grep -l ina a >actual && + test_cmp expect actual +' + +test_expect_success 'git grep -L bar a' ' + echo a >expect && + git grep -L bar a >actual && + test_cmp expect actual +' + +test_expect_success 'git grep -q ina a' ' + : >expect && + git grep -q ina a >actual && + test_cmp expect actual +' + +test_expect_success 'git grep -F ile a' ' + git grep -F ile a +' + +test_expect_success 'git grep -Fi iLE a' ' + git grep -Fi iLE a +' + +# This test actually passes on platforms where regexec() supports the +# flag REG_STARTEND. +test_expect_failure 'git grep ile a' ' + git grep ile a +' + +test_expect_failure 'git grep .fi a' ' + git grep .fi a +' + +test_expect_success 'git grep -F y<NUL>f a' " + printf 'y\000f' >f && + git grep -f f -F a +" + +test_expect_success 'git grep -F y<NUL>x a' " + printf 'y\000x' >f && + test_must_fail git grep -f f -F a +" + +test_expect_success 'git grep -Fi Y<NUL>f a' " + printf 'Y\000f' >f && + git grep -f f -Fi a +" + +test_expect_failure 'git grep -Fi Y<NUL>x a' " + printf 'Y\000x' >f && + test_must_fail git grep -f f -Fi a +" + +test_expect_success 'git grep y<NUL>f a' " + printf 'y\000f' >f && + git grep -f f a +" + +test_expect_failure 'git grep y<NUL>x a' " + printf 'y\000x' >f && + test_must_fail git grep -f f a +" + +test_done diff --git a/t/t7010-setup.sh b/t/t7010-setup.sh index d8a7c79852..0335a9a158 100755 --- a/t/t7010-setup.sh +++ b/t/t7010-setup.sh @@ -103,14 +103,10 @@ test_expect_success 'git ls-files (relative #3)' ' git add a && ( cd a/b && - if git ls-files "../e/f" - then - echo Gaah, should have failed - exit 1 - else - : happy - fi - ) + git ls-files "../e/f" + ) >current && + echo ../e/f >expect && + test_cmp expect current ' diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 1a4dc5f893..97ff074da7 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -11,226 +11,292 @@ subcommands of git submodule. . ./test-lib.sh -# -# Test setup: -# -create a repository in directory init -# -add a couple of files -# -add directory init to 'superproject', this creates a DIRLINK entry -# -add a couple of regular files to enable testing of submodule filtering -# -mv init subrepo -# -add an entry to .gitmodules for submodule 'example' -# -test_expect_success 'Prepare submodule testing' ' - : > t && +test_expect_success 'setup - initial commit' ' + >t && git add t && git commit -m "initial commit" && - git branch initial HEAD && + git branch initial +' + +test_expect_success 'setup - repository in init subdirectory' ' mkdir init && - cd init && - git init && - echo a >a && - git add a && - git commit -m "submodule commit 1" && - git tag -a -m "rev-1" rev-1 && - rev1=$(git rev-parse HEAD) && - if test -z "$rev1" - then - echo "[OOPS] submodule git rev-parse returned nothing" - false - fi && - cd .. && + ( + cd init && + git init && + echo a >a && + git add a && + git commit -m "submodule commit 1" && + git tag -a -m "rev-1" rev-1 + ) +' + +test_expect_success 'setup - commit with gitlink' ' echo a >a && echo z >z && git add a init z && - git commit -m "super commit 1" && - mv init .subrepo && - GIT_CONFIG=.gitmodules git config submodule.example.url git://example.com/init.git + git commit -m "super commit 1" +' + +test_expect_success 'setup - hide init subdirectory' ' + mv init .subrepo +' + +test_expect_success 'setup - repository to add submodules to' ' + git init addtest ' -test_expect_success 'Prepare submodule add testing' ' - submodurl=$(pwd) +# The 'submodule add' tests need some repository to add as a submodule. +# The trash directory is a good one as any. +submodurl=$TRASH_DIRECTORY + +listbranches() { + git for-each-ref --format='%(refname)' 'refs/heads/*' +} + +inspect() { + dir=$1 && + dotdot="${2:-..}" && + ( - mkdir addtest && - cd addtest && - git init + cd "$dir" && + listbranches >"$dotdot/heads" && + { git symbolic-ref HEAD || :; } >"$dotdot/head" && + git rev-parse HEAD >"$dotdot/head-sha1" && + git update-index --refresh && + git diff-files --exit-code && + git clean -n -d -x >"$dotdot/untracked" ) -' +} test_expect_success 'submodule add' ' + echo "refs/heads/master" >expect && + >empty && + ( cd addtest && git submodule add "$submodurl" submod && git submodule init - ) + ) && + + rm -f heads head untracked && + inspect addtest/submod ../.. && + test_cmp expect heads && + test_cmp expect head && + test_cmp empty untracked ' test_expect_success 'submodule add --branch' ' + echo "refs/heads/initial" >expect-head && + cat <<-\EOF >expect-heads && + refs/heads/initial + refs/heads/master + EOF + >empty && + ( cd addtest && git submodule add -b initial "$submodurl" submod-branch && - git submodule init && - cd submod-branch && - git branch | grep initial - ) + git submodule init + ) && + + rm -f heads head untracked && + inspect addtest/submod-branch ../.. && + test_cmp expect-heads heads && + test_cmp expect-head head && + test_cmp empty untracked ' test_expect_success 'submodule add with ./ in path' ' + echo "refs/heads/master" >expect && + >empty && + ( cd addtest && git submodule add "$submodurl" ././dotsubmod/./frotz/./ && git submodule init - ) + ) && + + rm -f heads head untracked && + inspect addtest/dotsubmod/frotz ../../.. && + test_cmp expect heads && + test_cmp expect head && + test_cmp empty untracked ' test_expect_success 'submodule add with // in path' ' + echo "refs/heads/master" >expect && + >empty && + ( cd addtest && git submodule add "$submodurl" slashslashsubmod///frotz// && git submodule init - ) + ) && + + rm -f heads head untracked && + inspect addtest/slashslashsubmod/frotz ../../.. && + test_cmp expect heads && + test_cmp expect head && + test_cmp empty untracked ' test_expect_success 'submodule add with /.. in path' ' + echo "refs/heads/master" >expect && + >empty && + ( cd addtest && git submodule add "$submodurl" dotdotsubmod/../realsubmod/frotz/.. && git submodule init - ) + ) && + + rm -f heads head untracked && + inspect addtest/realsubmod ../.. && + test_cmp expect heads && + test_cmp expect head && + test_cmp empty untracked ' test_expect_success 'submodule add with ./, /.. and // in path' ' + echo "refs/heads/master" >expect && + >empty && + ( cd addtest && git submodule add "$submodurl" dot/dotslashsubmod/./../..////realsubmod2/a/b/c/d/../../../../frotz//.. && git submodule init - ) + ) && + + rm -f heads head untracked && + inspect addtest/realsubmod2 ../.. && + test_cmp expect heads && + test_cmp expect head && + test_cmp empty untracked +' + +test_expect_success 'setup - add an example entry to .gitmodules' ' + GIT_CONFIG=.gitmodules \ + git config submodule.example.url git://example.com/init.git ' test_expect_success 'status should fail for unmapped paths' ' - if git submodule status - then - echo "[OOPS] submodule status succeeded" - false - elif ! GIT_CONFIG=.gitmodules git config submodule.example.path init - then - echo "[OOPS] git config failed to update .gitmodules" - false - fi + test_must_fail git submodule status +' + +test_expect_success 'setup - map path in .gitmodules' ' + cat <<\EOF >expect && +[submodule "example"] + url = git://example.com/init.git + path = init +EOF + + GIT_CONFIG=.gitmodules git config submodule.example.path init && + + test_cmp expect .gitmodules ' test_expect_success 'status should only print one line' ' - lines=$(git submodule status | wc -l) && - test $lines = 1 + git submodule status >lines && + test $(wc -l <lines) = 1 +' + +test_expect_success 'setup - fetch commit name from submodule' ' + rev1=$(cd .subrepo && git rev-parse HEAD) && + printf "rev1: %s\n" "$rev1" && + test -n "$rev1" ' test_expect_success 'status should initially be "missing"' ' - git submodule status | grep "^-$rev1" + git submodule status >lines && + grep "^-$rev1" lines ' test_expect_success 'init should register submodule url in .git/config' ' + echo git://example.com/init.git >expect && + git submodule init && - url=$(git config submodule.example.url) && - if test "$url" != "git://example.com/init.git" - then - echo "[OOPS] init succeeded but submodule url is wrong" - false - elif test_must_fail git config submodule.example.url ./.subrepo - then - echo "[OOPS] init succeeded but update of url failed" - false - fi + git config submodule.example.url >url && + git config submodule.example.url ./.subrepo && + + test_cmp expect url ' test_expect_success 'update should fail when path is used by a file' ' + echo hello >expect && + echo "hello" >init && - if git submodule update - then - echo "[OOPS] update should have failed" - false - elif test "$(cat init)" != "hello" - then - echo "[OOPS] update failed but init file was molested" - false - else - rm init - fi + test_must_fail git submodule update && + + test_cmp expect init ' test_expect_success 'update should fail when path is used by a nonempty directory' ' + echo hello >expect && + + rm -fr init && mkdir init && echo "hello" >init/a && - if git submodule update - then - echo "[OOPS] update should have failed" - false - elif test "$(cat init/a)" != "hello" - then - echo "[OOPS] update failed but init/a was molested" - false - else - rm init/a - fi + + test_must_fail git submodule update && + + test_cmp expect init/a ' test_expect_success 'update should work when path is an empty dir' ' - rm -rf init && + rm -fr init && + rm -f head-sha1 && + echo "$rev1" >expect && + mkdir init && git submodule update && - head=$(cd init && git rev-parse HEAD) && - if test -z "$head" - then - echo "[OOPS] Failed to obtain submodule head" - false - elif test "$head" != "$rev1" - then - echo "[OOPS] Submodule head is $head but should have been $rev1" - false - fi + + inspect init && + test_cmp expect head-sha1 ' test_expect_success 'status should be "up-to-date" after update' ' - git submodule status | grep "^ $rev1" + git submodule status >list && + grep "^ $rev1" list ' test_expect_success 'status should be "modified" after submodule commit' ' - cd init && - echo b >b && - git add b && - git commit -m "submodule commit 2" && - rev2=$(git rev-parse HEAD) && - cd .. && - if test -z "$rev2" - then - echo "[OOPS] submodule git rev-parse returned nothing" - false - fi && - git submodule status | grep "^+$rev2" + ( + cd init && + echo b >b && + git add b && + git commit -m "submodule commit 2" + ) && + + rev2=$(cd init && git rev-parse HEAD) && + test -n "$rev2" && + git submodule status >list && + + grep "^+$rev2" list ' test_expect_success 'the --cached sha1 should be rev1' ' - git submodule --cached status | grep "^+$rev1" + git submodule --cached status >list && + grep "^+$rev1" list ' test_expect_success 'git diff should report the SHA1 of the new submodule commit' ' - git diff | grep "^+Subproject commit $rev2" + git diff >diff && + grep "^+Subproject commit $rev2" diff ' test_expect_success 'update should checkout rev1' ' + rm -f head-sha1 && + echo "$rev1" >expect && + git submodule update init && - head=$(cd init && git rev-parse HEAD) && - if test -z "$head" - then - echo "[OOPS] submodule git rev-parse returned nothing" - false - elif test "$head" != "$rev1" - then - echo "[OOPS] init did not checkout correct head" - false - fi + inspect init && + + test_cmp expect head-sha1 ' test_expect_success 'status should be "up-to-date" after update' ' - git submodule status | grep "^ $rev1" + git submodule status >list && + grep "^ $rev1" list ' test_expect_success 'checkout superproject with subproject already present' ' @@ -239,6 +305,8 @@ test_expect_success 'checkout superproject with subproject already present' ' ' test_expect_success 'apply submodule diff' ' + >empty && + git branch second && ( cd init && @@ -251,21 +319,24 @@ test_expect_success 'apply submodule diff' ' git format-patch -1 --stdout >P.diff && git checkout second && git apply --index P.diff && - D=$(git diff --cached master) && - test -z "$D" + + git diff --cached master >staged && + test_cmp empty staged ' test_expect_success 'update --init' ' - mv init init2 && git config -f .gitmodules submodule.example.url "$(pwd)/init2" && - git config --remove-section submodule.example + git config --remove-section submodule.example && + test_must_fail git config submodule.example.url && + git submodule update init > update.out && + cat update.out && grep "not initialized" update.out && - test ! -d init/.git && + ! test -d init/.git && + git submodule update --init init && test -d init/.git - ' test_expect_success 'do not add files from a submodule' ' diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 2a527750ce..db9365b645 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -59,11 +59,13 @@ test_expect_success 'setup a submodule tree' ' sub1sha1=$(cd super/sub1 && git rev-parse HEAD) sub3sha1=$(cd super/sub3 && git rev-parse HEAD) +pwd=$(pwd) + cat > expect <<EOF Entering 'sub1' -foo1-sub1-$sub1sha1 +$pwd/clone-foo1-sub1-$sub1sha1 Entering 'sub3' -foo3-sub3-$sub3sha1 +$pwd/clone-foo3-sub3-$sub3sha1 EOF test_expect_success 'test basic "submodule foreach" usage' ' @@ -71,7 +73,9 @@ test_expect_success 'test basic "submodule foreach" usage' ' ( cd clone && git submodule update --init -- sub1 sub3 && - git submodule foreach "echo \$name-\$path-\$sha1" > ../actual + git submodule foreach "echo \$toplevel-\$name-\$path-\$sha1" > ../actual && + git config foo.bar zar && + git submodule foreach "git config --file \"\$toplevel/.git/config\" foo.bar" ) && test_cmp expect actual ' diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 9f5c3edb03..aa9c577e9e 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -193,4 +193,26 @@ test_expect_success 'commit -F overrides -t' ' commit_msg_is "-F log" ' +test_expect_success 'Commit without message is allowed with --allow-empty-message' ' + echo "more content" >>foo && + git add foo && + >empty && + git commit --allow-empty-message <empty && + commit_msg_is "" +' + +test_expect_success 'Commit without message is no-no without --allow-empty-message' ' + echo "more content" >>foo && + git add foo && + >empty && + test_must_fail git commit <empty +' + +test_expect_success 'Commit a message with --allow-empty-message' ' + echo "even more content" >>foo && + git add foo && + git commit --allow-empty-message -m"hello there" && + commit_msg_is "hello there" +' + test_done diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index 844fb43c6d..ac2e187a57 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -4,8 +4,76 @@ test_description='git commit porcelain-ish' . ./test-lib.sh +# Arguments: [<prefix] [<commit message>] [<commit options>] +check_summary_oneline() { + test_tick && + git commit ${3+"$3"} -m "$2" | head -1 > act && + + # branch name + SUMMARY_PREFIX="$(git name-rev --name-only HEAD)" && + + # append the "special" prefix, like "root-commit", "detached HEAD" + if test -n "$1" + then + SUMMARY_PREFIX="$SUMMARY_PREFIX ($1)" + fi + + # abbrev SHA-1 + SUMMARY_POSTFIX="$(git log -1 --pretty='format:%h')" + echo "[$SUMMARY_PREFIX $SUMMARY_POSTFIX] $2" >exp && + + test_cmp exp act +} + +test_expect_success 'output summary format' ' + + echo new >file1 && + git add file1 && + check_summary_oneline "root-commit" "initial" && + + echo change >>file1 && + git add file1 && + check_summary_oneline "" "a change" +' + +test_expect_success 'output summary format for commit with an empty diff' ' + + check_summary_oneline "" "empty" "--allow-empty" +' + +test_expect_success 'output summary format for merges' ' + + git checkout -b recursive-base && + test_commit base file1 && + + git checkout -b recursive-a recursive-base && + test_commit commit-a file1 && + + git checkout -b recursive-b recursive-base && + test_commit commit-b file1 && + + # conflict + git checkout recursive-a && + test_must_fail git merge recursive-b && + # resolve the conflict + echo commit-a > file1 && + git add file1 && + check_summary_oneline "" "Merge" +' + +output_tests_cleanup() { + # this is needed for "do not fire editor in the presence of conflicts" + git checkout master && + + # this is needed for the "partial removal" test to pass + git rm file1 && + git commit -m "cleanup" +} + test_expect_success 'the basics' ' + output_tests_cleanup && + echo doing partial >"commit is" && mkdir not && echo very much encouraged but we should >not/forbid && @@ -35,7 +103,7 @@ test_expect_success 'partial' ' ' -test_expect_success 'partial modification in a subdirecotry' ' +test_expect_success 'partial modification in a subdirectory' ' test_tick && git commit -m "partial commit to subdirectory" not && diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 556d0faa77..9e081073fb 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -69,6 +69,34 @@ test_expect_success 'status (2)' ' ' cat >expect <<\EOF +# On branch master +# Changes to be committed: +# new file: dir2/added +# +# Changed but not updated: +# modified: dir1/modified +# +# Untracked files: +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +git config advice.statusHints false + +test_expect_success 'status (advice.statusHints false)' ' + + git status >output && + test_cmp expect output + +' + +git config --unset advice.statusHints + +cat >expect <<\EOF M dir1/modified A dir2/added ?? dir1/untracked @@ -79,13 +107,32 @@ A dir2/added ?? untracked EOF -test_expect_success 'status -s (2)' ' +test_expect_success 'status -s' ' git status -s >output && test_cmp expect output ' +cat >expect <<\EOF +## master + M dir1/modified +A dir2/added +?? dir1/untracked +?? dir2/modified +?? dir2/untracked +?? expect +?? output +?? untracked +EOF + +test_expect_success 'status -s -b' ' + + git status -s -b >output && + test_cmp expect output + +' + cat >expect <<EOF # On branch master # Changes to be committed: @@ -115,6 +162,23 @@ test_expect_success 'status (status.showUntrackedFiles no)' ' test_cmp expect output ' +cat >expect <<EOF +# On branch master +# Changes to be committed: +# new file: dir2/added +# +# Changed but not updated: +# modified: dir1/modified +# +# Untracked files not listed +EOF +git config advice.statusHints false +test_expect_success 'status -uno (advice.statusHints false)' ' + git status -uno >output && + test_cmp expect output +' +git config --unset advice.statusHints + cat >expect << EOF M dir1/modified A dir2/added @@ -392,6 +456,25 @@ test_expect_success 'status -s with color.status' ' ' cat >expect <<\EOF +## <GREEN>master<RESET> + <RED>M<RESET> dir1/modified +<GREEN>A<RESET> dir2/added +<BLUE>??<RESET> dir1/untracked +<BLUE>??<RESET> dir2/modified +<BLUE>??<RESET> dir2/untracked +<BLUE>??<RESET> expect +<BLUE>??<RESET> output +<BLUE>??<RESET> untracked +EOF + +test_expect_success 'status -s -b with color.status' ' + + git status -s -b | test_decode_color >output && + test_cmp expect output + +' + +cat >expect <<\EOF M dir1/modified A dir2/added ?? dir1/untracked @@ -424,6 +507,13 @@ test_expect_success 'status --porcelain ignores color.status' ' git config --unset color.status git config --unset color.ui +test_expect_success 'status --porcelain ignores -b' ' + + git status --porcelain -b >output && + test_cmp expect output + +' + cat >expect <<\EOF # On branch master # Changes to be committed: @@ -496,6 +586,16 @@ test_expect_success 'dry-run of partial commit excluding new file in index' ' test_cmp expect output ' +cat >expect <<EOF +:100644 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 M dir1/modified +EOF +test_expect_success 'status refreshes the index' ' + touch dir2/added && + git status && + git diff-files >output && + test_cmp expect output +' + test_expect_success 'setup status submodule summary' ' test_create_repo sm && ( cd sm && @@ -693,4 +793,19 @@ test_expect_success 'commit --dry-run submodule summary (--amend)' ' test_cmp expect output ' +test_expect_success POSIXPERM 'status succeeds in a read-only repository' ' + ( + chmod a-w .git && + # make dir1/tracked stat-dirty + >dir1/tracked1 && mv -f dir1/tracked1 dir1/tracked && + git status -s >output && + ! grep dir1/tracked output && + # make sure "status" succeeded without writing index out + git diff-files | grep dir1/tracked + ) + status=$? + chmod 775 .git + (exit $status) +' + test_done diff --git a/t/t7509-commit.sh b/t/t7509-commit.sh index d52c060b06..3ea33db6c7 100755 --- a/t/t7509-commit.sh +++ b/t/t7509-commit.sh @@ -83,6 +83,52 @@ test_expect_success '--amend option copies authorship' ' test_cmp expect actual ' +sha1_file() { + echo "$*" | sed "s#..#.git/objects/&/#" +} +remove_object() { + rm -f $(sha1_file "$*") +} +no_reflog() { + cp .git/config .git/config.saved && + echo "[core] logallrefupdates = false" >>.git/config && + test_when_finished "mv -f .git/config.saved .git/config" && + + if test -e .git/logs + then + mv .git/logs . && + test_when_finished "mv logs .git/" + fi +} + +test_expect_success '--amend option with empty author' ' + git cat-file commit Initial >tmp && + sed "s/author [^<]* </author </" tmp >empty-author && + no_reflog && + sha=$(git hash-object -t commit -w empty-author) && + test_when_finished "remove_object $sha" && + git checkout $sha && + test_when_finished "git checkout Initial" && + echo "Empty author test" >>foo && + test_tick && + ! git commit -a -m "empty author" --amend 2>err && + grep "empty ident" err +' + +test_expect_success '--amend option with missing author' ' + git cat-file commit Initial >tmp && + sed "s/author [^<]* </author </" tmp >malformed && + no_reflog && + sha=$(git hash-object -t commit -w malformed) && + test_when_finished "remove_object $sha" && + git checkout $sha && + test_when_finished "git checkout Initial" && + echo "Missing author test" >>foo && + test_tick && + ! git commit -a -m "malformed author" --amend 2>err && + grep "empty ident" err +' + test_expect_success '--reset-author makes the commit ours even with --amend option' ' git checkout Initial && echo "Test 6" >>foo && diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 57f6d2bae7..cde8390c1b 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -554,8 +554,7 @@ test_debug 'gitk --all' test_expect_success 'refresh the index before merging' ' git reset --hard c1 && - sleep 1 && - touch file && + cp file file.n && mv -f file.n file && git merge c3 ' diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh index 269cfdf267..9114785ef7 100755 --- a/t/t7604-merge-custom-message.sh +++ b/t/t7604-merge-custom-message.sh @@ -6,6 +6,15 @@ Testing merge when using a custom message for the merge commit.' . ./test-lib.sh +create_merge_msgs() { + echo >exp.subject "custom message" + + cp exp.subject exp.log && + echo >>exp.log "" && + echo >>exp.log "* commit 'c2':" && + echo >>exp.log " c2" +} + test_expect_success 'setup' ' echo c0 > c0.c && git add c0.c && @@ -19,16 +28,23 @@ test_expect_success 'setup' ' echo c2 > c2.c && git add c2.c && git commit -m c2 && - git tag c2 + git tag c2 && + create_merge_msgs ' test_expect_success 'merge c2 with a custom message' ' git reset --hard c1 && - echo >expected "custom message" && - git merge -m "custom message" c2 && + git merge -m "$(cat exp.subject)" c2 && + git cat-file commit HEAD | sed -e "1,/^$/d" >actual && + test_cmp exp.subject actual +' + +test_expect_success 'merge --log appends to custom message' ' + git reset --hard c1 && + git merge --log -m "$(cat exp.subject)" c2 && git cat-file commit HEAD | sed -e "1,/^$/d" >actual && - test_cmp expected actual + test_cmp exp.log actual ' test_done diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index f4aa054750..c2f66ff170 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -8,6 +8,7 @@ test_expect_success 'objects in packs marked .keep are not repacked' ' echo content1 > file1 && echo content2 > file2 && git add . && + test_tick && git commit -m initial_commit && # Create two packs # The first pack will contain all of the objects except one @@ -40,6 +41,7 @@ test_expect_success 'loose objects in alternate ODB are not repacked' ' echo content3 > file3 && objsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) && git add file3 && + test_tick && git commit -m commit_file3 && git repack -a -d -l && git prune-packed && @@ -73,6 +75,7 @@ test_expect_success 'packed obs in alt ODB are repacked when local repo has pack rm -f .git/objects/pack/* && echo new_content >> file1 && git add file1 && + test_tick && git commit -m more_content && git repack && git repack -a -d && @@ -118,8 +121,8 @@ test_expect_success 'packed unreachable obs in alternate ODB are not loosened' ' mv .git/objects/pack/* alt_objects/pack/ && csha1=$(git rev-parse HEAD^{commit}) && git reset --hard HEAD^ && - sleep 1 && - git reflog expire --expire=now --expire-unreachable=now --all && + test_tick && + git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all && # The pack-objects call on the next line is equivalent to # git repack -A -d without the call to prune-packed git pack-objects --honor-pack-keep --non-empty --all --reflog \ @@ -156,7 +159,7 @@ test_expect_success 'objects made unreachable by grafts only are kept' ' H1=$(git rev-parse HEAD^) && H2=$(git rev-parse HEAD^^) && echo "$H0 $H2" > .git/info/grafts && - git reflog expire --expire=now --expire-unreachable=now --all && + git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all && git repack -a -d && git cat-file -t $H1 ' diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh index 5babdf26e6..200ab61278 100755 --- a/t/t7701-repack-unpack-unreachable.sh +++ b/t/t7701-repack-unpack-unreachable.sh @@ -11,17 +11,20 @@ tsha1= test_expect_success '-A with -d option leaves unreachable objects unpacked' ' echo content > file1 && git add . && + test_tick && git commit -m initial_commit && # create a transient branch with unique content git checkout -b transient_branch && echo more content >> file1 && # record the objects created in the database for file, commit, tree fsha1=$(git hash-object file1) && + test_tick && git commit -a -m more_content && csha1=$(git rev-parse HEAD^{commit}) && tsha1=$(git rev-parse HEAD^{tree}) && git checkout master && echo even more content >> file1 && + test_tick && git commit -a -m even_more_content && # delete the transient branch git branch -D transient_branch && @@ -34,9 +37,11 @@ test_expect_success '-A with -d option leaves unreachable objects unpacked' ' git show $fsha1 && git show $csha1 && git show $tsha1 && - # now expire the reflog - sleep 1 && - git reflog expire --expire-unreachable=now --all && + # now expire the reflog, while keeping reachable ones but expiring + # unreachables immediately + test_tick && + sometimeago=$(( $test_tick - 10000 )) && + git reflog expire --expire=$sometimeago --expire-unreachable=$test_tick --all && # and repack git repack -A -d -l && # verify objects are retained unpacked @@ -71,7 +76,7 @@ test_expect_success '-A without -d option leaves unreachable objects packed' ' test 1 = $(ls -1 .git/objects/pack/pack-*.pack | wc -l) && packfile=$(ls .git/objects/pack/pack-*.pack) && git branch -D transient_branch && - sleep 1 && + test_tick && git repack -A -l && test ! -f "$fsha1path" && test ! -f "$csha1path" && diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh index ac52bff0ef..7d7acc30b4 100755 --- a/t/t9118-git-svn-funky-branch-names.sh +++ b/t/t9118-git-svn-funky-branch-names.sh @@ -21,6 +21,14 @@ test_expect_success 'setup svnrepo' ' "$svnrepo/pr ject/branches/more fun plugin!" && svn_cmd cp -m "scary" "$svnrepo/pr ject/branches/fun plugin" \ "$svnrepo/pr ject/branches/$scary_uri" && + svn_cmd cp -m "leading dot" "$svnrepo/pr ject/trunk" \ + "$svnrepo/pr ject/branches/.leading_dot" && + svn_cmd cp -m "trailing dot" "$svnrepo/pr ject/trunk" \ + "$svnrepo/pr ject/branches/trailing_dot." && + svn_cmd cp -m "trailing .lock" "$svnrepo/pr ject/trunk" \ + "$svnrepo/pr ject/branches/trailing_dotlock.lock" && + svn_cmd cp -m "reflog" "$svnrepo/pr ject/trunk" \ + "$svnrepo/pr ject/branches/not-a@{0}reflog" && start_httpd ' @@ -30,6 +38,10 @@ test_expect_success 'test clone with funky branch names' ' git rev-parse "refs/remotes/fun%20plugin" && git rev-parse "refs/remotes/more%20fun%20plugin!" && git rev-parse "refs/remotes/$scary_ref" && + git rev-parse "refs/remotes/%2Eleading_dot" && + git rev-parse "refs/remotes/trailing_dot%2E" && + git rev-parse "refs/remotes/trailing_dotlock%2Elock" && + git rev-parse "refs/remotes/not-a%40{0}reflog" && cd .. ' @@ -51,6 +63,15 @@ test_expect_success 'test dcommit to scary branch' ' cd .. ' +test_expect_success 'test dcommit to trailing_dotlock branch' ' + cd project && + git reset --hard "refs/remotes/trailing_dotlock%2Elock" && + echo who names branches like this anyway? >> foo && + git commit -m "bar" -- foo && + git svn dcommit && + cd .. + ' + stop_httpd test_done diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index b9224bdb20..1e9a2eb12b 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -14,10 +14,22 @@ compare_git_head_with () { test_cmp current "$1" } +a_utf8_locale=$(locale -a | sed -n '/\.[uU][tT][fF]-*8$/{ + p + q +}') + +if test -n "$a_utf8_locale" +then + test_set_prereq UTF8 +else + say "UTF-8 locale not available, some tests are skipped" +fi + compare_svn_head_with () { # extract just the log message and strip out committer info. # don't use --limit here since svn 1.1.x doesn't have it, - LC_ALL=en_US.UTF-8 svn log `git svn info --url` | perl -w -e ' + LC_ALL="$a_utf8_locale" svn log `git svn info --url` | perl -w -e ' use bytes; $/ = ("-"x72) . "\n"; my @x = <STDIN>; @@ -69,12 +81,6 @@ do ' done -if locale -a |grep -q en_US.utf8; then - test_set_prereq UTF8 -else - say "UTF-8 locale not available, test skipped" -fi - test_expect_success UTF8 'ISO-8859-1 should match UTF-8 in svn' ' ( cd ISO8859-1 && diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index fc3795dc98..61bcb8fc86 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -63,10 +63,10 @@ test_expect_success \ check_entries B "newfile2.txt/1.1/" && check_entries C "newfile3.png/1.1/-kb" && check_entries D "newfile4.png/1.1/-kb" && - diff A/newfile1.txt ../A/newfile1.txt && - diff B/newfile2.txt ../B/newfile2.txt && - diff C/newfile3.png ../C/newfile3.png && - diff D/newfile4.png ../D/newfile4.png + test_cmp A/newfile1.txt ../A/newfile1.txt && + test_cmp B/newfile2.txt ../B/newfile2.txt && + test_cmp C/newfile3.png ../C/newfile3.png && + test_cmp D/newfile4.png ../D/newfile4.png )' test_expect_success \ @@ -89,10 +89,10 @@ test_expect_success \ check_entries D "newfile4.png/1.2/-kb" && check_entries E "newfile5.txt/1.1/" && check_entries F "newfile6.png/1.1/-kb" && - diff A/newfile1.txt ../A/newfile1.txt && - diff D/newfile4.png ../D/newfile4.png && - diff E/newfile5.txt ../E/newfile5.txt && - diff F/newfile6.png ../F/newfile6.png + test_cmp A/newfile1.txt ../A/newfile1.txt && + test_cmp D/newfile4.png ../D/newfile4.png && + test_cmp E/newfile5.txt ../E/newfile5.txt && + test_cmp F/newfile6.png ../F/newfile6.png )' # Should fail (but only on the git cvsexportcommit stage) @@ -137,9 +137,9 @@ test_expect_success \ check_entries D "" && check_entries E "newfile5.txt/1.1/" && check_entries F "newfile6.png/1.1/-kb" && - diff A/newfile1.txt ../A/newfile1.txt && - diff E/newfile5.txt ../E/newfile5.txt && - diff F/newfile6.png ../F/newfile6.png + test_cmp A/newfile1.txt ../A/newfile1.txt && + test_cmp E/newfile5.txt ../E/newfile5.txt && + test_cmp F/newfile6.png ../F/newfile6.png )' test_expect_success \ @@ -155,8 +155,8 @@ test_expect_success \ check_entries D "" && check_entries E "newfile5.txt/1.1/" && check_entries F "newfile6.png/1.1/-kb" && - diff E/newfile5.txt ../E/newfile5.txt && - diff F/newfile6.png ../F/newfile6.png + test_cmp E/newfile5.txt ../E/newfile5.txt && + test_cmp F/newfile6.png ../F/newfile6.png )' test_expect_success \ diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index daef2d6c23..86395065cf 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -48,7 +48,9 @@ test_expect_success 'setup' ' git pull secondroot master && git clone -q --bare "$WORKDIR/.git" "$SERVERDIR" >/dev/null 2>&1 && GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && - GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" + GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" && + GIT_DIR="$SERVERDIR" git config gitcvs.authdb "$SERVERDIR/auth.db" && + echo cvsuser:cvGVEarMLnhlA > "$SERVERDIR/auth.db" ' # note that cvs doesn't accept absolute pathnames @@ -94,6 +96,14 @@ git END VERIFICATION REQUEST EOF +cat >login-git-ok <<EOF +BEGIN VERIFICATION REQUEST +$SERVERDIR +cvsuser +Ah<Z:yZZ30 e +END VERIFICATION REQUEST +EOF + test_expect_success 'pserver authentication' \ 'cat request-anonymous | git-cvsserver pserver >log 2>&1 && sed -ne \$p log | grep "^I LOVE YOU\$"' @@ -107,6 +117,10 @@ test_expect_success 'pserver authentication failure (non-anonymous user)' \ fi && sed -ne \$p log | grep "^I HATE YOU\$"' +test_expect_success 'pserver authentication success (non-anonymous user with password)' \ + 'cat login-git-ok | git-cvsserver pserver >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$"' + test_expect_success 'pserver authentication (login)' \ 'cat login-anonymous | git-cvsserver pserver >log 2>&1 && sed -ne \$p log | grep "^I LOVE YOU\$"' @@ -435,7 +449,7 @@ test_expect_success 'cvs update (-p)' ' rm -f failures && for i in merge no-lf empty really-empty; do GIT_CONFIG="$git_config" cvs update -p "$i" >$i.out - diff $i.out ../$i >>failures 2>&1 + test_cmp $i.out ../$i >>failures 2>&1 done && test -z "$(cat failures)" ' diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 63b6b060e6..4f2b9b062b 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -647,4 +647,33 @@ test_expect_success \ gitweb_run "p=.git;a=summary"' test_debug 'cat gitweb.log' +# ---------------------------------------------------------------------- +# syntax highlighting + +cat >>gitweb_config.perl <<\EOF +$feature{'highlight'}{'override'} = 1; +EOF + +highlight --version >/dev/null 2>&1 +if [ $? -eq 127 ]; then + say "Skipping syntax highlighting test, because 'highlight' was not found" +else + test_set_prereq HIGHLIGHT +fi + +test_expect_success HIGHLIGHT \ + 'syntax highlighting (no highlight)' \ + 'git config gitweb.highlight yes && + gitweb_run "p=.git;a=blob;f=file"' +test_debug 'cat gitweb.log' + +test_expect_success HIGHLIGHT \ + 'syntax highlighting (highlighted)' \ + 'git config gitweb.highlight yes && + echo "#!/usr/bin/sh" > test.sh && + git add test.sh && + git commit -m "Add test.sh" && + gitweb_run "p=.git;a=blob;f=test.sh"' +test_debug 'cat gitweb.log' + test_done diff --git a/t/test-lib.sh b/t/test-lib.sh index c582964b0d..367f0537cd 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -2,6 +2,18 @@ # # Copyright (c) 2005 Junio C Hamano # +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . # if --tee was passed, write the output not only to the terminal, but # additionally to the file test-results/$BASENAME.out, too. @@ -63,7 +75,6 @@ export GIT_MERGE_VERBOSITY export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME export EDITOR -GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u} # Protect ourselves from common misconfiguration to export # CDPATH into the environment @@ -354,8 +365,10 @@ test_debug () { } test_run_ () { + test_cleanup=: eval >&3 2>&4 "$1" - eval_ret="$?" + eval_ret=$? + eval >&3 2>&4 "$test_cleanup" return 0 } @@ -459,6 +472,9 @@ test_external () { # Announce the script to reduce confusion about the # test output that follows. say_color "" " run $test_count: $descr ($*)" + # Export TEST_DIRECTORY, TRASH_DIRECTORY and GIT_TEST_LONG + # to be able to use them in script + export TEST_DIRECTORY TRASH_DIRECTORY GIT_TEST_LONG # Run command; redirect its stderr to &4 as in # test_run_, but keep its stdout on our stdout even in # non-verbose mode. @@ -516,6 +532,22 @@ test_must_fail () { test $? -gt 0 -a $? -le 129 -o $? -gt 192 } +# Similar to test_must_fail, but tolerates success, too. This is +# meant to be used in contexts like: +# +# test_expect_success 'some command works without configuration' ' +# test_might_fail git config --unset all.configuration && +# do something +# ' +# +# Writing "git config --unset all.configuration || :" would be wrong, +# because we want to notice if it fails due to segv. + +test_might_fail () { + "$@" + test $? -ge 0 -a $? -le 129 -o $? -gt 192 +} + # test_cmp is a helper function to compare actual and expected output. # You can use it like: # @@ -533,6 +565,31 @@ test_cmp() { $GIT_TEST_CMP "$@" } +# This function can be used to schedule some commands to be run +# unconditionally at the end of the test to restore sanity: +# +# test_expect_success 'test core.capslock' ' +# git config core.capslock true && +# test_when_finished "git config --unset core.capslock" && +# hello world +# ' +# +# That would be roughly equivalent to +# +# test_expect_success 'test core.capslock' ' +# git config core.capslock true && +# hello world +# git config --unset core.capslock +# ' +# +# except that the greeting and config --unset must both succeed for +# the test to pass. + +test_when_finished () { + test_cleanup="{ $* + } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup" +} + # Most tests can use the created repository, but some may need to create more. # Usage: test_create_repo <directory> test_create_repo () { @@ -682,6 +739,16 @@ export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_CONFIG_NOGLOB . ../GIT-BUILD-OPTIONS +if test -z "$GIT_TEST_CMP" +then + if test -n "$GIT_TEST_CMP_USE_COPIED_CONTEXT" + then + GIT_TEST_CMP="$DIFF -c" + else + GIT_TEST_CMP="$DIFF -u" + fi +fi + GITPERLLIB=$(pwd)/../perl/blib/lib:$(pwd)/../perl/blib/arch/auto/Git export GITPERLLIB test -d ../templates/blt || { |