diff options
Diffstat (limited to 't')
65 files changed, 2267 insertions, 791 deletions
@@ -595,6 +595,20 @@ library for your script to use. test_cmp expected actual ' + - test_ln_s_add <path1> <path2> + + This function helps systems whose filesystem does not support symbolic + links. Use it to add a symbolic link entry to the index when it is not + important that the file system entry is a symbolic link, i.e., instead + of the sequence + + ln -s foo bar && + git add bar + + Sometimes it is possible to split a test in a part that does not need + the symbolic link in the file system and a part that does; then only + the latter part need be protected by a SYMLINKS prerequisite (see below). + Prerequisites ------------- diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index b5bce459b6..dd17e3a09d 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -1,5 +1,4 @@ ServerName dummy -LockFile accept.lock PidFile httpd.pid DocumentRoot www LogFormat "%h %l %u %t \"%r\" %>s %b" common @@ -24,6 +23,10 @@ ErrorLog error.log LoadModule version_module modules/mod_version.so </IfModule> +<IfVersion < 2.4> +LockFile accept.lock +</IfVersion> + <IfVersion < 2.1> <IfModule !mod_auth.c> LoadModule auth_module modules/mod_auth.so @@ -45,6 +48,21 @@ ErrorLog error.log </IfModule> </IfVersion> +<IfVersion >= 2.4> +<IfModule !mod_authn_core.c> + LoadModule authn_core_module modules/mod_authn_core.so +</IfModule> +<IfModule !mod_authz_core.c> + LoadModule authz_core_module modules/mod_authz_core.so +</IfModule> +<IfModule !mod_access_compat.c> + LoadModule access_compat_module modules/mod_access_compat.so +</IfModule> +<IfModule !mod_mpm_prefork.c> + LoadModule mpm_prefork_module modules/mod_mpm_prefork.so +</IfModule> +</IfVersion> + PassEnv GIT_VALGRIND PassEnv GIT_VALGRIND_OPTIONS diff --git a/t/lib-rebase.sh b/t/lib-rebase.sh index 6ccf797091..4b74ae460b 100644 --- a/t/lib-rebase.sh +++ b/t/lib-rebase.sh @@ -65,3 +65,36 @@ EOF test_set_editor "$(pwd)/fake-editor.sh" chmod a+x fake-editor.sh } + +# checks that the revisions in "$2" represent a linear range with the +# subjects in "$1" +test_linear_range () { + revlist_merges=$(git rev-list --merges "$2") && + test -z "$revlist_merges" && + expected=$1 + set -- $(git log --reverse --format=%s "$2") + test "$expected" = "$*" +} + +reset_rebase () { + test_might_fail git rebase --abort && + git reset --hard && + git clean -f +} + +cherry_pick () { + git cherry-pick -n "$2" && + git commit -m "$1" && + git tag "$1" +} + +revert () { + git revert -n "$2" && + git commit -m "$1" && + git tag "$1" +} + +make_empty () { + git commit --allow-empty -m "$1" && + git tag "$1" +} diff --git a/t/perf/p0002-read-cache.sh b/t/perf/p0002-read-cache.sh new file mode 100755 index 0000000000..9180ae9343 --- /dev/null +++ b/t/perf/p0002-read-cache.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +test_description="Tests performance of reading the index" + +. ./perf-lib.sh + +test_perf_default_repo + +count=1000 +test_perf "read_cache/discard_cache $count times" " + test-read-cache $count +" + +test_done diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index cefe33d6d1..0f1318056c 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -367,22 +367,6 @@ test_expect_success 'validate object ID of a known tree' ' # Various types of objects -# Some filesystems do not support symblic links; on such systems -# some expected values are different -if test_have_prereq SYMLINKS -then - expectfilter=cat - expectedtree=087704a96baf1c2d1c869a8b084481e121c88b5b - expectedptree1=21ae8269cacbe57ae09138dcc3a2887f904d02b3 - expectedptree2=3c5e5399f3a333eddecce7a9b9465b63f65f51e2 -else - expectfilter='grep -v sym' - expectedtree=8e18edf7d7edcf4371a3ac6ae5f07c2641db7c46 - expectedptree1=cfb8591b2f65de8b8cc1020cd7d9e67e7793b325 - expectedptree2=ce580448f0148b985a513b693fdf7d802cacb44f -fi - - test_expect_success 'adding various types of objects with git update-index --add' ' mkdir path2 path3 path3/subp3 && paths="path0 path2/file2 path3/file3 path3/subp3/file3" && @@ -390,10 +374,7 @@ test_expect_success 'adding various types of objects with git update-index --add for p in $paths do echo "hello $p" >$p || exit 1 - if test_have_prereq SYMLINKS - then - ln -s "hello $p" ${p}sym || exit 1 - fi + test_ln_s_add "hello $p" ${p}sym || exit 1 done ) && find path* ! -type d -print | xargs git update-index --add @@ -405,7 +386,7 @@ test_expect_success 'showing stage with git ls-files --stage' ' ' test_expect_success 'validate git ls-files output for a known tree' ' - $expectfilter >expected <<-\EOF && + cat >expected <<-\EOF && 100644 f87290f8eb2cbbea7857214459a0739927eab154 0 path0 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0 path0sym 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0 path2/file2 @@ -423,14 +404,14 @@ test_expect_success 'writing tree out with git write-tree' ' ' test_expect_success 'validate object ID for a known tree' ' - test "$tree" = "$expectedtree" + test "$tree" = 087704a96baf1c2d1c869a8b084481e121c88b5b ' test_expect_success 'showing tree with git ls-tree' ' git ls-tree $tree >current ' -test_expect_success SYMLINKS 'git ls-tree output for a known tree' ' +test_expect_success 'git ls-tree output for a known tree' ' cat >expected <<-\EOF && 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym @@ -447,7 +428,7 @@ test_expect_success 'showing tree with git ls-tree -r' ' ' test_expect_success 'git ls-tree -r output for a known tree' ' - $expectfilter >expected <<-\EOF && + cat >expected <<-\EOF && 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym 100644 blob 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 path2/file2 @@ -465,7 +446,7 @@ test_expect_success 'showing tree with git ls-tree -r -t' ' git ls-tree -r -t $tree >current ' -test_expect_success SYMLINKS 'git ls-tree -r output for a known tree' ' +test_expect_success 'git ls-tree -r output for a known tree' ' cat >expected <<-\EOF && 100644 blob f87290f8eb2cbbea7857214459a0739927eab154 path0 120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01 path0sym @@ -487,7 +468,7 @@ test_expect_success 'writing partial tree out with git write-tree --prefix' ' ' test_expect_success 'validate object ID for a known tree' ' - test "$ptree" = "$expectedptree1" + test "$ptree" = 21ae8269cacbe57ae09138dcc3a2887f904d02b3 ' test_expect_success 'writing partial tree out with git write-tree --prefix' ' @@ -495,7 +476,7 @@ test_expect_success 'writing partial tree out with git write-tree --prefix' ' ' test_expect_success 'validate object ID for a known tree' ' - test "$ptree" = "$expectedptree2" + test "$ptree" = 3c5e5399f3a333eddecce7a9b9465b63f65f51e2 ' test_expect_success 'put invalid objects into the index' ' @@ -529,7 +510,7 @@ test_expect_success 'git read-tree followed by write-tree should be idempotent' ' test_expect_success 'validate git diff-files output for a know cache/work tree state' ' - $expectfilter >expected <<\EOF && + cat >expected <<\EOF && :100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M path0 :120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M path0sym :100644 100644 3feff949ed00a62d9f7af97c15cd8a30595e7ac7 0000000000000000000000000000000000000000 M path2/file2 @@ -553,7 +534,7 @@ test_expect_success 'no diff after checkout and git update-index --refresh' ' ' ################################################################ -P=$expectedtree +P=087704a96baf1c2d1c869a8b084481e121c88b5b test_expect_success 'git commit-tree records the correct tree in a commit' ' commit0=$(echo NO | git commit-tree $P) && diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 244a43c920..65606df3ed 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -50,7 +50,7 @@ EOF test_expect_success 'test help' ' test_must_fail test-parse-options -h > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_i18ncmp expect output ' @@ -75,7 +75,7 @@ check() { shift && sed "s/^$what .*/$what $expect/" <expect.template >expect && test-parse-options $* >output 2>output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output } @@ -86,7 +86,7 @@ check_i18n() { shift && sed "s/^$what .*/$what $expect/" <expect.template >expect && test-parse-options $* >output 2>output.err && - test ! -s output.err && + test_must_be_empty output.err && test_i18ncmp expect output } @@ -99,7 +99,7 @@ check_unknown() { esac && cat expect.err >>expect && test_must_fail test-parse-options $* >output 2>output.err && - test ! -s output && + test_must_be_empty output && test_cmp expect output.err } @@ -112,7 +112,7 @@ check_unknown_i18n() { esac && cat expect.err >>expect && test_must_fail test-parse-options $* >output 2>output.err && - test ! -s output && + test_must_be_empty output && test_i18ncmp expect output.err } @@ -149,7 +149,7 @@ test_expect_success 'short options' ' test-parse-options -s123 -b -i 1729 -b -vv -n -F my.file \ > output 2> output.err && test_cmp expect output && - test ! -s output.err + test_must_be_empty output.err ' cat > expect << EOF @@ -168,7 +168,7 @@ test_expect_success 'long options' ' test-parse-options --boolean --integer 1729 --boolean --string2=321 \ --verbose --verbose --no-dry-run --abbrev=10 --file fi.le\ --obsolete > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -199,7 +199,7 @@ EOF test_expect_success 'intermingled arguments' ' test-parse-options a1 --string 123 b1 --boolean -j 13 -- --boolean \ > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -217,13 +217,13 @@ EOF test_expect_success 'unambiguously abbreviated option' ' test-parse-options --int 2 --boolean --no-bo > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'unambiguously abbreviated option with "="' ' test-parse-options --int=2 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -246,7 +246,7 @@ EOF test_expect_success 'non ambiguous option (after two options it abbreviates)' ' test-parse-options --st 123 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -256,7 +256,7 @@ EOF test_expect_success 'detect possible typos' ' test_must_fail test-parse-options -boolean > output 2> output.err && - test ! -s output && + test_must_be_empty output && test_cmp typo.err output.err ' @@ -266,7 +266,7 @@ EOF test_expect_success 'detect possible typos' ' test_must_fail test-parse-options -ambiguous > output 2> output.err && - test ! -s output && + test_must_be_empty output && test_cmp typo.err output.err ' @@ -285,7 +285,7 @@ EOF test_expect_success 'keep some options as arguments' ' test-parse-options --quux > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -305,7 +305,7 @@ EOF test_expect_success 'OPT_DATE() and OPT_SET_PTR() work' ' test-parse-options -t "1970-01-01 00:00:01 +0000" --default-string \ foo -q > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -324,7 +324,7 @@ EOF test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' ' test-parse-options --length=four -b -4 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -352,13 +352,13 @@ EOF test_expect_success 'OPT_BIT() and OPT_SET_INT() work' ' test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' ' test-parse-options --set23 -bbbbb --neg-or4 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -376,19 +376,19 @@ EOF test_expect_success 'OPT_BIT() works' ' test-parse-options -bb --or4 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_NEGBIT() works' ' test-parse-options -bb --no-neg-or4 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' ' test-parse-options + + + + + + > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -406,7 +406,7 @@ EOF test_expect_success 'OPT_NUMBER_CALLBACK() works' ' test-parse-options -12345 > output 2> output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' @@ -424,7 +424,7 @@ EOF test_expect_success 'negation of OPT_NONEG flags is not ambiguous' ' test-parse-options --no-ambig >output 2>output.err && - test ! -s output.err && + test_must_be_empty output.err && test_cmp expect output ' diff --git a/t/t1004-read-tree-m-u-wf.sh b/t/t1004-read-tree-m-u-wf.sh index b3ae7d52c6..3e72aff470 100755 --- a/t/t1004-read-tree-m-u-wf.sh +++ b/t/t1004-read-tree-m-u-wf.sh @@ -158,7 +158,7 @@ test_expect_success '3-way not overwriting local changes (their side)' ' ' -test_expect_success SYMLINKS 'funny symlink in work tree' ' +test_expect_success 'funny symlink in work tree' ' git reset --hard && git checkout -b sym-b side-b && @@ -170,15 +170,14 @@ test_expect_success SYMLINKS 'funny symlink in work tree' ' rm -fr a && git checkout -b sym-a side-a && mkdir -p a && - ln -s ../b a/b && - git add a/b && + test_ln_s_add ../b a/b && git commit -m "we add a/b" && read_tree_u_must_succeed -m -u sym-a sym-a sym-b ' -test_expect_success SYMLINKS,SANITY 'funny symlink in work tree, un-unlink-able' ' +test_expect_success SANITY 'funny symlink in work tree, un-unlink-able' ' rm -fr a b && git reset --hard && diff --git a/t/t1513-rev-parse-prefix.sh b/t/t1513-rev-parse-prefix.sh new file mode 100755 index 0000000000..87ec3ae714 --- /dev/null +++ b/t/t1513-rev-parse-prefix.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +test_description='Tests for rev-parse --prefix' + +. ./test-lib.sh + +test_expect_success 'setup' ' + mkdir -p sub1/sub2 && + echo top >top && + echo file1 >sub1/file1 && + echo file2 >sub1/sub2/file2 && + git add top sub1/file1 sub1/sub2/file2 && + git commit -m commit +' + +test_expect_success 'empty prefix -- file' ' + git rev-parse --prefix "" -- top sub1/file1 >actual && + cat <<-\EOF >expected && + -- + top + sub1/file1 + EOF + test_cmp expected actual +' + +test_expect_success 'valid prefix -- file' ' + git rev-parse --prefix sub1/ -- file1 sub2/file2 >actual && + cat <<-\EOF >expected && + -- + sub1/file1 + sub1/sub2/file2 + EOF + test_cmp expected actual +' + +test_expect_success 'valid prefix -- ../file' ' + git rev-parse --prefix sub1/ -- ../top sub2/file2 >actual && + cat <<-\EOF >expected && + -- + sub1/../top + sub1/sub2/file2 + EOF + test_cmp expected actual +' + +test_expect_success 'empty prefix HEAD:./path' ' + git rev-parse --prefix "" HEAD:./top >actual && + git rev-parse HEAD:top >expected && + test_cmp expected actual +' + +test_expect_success 'valid prefix HEAD:./path' ' + git rev-parse --prefix sub1/ HEAD:./file1 >actual && + git rev-parse HEAD:sub1/file1 >expected && + test_cmp expected actual +' + +test_expect_success 'valid prefix HEAD:../path' ' + git rev-parse --prefix sub1/ HEAD:../top >actual && + git rev-parse HEAD:top >expected && + test_cmp expected actual +' + +test_expect_success 'prefix ignored with HEAD:top' ' + git rev-parse --prefix sub1/ HEAD:top >actual && + git rev-parse HEAD:top >expected && + test_cmp expected actual +' + +test_expect_success 'disambiguate path with valid prefix' ' + git rev-parse --prefix sub1/ file1 >actual && + cat <<-\EOF >expected && + sub1/file1 + EOF + test_cmp expected actual +' + +test_expect_success 'file and refs with prefix' ' + git rev-parse --prefix sub1/ master file1 >actual && + cat <<-EOF >expected && + $(git rev-parse master) + sub1/file1 + EOF + test_cmp expected actual +' + +test_expect_success 'two-levels deep' ' + git rev-parse --prefix sub1/sub2/ -- file2 >actual && + cat <<-\EOF >expected && + -- + sub1/sub2/file2 + EOF + test_cmp expected actual +' + +test_done diff --git a/t/t2001-checkout-cache-clash.sh b/t/t2001-checkout-cache-clash.sh index 98aa73e823..1fc8e634b7 100755 --- a/t/t2001-checkout-cache-clash.sh +++ b/t/t2001-checkout-cache-clash.sh @@ -59,10 +59,9 @@ test_expect_success \ 'git read-tree -m $tree1 && git checkout-index -f -a' test_debug 'show_files $tree1' -test_expect_success SYMLINKS \ - 'git update-index --add a symlink.' \ - 'ln -s path0 path1 && - git update-index --add path1' +test_expect_success \ + 'add a symlink' \ + 'test_ln_s_add path0 path1' test_expect_success \ 'writing tree out with git write-tree' \ 'tree3=$(git write-tree)' diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh index 0f4b2896af..f171a5578b 100755 --- a/t/t2004-checkout-cache-temp.sh +++ b/t/t2004-checkout-cache-temp.sh @@ -194,11 +194,10 @@ test_expect_success \ test $(cat ../$s1) = tree1asubdir/path5) )' -test_expect_success SYMLINKS \ +test_expect_success \ 'checkout --temp symlink' ' rm -f path* .merge_* out .git/index && -ln -s b a && -git update-index --add a && +test_ln_s_add b a && t4=$(git write-tree) && rm -f .git/index && git read-tree $t4 && diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh index e6f59f1914..fc9aad530e 100755 --- a/t/t2007-checkout-symlink.sh +++ b/t/t2007-checkout-symlink.sh @@ -6,7 +6,7 @@ test_description='git checkout to switch between branches with symlink<->dir' . ./test-lib.sh -test_expect_success SYMLINKS setup ' +test_expect_success setup ' mkdir frotz && echo hello >frotz/filfre && @@ -25,25 +25,25 @@ test_expect_success SYMLINKS setup ' git rm --cached frotz/filfre && mv frotz xyzzy && - ln -s xyzzy frotz && - git add xyzzy/filfre frotz && + test_ln_s_add xyzzy frotz && + git add xyzzy/filfre && test_tick && git commit -m "side moves frotz/ to xyzzy/ and adds frotz->xyzzy/" ' -test_expect_success SYMLINKS 'switch from symlink to dir' ' +test_expect_success 'switch from symlink to dir' ' git checkout master ' -test_expect_success SYMLINKS 'Remove temporary directories & switch to master' ' +test_expect_success 'Remove temporary directories & switch to master' ' rm -fr frotz xyzzy nitfol && git checkout -f master ' -test_expect_success SYMLINKS 'switch from dir to symlink' ' +test_expect_success 'switch from dir to symlink' ' git checkout side diff --git a/t/t2021-checkout-overwrite.sh b/t/t2021-checkout-overwrite.sh index 5da63e9fa2..c2ada7de37 100755 --- a/t/t2021-checkout-overwrite.sh +++ b/t/t2021-checkout-overwrite.sh @@ -29,21 +29,25 @@ test_expect_success 'checkout commit with dir must not remove untracked a/b' ' test -f a/b ' -test_expect_success SYMLINKS 'create a commit where dir a/b changed to symlink' ' +test_expect_success 'create a commit where dir a/b changed to symlink' ' rm -rf a/b && # cleanup if previous test failed git checkout -f -b symlink start && rm -rf a/b && - ln -s foo a/b && git add -A && + test_ln_s_add foo a/b && git commit -m "dir to symlink" ' -test_expect_success SYMLINKS 'checkout commit with dir must not remove untracked a/b' ' +test_expect_success 'checkout commit with dir must not remove untracked a/b' ' git rm --cached a/b && git commit -m "un-track the symlink" && - test_must_fail git checkout start && + test_must_fail git checkout start +' + +test_expect_success SYMLINKS 'the symlink remained' ' + test -h a/b ' diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index b2bd41918e..9bf2bdffd2 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -96,11 +96,10 @@ test_expect_success 'non-limited update in subdir leaves root alone' ' test_cmp expect actual ' -test_expect_success SYMLINKS 'replace a file with a symlink' ' +test_expect_success 'replace a file with a symlink' ' rm foo && - ln -s top foo && - git add -u -- foo + test_ln_s_add top foo ' diff --git a/t/t3010-ls-files-killed-modified.sh b/t/t3010-ls-files-killed-modified.sh index 95671c2053..262e617445 100755 --- a/t/t3010-ls-files-killed-modified.sh +++ b/t/t3010-ls-files-killed-modified.sh @@ -37,71 +37,65 @@ modified without reporting path9 and path10. ' . ./test-lib.sh -date >path0 -if test_have_prereq SYMLINKS -then - ln -s xyzzy path1 -else - date > path1 -fi -mkdir path2 path3 -date >path2/file2 -date >path3/file3 -: >path7 -date >path8 -: >path9 -date >path10 -test_expect_success \ - 'git update-index --add to add various paths.' \ - "git update-index --add -- path0 path1 path?/file? path7 path8 path9 path10" - -rm -fr path? ;# leave path10 alone -date >path2 -if test_have_prereq SYMLINKS -then - ln -s frotz path3 - ln -s nitfol path5 -else - date > path3 - date > path5 -fi -mkdir path0 path1 path6 -date >path0/file0 -date >path1/file1 -date >path6/file6 -date >path7 -: >path8 -: >path9 -touch path10 +test_expect_success 'git update-index --add to add various paths.' ' + date >path0 && + test_ln_s_add xyzzy path1 && + mkdir path2 path3 && + date >path2/file2 && + date >path3/file3 && + : >path7 && + date >path8 && + : >path9 && + date >path10 && + git update-index --add -- path0 path?/file? path7 path8 path9 path10 && + rm -fr path? # leave path10 alone +' -test_expect_success \ - 'git ls-files -k to show killed files.' \ - 'git ls-files -k >.output' -cat >.expected <<EOF -path0/file0 -path1/file1 -path2 -path3 -EOF +test_expect_success 'git ls-files -k to show killed files.' ' + date >path2 && + if test_have_prereq SYMLINKS + then + ln -s frotz path3 && + ln -s nitfol path5 + else + date >path3 && + date >path5 + fi && + mkdir path0 path1 path6 && + date >path0/file0 && + date >path1/file1 && + date >path6/file6 && + date >path7 && + : >path8 && + : >path9 && + touch path10 && + git ls-files -k >.output +' -test_expect_success \ - 'validate git ls-files -k output.' \ - 'test_cmp .expected .output' +test_expect_success 'validate git ls-files -k output.' ' + cat >.expected <<-\EOF && + path0/file0 + path1/file1 + path2 + path3 + EOF + test_cmp .expected .output +' -test_expect_success \ - 'git ls-files -m to show modified files.' \ - 'git ls-files -m >.output' -cat >.expected <<EOF -path0 -path1 -path2/file2 -path3/file3 -path7 -path8 -EOF +test_expect_success 'git ls-files -m to show modified files.' ' + git ls-files -m >.output +' -test_expect_success \ - 'validate git ls-files -m output.' \ - 'test_cmp .expected .output' +test_expect_success 'validate git ls-files -m output.' ' + cat >.expected <<-\EOF && + path0 + path1 + path2/file2 + path3/file3 + path7 + path8 + EOF + test_cmp .expected .output +' test_done diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index a5e3da7e41..2f96100a5f 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -25,10 +25,7 @@ test_expect_success 'setup 1' ' git branch submod && git branch copy && git branch rename && - if test_have_prereq SYMLINKS - then - git branch rename-ln - fi && + git branch rename-ln && echo hello >>a && cp a d/e && @@ -260,16 +257,12 @@ test_expect_success 'setup 8' ' git add e && test_tick && git commit -m "rename a->e" && - if test_have_prereq SYMLINKS - then - git checkout rename-ln && - git mv a e && - ln -s e a && - git add a e && - test_tick && - git commit -m "rename a->e, symlink a->e" && - oln=`printf e | git hash-object --stdin` - fi + git checkout rename-ln && + git mv a e && + test_ln_s_add e a && + test_tick && + git commit -m "rename a->e, symlink a->e" && + oln=`printf e | git hash-object --stdin` ' test_expect_success 'setup 9' ' @@ -569,28 +562,25 @@ test_expect_success 'merge-recursive copy vs. rename' ' test_cmp expected actual ' -if test_have_prereq SYMLINKS -then - test_expect_failure 'merge-recursive rename vs. rename/symlink' ' - - git checkout -f rename && - git merge rename-ln && - ( git ls-tree -r HEAD ; git ls-files -s ) >actual && - ( - echo "120000 blob $oln a" - echo "100644 blob $o0 b" - echo "100644 blob $o0 c" - echo "100644 blob $o0 d/e" - echo "100644 blob $o0 e" - echo "120000 $oln 0 a" - echo "100644 $o0 0 b" - echo "100644 $o0 0 c" - echo "100644 $o0 0 d/e" - echo "100644 $o0 0 e" - ) >expected && - test_cmp expected actual - ' -fi +test_expect_failure 'merge-recursive rename vs. rename/symlink' ' + + git checkout -f rename && + git merge rename-ln && + ( git ls-tree -r HEAD ; git ls-files -s ) >actual && + ( + echo "120000 blob $oln a" + echo "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 blob $o0 e" + echo "120000 $oln 0 a" + echo "100644 $o0 0 b" + echo "100644 $o0 0 c" + echo "100644 $o0 0 d/e" + echo "100644 $o0 0 e" + ) >expected && + test_cmp expected actual +' test_done diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh index 81d90b66c5..eb73c06a4e 100755 --- a/t/t3100-ls-tree-restrict.sh +++ b/t/t3100-ls-tree-restrict.sh @@ -22,20 +22,8 @@ test_expect_success \ 'setup' \ 'mkdir path2 path2/baz && echo Hi >path0 && - if test_have_prereq SYMLINKS - then - ln -s path0 path1 && - ln -s ../path1 path2/bazbo - make_expected () { - cat >expected - } - else - printf path0 > path1 && - printf ../path1 > path2/bazbo - make_expected () { - sed -e "s/120000 /100644 /" >expected - } - fi && + test_ln_s_add path0 path1 && + test_ln_s_add ../path1 path2/bazbo && echo Lo >path2/foo && echo Mi >path2/baz/b && find path? \( -type f -o -type l \) -print | @@ -51,7 +39,7 @@ test_output () { test_expect_success \ 'ls-tree plain' \ 'git ls-tree $tree >current && - make_expected <<\EOF && + cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 040000 tree X path2 @@ -61,7 +49,7 @@ EOF test_expect_success \ 'ls-tree recursive' \ 'git ls-tree -r $tree >current && - make_expected <<\EOF && + cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 100644 blob X path2/baz/b @@ -73,7 +61,7 @@ EOF test_expect_success \ 'ls-tree recursive with -t' \ 'git ls-tree -r -t $tree >current && - make_expected <<\EOF && + cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 040000 tree X path2 @@ -87,7 +75,7 @@ EOF test_expect_success \ 'ls-tree recursive with -d' \ 'git ls-tree -r -d $tree >current && - make_expected <<\EOF && + cat >expected <<\EOF && 040000 tree X path2 040000 tree X path2/baz EOF @@ -96,7 +84,7 @@ EOF test_expect_success \ 'ls-tree filtered with path' \ 'git ls-tree $tree path >current && - make_expected <<\EOF && + cat >expected <<\EOF && EOF test_output' @@ -106,7 +94,7 @@ EOF test_expect_success \ 'ls-tree filtered with path1 path0' \ 'git ls-tree $tree path1 path0 >current && - make_expected <<\EOF && + cat >expected <<\EOF && 100644 blob X path0 120000 blob X path1 EOF @@ -115,7 +103,7 @@ EOF test_expect_success \ 'ls-tree filtered with path0/' \ 'git ls-tree $tree path0/ >current && - make_expected <<\EOF && + cat >expected <<\EOF && EOF test_output' @@ -124,7 +112,7 @@ EOF test_expect_success \ 'ls-tree filtered with path2' \ 'git ls-tree $tree path2 >current && - make_expected <<\EOF && + cat >expected <<\EOF && 040000 tree X path2 EOF test_output' @@ -133,7 +121,7 @@ EOF test_expect_success \ 'ls-tree filtered with path2/' \ 'git ls-tree $tree path2/ >current && - make_expected <<\EOF && + cat >expected <<\EOF && 040000 tree X path2/baz 120000 blob X path2/bazbo 100644 blob X path2/foo @@ -145,7 +133,7 @@ EOF test_expect_success \ 'ls-tree filtered with path2/baz' \ 'git ls-tree $tree path2/baz >current && - make_expected <<\EOF && + cat >expected <<\EOF && 040000 tree X path2/baz EOF test_output' @@ -153,14 +141,14 @@ EOF test_expect_success \ 'ls-tree filtered with path2/bak' \ 'git ls-tree $tree path2/bak >current && - make_expected <<\EOF && + cat >expected <<\EOF && EOF test_output' test_expect_success \ 'ls-tree -t filtered with path2/bak' \ 'git ls-tree -t $tree path2/bak >current && - make_expected <<\EOF && + cat >expected <<\EOF && 040000 tree X path2 EOF test_output' @@ -168,7 +156,7 @@ EOF test_expect_success \ 'ls-tree with one path a prefix of the other' \ 'git ls-tree $tree path2/baz path2/bazbo >current && - make_expected <<\EOF && + cat >expected <<\EOF && 040000 tree X path2/baz 120000 blob X path2/bazbo EOF diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index b58fa1a232..ebf93b0695 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -40,13 +40,6 @@ test_expect_success 'prepare repository with topic branches' ' echo Side >>C && git add C && git commit -m "Add C" && - git checkout -b nonlinear my-topic-branch && - echo Edit >>B && - git add B && - git commit -m "Modify B" && - git merge side && - git checkout -b upstream-merged-nonlinear && - git merge master && git checkout -f my-topic-branch && git tag topic ' @@ -66,26 +59,15 @@ test_expect_success 'rebase against master' ' git rebase master ' -test_expect_success 'rebase against master twice' ' - git rebase master >out && - test_i18ngrep "Current branch my-topic-branch is up to date" out -' - -test_expect_success 'rebase against master twice with --force' ' - git rebase --force-rebase master >out && - test_i18ngrep "Current branch my-topic-branch is up to date, rebase forced" out -' - -test_expect_success 'rebase against master twice from another branch' ' - git checkout my-topic-branch^ && - git rebase master my-topic-branch >out && - test_i18ngrep "Current branch my-topic-branch is up to date" out -' - -test_expect_success 'rebase fast-forward to master' ' - git checkout my-topic-branch^ && - git rebase my-topic-branch >out && - test_i18ngrep "Fast-forwarded HEAD to my-topic-branch" out +test_expect_success 'rebase, with <onto> and <upstream> specified as :/quuxery' ' + test_when_finished "git branch -D torebase" && + git checkout -b torebase my-topic-branch^ && + upstream=$(git rev-parse ":/Add B") && + onto=$(git rev-parse ":/Add A") && + git rebase --onto $onto $upstream && + git reset --hard my-topic-branch^ && + git rebase --onto ":/Add A" ":/Add B" && + git checkout my-topic-branch ' test_expect_success 'the rebase operation should not have destroyed author information' ' @@ -106,31 +88,9 @@ test_expect_success 'rebase from ambiguous branch name' ' git rebase master ' -test_expect_success 'rebase after merge master' ' - git checkout --detach refs/tags/topic && - git branch -D topic && - git reset --hard topic && - git merge master && - git rebase master && - ! (git show | grep "^Merge:") -' - -test_expect_success 'rebase of history with merges is linearized' ' - git checkout nonlinear && - test 4 = $(git rev-list master.. | wc -l) && - git rebase master && - test 3 = $(git rev-list master.. | wc -l) -' - -test_expect_success 'rebase of history with merges after upstream merge is linearized' ' - git checkout upstream-merged-nonlinear && - test 5 = $(git rev-list master.. | wc -l) && - git rebase master && - test 3 = $(git rev-list master.. | wc -l) -' - test_expect_success 'rebase a single mode change' ' git checkout master && + git branch -D topic && echo 1 >X && git add X && test_tick && @@ -185,7 +145,7 @@ test_expect_success 'default to @{upstream} when upstream arg is missing' ' test_expect_success 'rebase -q is quiet' ' git checkout -b quiet topic && git rebase -q master >output.out 2>&1 && - test ! -s output.out + test_must_be_empty output.out ' test_expect_success 'Rebase a commit that sprinkles CRs in' ' diff --git a/t/t3401-rebase-partial.sh b/t/t3401-rebase-partial.sh deleted file mode 100755 index 58f4823783..0000000000 --- a/t/t3401-rebase-partial.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006 Yann Dirson, based on t3400 by Amos Waterland -# - -test_description='git rebase should detect patches integrated upstream - -This test cherry-picks one local change of two into master branch, and -checks that git rebase succeeds with only the second patch in the -local branch. -' -. ./test-lib.sh - -test_expect_success 'prepare repository with topic branch' ' - test_commit A && - git checkout -b my-topic-branch && - test_commit B && - test_commit C && - git checkout -f master && - test_commit A2 A.t -' - -test_expect_success 'pick top patch from topic branch into master' ' - git cherry-pick C && - git checkout -f my-topic-branch -' - -test_debug ' - git cherry master && - git format-patch -k --stdout --full-index master >/dev/null && - gitk --all & sleep 1 -' - -test_expect_success 'rebase topic branch against new master and check git am did not get halted' ' - git rebase master && - test_path_is_missing .git/rebase-apply -' - -test_expect_success 'rebase --merge topic branch that was partially merged upstream' ' - git reset --hard C && - git rebase --merge master && - test_path_is_missing .git/rebase-merge -' - -test_expect_success 'rebase ignores empty commit' ' - git reset --hard A && - git commit --allow-empty -m empty && - test_commit D && - git rebase C && - test "$(git log --format=%s C..)" = "D" -' - -test_expect_success 'rebase --keep-empty' ' - git reset --hard D && - git rebase --keep-empty C && - test "$(git log --format=%s C..)" = "D -empty" -' - -test_expect_success 'rebase --keep-empty keeps empty even if already in upstream' ' - git reset --hard A && - git commit --allow-empty -m also-empty && - git rebase --keep-empty D && - test "$(git log --format=%s A..)" = "also-empty -D -empty" -' - -test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 79e8d3c596..d6b4143773 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -477,19 +477,11 @@ test_expect_success 'interrupted squash works as expected (case 2)' ' test $one = $(git rev-parse HEAD~2) ' -test_expect_success 'ignore patch if in upstream' ' - HEAD=$(git rev-parse HEAD) && - git checkout -b has-cherry-picked HEAD^ && +test_expect_success '--continue tries to commit, even for "edit"' ' echo unrelated > file7 && git add file7 && test_tick && git commit -m "unrelated change" && - git cherry-pick $HEAD && - EXPECT_COUNT=1 git rebase -i $HEAD && - test $HEAD = $(git rev-parse HEAD^) -' - -test_expect_success '--continue tries to commit, even for "edit"' ' parent=$(git rev-parse HEAD^) && test_tick && FAKE_LINES="edit 1" git rebase -i HEAD^ && @@ -947,4 +939,15 @@ test_expect_success 'rebase -i respects core.commentchar' ' test B = $(git cat-file commit HEAD^ | sed -ne \$p) ' +test_expect_success 'rebase -i, with <onto> and <upstream> specified as :/quuxery' ' + test_when_finished "git branch -D torebase" && + git checkout -b torebase branch1 && + upstream=$(git rev-parse ":/J") && + onto=$(git rev-parse ":/A") && + git rebase --onto $onto $upstream && + git reset --hard branch1 && + git rebase --onto ":/A" ":/J" && + git checkout branch1 +' + test_done diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index e6a9a0d436..0392e36d23 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -4,27 +4,17 @@ test_description='messages from rebase operation' . ./test-lib.sh -quick_one () { - echo "$1" >"file$1" && - git add "file$1" && - test_tick && - git commit -m "$1" -} +test_expect_success 'setup' ' + test_commit O fileO && + test_commit X fileX && + test_commit A fileA && + test_commit B fileB && + test_commit Y fileY && -test_expect_success setup ' - quick_one O && - git branch topic && - quick_one X && - quick_one A && - quick_one B && - quick_one Y && - - git checkout topic && - quick_one A && - quick_one B && - quick_one Z && + git checkout -b topic O && + git cherry-pick A B && + test_commit Z fileZ && git tag start - ' cat >expect <<\EOF @@ -34,12 +24,32 @@ Committed: 0003 Z EOF test_expect_success 'rebase -m' ' - git rebase -m master >report && sed -n -e "/^Already applied: /p" \ -e "/^Committed: /p" report >actual && test_cmp expect actual +' + +test_expect_success 'rebase against master twice' ' + git rebase master >out && + test_i18ngrep "Current branch topic is up to date" out +' + +test_expect_success 'rebase against master twice with --force' ' + git rebase --force-rebase master >out && + test_i18ngrep "Current branch topic is up to date, rebase forced" out +' + +test_expect_success 'rebase against master twice from another branch' ' + git checkout topic^ && + git rebase master topic >out && + test_i18ngrep "Current branch topic is up to date" out +' +test_expect_success 'rebase fast-forward to master' ' + git checkout topic^ && + git rebase topic >out && + test_i18ngrep "Fast-forwarded HEAD to topic" out ' test_expect_success 'rebase --stat' ' diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh index 6de4e2263f..2e0c36415f 100755 --- a/t/t3409-rebase-preserve-merges.sh +++ b/t/t3409-rebase-preserve-merges.sh @@ -11,14 +11,6 @@ Run "git rebase -p" and check that merges are properly carried along GIT_AUTHOR_EMAIL=bogus_email_address export GIT_AUTHOR_EMAIL -# Clone 1 (trivial merge): -# -# A1--A2 <-- origin/master -# \ \ -# B1--M <-- topic -# \ -# B2 <-- origin/topic -# # Clone 2 (conflicting merge): # # A1--A2--B3 <-- origin/master @@ -36,16 +28,6 @@ export GIT_AUTHOR_EMAIL # \--A3 <-- topic2 # \ # B2 <-- origin/topic -# -# Clone 4 (merge using second parent as base): -# -# A1--A2--B3 <-- origin/master -# \ -# B1--A3--M <-- topic -# \ / -# \--A4 <-- topic2 -# \ -# B2 <-- origin/topic test_expect_success 'setup for merge-preserving rebase' \ 'echo First > A && @@ -58,20 +40,6 @@ test_expect_success 'setup for merge-preserving rebase' \ git checkout -f master && echo Third >> A && git commit -a -m "Modify A2" && - - git clone ./. clone1 && - (cd clone1 && - git checkout -b topic origin/topic && - git merge origin/master - ) && - - git clone ./. clone4 && - ( - cd clone4 && - git checkout -b topic origin/topic && - git merge origin/master - ) && - echo Fifth > B && git add B && git commit -m "Add different B" && @@ -101,16 +69,6 @@ test_expect_success 'setup for merge-preserving rebase' \ git commit -a -m "Modify B2" ' -test_expect_success 'rebase -p fakes interactive rebase' ' - ( - cd clone1 && - git fetch && - git rebase -p origin/topic && - test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && - test 1 = $(git rev-list --all --pretty=oneline | grep "Merge remote-tracking branch " | wc -l) - ) -' - test_expect_success '--continue works after a conflict' ' ( cd clone2 && @@ -138,15 +96,4 @@ test_expect_success 'rebase -p preserves no-ff merges' ' ) ' -test_expect_success 'rebase -p works when base inside second parent' ' - ( - cd clone4 && - git fetch && - git rebase -p HEAD^2 && - test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && - test 1 = $(git rev-list --all --pretty=oneline | grep "Modify B" | wc -l) && - test 1 = $(git rev-list --all --pretty=oneline | grep "Merge remote-tracking branch " | wc -l) - ) -' - test_done diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index 479cbb215f..90eb26493c 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -141,6 +141,28 @@ testrebase() { ' } +test_expect_success "rebase: fast-forward rebase" ' + test_config rebase.autostash true && + git reset --hard && + git checkout -b behind-feature-branch feature-branch~1 && + test_when_finished git branch -D behind-feature-branch && + echo dirty >>file1 && + git rebase feature-branch && + grep dirty file1 && + git checkout feature-branch +' + +test_expect_success "rebase: noop rebase" ' + test_config rebase.autostash true && + git reset --hard && + git checkout -b same-feature-branch feature-branch && + test_when_finished git branch -D same-feature-branch && + echo dirty >>file1 && + git rebase feature-branch && + grep dirty file1 && + git checkout feature-branch +' + testrebase "" .git/rebase-apply testrebase " --merge" .git/rebase-merge testrebase " --interactive" .git/rebase-merge diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh new file mode 100755 index 0000000000..9c55cba198 --- /dev/null +++ b/t/t3421-rebase-topology-linear.sh @@ -0,0 +1,350 @@ +#!/bin/sh + +test_description='basic rebase topology tests' +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + +# a---b---c +# \ +# d---e +test_expect_success 'setup' ' + test_commit a && + test_commit b && + test_commit c && + git checkout b && + test_commit d && + test_commit e +' + +test_run_rebase () { + result=$1 + shift + test_expect_$result "simple rebase $*" " + reset_rebase && + git rebase $* c e && + test_cmp_rev c HEAD~2 && + test_linear_range 'd e' c.. + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* is no-op if upstream is an ancestor" " + reset_rebase && + git rebase $* b e && + test_cmp_rev e HEAD + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* -f rewrites even if upstream is an ancestor" " + reset_rebase && + git rebase $* -f b e && + ! test_cmp_rev e HEAD && + test_cmp_rev b HEAD~2 && + test_linear_range 'd e' b.. + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase failure -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* fast-forwards from ancestor of upstream" " + reset_rebase && + git rebase $* e b && + test_cmp_rev e HEAD + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase success -p + +# f +# / +# a---b---c---g---h +# \ +# d---gp--i +# +# gp = cherry-picked g +# h = reverted g +# +# Reverted patches are there for tests to be able to check if a commit +# that introduced the same change as another commit is +# dropped. Without reverted commits, we could get false positives +# because applying the patch succeeds, but simply results in no +# changes. +test_expect_success 'setup of linear history for range selection tests' ' + git checkout c && + test_commit g && + revert h g && + git checkout d && + cherry_pick gp g && + test_commit i && + git checkout b && + test_commit f +' + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* drops patches in upstream" " + reset_rebase && + git rebase $* h i && + test_cmp_rev h HEAD~2 && + test_linear_range 'd i' h.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* can drop last patch if in upstream" " + reset_rebase && + git rebase $* h gp && + test_cmp_rev h HEAD^ && + test_linear_range 'd' h.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --onto drops patches in upstream" " + reset_rebase && + git rebase $* --onto f h i && + test_cmp_rev f HEAD~2 && + test_linear_range 'd i' f.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --onto does not drop patches in onto" " + reset_rebase && + git rebase $* --onto h f i && + test_cmp_rev h HEAD~3 && + test_linear_range 'd gp i' h.. + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase success -p + +# a---b---c---j! +# \ +# d---k!--l +# +# ! = empty +test_expect_success 'setup of linear history for empty commit tests' ' + git checkout c && + make_empty j && + git checkout d && + make_empty k && + test_commit l +' + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* drops empty commit" " + reset_rebase && + git rebase $* c l && + test_cmp_rev c HEAD~2 && + test_linear_range 'd l' c.. + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --keep-empty" " + reset_rebase && + git rebase $* --keep-empty c l && + test_cmp_rev c HEAD~3 && + test_linear_range 'd k l' c.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase failure -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --keep-empty keeps empty even if already in upstream" " + reset_rebase && + git rebase $* --keep-empty j l && + test_cmp_rev j HEAD~3 && + test_linear_range 'd k l' j.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase failure -i +test_run_rebase failure -p + +# m +# / +# a---b---c---g +# +# x---y---bp +# +# bp = cherry-picked b +# m = reverted b +# +# Reverted patches are there for tests to be able to check if a commit +# that introduced the same change as another commit is +# dropped. Without reverted commits, we could get false positives +# because applying the patch succeeds, but simply results in no +# changes. +test_expect_success 'setup of linear history for test involving root' ' + git checkout b && + revert m b && + git checkout --orphan disjoint && + git rm -rf . && + test_commit x && + test_commit y && + cherry_pick bp b +' + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --onto --root" " + reset_rebase && + git rebase $* --onto c --root y && + test_cmp_rev c HEAD~2 && + test_linear_range 'x y' c.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* without --onto --root with disjoint history" " + reset_rebase && + git rebase $* c y && + test_cmp_rev c HEAD~2 && + test_linear_range 'x y' c.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase failure -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --onto --root drops patch in onto" " + reset_rebase && + git rebase $* --onto m --root bp && + test_cmp_rev m HEAD~2 && + test_linear_range 'x y' m.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase success -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --onto --root with merge-base does not go to root" " + reset_rebase && + git rebase $* --onto m --root g && + test_cmp_rev m HEAD~2 && + test_linear_range 'c g' m.. + " +} + +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase failure -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* without --onto --root with disjoint history drops patch in onto" " + reset_rebase && + git rebase $* m bp && + test_cmp_rev m HEAD~2 && + test_linear_range 'x y' m.. + " +} +test_run_rebase success '' +test_run_rebase failure -m +test_run_rebase success -i +test_run_rebase failure -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* --root on linear history is a no-op" " + reset_rebase && + git rebase $* --root c && + test_cmp_rev c HEAD + " +} +test_run_rebase failure '' +test_run_rebase failure -m +test_run_rebase failure -i +test_run_rebase failure -p + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* -f --root on linear history causes re-write" " + reset_rebase && + git rebase $* -f --root c && + ! test_cmp_rev a HEAD~2 && + test_linear_range 'a b c' HEAD + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i +test_run_rebase success -p + +test_done diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh new file mode 100755 index 0000000000..1d195fbd64 --- /dev/null +++ b/t/t3425-rebase-topology-merges.sh @@ -0,0 +1,258 @@ +#!/bin/sh + +test_description='rebase topology tests with merges' +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + +test_revision_subjects () { + expected="$1" + shift + set -- $(git log --format=%s --no-walk=unsorted "$@") + test "$expected" = "$*" +} + +# a---b-----------c +# \ \ +# d-------e \ +# \ \ \ +# n---o---w---v +# \ +# z +test_expect_success 'setup of non-linear-history' ' + test_commit a && + test_commit b && + test_commit c && + git checkout b && + test_commit d && + test_commit e + + git checkout c && + test_commit g && + revert h g && + git checkout d && + cherry_pick gp g && + test_commit i && + git checkout b && + test_commit f + + git checkout d && + test_commit n && + test_commit o && + test_merge w e && + test_merge v c && + git checkout o && + test_commit z +' + +test_run_rebase () { + result=$1 + shift + test_expect_$result "rebase $* after merge from upstream" " + reset_rebase && + git rebase $* e w && + test_cmp_rev e HEAD~2 && + test_linear_range 'n o' e.. + " +} +test_run_rebase success '' +test_run_rebase success -m +test_run_rebase success -i + +test_run_rebase () { + result=$1 + shift + expected=$1 + shift + test_expect_$result "rebase $* of non-linear history is linearized in place" " + reset_rebase && + git rebase $* d w && + test_cmp_rev d HEAD~3 && + test_linear_range "\'"$expected"\'" d.. + " +} +#TODO: make order consistent across all flavors of rebase +test_run_rebase success 'e n o' '' +test_run_rebase success 'e n o' -m +test_run_rebase success 'n o e' -i + +test_run_rebase () { + result=$1 + shift + expected=$1 + shift + test_expect_$result "rebase $* of non-linear history is linearized upstream" " + reset_rebase && + git rebase $* c w && + test_cmp_rev c HEAD~4 && + test_linear_range "\'"$expected"\'" c.. + " +} +#TODO: make order consistent across all flavors of rebase +test_run_rebase success 'd e n o' '' +test_run_rebase success 'd e n o' -m +test_run_rebase success 'd n o e' -i + +test_run_rebase () { + result=$1 + shift + expected=$1 + shift + test_expect_$result "rebase $* of non-linear history with merges after upstream merge is linearized" " + reset_rebase && + git rebase $* c v && + test_cmp_rev c HEAD~4 && + test_linear_range "\'"$expected"\'" c.. + " +} +#TODO: make order consistent across all flavors of rebase +test_run_rebase success 'd e n o' '' +test_run_rebase success 'd e n o' -m +test_run_rebase success 'd n o e' -i + +test_expect_success "rebase -p is no-op in non-linear history" " + reset_rebase && + git rebase -p d w && + test_cmp_rev w HEAD +" + +test_expect_success "rebase -p is no-op when base inside second parent" " + reset_rebase && + git rebase -p e w && + test_cmp_rev w HEAD +" + +test_expect_failure "rebase -p --root on non-linear history is a no-op" " + reset_rebase && + git rebase -p --root w && + test_cmp_rev w HEAD +" + +test_expect_success "rebase -p re-creates merge from side branch" " + reset_rebase && + git rebase -p z w && + test_cmp_rev z HEAD^ && + test_cmp_rev w^2 HEAD^2 +" + +test_expect_success "rebase -p re-creates internal merge" " + reset_rebase && + git rebase -p c w && + test_cmp_rev c HEAD~4 && + test_cmp_rev HEAD^2^ HEAD~3 && + test_revision_subjects 'd n e o w' HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD +" + +test_expect_success "rebase -p can re-create two branches on onto" " + reset_rebase && + git rebase -p --onto c d w && + test_cmp_rev c HEAD~3 && + test_cmp_rev c HEAD^2^ && + test_revision_subjects 'n e o w' HEAD~2 HEAD^2 HEAD^ HEAD +" + +# f +# / +# a---b---c---g---h +# \ +# d---gp--i +# \ \ +# e-------u +# +# gp = cherry-picked g +# h = reverted g +test_expect_success 'setup of non-linear-history for patch-equivalence tests' ' + git checkout e && + test_merge u i +' + +test_expect_success "rebase -p re-creates history around dropped commit matching upstream" " + reset_rebase && + git rebase -p h u && + test_cmp_rev h HEAD~3 && + test_cmp_rev HEAD^2^ HEAD~2 && + test_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD +" + +test_expect_success "rebase -p --onto in merged history drops patches in upstream" " + reset_rebase && + git rebase -p --onto f h u && + test_cmp_rev f HEAD~3 && + test_cmp_rev HEAD^2^ HEAD~2 && + test_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD +" + +test_expect_success "rebase -p --onto in merged history does not drop patches in onto" " + reset_rebase && + git rebase -p --onto h f u && + test_cmp_rev h HEAD~3 && + test_cmp_rev HEAD^2~2 HEAD~2 && + test_revision_subjects 'd gp i e u' HEAD~2 HEAD^2^ HEAD^2 HEAD^ HEAD +" + +# a---b---c---g---h +# \ +# d---gp--s +# \ \ / +# \ X +# \ / \ +# e---t +# +# gp = cherry-picked g +# h = reverted g +test_expect_success 'setup of non-linear-history for dropping whole side' ' + git checkout gp && + test_merge s e && + git checkout e && + test_merge t gp +' + +test_expect_failure "rebase -p drops merge commit when entire first-parent side is dropped" " + reset_rebase && + git rebase -p h s && + test_cmp_rev h HEAD~2 && + test_linear_range 'd e' h.. +" + +test_expect_success "rebase -p drops merge commit when entire second-parent side is dropped" " + reset_rebase && + git rebase -p h t && + test_cmp_rev h HEAD~2 && + test_linear_range 'd e' h.. +" + +# a---b---c +# \ +# d---e +# \ \ +# n---r +# \ +# o +# +# r = tree-same with n +test_expect_success 'setup of non-linear-history for empty commits' ' + git checkout n && + git merge --no-commit e && + git reset n . && + git commit -m r && + git reset --hard && + git clean -f && + git tag r +' + +test_expect_success "rebase -p re-creates empty internal merge commit" " + reset_rebase && + git rebase -p c r && + test_cmp_rev c HEAD~3 && + test_cmp_rev HEAD^2^ HEAD~2 && + test_revision_subjects 'd e n r' HEAD~2 HEAD^2 HEAD^ HEAD +" + +test_expect_success "rebase -p re-creates empty merge commit" " + reset_rebase && + git rebase -p o r && + test_cmp_rev e HEAD^2 && + test_cmp_rev o HEAD^ && + test_revision_subjects 'r' HEAD +" + +test_done diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh index df921d1f33..a5b6a5f331 100755 --- a/t/t3509-cherry-pick-merge-df.sh +++ b/t/t3509-cherry-pick-merge-df.sh @@ -10,17 +10,15 @@ test_expect_success 'Initialize repository' ' git commit -m a ' -test_expect_success SYMLINKS 'Setup rename across paths each below D/F conflicts' ' +test_expect_success 'Setup rename across paths each below D/F conflicts' ' mkdir b && - ln -s ../a b/a && - git add b && + test_ln_s_add ../a b/a && git commit -m b && git checkout -b branch && rm b/a && - mv a b/a && - ln -s b/a a && - git add . && + git mv a b/a && + test_ln_s_add b/a a && git commit -m swap && >f1 && @@ -28,7 +26,7 @@ test_expect_success SYMLINKS 'Setup rename across paths each below D/F conflicts git commit -m f1 ' -test_expect_success SYMLINKS 'Cherry-pick succeeds with rename across D/F conflicts' ' +test_expect_success 'Cherry-pick succeeds with rename across D/F conflicts' ' git reset --hard && git checkout master^0 && git cherry-pick branch diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 0c44e9f5d0..5c87b55645 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -687,4 +687,100 @@ test_expect_failure SYMLINKS 'rm across a symlinked leading path (w/ index)' ' test_path_is_file e/f ' +test_expect_success 'setup for testing rm messages' ' + >bar.txt && + >foo.txt && + git add bar.txt foo.txt +' + +test_expect_success 'rm files with different staged content' ' + cat >expect <<-\EOF && + error: the following files have staged content different from both the + file and the HEAD: + bar.txt + foo.txt + (use -f to force removal) + EOF + echo content1 >foo.txt && + echo content1 >bar.txt && + test_must_fail git rm foo.txt bar.txt 2>actual && + test_i18ncmp expect actual +' + +test_expect_success 'rm files with different staged content without hints' ' + cat >expect <<-\EOF && + error: the following files have staged content different from both the + file and the HEAD: + bar.txt + foo.txt + EOF + echo content2 >foo.txt && + echo content2 >bar.txt && + test_must_fail git -c advice.rmhints=false rm foo.txt bar.txt 2>actual && + test_i18ncmp expect actual +' + +test_expect_success 'rm file with local modification' ' + cat >expect <<-\EOF && + error: the following file has local modifications: + foo.txt + (use --cached to keep the file, or -f to force removal) + EOF + git commit -m "testing rm 3" && + echo content3 >foo.txt && + test_must_fail git rm foo.txt 2>actual && + test_i18ncmp expect actual +' + +test_expect_success 'rm file with local modification without hints' ' + cat >expect <<-\EOF && + error: the following file has local modifications: + bar.txt + EOF + echo content4 >bar.txt && + test_must_fail git -c advice.rmhints=false rm bar.txt 2>actual && + test_i18ncmp expect actual +' + +test_expect_success 'rm file with changes in the index' ' + cat >expect <<-\EOF && + error: the following file has changes staged in the index: + foo.txt + (use --cached to keep the file, or -f to force removal) + EOF + git reset --hard && + echo content5 >foo.txt && + git add foo.txt && + test_must_fail git rm foo.txt 2>actual && + test_i18ncmp expect actual +' + +test_expect_success 'rm file with changes in the index without hints' ' + cat >expect <<-\EOF && + error: the following file has changes staged in the index: + foo.txt + EOF + test_must_fail git -c advice.rmhints=false rm foo.txt 2>actual && + test_i18ncmp expect actual +' + +test_expect_success 'rm files with two different errors' ' + cat >expect <<-\EOF && + error: the following file has staged content different from both the + file and the HEAD: + foo1.txt + (use -f to force removal) + error: the following file has changes staged in the index: + bar1.txt + (use --cached to keep the file, or -f to force removal) + EOF + echo content >foo1.txt && + git add foo1.txt && + echo content6 >foo1.txt && + echo content6 >bar1.txt && + git add bar1.txt && + test_must_fail git rm bar1.txt foo1.txt 2>actual && + test_i18ncmp expect actual +' + test_done diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 874b3a6444..aab86e838b 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -30,10 +30,9 @@ test_expect_success \ *) echo fail; git ls-files --stage xfoo1; (exit 1);; esac' -test_expect_success SYMLINKS 'git add: filemode=0 should not get confused by symlink' ' +test_expect_success 'git add: filemode=0 should not get confused by symlink' ' rm -f xfoo1 && - ln -s foo xfoo1 && - git add xfoo1 && + test_ln_s_add foo xfoo1 && case "`git ls-files --stage xfoo1`" in 120000" "*xfoo1) echo pass;; *) echo fail; git ls-files --stage xfoo1; (exit 1);; @@ -51,21 +50,19 @@ test_expect_success \ *) echo fail; git ls-files --stage xfoo2; (exit 1);; esac' -test_expect_success SYMLINKS 'git add: filemode=0 should not get confused by symlink' ' +test_expect_success 'git add: filemode=0 should not get confused by symlink' ' rm -f xfoo2 && - ln -s foo xfoo2 && - git update-index --add xfoo2 && + test_ln_s_add foo xfoo2 && case "`git ls-files --stage xfoo2`" in 120000" "*xfoo2) echo pass;; *) echo fail; git ls-files --stage xfoo2; (exit 1);; esac ' -test_expect_success SYMLINKS \ +test_expect_success \ 'git update-index --add: Test that executable bit is not used...' \ 'git config core.filemode 0 && - ln -s xfoo2 xfoo3 && - git update-index --add xfoo3 && + test_ln_s_add xfoo2 xfoo3 && # runs git update-index --add case "`git ls-files --stage xfoo3`" in 120000" "*xfoo3) echo pass;; *) echo fail; git ls-files --stage xfoo3; (exit 1);; diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 5dfbda7491..debda7a678 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -200,17 +200,17 @@ test_expect_success 'apply -q is quiet' ' echo foo > file && git stash && git stash apply -q > output.out 2>&1 && - test ! -s output.out + test_must_be_empty output.out ' test_expect_success 'save -q is quiet' ' git stash save --quiet > output.out 2>&1 && - test ! -s output.out + test_must_be_empty output.out ' test_expect_success 'pop -q is quiet' ' git stash pop -q > output.out 2>&1 && - test ! -s output.out + test_must_be_empty output.out ' test_expect_success 'pop -q --index works and is quiet' ' @@ -219,13 +219,13 @@ test_expect_success 'pop -q --index works and is quiet' ' git stash save --quiet && git stash pop -q --index > output.out 2>&1 && test foo = "$(git show :file)" && - test ! -s output.out + test_must_be_empty output.out ' test_expect_success 'drop -q is quiet' ' git stash && git stash drop -q > output.out 2>&1 && - test ! -s output.out + test_must_be_empty output.out ' test_expect_success 'stash -k' ' @@ -336,41 +336,58 @@ test_expect_success SYMLINKS 'stash file to symlink (full stage)' ' # This test creates a commit with a symlink used for the following tests -test_expect_success SYMLINKS 'stash symlink to file' ' +test_expect_success 'stash symlink to file' ' git reset --hard && - ln -s file filelink && - git add filelink && + test_ln_s_add file filelink && git commit -m "Add symlink" && rm filelink && cp file filelink && - git stash save "symlink to file" && + git stash save "symlink to file" +' + +test_expect_success SYMLINKS 'this must have re-created the symlink' ' test -h filelink && - case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac && + case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac +' + +test_expect_success 'unstash must re-create the file' ' git stash apply && ! test -h filelink && test bar = "$(cat file)" ' -test_expect_success SYMLINKS 'stash symlink to file (stage rm)' ' +test_expect_success 'stash symlink to file (stage rm)' ' git reset --hard && git rm filelink && cp file filelink && - git stash save "symlink to file (stage rm)" && + git stash save "symlink to file (stage rm)" +' + +test_expect_success SYMLINKS 'this must have re-created the symlink' ' test -h filelink && - case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac && + case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac +' + +test_expect_success 'unstash must re-create the file' ' git stash apply && ! test -h filelink && test bar = "$(cat file)" ' -test_expect_success SYMLINKS 'stash symlink to file (full stage)' ' +test_expect_success '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)" && + git stash save "symlink to file (full stage)" +' + +test_expect_success SYMLINKS 'this must have re-created the symlink' ' test -h filelink && - case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac && + case "$(ls -l filelink)" in *" filelink -> file") :;; *) false;; esac +' + +test_expect_success 'unstash must re-create the file' ' git stash apply && ! test -h filelink && test bar = "$(cat file)" @@ -637,4 +654,23 @@ test_expect_success 'stash where working directory contains "HEAD" file' ' test_cmp output expect ' +test_expect_success 'store called with invalid commit' ' + test_must_fail git stash store foo +' + +test_expect_success 'store updates stash ref and reflog' ' + git stash clear && + git reset --hard && + echo quux >bazzy && + git add bazzy && + STASH_ID=$(git stash create) && + git reset --hard && + ! grep quux bazzy && + git stash store -m quuxery $STASH_ID && + test $(cat .git/refs/stash) = $STASH_ID && + grep $STASH_ID .git/logs/refs/stash && + git stash pop && + grep quux bazzy +' + test_done diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh index 73b4a24f5e..27e98a8f9d 100755 --- a/t/t4008-diff-break-rewrite.sh +++ b/t/t4008-diff-break-rewrite.sh @@ -99,11 +99,11 @@ test_expect_success \ 'validate result of -B -M (#4)' \ 'compare_diff_raw expected current' -test_expect_success SYMLINKS \ +test_expect_success \ 'make file0 into something completely different' \ 'rm -f file0 && - ln -s frotz file0 && - git update-index file0 file1' + test_ln_s_add frotz file0 && + git update-index file1' test_expect_success \ 'run diff with -B' \ @@ -114,7 +114,7 @@ cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 M100 file1 EOF -test_expect_success SYMLINKS \ +test_expect_success \ 'validate result of -B (#5)' \ 'compare_diff_raw expected current' @@ -129,7 +129,7 @@ cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 R file0 file1 EOF -test_expect_success SYMLINKS \ +test_expect_success \ 'validate result of -B -M (#6)' \ 'compare_diff_raw expected current' @@ -144,7 +144,7 @@ cat >expected <<\EOF :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 f5deac7be59e7eeab8657fd9ae706fd6a57daed2 M file1 EOF -test_expect_success SYMLINKS \ +test_expect_success \ 'validate result of -M (#7)' \ 'compare_diff_raw expected current' diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index f0d5041c11..13e7f621ab 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -9,7 +9,7 @@ test_description='Test diff of symlinks. . ./test-lib.sh . "$TEST_DIRECTORY"/diff-lib.sh -test_expect_success SYMLINKS 'diff new symlink and file' ' +test_expect_success 'diff new symlink and file' ' cat >expected <<-\EOF && diff --git a/frotz b/frotz new file mode 120000 @@ -27,22 +27,25 @@ test_expect_success SYMLINKS 'diff new symlink and file' ' @@ -0,0 +1 @@ +xyzzy EOF - ln -s xyzzy frotz && - echo xyzzy >nitfol && + + # the empty tree git update-index && tree=$(git write-tree) && - git update-index --add frotz nitfol && + + test_ln_s_add xyzzy frotz && + echo xyzzy >nitfol && + git update-index --add nitfol && GIT_DIFF_OPTS=--unified=0 git diff-index -M -p $tree >current && compare_diff_patch expected current ' -test_expect_success SYMLINKS 'diff unchanged symlink and file' ' +test_expect_success 'diff unchanged symlink and file' ' tree=$(git write-tree) && git update-index frotz nitfol && test -z "$(git diff-index --name-only $tree)" ' -test_expect_success SYMLINKS 'diff removed symlink and file' ' +test_expect_success 'diff removed symlink and file' ' cat >expected <<-\EOF && diff --git a/frotz b/frotz deleted file mode 120000 @@ -66,12 +69,18 @@ test_expect_success SYMLINKS 'diff removed symlink and file' ' compare_diff_patch expected current ' -test_expect_success SYMLINKS 'diff identical, but newly created symlink and file' ' +test_expect_success 'diff identical, but newly created symlink and file' ' >expected && rm -f frotz nitfol && echo xyzzy >nitfol && test-chmtime +10 nitfol && - ln -s xyzzy frotz && + if test_have_prereq SYMLINKS + then + ln -s xyzzy frotz + else + printf xyzzy >frotz + # the symlink property propagates from the index + fi && git diff-index -M -p $tree >current && compare_diff_patch expected current && @@ -80,7 +89,7 @@ test_expect_success SYMLINKS 'diff identical, but newly created symlink and file compare_diff_patch expected current ' -test_expect_success SYMLINKS 'diff different symlink and file' ' +test_expect_success 'diff different symlink and file' ' cat >expected <<-\EOF && diff --git a/frotz b/frotz index 7c465af..df1db54 120000 @@ -100,7 +109,13 @@ test_expect_success SYMLINKS 'diff different symlink and file' ' +yxyyz EOF rm -f frotz && - ln -s yxyyz frotz && + if test_have_prereq SYMLINKS + then + ln -s yxyyz frotz + else + printf yxyyz >frotz + # the symlink property propagates from the index + fi && echo yxyyz >nitfol && git diff-index -M -p $tree >current && compare_diff_patch expected current diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh index 5d20acf436..55d549fcf4 100755 --- a/t/t4023-diff-rename-typechange.sh +++ b/t/t4023-diff-rename-typechange.sh @@ -4,44 +4,44 @@ test_description='typechange rename detection' . ./test-lib.sh -test_expect_success SYMLINKS setup ' +test_expect_success setup ' rm -f foo bar && cat "$TEST_DIRECTORY"/../COPYING >foo && - ln -s linklink bar && - git add foo bar && + test_ln_s_add linklink bar && + git add foo && git commit -a -m Initial && git tag one && - rm -f foo bar && + git rm -f foo bar && cat "$TEST_DIRECTORY"/../COPYING >bar && - ln -s linklink foo && - git add foo bar && + test_ln_s_add linklink foo && + git add bar && git commit -a -m Second && git tag two && - rm -f foo bar && + git rm -f foo bar && cat "$TEST_DIRECTORY"/../COPYING >foo && git add foo && git commit -a -m Third && git tag three && mv foo bar && - ln -s linklink foo && - git add foo bar && + test_ln_s_add linklink foo && + git add bar && git commit -a -m Fourth && git tag four && # This is purely for sanity check - rm -f foo bar && + git rm -f foo bar && cat "$TEST_DIRECTORY"/../COPYING >foo && cat "$TEST_DIRECTORY"/../Makefile >bar && git add foo bar && git commit -a -m Fifth && git tag five && - rm -f foo bar && + git rm -f foo bar && cat "$TEST_DIRECTORY"/../Makefile >foo && cat "$TEST_DIRECTORY"/../COPYING >bar && git add foo bar && @@ -50,7 +50,7 @@ test_expect_success SYMLINKS setup ' ' -test_expect_success SYMLINKS 'cross renames to be detected for regular files' ' +test_expect_success 'cross renames to be detected for regular files' ' git diff-tree five six -r --name-status -B -M | sort >actual && { @@ -61,7 +61,7 @@ test_expect_success SYMLINKS 'cross renames to be detected for regular files' ' ' -test_expect_success SYMLINKS 'cross renames to be detected for typechange' ' +test_expect_success 'cross renames to be detected for typechange' ' git diff-tree one two -r --name-status -B -M | sort >actual && { @@ -72,7 +72,7 @@ test_expect_success SYMLINKS 'cross renames to be detected for typechange' ' ' -test_expect_success SYMLINKS 'moves and renames' ' +test_expect_success 'moves and renames' ' git diff-tree three four -r --name-status -B -M | sort >actual && { diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh index 53ec330ce8..f75f46f92d 100755 --- a/t/t4030-diff-textconv.sh +++ b/t/t4030-diff-textconv.sh @@ -139,12 +139,10 @@ index 0000000..67be421 +frotz \ No newline at end of file EOF -# make a symlink the hard way that works on symlink-challenged file systems + test_expect_success 'textconv does not act on symlinks' ' - printf frotz > file && - git add file && - git ls-files -s | sed -e s/100644/120000/ | - git update-index --index-info && + rm -f file && + test_ln_s_add frotz file && git commit -m typechange && git show >diff && find_diff <diff >actual && diff --git a/t/t4111-apply-subdir.sh b/t/t4111-apply-subdir.sh index 7c398432ba..1618a6dbc7 100755 --- a/t/t4111-apply-subdir.sh +++ b/t/t4111-apply-subdir.sh @@ -86,6 +86,20 @@ test_expect_success 'apply --index from subdir of toplevel' ' test_cmp expected sub/dir/file ' +test_expect_success 'apply half-broken patch from subdir of toplevel' ' + ( + cd sub/dir && + test_must_fail git apply <<-EOF + --- sub/dir/file + +++ sub/dir/file + @@ -1,0 +1,0 @@ + --- file_in_root + +++ file_in_root + @@ -1,0 +1,0 @@ + EOF + ) +' + test_expect_success 'apply from .git dir' ' cp postimage expected && cp preimage .git/file && diff --git a/t/t4114-apply-typechange.sh b/t/t4114-apply-typechange.sh index f12826fb09..ebadbc347f 100755 --- a/t/t4114-apply-typechange.sh +++ b/t/t4114-apply-typechange.sh @@ -9,20 +9,19 @@ test_description='git apply should not get confused with type changes. . ./test-lib.sh -test_expect_success SYMLINKS 'setup repository and commits' ' +test_expect_success 'setup repository and commits' ' echo "hello world" > foo && echo "hi planet" > bar && git update-index --add foo bar && git commit -m initial && git branch initial && rm -f foo && - ln -s bar foo && - git update-index foo && + test_ln_s_add bar foo && git commit -m "foo symlinked to bar" && git branch foo-symlinked-to-bar && - rm -f foo && + git rm -f foo && echo "how far is the sun?" > foo && - git update-index foo && + git update-index --add foo && git commit -m "foo back to file" && git branch foo-back-to-file && printf "\0" > foo && @@ -42,7 +41,7 @@ test_expect_success SYMLINKS 'setup repository and commits' ' git branch foo-baz-renamed-from-foo ' -test_expect_success SYMLINKS 'file renamed from foo to foo/baz' ' +test_expect_success 'file renamed from foo to foo/baz' ' git checkout -f initial && git diff-tree -M -p HEAD foo-baz-renamed-from-foo > patch && git apply --index < patch @@ -50,7 +49,7 @@ test_expect_success SYMLINKS 'file renamed from foo to foo/baz' ' test_debug 'cat patch' -test_expect_success SYMLINKS 'file renamed from foo/baz to foo' ' +test_expect_success 'file renamed from foo/baz to foo' ' git checkout -f foo-baz-renamed-from-foo && git diff-tree -M -p HEAD initial > patch && git apply --index < patch @@ -58,7 +57,7 @@ test_expect_success SYMLINKS 'file renamed from foo/baz to foo' ' test_debug 'cat patch' -test_expect_success SYMLINKS 'directory becomes file' ' +test_expect_success 'directory becomes file' ' git checkout -f foo-becomes-a-directory && git diff-tree -p HEAD initial > patch && git apply --index < patch @@ -66,7 +65,7 @@ test_expect_success SYMLINKS 'directory becomes file' ' test_debug 'cat patch' -test_expect_success SYMLINKS 'file becomes directory' ' +test_expect_success 'file becomes directory' ' git checkout -f initial && git diff-tree -p HEAD foo-becomes-a-directory > patch && git apply --index < patch @@ -74,7 +73,7 @@ test_expect_success SYMLINKS 'file becomes directory' ' test_debug 'cat patch' -test_expect_success SYMLINKS 'file becomes symlink' ' +test_expect_success 'file becomes symlink' ' git checkout -f initial && git diff-tree -p HEAD foo-symlinked-to-bar > patch && git apply --index < patch @@ -82,21 +81,21 @@ test_expect_success SYMLINKS 'file becomes symlink' ' test_debug 'cat patch' -test_expect_success SYMLINKS 'symlink becomes file' ' +test_expect_success 'symlink becomes file' ' git checkout -f foo-symlinked-to-bar && git diff-tree -p HEAD foo-back-to-file > patch && git apply --index < patch ' test_debug 'cat patch' -test_expect_success SYMLINKS 'binary file becomes symlink' ' +test_expect_success 'binary file becomes symlink' ' git checkout -f foo-becomes-binary && git diff-tree -p --binary HEAD foo-symlinked-to-bar > patch && git apply --index < patch ' test_debug 'cat patch' -test_expect_success SYMLINKS 'symlink becomes binary file' ' +test_expect_success 'symlink becomes binary file' ' git checkout -f foo-symlinked-to-bar && git diff-tree -p --binary HEAD foo-becomes-binary > patch && git apply --index < patch @@ -104,7 +103,7 @@ test_expect_success SYMLINKS 'symlink becomes binary file' ' test_debug 'cat patch' -test_expect_success SYMLINKS 'symlink becomes directory' ' +test_expect_success 'symlink becomes directory' ' git checkout -f foo-symlinked-to-bar && git diff-tree -p HEAD foo-becomes-a-directory > patch && git apply --index < patch @@ -112,7 +111,7 @@ test_expect_success SYMLINKS 'symlink becomes directory' ' test_debug 'cat patch' -test_expect_success SYMLINKS 'directory becomes symlink' ' +test_expect_success 'directory becomes symlink' ' git checkout -f foo-becomes-a-directory && git diff-tree -p HEAD foo-symlinked-to-bar > patch && git apply --index < patch diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh index 7674dd2ec9..872fcda6cb 100755 --- a/t/t4115-apply-symlink.sh +++ b/t/t4115-apply-symlink.sh @@ -9,18 +9,16 @@ test_description='git apply symlinks and partial files . ./test-lib.sh -test_expect_success SYMLINKS setup ' +test_expect_success setup ' - ln -s path1/path2/path3/path4/path5 link1 && - git add link? && + test_ln_s_add path1/path2/path3/path4/path5 link1 && git commit -m initial && git branch side && rm -f link? && - ln -s htap6 link1 && - git update-index link? && + test_ln_s_add htap6 link1 && git commit -m second && git diff-tree -p HEAD^ HEAD >patch && @@ -37,7 +35,7 @@ test_expect_success SYMLINKS 'apply symlink patch' ' ' -test_expect_success SYMLINKS 'apply --index symlink patch' ' +test_expect_success 'apply --index symlink patch' ' git checkout -f side && git apply --index patch && diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh index 39407376ba..70b3a06e1d 100755 --- a/t/t4122-apply-symlink-inside.sh +++ b/t/t4122-apply-symlink-inside.sh @@ -10,11 +10,11 @@ lecho () { done } -test_expect_success SYMLINKS setup ' +test_expect_success setup ' mkdir -p arch/i386/boot arch/x86_64 && lecho 1 2 3 4 5 >arch/i386/boot/Makefile && - ln -s ../i386/boot arch/x86_64/boot && + test_ln_s_add ../i386/boot arch/x86_64/boot && git add . && test_tick && git commit -m initial && @@ -31,7 +31,7 @@ test_expect_success SYMLINKS setup ' ' -test_expect_success SYMLINKS apply ' +test_expect_success apply ' git checkout test && git diff --exit-code test && @@ -40,7 +40,7 @@ test_expect_success SYMLINKS apply ' ' -test_expect_success SYMLINKS 'check result' ' +test_expect_success 'check result' ' git diff --exit-code master && git diff --exit-code --cached master && diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 12f6b027ac..5edb79a058 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -147,7 +147,7 @@ test_expect_success 'am applies patch correctly' ' git checkout first && test_tick && git am <patch1 && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code second && test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" @@ -158,7 +158,7 @@ test_expect_success 'am applies patch e-mail not in a mbox' ' git reset --hard && git checkout first && git am patch1.eml && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code second && test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" @@ -169,7 +169,7 @@ test_expect_success 'am applies patch e-mail not in a mbox with CRLF' ' git reset --hard && git checkout first && git am patch1-crlf.eml && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code second && test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" @@ -180,7 +180,7 @@ test_expect_success 'am applies patch e-mail with preceding whitespace' ' git reset --hard && git checkout first && git am patch1-ws.eml && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code second && test "$(git rev-parse second)" = "$(git rev-parse HEAD)" && test "$(git rev-parse second^)" = "$(git rev-parse HEAD^)" @@ -206,7 +206,7 @@ test_expect_success 'am changes committer and keeps author' ' git reset --hard && git checkout first && git am patch2 && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && test "$(git rev-parse master^^)" = "$(git rev-parse HEAD^^)" && git diff --exit-code master..HEAD && git diff --exit-code master^..HEAD^ && @@ -258,7 +258,7 @@ test_expect_success 'am --keep really keeps the subject' ' git reset --hard && git checkout HEAD^ && git am --keep patch4 && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git cat-file commit HEAD >actual && grep "Re: Re: Re: \[PATCH 1/5 v2\] \[foo\] third" actual ' @@ -268,7 +268,7 @@ test_expect_success 'am --keep-non-patch really keeps the non-patch part' ' git reset --hard && git checkout HEAD^ && git am --keep-non-patch patch4 && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git cat-file commit HEAD >actual && grep "^\[foo\] third" actual ' @@ -283,7 +283,7 @@ test_expect_success 'am -3 falls back to 3-way merge' ' test_tick && git commit -m "copied stuff" && git am -3 lorem-move.patch && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code lorem ' @@ -297,7 +297,7 @@ test_expect_success 'am -3 -p0 can read --no-prefix patch' ' test_tick && git commit -m "copied stuff" && git am -3 -p0 lorem-zero.patch && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code lorem ' @@ -307,7 +307,7 @@ test_expect_success 'am can rename a file' ' git reset --hard && git checkout lorem^0 && git am rename.patch && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git update-index --refresh && git diff --exit-code rename ' @@ -318,7 +318,7 @@ test_expect_success 'am -3 can rename a file' ' git reset --hard && git checkout lorem^0 && git am -3 rename.patch && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git update-index --refresh && git diff --exit-code rename ' @@ -329,7 +329,7 @@ test_expect_success 'am -3 can rename a file after falling back to 3-way merge' git reset --hard && git checkout lorem^0 && git am -3 rename-add.patch && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git update-index --refresh && git diff --exit-code rename ' @@ -358,11 +358,17 @@ test_expect_success 'am pauses on conflict' ' test_expect_success 'am --skip works' ' echo goodbye >expected && git am --skip && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code lorem2^^ -- file && test_cmp expected another ' +test_expect_success 'am --abort removes a stray directory' ' + mkdir .git/rebase-apply && + git am --abort && + test_path_is_missing .git/rebase-apply +' + test_expect_success 'am --resolved works' ' echo goodbye >expected && rm -fr .git/rebase-apply && @@ -373,7 +379,7 @@ test_expect_success 'am --resolved works' ' echo resolved >>file && git add file && git am --resolved && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && test_cmp expected another ' @@ -382,7 +388,7 @@ test_expect_success 'am takes patches from a Pine mailbox' ' git reset --hard && git checkout first && cat pine patch1 | git am && - ! test -d .git/rebase-apply && + test_path_is_missing .git/rebase-apply && git diff --exit-code master^..HEAD ' @@ -391,7 +397,7 @@ test_expect_success 'am fails on mail without patch' ' git reset --hard && test_must_fail git am <failmail && git am --abort && - ! test -d .git/rebase-apply + test_path_is_missing .git/rebase-apply ' test_expect_success 'am fails on empty patch' ' @@ -400,7 +406,7 @@ test_expect_success 'am fails on empty patch' ' echo "---" >>failmail && test_must_fail git am <failmail && git am --skip && - ! test -d .git/rebase-apply + test_path_is_missing .git/rebase-apply ' test_expect_success 'am works from stdin in subdirectory' ' diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh index 432f98c357..1afa0d5c44 100755 --- a/t/t5150-request-pull.sh +++ b/t/t5150-request-pull.sh @@ -80,12 +80,12 @@ test_expect_success 'setup: two scripts for reading pull requests' ' cat <<-EOT >fuzz.sed #!/bin/sed -nf + s/$downstream_url_for_sed/URL/g 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 s/^version [0-9]/VERSION/ diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh index 5b1250f0d2..35926debe3 100755 --- a/t/t5303-pack-corruption-resilience.sh +++ b/t/t5303-pack-corruption-resilience.sh @@ -51,7 +51,7 @@ do_corrupt_object() { ofs=`git show-index < ${pack}.idx | grep $1 | cut -f1 -d" "` && ofs=$(($ofs + $2)) && chmod +w ${pack}.pack && - dd of=${pack}.pack count=1 bs=1 conv=notrunc seek=$ofs && + dd of=${pack}.pack bs=1 conv=notrunc seek=$ofs && test_must_fail git verify-pack ${pack}.pack } @@ -276,6 +276,33 @@ test_expect_success \ git cat-file blob $blob_3 > /dev/null' test_expect_success \ + 'corruption of delta base reference pointing to wrong object' \ + 'create_new_pack --delta-base-offset && + git prune-packed && + printf "\220\033" | do_corrupt_object $blob_3 2 && + git cat-file blob $blob_1 >/dev/null && + git cat-file blob $blob_2 >/dev/null && + test_must_fail git cat-file blob $blob_3 >/dev/null' + +test_expect_success \ + '... but having a loose copy allows for full recovery' \ + 'mv ${pack}.idx tmp && + git hash-object -t blob -w file_3 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ + '... and then a repack "clears" the corruption' \ + 'do_repack --delta-base-offset --no-reuse-delta && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null' + +test_expect_success \ 'corrupting header to have too small output buffer fails unpack' \ 'create_new_pack && git prune-packed && diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 6af6c63350..ed4d9c8318 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -57,6 +57,35 @@ test_expect_success 'pulling into void does not overwrite untracked files' ' ) ' +test_expect_success 'pulling into void does not overwrite staged files' ' + git init cloned-staged-colliding && + ( + cd cloned-staged-colliding && + echo "alternate content" >file && + git add file && + test_must_fail git pull .. master && + echo "alternate content" >expect && + test_cmp expect file && + git cat-file blob :file >file.index && + test_cmp expect file.index + ) +' + + +test_expect_success 'pulling into void does not remove new staged files' ' + git init cloned-staged-new && + ( + cd cloned-staged-new && + echo "new tracked file" >newfile && + git add newfile && + git pull .. master && + echo "new tracked file" >expect && + test_cmp expect newfile && + git cat-file blob :newfile >newfile.index && + test_cmp expect newfile.index + ) +' + test_expect_success 'test . as a remote' ' git branch copy master && diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index aa31abe32b..453aba53f4 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -15,19 +15,19 @@ test_expect_success 'git pull -q' ' mkdir clonedq && (cd clonedq && git init && git pull -q "../parent" >out 2>err && - test ! -s err && - test ! -s out) + test_must_be_empty err && + test_must_be_empty out) ' test_expect_success 'git pull -q --rebase' ' mkdir clonedqrb && (cd clonedqrb && git init && git pull -q --rebase "../parent" >out 2>err && - test ! -s err && - test ! -s out && + test_must_be_empty err && + test_must_be_empty out && git pull -q --rebase "../parent" >out 2>err && - test ! -s err && - test ! -s out) + test_must_be_empty err && + test_must_be_empty out) ' test_expect_success 'git pull' ' @@ -35,7 +35,7 @@ test_expect_success 'git pull' ' (cd cloned && git init && git pull "../parent" >out 2>err && test -s err && - test ! -s out) + test_must_be_empty out) ' test_expect_success 'git pull --rebase' ' @@ -43,7 +43,7 @@ test_expect_success 'git pull --rebase' ' (cd clonedrb && git init && git pull --rebase "../parent" >out 2>err && test -s err && - test ! -s out) + test_must_be_empty out) ' test_expect_success 'git pull -v' ' @@ -51,7 +51,7 @@ test_expect_success 'git pull -v' ' (cd clonedv && git init && git pull -v "../parent" >out 2>err && test -s err && - test ! -s out) + test_must_be_empty out) ' test_expect_success 'git pull -v --rebase' ' @@ -59,22 +59,22 @@ test_expect_success 'git pull -v --rebase' ' (cd clonedvrb && git init && git pull -v --rebase "../parent" >out 2>err && test -s err && - test ! -s out) + test_must_be_empty out) ' test_expect_success 'git pull -v -q' ' mkdir clonedvq && (cd clonedvq && git init && git pull -v -q "../parent" >out 2>err && - test ! -s out && - test ! -s err) + test_must_be_empty out && + test_must_be_empty err) ' test_expect_success 'git pull -q -v' ' mkdir clonedqv && (cd clonedqv && git init && git pull -q -v "../parent" >out 2>err && - test ! -s out && + test_must_be_empty out && test -s err) ' diff --git a/t/t5702-clone-options.sh b/t/t5702-clone-options.sh index 02cb024723..85cadfad6d 100755 --- a/t/t5702-clone-options.sh +++ b/t/t5702-clone-options.sh @@ -22,7 +22,7 @@ test_expect_success 'clone -o' ' test_expect_success 'redirected clone' ' git clone "file://$(pwd)/parent" clone-redirected >out 2>err && - test ! -s err + test_must_be_empty err ' test_expect_success 'redirected clone -v' ' diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index 4899af3f7a..8c4c5396a8 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -210,9 +210,7 @@ test_expect_success 'proper failure checks for pushing' ' (GIT_REMOTE_TESTGIT_FAILURE=1 && export GIT_REMOTE_TESTGIT_FAILURE && cd local && - test_must_fail git push --all 2> error && - cat error && - grep -q "Reading from helper .git-remote-testgit. failed" error + test_must_fail git push --all ) ' diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh index dd6dc844e7..57ce2395d6 100755 --- a/t/t6012-rev-list-simplify.sh +++ b/t/t6012-rev-list-simplify.sh @@ -14,21 +14,24 @@ unnote () { test_expect_success setup ' echo "Hi there" >file && - git add file && - test_tick && git commit -m "Initial file" && + echo "initial" >lost && + git add file lost && + test_tick && git commit -m "Initial file and lost" && note A && git branch other-branch && echo "Hello" >file && - git add file && - test_tick && git commit -m "Modified file" && + echo "second" >lost && + git add file lost && + test_tick && git commit -m "Modified file and lost" && note B && git checkout other-branch && echo "Hello" >file && - git add file && + >lost && + git add file lost && test_tick && git commit -m "Modified the file identically" && note C && @@ -37,7 +40,9 @@ test_expect_success setup ' test_tick && git commit -m "Add another file" && note D && - test_tick && git merge -m "merge" master && + test_tick && + test_must_fail git merge -m "merge" master && + >lost && git commit -a -m "merge" && note E && echo "Yet another" >elif && @@ -105,9 +110,21 @@ check_result 'L K J I H G F E D C B A' --full-history check_result 'K I H E C B A' --full-history -- file check_result 'K I H E C B A' --full-history --topo-order -- file check_result 'K I H E C B A' --full-history --date-order -- file -check_outcome failure 'I E C B A' --simplify-merges -- file +check_result 'I E C B A' --simplify-merges -- file check_result 'I B A' -- file check_result 'I B A' --topo-order -- file check_result 'H' --first-parent -- another-file +check_result 'E C B A' --full-history E -- lost +test_expect_success 'full history simplification without parent' ' + printf "%s\n" E C B A >expect && + git log --pretty="$FMT" --full-history E -- lost | + unnote >actual && + sed -e "s/^.* \([^ ]*\) .*/\1/" >check <actual && + test_cmp expect check || { + cat actual + false + } +' + test_done diff --git a/t/t6019-rev-list-ancestry-path.sh b/t/t6019-rev-list-ancestry-path.sh index dd5b0e55d2..dabebaee0b 100755 --- a/t/t6019-rev-list-ancestry-path.sh +++ b/t/t6019-rev-list-ancestry-path.sh @@ -16,6 +16,10 @@ test_description='--ancestry-path' # # F...I == F G H I # --ancestry-path F...I == F H I +# +# G..M -- G.t == [nothing - was dropped in "-s ours" merge L] +# --ancestry-path G..M -- G.t == L +# --ancestry-path --simplify-merges G^..M -- G.t == G L . ./test-lib.sh @@ -89,6 +93,29 @@ test_expect_success 'rev-list --ancestry-path F...I' ' test_cmp expect actual ' +# G.t is dropped in an "-s ours" merge +test_expect_success 'rev-list G..M -- G.t' ' + >expect && + git rev-list --format=%s G..M -- G.t | + sed -e "/^commit /d" >actual && + test_cmp expect actual +' + +test_expect_success 'rev-list --ancestry-path G..M -- G.t' ' + echo L >expect && + git rev-list --ancestry-path --format=%s G..M -- G.t | + sed -e "/^commit /d" >actual && + test_cmp expect actual +' + +test_expect_success 'rev-list --ancestry-path --simplify-merges G^..M -- G.t' ' + for c in G L; do echo $c; done >expect && + git rev-list --ancestry-path --simplify-merges --format=%s G^..M -- G.t | + sed -e "/^commit /d" | + sort >actual && + test_cmp expect actual +' + # b---bc # / \ / # a X diff --git a/t/t6035-merge-dir-to-symlink.sh b/t/t6035-merge-dir-to-symlink.sh index 2599ae50eb..9324ea4416 100755 --- a/t/t6035-merge-dir-to-symlink.sh +++ b/t/t6035-merge-dir-to-symlink.sh @@ -3,7 +3,7 @@ test_description='merging when a directory was replaced with a symlink' . ./test-lib.sh -test_expect_success SYMLINKS 'create a commit where dir a/b changed to symlink' ' +test_expect_success 'create a commit where dir a/b changed to symlink' ' mkdir -p a/b/c a/b-2/c && > a/b/c/d && > a/b-2/c/d && @@ -12,12 +12,12 @@ test_expect_success SYMLINKS 'create a commit where dir a/b changed to symlink' git commit -m base && git tag start && rm -rf a/b && - ln -s b-2 a/b && git add -A && + test_ln_s_add b-2 a/b && git commit -m "dir to symlink" ' -test_expect_success SYMLINKS 'checkout does not clobber untracked symlink' ' +test_expect_success 'checkout does not clobber untracked symlink' ' git checkout HEAD^0 && git reset --hard master && git rm --cached a/b && @@ -25,7 +25,7 @@ test_expect_success SYMLINKS 'checkout does not clobber untracked symlink' ' test_must_fail git checkout start^0 ' -test_expect_success SYMLINKS 'a/b-2/c/d is kept when clobbering symlink b' ' +test_expect_success 'a/b-2/c/d is kept when clobbering symlink b' ' git checkout HEAD^0 && git reset --hard master && git rm --cached a/b && @@ -34,14 +34,14 @@ test_expect_success SYMLINKS 'a/b-2/c/d is kept when clobbering symlink b' ' test -f a/b-2/c/d ' -test_expect_success SYMLINKS 'checkout should not have deleted a/b-2/c/d' ' +test_expect_success 'checkout should not have deleted a/b-2/c/d' ' git checkout HEAD^0 && git reset --hard master && git checkout start^0 && test -f a/b-2/c/d ' -test_expect_success SYMLINKS 'setup for merge test' ' +test_expect_success 'setup for merge test' ' git reset --hard && test -f a/b-2/c/d && echo x > a/x && @@ -50,39 +50,51 @@ test_expect_success SYMLINKS 'setup for merge test' ' git tag baseline ' -test_expect_success SYMLINKS 'Handle D/F conflict, do not lose a/b-2/c/d in merge (resolve)' ' +test_expect_success 'Handle D/F conflict, do not lose a/b-2/c/d in merge (resolve)' ' git reset --hard && git checkout baseline^0 && git merge -s resolve master && - test -h a/b && test -f a/b-2/c/d ' -test_expect_success SYMLINKS 'Handle D/F conflict, do not lose a/b-2/c/d in merge (recursive)' ' +test_expect_success SYMLINKS 'a/b was resolved as symlink' ' + test -h a/b +' + +test_expect_success 'Handle D/F conflict, do not lose a/b-2/c/d in merge (recursive)' ' git reset --hard && git checkout baseline^0 && git merge -s recursive master && - test -h a/b && test -f a/b-2/c/d ' -test_expect_success SYMLINKS 'Handle F/D conflict, do not lose a/b-2/c/d in merge (resolve)' ' +test_expect_success SYMLINKS 'a/b was resolved as symlink' ' + test -h a/b +' + +test_expect_success 'Handle F/D conflict, do not lose a/b-2/c/d in merge (resolve)' ' git reset --hard && git checkout master^0 && git merge -s resolve baseline^0 && - test -h a/b && test -f a/b-2/c/d ' -test_expect_success SYMLINKS 'Handle F/D conflict, do not lose a/b-2/c/d in merge (recursive)' ' +test_expect_success SYMLINKS 'a/b was resolved as symlink' ' + test -h a/b +' + +test_expect_success 'Handle F/D conflict, do not lose a/b-2/c/d in merge (recursive)' ' git reset --hard && git checkout master^0 && git merge -s recursive baseline^0 && - test -h a/b && test -f a/b-2/c/d ' -test_expect_failure SYMLINKS 'do not lose untracked in merge (resolve)' ' +test_expect_success SYMLINKS 'a/b was resolved as symlink' ' + test -h a/b +' + +test_expect_failure 'do not lose untracked in merge (resolve)' ' git reset --hard && git checkout baseline^0 && >a/b/c/e && @@ -91,7 +103,7 @@ test_expect_failure SYMLINKS 'do not lose untracked in merge (resolve)' ' test -f a/b-2/c/d ' -test_expect_success SYMLINKS 'do not lose untracked in merge (recursive)' ' +test_expect_success 'do not lose untracked in merge (recursive)' ' git reset --hard && git checkout baseline^0 && >a/b/c/e && @@ -100,52 +112,61 @@ test_expect_success SYMLINKS 'do not lose untracked in merge (recursive)' ' test -f a/b-2/c/d ' -test_expect_success SYMLINKS 'do not lose modifications in merge (resolve)' ' +test_expect_success 'do not lose modifications in merge (resolve)' ' git reset --hard && git checkout baseline^0 && echo more content >>a/b/c/d && test_must_fail git merge -s resolve master ' -test_expect_success SYMLINKS 'do not lose modifications in merge (recursive)' ' +test_expect_success 'do not lose modifications in merge (recursive)' ' git reset --hard && git checkout baseline^0 && echo more content >>a/b/c/d && test_must_fail git merge -s recursive master ' -test_expect_success SYMLINKS 'setup a merge where dir a/b-2 changed to symlink' ' +test_expect_success 'setup a merge where dir a/b-2 changed to symlink' ' git reset --hard && git checkout start^0 && rm -rf a/b-2 && - ln -s b a/b-2 && git add -A && + test_ln_s_add b a/b-2 && git commit -m "dir a/b-2 to symlink" && git tag test2 ' -test_expect_success SYMLINKS 'merge should not have D/F conflicts (resolve)' ' +test_expect_success 'merge should not have D/F conflicts (resolve)' ' git reset --hard && git checkout baseline^0 && git merge -s resolve test2 && - test -h a/b-2 && test -f a/b/c/d ' -test_expect_success SYMLINKS 'merge should not have D/F conflicts (recursive)' ' +test_expect_success SYMLINKS 'a/b-2 was resolved as symlink' ' + test -h a/b-2 +' + +test_expect_success 'merge should not have D/F conflicts (recursive)' ' git reset --hard && git checkout baseline^0 && git merge -s recursive test2 && - test -h a/b-2 && test -f a/b/c/d ' -test_expect_success SYMLINKS 'merge should not have F/D conflicts (recursive)' ' +test_expect_success SYMLINKS 'a/b-2 was resolved as symlink' ' + test -h a/b-2 +' + +test_expect_success 'merge should not have F/D conflicts (recursive)' ' git reset --hard && git checkout -b foo test2 && git merge -s recursive baseline^0 && - test -h a/b-2 && test -f a/b/c/d ' +test_expect_success SYMLINKS 'a/b-2 was resolved as symlink' ' + test -h a/b-2 +' + test_done diff --git a/t/t6111-rev-list-treesame.sh b/t/t6111-rev-list-treesame.sh new file mode 100755 index 0000000000..88b84dfa73 --- /dev/null +++ b/t/t6111-rev-list-treesame.sh @@ -0,0 +1,196 @@ +#!/bin/sh +# +# ,---E--. *H----------. * marks !TREESAME parent paths +# / \ / \* +# *A--*B---D--*F-*G---------K-*L-*M +# \ /* \ / +# `-C-' `-*I-*J +# +# A creates "file", B and F change it. +# Odd merge G takes the old version from B. +# I changes it, but J reverts it, so K is TREESAME to both parents. +# H and L both change "file", and M merges those changes. + +test_description='TREESAME and limiting' + +. ./test-lib.sh + +note () { + git tag "$1" +} + +unnote () { + git name-rev --tags --stdin | sed -e "s|$_x40 (tags/\([^)]*\))\([ ]\)|\1\2|g" +} + +test_expect_success setup ' + test_commit "Initial file" file "Hi there" A && + git branch other-branch && + + test_commit "file=Hello" file "Hello" B && + git branch third-branch && + + git checkout other-branch && + test_commit "Added other" other "Hello" C && + + git checkout master && + test_merge D other-branch && + + git checkout third-branch && + test_commit "Third file" third "Nothing" E && + + git checkout master && + test_commit "file=Blah" file "Blah" F && + + test_tick && git merge --no-commit third-branch && + git checkout third-branch file && + git commit && + note G && + git branch fiddler-branch && + + git checkout -b part2-branch && + test_commit "file=Part 2" file "Part 2" H && + + git checkout fiddler-branch && + test_commit "Bad commit" file "Silly" I && + + test_tick && git revert I && note J && + + git checkout master && + test_tick && git merge --no-ff fiddler-branch && + note K + + test_commit "file=Part 1" file "Part 1" L && + + test_tick && test_must_fail git merge part2-branch && + test_commit M file "Parts 1+2" +' + +check_outcome () { + outcome=$1 + shift + + case "$1" in + *"("*) + FMT="%P %H | %s" + munge_actual=" + s/^\([^ ]*\) \([^ ]*\) .*/(\1)\2/ + s/ //g + s/()// + " + ;; + *) + FMT="%H | %s" + munge_actual="s/^\([^ ]*\) .*/\1/" + ;; + esac && + printf "%s\n" $1 >expect && + shift + + param="$*" && + test_expect_$outcome "log $param" ' + git log --format="$FMT" $param | + unnote >actual && + sed -e "$munge_actual" <actual >check && + test_cmp expect check || { + cat actual + false + } + ' +} + +check_result () { + check_outcome success "$@" +} + +# Odd merge G drops a change in F. Important that G is listed in all +# except the most basic list. Achieving this means normal merge D will also be +# shown in normal full-history, as we can't distinguish unless we do a +# simplification pass. After simplification, D is dropped but G remains. +# Also, merge simplification of G should not drop the parent B that the default +# simple history follows. +check_result 'M L K J I H G F E D C B A' +check_result '(LH)M (K)L (GJ)K (I)J (G)I (G)H (FE)G (D)F (B)E (BC)D (A)C (A)B A' +check_result 'M H L K J I G E F D C B A' --topo-order +check_result 'M L H B A' -- file +check_result '(LH)M (B)L (B)H (A)B A' --parents -- file +check_result 'M L J I H G F D B A' --full-history -- file +check_result '(LH)M (K)L (GJ)K (I)J (G)I (G)H (FB)G (D)F (BA)D (A)B A' --full-history --parents -- file +check_result '(LH)M (G)H (J)L (I)J (G)I (FB)G (B)F (A)B A' --simplify-merges -- file +check_result 'M L K G F D B A' --first-parent +check_result 'M L G F B A' --first-parent -- file + +# Check that odd merge G remains shown when F is the bottom. +check_result 'M L K J I H G E' F..M +check_result 'M H L K J I G E' F..M --topo-order +check_result 'M L H' F..M -- file +check_result '(LH)M (B)L (B)H' --parents F..M -- file +check_result 'M L J I H G' F..M --full-history -- file +check_result '(LH)M (K)L (GJ)K (I)J (G)I (G)H (FB)G' F..M --full-history --parents -- file +check_result '(LH)M (G)H (J)L (I)J (G)I (FB)G' F..M --simplify-merges -- file +check_result 'M L K J I H G' F..M --ancestry-path +check_result 'M L J I H G' F..M --ancestry-path -- file +check_result '(LH)M (K)L (GJ)K (I)J (G)I (G)H (FE)G' F..M --ancestry-path --parents -- file +check_result '(LH)M (G)H (J)L (I)J (G)I (FE)G' F..M --ancestry-path --simplify-merges -- file +check_result 'M L K G' F..M --first-parent +check_result 'M L G' F..M --first-parent -- file + +# Note that G is pruned when E is the bottom, even if it's the same commit list +# If we want history since E, then we're quite happy to ignore G that took E. +check_result 'M L K J I H G' E..M --ancestry-path +check_result 'M L J I H' E..M --ancestry-path -- file +check_result '(LH)M (K)L (EJ)K (I)J (E)I (E)H' E..M --ancestry-path --parents -- file +check_result '(LH)M (E)H (J)L (I)J (E)I' E..M --ancestry-path --simplify-merges -- file + +# Should still be able to ignore I-J branch in simple log, despite limiting +# to G. +check_result 'M L K J I H' G..M +check_result 'M H L K J I' G..M --topo-order +check_result 'M L H' G..M -- file +check_result '(LH)M (G)L (G)H' G..M --parents -- file +check_result 'M L J I H' G..M --full-history -- file +check_result 'M L K J I H' G..M --full-history --parents -- file +check_result 'M H L J I' G..M --simplify-merges -- file +check_result 'M L K J I H' G..M --ancestry-path +check_result 'M L J I H' G..M --ancestry-path -- file +check_result 'M L K J I H' G..M --ancestry-path --parents -- file +check_result 'M H L J I' G..M --ancestry-path --simplify-merges -- file + +# B..F should be able to simplify the merge D from irrelevant side branch C. +# Default log should also be free to follow B-D, and ignore C. +# But --full-history shouldn't drop D on its own - without simplification, +# we can't decide if the merge from INTERESTING commit C was sensible. +check_result 'F D C' B..F +check_result 'F' B..F -- file +check_result '(B)F' B..F --parents -- file +check_result 'F D' B..F --full-history -- file +check_result '(D)F (BA)D' B..F --full-history --parents -- file +check_result '(B)F' B..F --simplify-merges -- file +check_result 'F D' B..F --ancestry-path +check_result 'F' B..F --ancestry-path -- file +check_result 'F' B..F --ancestry-path --parents -- file +check_result 'F' B..F --ancestry-path --simplify-merges -- file +check_result 'F D' B..F --first-parent +check_result 'F' B..F --first-parent -- file + +# E...F should be equivalent to E F ^B, and be able to drop D as above. +check_result 'F' E F ^B -- file # includes D +check_result 'F' E...F -- file # includes D + +# Any sort of full history of C..F should show D, as it's the connection to C, +# and it differs from it. +check_result 'F D B' C..F +check_result 'F B' C..F -- file +check_result '(B)F (A)B' C..F --parents -- file +check_result 'F D B' C..F --full-history -- file +check_result '(D)F (BC)D (A)B' C..F --full-history --parents -- file +check_result '(D)F (BC)D (A)B' C..F --simplify-merges -- file +check_result 'F D' C..F --ancestry-path +check_result 'F D' C..F --ancestry-path -- file +check_result 'F D' C..F --ancestry-path --parents -- file +check_result 'F D' C..F --ancestry-path --simplify-merges -- file +check_result 'F D B' C..F --first-parent +check_result 'F B' C..F --first-parent -- file + + +test_done diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index a845b154e4..101816e718 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -218,13 +218,13 @@ test_expect_success 'git mv should not change sha1 of moved cache entry' ' rm -f dirty dirty2 -test_expect_success SYMLINKS 'git mv should overwrite symlink to a file' ' +test_expect_success 'git mv should overwrite symlink to a file' ' rm -fr .git && git init && echo 1 >moved && - ln -s moved symlink && - git add moved symlink && + test_ln_s_add moved symlink && + git add moved && test_must_fail git mv moved symlink && git mv -f moved symlink && ! test -e moved && @@ -237,22 +237,26 @@ test_expect_success SYMLINKS 'git mv should overwrite symlink to a file' ' rm -f moved symlink -test_expect_success SYMLINKS 'git mv should overwrite file with a symlink' ' +test_expect_success 'git mv should overwrite file with a symlink' ' rm -fr .git && git init && echo 1 >moved && - ln -s moved symlink && - git add moved symlink && + test_ln_s_add moved symlink && + git add moved && test_must_fail git mv symlink moved && git mv -f symlink moved && ! test -e symlink && - test -h moved && git update-index --refresh && git diff-files --quiet ' +test_expect_success SYMLINKS 'check moved symlink' ' + + test -h moved +' + rm -f moved symlink test_done diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index df82ec9dda..300be86c38 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -457,7 +457,7 @@ test_expect_success 'disambiguation (1)' ' test_must_fail git diff --quiet -- secondfile && test -z "$(git diff --cached --name-only)" && test -f secondfile && - test ! -s secondfile + test_must_be_empty secondfile ' diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index ff265353a3..50e6ad7458 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -78,7 +78,7 @@ test_expect_success 'submodule add' ' ( cd addtest && git submodule add -q "$submodurl" submod >actual && - test ! -s actual && + test_must_be_empty actual && echo "gitdir: ../.git/modules/submod" >expect && test_cmp expect submod/.git && ( @@ -212,6 +212,32 @@ test_expect_success 'submodule add with ./, /.. and // in path' ' test_cmp empty untracked ' +test_expect_success 'submodule add in subdirectory' ' + echo "refs/heads/master" >expect && + >empty && + + mkdir addtest/sub && + ( + cd addtest/sub && + git submodule add "$submodurl" ../realsubmod3 && + git submodule init + ) && + + rm -f heads head untracked && + inspect addtest/realsubmod3 ../.. && + test_cmp expect heads && + test_cmp expect head && + test_cmp empty untracked +' + +test_expect_success 'submodule add in subdirectory with relative path should fail' ' + ( + cd addtest/sub && + test_must_fail git submodule add ../../ submod3 2>../../output.err + ) && + test_i18ngrep toplevel output.err +' + test_expect_success 'setup - add an example entry to .gitmodules' ' GIT_CONFIG=.gitmodules \ git config submodule.example.url git://example.com/init.git @@ -308,7 +334,7 @@ test_expect_success 'update should work when path is an empty dir' ' mkdir init && git submodule update -q >update.out && - test ! -s update.out && + test_must_be_empty update.out && inspect init && test_cmp expect head-sha1 @@ -319,6 +345,26 @@ test_expect_success 'status should be "up-to-date" after update' ' grep "^ $rev1" list ' +test_expect_success 'status "up-to-date" from subdirectory' ' + mkdir -p sub && + ( + cd sub && + git submodule status >../list + ) && + grep "^ $rev1" list && + grep "\\.\\./init" list +' + +test_expect_success 'status "up-to-date" from subdirectory with path' ' + mkdir -p sub && + ( + cd sub && + git submodule status ../init >../list + ) && + grep "^ $rev1" list && + grep "\\.\\./init" list +' + test_expect_success 'status should be "modified" after submodule commit' ' ( cd init && @@ -399,6 +445,25 @@ test_expect_success 'update --init' ' git rev-parse --resolve-git-dir init/.git ' +test_expect_success 'update --init from subdirectory' ' + mv init init2 && + git config -f .gitmodules submodule.example.url "$(pwd)/init2" && + git config --remove-section submodule.example && + test_must_fail git config submodule.example.url && + + mkdir -p sub && + ( + cd sub && + git submodule update ../init >update.out && + cat update.out && + test_i18ngrep "not initialized" update.out && + test_must_fail git rev-parse --resolve-git-dir ../init/.git && + + git submodule update --init ../init + ) && + git rev-parse --resolve-git-dir init/.git +' + test_expect_success 'do not add files from a submodule' ' git reset --hard && @@ -696,7 +761,7 @@ test_expect_success 'submodule add --name allows to replace a submodule with ano rm -rf repo && git rm repo && git submodule add -q --name repo_new "$submodurl/bare.git" repo >actual && - test ! -s actual && + test_must_be_empty actual && echo "gitdir: ../.git/modules/submod" >expect && test_cmp expect submod/.git && ( @@ -772,6 +837,21 @@ test_expect_success 'submodule deinit should remove the whole submodule section rmdir init ' +test_expect_success 'submodule deinit from subdirectory' ' + git submodule update --init && + git config submodule.example.foo bar && + mkdir -p sub && + ( + cd sub && + git submodule deinit ../init >../output + ) && + grep "\\.\\./init" output && + test -z "$(git config --get-regexp "submodule\.example\.")" && + test -n "$(git config --get-regexp "submodule\.example2\.")" && + test -f example2/.git && + rmdir init +' + test_expect_success 'submodule deinit . deinits all initialized submodules' ' git submodule update --init && git config submodule.example.foo bar && @@ -868,4 +948,19 @@ test_expect_success 'submodule deinit fails when submodule has a .git directory test -n "$(git config --get-regexp "submodule\.example\.")" ' +test_expect_success 'submodule with UTF-8 name' ' + svname=$(printf "\303\245 \303\244\303\266") && + mkdir "$svname" && + ( + cd "$svname" && + git init && + >sub && + git add sub && + git commit -m "init sub" + ) && + test_config core.precomposeunicode true && + git submodule add ./"$svname" && + git submodule >&2 && + test -n "$(git submodule | grep "$svname")" +' test_done diff --git a/t/t7401-submodule-summary.sh b/t/t7401-submodule-summary.sh index 30b429e7dc..ac2434c0db 100755 --- a/t/t7401-submodule-summary.sh +++ b/t/t7401-submodule-summary.sh @@ -45,6 +45,42 @@ EOF test_cmp expected actual " +test_expect_success 'added submodule (subdirectory)' " + mkdir sub && + ( + cd sub && + git submodule summary >../actual + ) && + cat >expected <<-EOF && +* ../sm1 0000000...$head1 (2): + > Add foo2 + +EOF + test_cmp expected actual +" + +test_expect_success 'added submodule (subdirectory only)' " + ( + cd sub && + git submodule summary . >../actual + ) && + >expected && + test_cmp expected actual +" + +test_expect_success 'added submodule (subdirectory with explicit path)' " + ( + cd sub && + git submodule summary ../sm1 >../actual + ) && + cat >expected <<-EOF && +* ../sm1 0000000...$head1 (2): + > Add foo2 + +EOF + test_cmp expected actual +" + commit_file sm1 && head2=$(add_file sm1 foo3) @@ -76,8 +112,8 @@ head3=$( ) test_expect_success 'modified submodule(backward)' " - git submodule summary >actual && - cat >expected <<-EOF && + git submodule summary >actual && + cat >expected <<-EOF && * sm1 $head2...$head3 (2): < Add foo3 < Add foo2 @@ -89,8 +125,8 @@ EOF head4=$(add_file sm1 foo4 foo5) && head4_full=$(GIT_DIR=sm1/.git git rev-parse --verify HEAD) test_expect_success 'modified submodule(backward and forward)' " - git submodule summary >actual && - cat >expected <<-EOF && + git submodule summary >actual && + cat >expected <<-EOF && * sm1 $head2...$head4 (4): > Add foo5 > Add foo4 @@ -102,15 +138,15 @@ EOF " test_expect_success '--summary-limit' " - git submodule summary -n 3 >actual && - cat >expected <<-EOF && + git submodule summary -n 3 >actual && + cat >expected <<-EOF && * sm1 $head2...$head4 (4): > Add foo5 > Add foo4 < Add foo3 EOF - test_cmp expected actual + test_cmp expected actual " commit_file sm1 && @@ -122,8 +158,8 @@ rm -f sm1 && mv sm1-bak sm1 test_expect_success 'typechanged submodule(submodule->blob), --cached' " - git submodule summary --cached >actual && - cat >expected <<-EOF && + git submodule summary --cached >actual && + cat >expected <<-EOF && * sm1 $head4(submodule)->$head5(blob) (3): < Add foo5 @@ -132,59 +168,59 @@ EOF " test_expect_success 'typechanged submodule(submodule->blob), --files' " - git submodule summary --files >actual && - cat >expected <<-EOF && + git submodule summary --files >actual && + cat >expected <<-EOF && * sm1 $head5(blob)->$head4(submodule) (3): > Add foo5 EOF - test_i18ncmp actual expected + test_i18ncmp actual expected " rm -rf sm1 && git checkout-index sm1 test_expect_success 'typechanged submodule(submodule->blob)' " - git submodule summary >actual && - cat >expected <<-EOF && + git submodule summary >actual && + cat >expected <<-EOF && * sm1 $head4(submodule)->$head5(blob): EOF - test_i18ncmp actual expected + test_i18ncmp actual expected " rm -f sm1 && test_create_repo sm1 && head6=$(add_file sm1 foo6 foo7) test_expect_success 'nonexistent commit' " - git submodule summary >actual && - cat >expected <<-EOF && + git submodule summary >actual && + cat >expected <<-EOF && * sm1 $head4...$head6: Warn: sm1 doesn't contain commit $head4_full EOF - test_i18ncmp actual expected + test_i18ncmp actual expected " commit_file test_expect_success 'typechanged submodule(blob->submodule)' " - git submodule summary >actual && - cat >expected <<-EOF && + git submodule summary >actual && + cat >expected <<-EOF && * sm1 $head5(blob)->$head6(submodule) (2): > Add foo7 EOF - test_i18ncmp expected actual + test_i18ncmp expected actual " commit_file sm1 && rm -rf sm1 test_expect_success 'deleted submodule' " - git submodule summary >actual && - cat >expected <<-EOF && + git submodule summary >actual && + cat >expected <<-EOF && * sm1 $head6...0000000: EOF - test_cmp expected actual + test_cmp expected actual " test_create_repo sm2 && @@ -192,43 +228,43 @@ head7=$(add_file sm2 foo8 foo9) && git add sm2 test_expect_success 'multiple submodules' " - git submodule summary >actual && - cat >expected <<-EOF && + git submodule summary >actual && + cat >expected <<-EOF && * sm1 $head6...0000000: * sm2 0000000...$head7 (2): > Add foo9 EOF - test_cmp expected actual + test_cmp expected actual " test_expect_success 'path filter' " - git submodule summary sm2 >actual && - cat >expected <<-EOF && + git submodule summary sm2 >actual && + cat >expected <<-EOF && * sm2 0000000...$head7 (2): > Add foo9 EOF - test_cmp expected actual + test_cmp expected actual " commit_file sm2 test_expect_success 'given commit' " - git submodule summary HEAD^ >actual && - cat >expected <<-EOF && + git submodule summary HEAD^ >actual && + cat >expected <<-EOF && * sm1 $head6...0000000: * sm2 0000000...$head7 (2): > Add foo9 EOF - test_cmp expected actual + test_cmp expected actual " test_expect_success '--for-status' " - git submodule summary --for-status HEAD^ >actual && - test_i18ncmp actual - <<EOF + git submodule summary --for-status HEAD^ >actual && + test_i18ncmp actual - <<EOF # Submodule changes to be committed: # # * sm1 $head6...0000000: @@ -240,14 +276,14 @@ EOF " test_expect_success 'fail when using --files together with --cached' " - test_must_fail git submodule summary --files --cached + test_must_fail git submodule summary --files --cached " test_expect_success 'should not fail in an empty repo' " - git init xyzzy && - cd xyzzy && - git submodule summary >output 2>&1 && - test_cmp output /dev/null + git init xyzzy && + cd xyzzy && + git submodule summary >output 2>&1 && + test_cmp output /dev/null " test_done diff --git a/t/t7403-submodule-sync.sh b/t/t7403-submodule-sync.sh index 94e26c47ea..79bc135bf6 100755 --- a/t/t7403-submodule-sync.sh +++ b/t/t7403-submodule-sync.sh @@ -11,216 +11,338 @@ These tests exercise the "git submodule sync" subcommand. . ./test-lib.sh test_expect_success setup ' - echo file > file && + echo file >file && git add file && test_tick && git commit -m upstream && git clone . super && git clone super submodule && - (cd submodule && - git submodule add ../submodule sub-submodule && - test_tick && - git commit -m "sub-submodule" + ( + cd submodule && + git submodule add ../submodule sub-submodule && + test_tick && + git commit -m "sub-submodule" ) && - (cd super && - git submodule add ../submodule submodule && - test_tick && - git commit -m "submodule" + ( + cd super && + git submodule add ../submodule submodule && + test_tick && + git commit -m "submodule" ) && git clone super super-clone && - (cd super-clone && git submodule update --init --recursive) && + ( + cd super-clone && + git submodule update --init --recursive + ) && git clone super empty-clone && - (cd empty-clone && git submodule init) && + ( + cd empty-clone && + git submodule init + ) && git clone super top-only-clone && git clone super relative-clone && - (cd relative-clone && git submodule update --init --recursive) && + ( + cd relative-clone && + git submodule update --init --recursive + ) && git clone super recursive-clone && - (cd recursive-clone && git submodule update --init --recursive) + ( + cd recursive-clone && + git submodule update --init --recursive + ) ' test_expect_success 'change submodule' ' - (cd submodule && - echo second line >> file && - test_tick && - git commit -a -m "change submodule" + ( + cd submodule && + echo second line >>file && + test_tick && + git commit -a -m "change submodule" ) ' +reset_submodule_urls () { + local root + root=$(pwd) && + ( + cd super-clone/submodule && + git config remote.origin.url "$root/submodule" + ) && + ( + cd super-clone/submodule/sub-submodule && + git config remote.origin.url "$root/submodule" + ) +} + test_expect_success 'change submodule url' ' - (cd super && - cd submodule && - git checkout master && - git pull + ( + cd super && + cd submodule && + git checkout master && + git pull ) && mv submodule moved-submodule && - (cd moved-submodule && - git config -f .gitmodules submodule.sub-submodule.url ../moved-submodule && - test_tick && - git commit -a -m moved-sub-submodule + ( + cd moved-submodule && + git config -f .gitmodules submodule.sub-submodule.url ../moved-submodule && + test_tick && + git commit -a -m moved-sub-submodule ) && - (cd super && - git config -f .gitmodules submodule.submodule.url ../moved-submodule && - test_tick && - git commit -a -m moved-submodule + ( + cd super && + git config -f .gitmodules submodule.submodule.url ../moved-submodule && + test_tick && + git commit -a -m moved-submodule ) ' test_expect_success '"git submodule sync" should update submodule URLs' ' - (cd super-clone && - git pull --no-recurse-submodules && - git submodule sync + ( + cd super-clone && + git pull --no-recurse-submodules && + git submodule sync ) && - test -d "$(cd super-clone/submodule && - git config remote.origin.url + test -d "$( + cd super-clone/submodule && + git config remote.origin.url )" && - test ! -d "$(cd super-clone/submodule/sub-submodule && - git config remote.origin.url + test ! -d "$( + cd super-clone/submodule/sub-submodule && + git config remote.origin.url )" && - (cd super-clone/submodule && - git checkout master && - git pull + ( + cd super-clone/submodule && + git checkout master && + git pull ) && - (cd super-clone && - test -d "$(git config submodule.submodule.url)" + ( + cd super-clone && + test -d "$(git config submodule.submodule.url)" ) ' test_expect_success '"git submodule sync --recursive" should update all submodule URLs' ' - (cd super-clone && - (cd submodule && - git pull --no-recurse-submodules - ) && - git submodule sync --recursive + ( + cd super-clone && + ( + cd submodule && + git pull --no-recurse-submodules + ) && + git submodule sync --recursive + ) && + test -d "$( + cd super-clone/submodule && + git config remote.origin.url + )" && + test -d "$( + cd super-clone/submodule/sub-submodule && + git config remote.origin.url + )" && + ( + cd super-clone/submodule/sub-submodule && + git checkout master && + git pull + ) +' + +test_expect_success 'reset submodule URLs' ' + reset_submodule_urls super-clone +' + +test_expect_success '"git submodule sync" should update submodule URLs - subdirectory' ' + ( + cd super-clone && + git pull --no-recurse-submodules && + mkdir -p sub && + cd sub && + git submodule sync >../../output + ) && + grep "\\.\\./submodule" output && + test -d "$( + cd super-clone/submodule && + git config remote.origin.url + )" && + test ! -d "$( + cd super-clone/submodule/sub-submodule && + git config remote.origin.url + )" && + ( + cd super-clone/submodule && + git checkout master && + git pull + ) && + ( + cd super-clone && + test -d "$(git config submodule.submodule.url)" + ) +' + +test_expect_success '"git submodule sync --recursive" should update all submodule URLs - subdirectory' ' + ( + cd super-clone && + ( + cd submodule && + git pull --no-recurse-submodules + ) && + mkdir -p sub && + cd sub && + git submodule sync --recursive >../../output ) && - test -d "$(cd super-clone/submodule && - git config remote.origin.url + grep "\\.\\./submodule/sub-submodule" output && + test -d "$( + cd super-clone/submodule && + git config remote.origin.url )" && - test -d "$(cd super-clone/submodule/sub-submodule && - git config remote.origin.url + test -d "$( + cd super-clone/submodule/sub-submodule && + git config remote.origin.url )" && - (cd super-clone/submodule/sub-submodule && - git checkout master && - git pull + ( + cd super-clone/submodule/sub-submodule && + git checkout master && + git pull ) ' test_expect_success '"git submodule sync" should update known submodule URLs' ' - (cd empty-clone && - git pull && - git submodule sync && - test -d "$(git config submodule.submodule.url)" + ( + cd empty-clone && + git pull && + git submodule sync && + test -d "$(git config submodule.submodule.url)" ) ' test_expect_success '"git submodule sync" should not vivify uninteresting submodule' ' - (cd top-only-clone && - git pull && - git submodule sync && - test -z "$(git config submodule.submodule.url)" && - git submodule sync submodule && - test -z "$(git config submodule.submodule.url)" + ( + cd top-only-clone && + git pull && + git submodule sync && + test -z "$(git config submodule.submodule.url)" && + git submodule sync submodule && + test -z "$(git config submodule.submodule.url)" ) ' test_expect_success '"git submodule sync" handles origin URL of the form foo' ' - (cd relative-clone && - git remote set-url origin foo && - git submodule sync && - (cd submodule && - #actual fails with: "cannot strip off url foo - test "$(git config remote.origin.url)" = "../submodule" - ) + ( + cd relative-clone && + git remote set-url origin foo && + git submodule sync && + ( + cd submodule && + #actual fails with: "cannot strip off url foo + test "$(git config remote.origin.url)" = "../submodule" + ) ) ' test_expect_success '"git submodule sync" handles origin URL of the form foo/bar' ' - (cd relative-clone && - git remote set-url origin foo/bar && - git submodule sync && - (cd submodule && - #actual foo/submodule - test "$(git config remote.origin.url)" = "../foo/submodule" - ) - (cd submodule/sub-submodule && - test "$(git config remote.origin.url)" != "../../foo/submodule" - ) + ( + cd relative-clone && + git remote set-url origin foo/bar && + git submodule sync && + ( + cd submodule && + #actual foo/submodule + test "$(git config remote.origin.url)" = "../foo/submodule" + ) && + ( + cd submodule/sub-submodule && + test "$(git config remote.origin.url)" != "../../foo/submodule" + ) ) ' test_expect_success '"git submodule sync --recursive" propagates changes in origin' ' - (cd recursive-clone && - git remote set-url origin foo/bar && - git submodule sync --recursive && - (cd submodule && - #actual foo/submodule - test "$(git config remote.origin.url)" = "../foo/submodule" - ) - (cd submodule/sub-submodule && - test "$(git config remote.origin.url)" = "../../foo/submodule" - ) + ( + cd recursive-clone && + git remote set-url origin foo/bar && + git submodule sync --recursive && + ( + cd submodule && + #actual foo/submodule + test "$(git config remote.origin.url)" = "../foo/submodule" + ) && + ( + cd submodule/sub-submodule && + test "$(git config remote.origin.url)" = "../../foo/submodule" + ) ) ' test_expect_success '"git submodule sync" handles origin URL of the form ./foo' ' - (cd relative-clone && - git remote set-url origin ./foo && - git submodule sync && - (cd submodule && - #actual ./submodule - test "$(git config remote.origin.url)" = "../submodule" - ) + ( + cd relative-clone && + git remote set-url origin ./foo && + git submodule sync && + ( + cd submodule && + #actual ./submodule + test "$(git config remote.origin.url)" = "../submodule" + ) ) ' test_expect_success '"git submodule sync" handles origin URL of the form ./foo/bar' ' - (cd relative-clone && - git remote set-url origin ./foo/bar && - git submodule sync && - (cd submodule && - #actual ./foo/submodule - test "$(git config remote.origin.url)" = "../foo/submodule" - ) + ( + cd relative-clone && + git remote set-url origin ./foo/bar && + git submodule sync && + ( + cd submodule && + #actual ./foo/submodule + test "$(git config remote.origin.url)" = "../foo/submodule" + ) ) ' test_expect_success '"git submodule sync" handles origin URL of the form ../foo' ' - (cd relative-clone && - git remote set-url origin ../foo && - git submodule sync && - (cd submodule && - #actual ../submodule - test "$(git config remote.origin.url)" = "../../submodule" - ) + ( + cd relative-clone && + git remote set-url origin ../foo && + git submodule sync && + ( + cd submodule && + #actual ../submodule + test "$(git config remote.origin.url)" = "../../submodule" + ) ) ' test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar' ' - (cd relative-clone && - git remote set-url origin ../foo/bar && - git submodule sync && - (cd submodule && - #actual ../foo/submodule - test "$(git config remote.origin.url)" = "../../foo/submodule" - ) + ( + cd relative-clone && + git remote set-url origin ../foo/bar && + git submodule sync && + ( + cd submodule && + #actual ../foo/submodule + test "$(git config remote.origin.url)" = "../../foo/submodule" + ) ) ' test_expect_success '"git submodule sync" handles origin URL of the form ../foo/bar with deeply nested submodule' ' - (cd relative-clone && - git remote set-url origin ../foo/bar && - mkdir -p a/b/c && - ( cd a/b/c && - git init && - :> .gitignore && - git add .gitignore && - test_tick && - git commit -m "initial commit" ) && - git submodule add ../bar/a/b/c ./a/b/c && - git submodule sync && - (cd a/b/c && - #actual ../foo/bar/a/b/c - test "$(git config remote.origin.url)" = "../../../../foo/bar/a/b/c" - ) + ( + cd relative-clone && + git remote set-url origin ../foo/bar && + mkdir -p a/b/c && + ( + cd a/b/c && + git init && + >.gitignore && + git add .gitignore && + test_tick && + git commit -m "initial commit" + ) && + git submodule add ../bar/a/b/c ./a/b/c && + git submodule sync && + ( + cd a/b/c && + #actual ../foo/bar/a/b/c + test "$(git config remote.origin.url)" = "../../../../foo/bar/a/b/c" + ) ) ' diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index a4ffea0dbe..cdb0538392 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -80,6 +80,21 @@ test_expect_success 'submodule update detaching the HEAD ' ' ) ' +test_expect_success 'submodule update from subdirectory' ' + (cd super/submodule && + git reset --hard HEAD~1 + ) && + mkdir super/sub && + (cd super/sub && + (cd ../submodule && + compare_head + ) && + git submodule update ../submodule && + cd ../submodule && + ! compare_head + ) +' + apos="'"; test_expect_success 'submodule update does not fetch already present commits' ' (cd submodule && diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 107b4b7c45..91d4fd1fac 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -80,6 +80,22 @@ test_expect_success 'test basic "submodule foreach" usage' ' test_i18ncmp expect actual ' +cat >expect <<EOF +Entering '../sub1' +$pwd/clone-foo1-../sub1-$sub1sha1 +Entering '../sub3' +$pwd/clone-foo3-../sub3-$sub3sha1 +EOF + +test_expect_success 'test "submodule foreach" from subdirectory' ' + mkdir clone/sub && + ( + cd clone/sub && + git submodule foreach "echo \$toplevel-\$name-\$sm_path-\$sha1" >../../actual + ) && + test_i18ncmp expect actual +' + test_expect_success 'setup nested submodules' ' git clone submodule nested1 && git clone submodule nested2 && diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index bf08d4e098..4f09beca90 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -632,7 +632,8 @@ test_expect_success 'status when cherry-picking before resolving conflicts' ' cat >expected <<-\EOF && # On branch cherry_branch # You are currently cherry-picking. - # (fix conflicts and run "git commit") + # (fix conflicts and run "git cherry-pick --continue") + # (use "git cherry-pick --abort" to cancel the cherry-pick operation) # # Unmerged paths: # (use "git add <file>..." to mark resolution) @@ -655,7 +656,8 @@ test_expect_success 'status when cherry-picking after resolving conflicts' ' cat >expected <<-\EOF && # On branch cherry_branch # You are currently cherry-picking. - # (all conflicts fixed: run "git commit") + # (all conflicts fixed: run "git cherry-pick --continue") + # (use "git cherry-pick --abort" to cancel the cherry-pick operation) # # Changes to be committed: # diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 2f70433568..460d8ebf48 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -316,7 +316,7 @@ test_expect_success 'merge c1 with c2 (squash)' ' test_debug 'git log --graph --decorate --oneline --all' -test_expect_success 'unsuccesful merge of c1 with c2 (squash, ff-only)' ' +test_expect_success 'unsuccessful merge of c1 with c2 (squash, ff-only)' ' git reset --hard c1 && test_must_fail git merge --squash --ff-only c2 ' diff --git a/t/t7607-merge-overwrite.sh b/t/t7607-merge-overwrite.sh index 6547eb8f54..758a623cdb 100755 --- a/t/t7607-merge-overwrite.sh +++ b/t/t7607-merge-overwrite.sh @@ -141,11 +141,10 @@ test_expect_success SYMLINKS 'will not overwrite untracked symlink in leading pa test_path_is_missing .git/MERGE_HEAD ' -test_expect_success SYMLINKS 'will not be confused by symlink in leading path' ' +test_expect_success 'will not be confused by symlink in leading path' ' git reset --hard c0 && rm -rf sub && - ln -s sub2 sub && - git add sub && + test_ln_s_add sub2 sub && git commit -m ln && git checkout sub ' diff --git a/t/t8006-blame-textconv.sh b/t/t8006-blame-textconv.sh index bf6caa4dc3..7683515155 100755 --- a/t/t8006-blame-textconv.sh +++ b/t/t8006-blame-textconv.sh @@ -18,17 +18,13 @@ test_expect_success 'setup ' ' echo "bin: test number 0" >zero.bin && echo "bin: test 1" >one.bin && echo "bin: test number 2" >two.bin && - if test_have_prereq SYMLINKS; then - ln -s one.bin symlink.bin - fi && + test_ln_s_add one.bin symlink.bin && git add . && GIT_AUTHOR_NAME=Number1 git commit -a -m First --date="2010-01-01 18:00:00" && echo "bin: test 1 version 2" >one.bin && echo "bin: test number 2 version 2" >>two.bin && - if test_have_prereq SYMLINKS; then - rm symlink.bin && - ln -s two.bin symlink.bin - fi && + rm -f symlink.bin && + test_ln_s_add two.bin symlink.bin && GIT_AUTHOR_NAME=Number2 git commit -a -m Second --date="2010-01-01 20:00:00" ' @@ -135,7 +131,7 @@ test_expect_success SYMLINKS 'blame --textconv (on symlink)' ' # cp two.bin three.bin and make small tweak # (this will direct blame -C -C three.bin to consider two.bin and symlink.bin) -test_expect_success SYMLINKS 'make another new commit' ' +test_expect_success 'make another new commit' ' cat >three.bin <<\EOF && bin: test number 2 bin: test number 2 version 2 @@ -146,7 +142,7 @@ EOF GIT_AUTHOR_NAME=Number4 git commit -a -m Fourth --date="2010-01-01 23:00:00" ' -test_expect_success SYMLINKS 'blame on last commit (-C -C, symlink)' ' +test_expect_success 'blame on last commit (-C -C, symlink)' ' git blame -C -C three.bin >blame && find_blame <blame >result && cat >expected <<\EOF && diff --git a/t/t8007-cat-file-textconv.sh b/t/t8007-cat-file-textconv.sh index 78a0085e64..b95e102891 100755 --- a/t/t8007-cat-file-textconv.sh +++ b/t/t8007-cat-file-textconv.sh @@ -12,9 +12,7 @@ chmod +x helper test_expect_success 'setup ' ' echo "bin: test" >one.bin && - if test_have_prereq SYMLINKS; then - ln -s one.bin symlink.bin - fi && + test_ln_s_add one.bin symlink.bin && git add . && GIT_AUTHOR_NAME=Number1 git commit -a -m First --date="2010-01-01 18:00:00" && echo "bin: test version 2" >one.bin && @@ -72,14 +70,14 @@ test_expect_success 'cat-file --textconv on previous commit' ' test_cmp expected result ' -test_expect_success SYMLINKS 'cat-file without --textconv (symlink)' ' +test_expect_success 'cat-file without --textconv (symlink)' ' git cat-file blob :symlink.bin >result && printf "%s" "one.bin" >expected test_cmp expected result ' -test_expect_success SYMLINKS 'cat-file --textconv on index (symlink)' ' +test_expect_success 'cat-file --textconv on index (symlink)' ' ! git cat-file --textconv :symlink.bin 2>result && cat >expected <<\EOF && fatal: git cat-file --textconv: unable to run textconv on :symlink.bin @@ -87,7 +85,7 @@ EOF test_cmp expected result ' -test_expect_success SYMLINKS 'cat-file --textconv on HEAD (symlink)' ' +test_expect_success 'cat-file --textconv on HEAD (symlink)' ' ! git cat-file --textconv HEAD:symlink.bin 2>result && cat >expected <<EOF && fatal: git cat-file --textconv: unable to run textconv on HEAD:symlink.bin diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 5d2dbe98d5..2813aa9a61 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -171,6 +171,81 @@ Result: OK EOF " +test_suppress_self () { + test_commit $3 && + test_when_finished "git reset --hard HEAD^" && + + write_script cccmd-sed <<-EOF && + sed -n -e s/^cccmd--//p "\$1" + EOF + + git commit --amend --author="$1 <$2>" -F - && + clean_fake_sendmail && + git format-patch --stdout -1 >"suppress-self-$3.patch" && + + git send-email --from="$1 <$2>" \ + --to=nobody@example.com \ + --cc-cmd=./cccmd-sed \ + --suppress-cc=self \ + --smtp-server="$(pwd)/fake.sendmail" \ + suppress-self-$3.patch && + + mv msgtxt1 msgtxt1-$3 && + sed -e '/^$/q' msgtxt1-$3 >"msghdr1-$3" && + >"expected-no-cc-$3" && + + (grep '^Cc:' msghdr1-$3 >"actual-no-cc-$3"; + test_cmp expected-no-cc-$3 actual-no-cc-$3) +} + +test_suppress_self_unquoted () { + test_suppress_self "$1" "$2" "unquoted-$3" <<-EOF + test suppress-cc.self unquoted-$3 with name $1 email $2 + + unquoted-$3 + + cccmd--$1 <$2> + + Cc: $1 <$2> + Signed-off-by: $1 <$2> + EOF +} + +test_suppress_self_quoted () { + test_suppress_self "$1" "$2" "quoted-$3" <<-EOF + test suppress-cc.self quoted-$3 with name $1 email $2 + + quoted-$3 + + cccmd--"$1" <$2> + + Cc: $1 <$2> + Cc: "$1" <$2> + Signed-off-by: $1 <$2> + Signed-off-by: "$1" <$2> + EOF +} + +test_expect_success $PREREQ 'self name is suppressed' " + test_suppress_self_unquoted 'A U Thor' 'author@example.com' \ + 'self_name_suppressed' +" + +test_expect_success $PREREQ 'self name with dot is suppressed' " + test_suppress_self_quoted 'A U. Thor' 'author@example.com' \ + 'self_name_dot_suppressed' +" + +test_expect_success $PREREQ 'non-ascii self name is suppressed' " + test_suppress_self_quoted 'Füñný Nâmé' 'odd_?=mail@example.com' \ + 'non_ascii_self_suppressed' +" + +test_expect_success $PREREQ 'sanitized self name is suppressed' " + test_suppress_self_unquoted '\"A U. Thor\"' 'author@example.com' \ + 'self_name_sanitized_suppressed' +" + test_expect_success $PREREQ 'Show all headers' ' git send-email \ --dry-run \ @@ -881,6 +956,20 @@ test_expect_success $PREREQ 'utf8 author is correctly passed on' ' grep "^From: Füñný Nâmé <odd_?=mail@example.com>" msgtxt1 ' +test_expect_success $PREREQ 'utf8 sender is not duplicated' ' + clean_fake_sendmail && + test_commit weird_sender && + test_when_finished "git reset --hard HEAD^" && + git commit --amend --author "Füñný Nâmé <odd_?=mail@example.com>" && + git format-patch --stdout -1 >funny_name.patch && + git send-email --from="Füñný Nâmé <odd_?=mail@example.com>" \ + --to=nobody@example.com \ + --smtp-server="$(pwd)/fake.sendmail" \ + funny_name.patch && + grep "^From: " msgtxt1 >msgfrom && + test_line_count = 1 msgfrom +' + test_expect_success $PREREQ 'sendemail.composeencoding works' ' clean_fake_sendmail && git config sendemail.composeencoding iso-8859-1 && diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 2471bc6777..34c2d8f49a 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -396,7 +396,7 @@ test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj' test_expect_success 'tag-obj_tag' 'git fast-export tag-obj_tag' test_expect_success 'tag-obj_tag-obj' 'git fast-export tag-obj_tag-obj' -test_expect_success SYMLINKS 'directory becomes symlink' ' +test_expect_success 'directory becomes symlink' ' git init dirtosymlink && git init result && ( @@ -408,8 +408,7 @@ test_expect_success SYMLINKS 'directory becomes symlink' ' git add foo/world bar/world && git commit -q -mone && git rm -r foo && - ln -s bar foo && - git add foo && + test_ln_s_add bar foo && git commit -q -mtwo ) && ( diff --git a/t/t9402-git-cvsserver-refs.sh b/t/t9402-git-cvsserver-refs.sh index 735a018ecc..db69af2cff 100755 --- a/t/t9402-git-cvsserver-refs.sh +++ b/t/t9402-git-cvsserver-refs.sh @@ -330,7 +330,7 @@ test_expect_success 'validate result of edits [cvswork2]' ' test_expect_success 'validate basic diffs saved during above cvswork2 edits' ' test $(grep Index: cvsEdit1.diff | wc -l) = 1 && - test ! -s cvsEdit2-empty.diff && + test_must_be_empty cvsEdit2-empty.diff && test $(grep Index: cvsEdit2-N.diff | wc -l) = 1 && test $(grep Index: cvsEdit3.diff | wc -l) = 3 && rm -rf diffSandbox && @@ -456,20 +456,20 @@ test_expect_success 'cvs up -r $(git rev-parse v1)' ' test_expect_success 'cvs diff -r v1 -u' ' ( cd cvswork && cvs -f diff -r v1 -u ) >cvsDiff.out 2>cvs.log && - test ! -s cvsDiff.out && - test ! -s cvs.log + test_must_be_empty cvsDiff.out && + test_must_be_empty cvs.log ' test_expect_success 'cvs diff -N -r v2 -u' ' ( cd cvswork && ! cvs -f diff -N -r v2 -u ) >cvsDiff.out 2>cvs.log && - test ! -s cvs.log && + test_must_be_empty cvs.log && test -s cvsDiff.out && check_diff cvsDiff.out v2 v1 >check_diff.out 2>&1 ' test_expect_success 'cvs diff -N -r v2 -r v1.2' ' ( cd cvswork && ! cvs -f diff -N -r v2 -r v1.2 -u ) >cvsDiff.out 2>cvs.log && - test ! -s cvs.log && + test_must_be_empty cvs.log && test -s cvsDiff.out && check_diff cvsDiff.out v2 v1.2 >check_diff.out 2>&1 ' @@ -488,7 +488,7 @@ test_expect_success 'apply early [cvswork3] diff to b3' ' test_expect_success 'check [cvswork3] diff' ' ( cd cvswork3 && ! cvs -f diff -N -u ) >"$WORKDIR/cvsDiff.out" 2>cvs.log && - test ! -s cvs.log && + test_must_be_empty cvs.log && test -s cvsDiff.out && test $(grep Index: cvsDiff.out | wc -l) = 3 && test_cmp cvsDiff.out cvswork3edit.diff && diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 6783c14c1a..6fca19353d 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -156,10 +156,10 @@ test_expect_success \ git commit -a -m "File renamed." && gitweb_run "p=.git;a=commitdiff"' -test_expect_success SYMLINKS \ +test_expect_success \ 'commitdiff(0): file to symlink' \ 'rm renamed_file && - ln -s file renamed_file && + test_ln_s_add file renamed_file && git commit -a -m "File to symlink." && gitweb_run "p=.git;a=commitdiff"' @@ -212,15 +212,14 @@ test_expect_success \ # ---------------------------------------------------------------------- # commitdiff testing (taken from t4114-apply-typechange.sh) -test_expect_success SYMLINKS 'setup typechange commits' ' +test_expect_success 'setup typechange commits' ' echo "hello world" > foo && echo "hi planet" > bar && git update-index --add foo bar && git commit -m initial && git branch initial && rm -f foo && - ln -s bar foo && - git update-index foo && + test_ln_s_add bar foo && git commit -m "foo symlinked to bar" && git branch foo-symlinked-to-bar && rm -f foo && @@ -361,11 +360,7 @@ test_expect_success \ echo "Changed" >> 04-rename-to && test_chmod +x 05-mode-change && rm -f 06-file-or-symlink && - if test_have_prereq SYMLINKS; then - ln -s 01-change 06-file-or-symlink - else - printf %s 01-change > 06-file-or-symlink - fi && + test_ln_s_add 01-change 06-file-or-symlink && echo "Changed and have mode changed" > 07-change-mode-change && test_chmod +x 07-change-mode-change && git commit -a -m "Large commit" && diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh index eeefa67904..b0d1d94bf4 100755 --- a/t/t9802-git-p4-filetype.sh +++ b/t/t9802-git-p4-filetype.sh @@ -95,7 +95,7 @@ test_expect_success 'gitattributes setting eol=lf produces lf newlines' ' git init && echo "* eol=lf" >.gitattributes && git p4 sync //depot@all && - git checkout master && + git checkout -b master p4/master && test_cmp "$cli"/f-unix-orig f-unix && test_cmp "$cli"/f-win-as-lf f-win ) @@ -109,7 +109,7 @@ test_expect_success 'gitattributes setting eol=crlf produces crlf newlines' ' git init && echo "* eol=crlf" >.gitattributes && git p4 sync //depot@all && - git checkout master && + git checkout -b master p4/master && test_cmp "$cli"/f-unix-as-crlf f-unix && test_cmp "$cli"/f-win-orig f-win ) diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 52510094ad..8828ff78f1 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -609,6 +609,18 @@ test_cmp() { $GIT_TEST_CMP "$@" } +# Check if the file expected to be empty is indeed empty, and barfs +# otherwise. + +test_must_be_empty () { + if test -s "$1" + then + echo "'$1' is not empty, it contains:" + cat "$1" + return 1 + fi +} + # Tests that its two parameters refer to the same revision test_cmp_rev () { git rev-parse --verify "$1" >expect.rev && @@ -679,3 +691,20 @@ test_create_repo () { mv .git/hooks .git/hooks-disabled ) || exit } + +# This function helps on symlink challenged file systems when it is not +# important that the file system entry is a symbolic link. +# Use test_ln_s_add instead of "ln -s x y && git add y" to add a +# symbolic link entry y to the index. + +test_ln_s_add () { + if test_have_prereq SYMLINKS + then + ln -s "$1" "$2" && + git update-index --add "$2" + else + printf '%s' "$1" >"$2" && + ln_s_obj=$(git hash-object -w "$2") && + git update-index --add --cacheinfo 120000 $ln_s_obj "$2" + fi +} |