diff options
Diffstat (limited to 't')
160 files changed, 4703 insertions, 752 deletions
@@ -265,14 +265,11 @@ Do: test ... That way all of the commands in your tests will succeed or fail. If - you must ignore the return value of something (e.g., the return - after unsetting a variable that was already unset is unportable) it's - best to indicate so explicitly with a semicolon: - - unset HLAGH; - git merge hla && - git push gh && - test ... + you must ignore the return value of something, consider using a + helper function (e.g. use sane_unset instead of unset, in order + to avoid unportable return value for unsetting a variable that was + already unset), or prepending the command with test_might_fail or + test_must_fail. - Check the test coverage for your tests. See the "Test coverage" below. @@ -401,13 +398,6 @@ library for your script to use. Like test_expect_success this function can optionally use a three argument invocation with a prerequisite as the first argument. - - test_expect_code [<prereq>] <code> <message> <script> - - Analogous to test_expect_success, but pass the test if it exits - with a given exit <code> - - test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master' - - test_debug <script> This takes a single argument, <script>, and evaluates it only @@ -488,6 +478,15 @@ library for your script to use. 'Perl API' \ "$PERL_PATH" "$TEST_DIRECTORY"/t9700/test.pl + - test_expect_code <exit-code> <command> + + Run a command and ensure that it exits with the given exit code. + For example: + + test_expect_success 'Merge with d/f conflicts' ' + test_expect_code 1 git merge "merge msg" B master + ' + - test_must_fail <git-command> Run a git command and ensure it fails in a controlled way. Use @@ -507,6 +506,10 @@ library for your script to use. <expected> file. This behaves like "cmp" but produces more helpful output when the test is run with "-v" option. + - test_line_count (= | -lt | -ge | ...) <length> <file> + + Check whether a file has the length it is expected to. + - test_path_is_file <file> [<diagnosis>] test_path_is_dir <dir> [<diagnosis>] test_path_is_missing <path> [<diagnosis>] diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index 141b60cdcb..d34208cc27 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -38,8 +38,8 @@ test_expect_success \ 'prepare reference tree' \ 'echo "1A quick brown fox jumps over the" >file && echo "lazy dog" >>file && - git add file - GIT_AUTHOR_NAME="A" git commit -a -m "Initial."' + git add file && + GIT_AUTHOR_NAME="A" GIT_AUTHOR_EMAIL="A@test.git" git commit -a -m "Initial."' test_expect_success \ 'check all lines blamed on A' \ @@ -49,7 +49,7 @@ test_expect_success \ 'Setup new lines blamed on B' \ 'echo "2A quick brown fox jumps over the" >>file && echo "lazy dog" >> file && - GIT_AUTHOR_NAME="B" git commit -a -m "Second."' + GIT_AUTHOR_NAME="B" GIT_AUTHOR_EMAIL="B@test.git" git commit -a -m "Second."' test_expect_success \ 'Two lines blamed on A, two on B' \ @@ -60,7 +60,7 @@ test_expect_success \ 'git checkout -b branch1 master && echo "3A slow green fox jumps into the" >> file && echo "well." >> file && - GIT_AUTHOR_NAME="B1" git commit -a -m "Branch1-1"' + GIT_AUTHOR_NAME="B1" GIT_AUTHOR_EMAIL="B1@test.git" git commit -a -m "Branch1-1"' test_expect_success \ 'Two lines blamed on A, two on B, two on B1' \ @@ -71,7 +71,7 @@ test_expect_success \ 'git checkout -b branch2 master && sed -e "s/2A quick brown/4A quick brown lazy dog/" < file > file.new && mv file.new file && - GIT_AUTHOR_NAME="B2" git commit -a -m "Branch2-1"' + GIT_AUTHOR_NAME="B2" GIT_AUTHOR_EMAIL="B2@test.git" git commit -a -m "Branch2-1"' test_expect_success \ 'Two lines blamed on A, one on B, one on B2' \ @@ -105,7 +105,7 @@ test_expect_success \ test_expect_success \ 'an incomplete line added' \ 'echo "incomplete" | tr -d "\\012" >>file && - GIT_AUTHOR_NAME="C" git commit -a -m "Incomplete"' + GIT_AUTHOR_NAME="C" GIT_AUTHOR_EMAIL="C@test.git" git commit -a -m "Incomplete"' test_expect_success \ 'With incomplete lines.' \ @@ -119,7 +119,7 @@ test_expect_success \ echo } | sed -e "s/^3A/99/" -e "/^1A/d" -e "/^incomplete/d" > file && echo "incomplete" | tr -d "\\012" >>file && - GIT_AUTHOR_NAME="D" git commit -a -m "edit"' + GIT_AUTHOR_NAME="D" GIT_AUTHOR_EMAIL="D@test.git" git commit -a -m "edit"' test_expect_success \ 'some edit' \ diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index e733f6516f..3f24384371 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -75,12 +75,14 @@ fi prepare_httpd() { mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH" + cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH" ln -s "$LIB_HTTPD_MODULE_PATH" "$HTTPD_ROOT_PATH/modules" if test -n "$LIB_HTTPD_SSL" then HTTPD_URL=https://127.0.0.1:$LIB_HTTPD_PORT + AUTH_HTTPD_URL=https://user%40host:user%40host@127.0.0.1:$LIB_HTTPD_PORT RANDFILE_PATH="$HTTPD_ROOT_PATH"/.rnd openssl req \ -config "$TEST_PATH/ssl.cnf" \ @@ -92,6 +94,7 @@ prepare_httpd() { HTTPD_PARA="$HTTPD_PARA -DSSL" else HTTPD_URL=http://127.0.0.1:$LIB_HTTPD_PORT + AUTH_HTTPD_URL=http://user%40host:user%40host@127.0.0.1:$LIB_HTTPD_PORT fi if test -n "$LIB_HTTPD_DAV" -o -n "$LIB_HTTPD_SVN" diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 4961505d1d..0a4cdfa93e 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -17,8 +17,33 @@ ErrorLog error.log <IfModule !mod_env.c> LoadModule env_module modules/mod_env.so </IfModule> +<IfModule !mod_rewrite.c> + LoadModule rewrite_module modules/mod_rewrite.so +</IFModule> +<IfModule !mod_version.c> + LoadModule version_module modules/mod_version.so +</IfModule> + +<IfVersion < 2.1> +<IfModule !mod_auth.c> + LoadModule auth_module modules/mod_auth.so +</IfModule> +</IfVersion> + +<IfVersion >= 2.1> +<IfModule !mod_auth_basic.c> + LoadModule auth_basic_module modules/mod_auth_basic.so +</IfModule> +<IfModule !mod_authn_file.c> + LoadModule authn_file_module modules/mod_authn_file.so +</IfModule> +<IfModule !mod_authz_user.c> + LoadModule authz_user_module modules/mod_authz_user.so +</IfModule> +</IfVersion> Alias /dumb/ www/ +Alias /auth/ www/auth/ <Location /smart/> SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} @@ -36,6 +61,10 @@ ScriptAlias /smart_noexport/ ${GIT_EXEC_PATH}/git-http-backend/ Options ExecCGI </Files> +RewriteEngine on +RewriteRule ^/smart-redir-perm/(.*)$ /smart/$1 [R=301] +RewriteRule ^/smart-redir-temp/(.*)$ /smart/$1 [R=302] + <IfDefine SSL> LoadModule ssl_module modules/mod_ssl.so @@ -48,6 +77,13 @@ SSLMutex file:ssl_mutex SSLEngine On </IfDefine> +<Location /auth/> + AuthType Basic + AuthName "git-auth" + AuthUserFile passwd + Require valid-user +</Location> + <IfDefine DAV> LoadModule dav_module modules/mod_dav.so LoadModule dav_fs_module modules/mod_dav_fs.so diff --git a/t/lib-httpd/passwd b/t/lib-httpd/passwd new file mode 100644 index 0000000000..f2fbcad33e --- /dev/null +++ b/t/lib-httpd/passwd @@ -0,0 +1 @@ +user@host:nKpa8pZUHx/ic diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index f688bd3ef5..2f7002a5e5 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -130,22 +130,57 @@ test_expect_success 'tests clean up after themselves' ' test_when_finished clean=yes ' -cleaner=no -test_expect_code 1 'tests clean up even after a failure' ' - test_when_finished cleaner=yes && - (exit 1) -' - -if test $clean$cleaner != yesyes +if test $clean != yes then - say "bug in test framework: cleanup commands do not work reliably" + say "bug in test framework: basic cleanup command does not work reliably" exit 1 fi -test_expect_code 2 'failure to clean up causes the test to fail' ' - test_when_finished "(exit 2)" +test_expect_success 'tests clean up even on failures' " + mkdir failing-cleanup && + (cd failing-cleanup && + cat >failing-cleanup.sh <<EOF && +#!$SHELL_PATH + +test_description='Failing tests with cleanup commands' + +# Point to the t/test-lib.sh, which isn't in ../ as usual +TEST_DIRECTORY=\"$TEST_DIRECTORY\" +. \"\$TEST_DIRECTORY\"/test-lib.sh + +test_expect_success 'tests clean up even after a failure' ' + touch clean-after-failure && + test_when_finished rm clean-after-failure && + (exit 1) +' + +test_expect_success 'failure to clean up causes the test to fail' ' + test_when_finished \"(exit 2)\" ' +test_done +EOF + chmod +x failing-cleanup.sh && + test_must_fail ./failing-cleanup.sh >out 2>err && + ! test -s err && + ! test -f \"trash directory.failing-cleanup/clean-after-failure\" && +sed -e 's/Z$//' >expect <<\EOF && +not ok - 1 tests clean up even after a failure +# Z +# touch clean-after-failure && +# test_when_finished rm clean-after-failure && +# (exit 1) +# Z +not ok - 2 failure to clean up causes the test to fail +# Z +# test_when_finished \"(exit 2)\" +# Z +# failed 2 among 2 test(s) +1..2 +EOF + test_cmp expect out) +" + ################################################################ # Basics of the basics diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 7fe8883ae0..d44194c35f 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -25,7 +25,7 @@ check_config () { test_expect_success 'plain' ' ( - unset GIT_DIR GIT_WORK_TREE + sane_unset GIT_DIR GIT_WORK_TREE && mkdir plain && cd plain && git init @@ -35,7 +35,7 @@ test_expect_success 'plain' ' test_expect_success 'plain with GIT_WORK_TREE' ' if ( - unset GIT_DIR + sane_unset GIT_DIR && mkdir plain-wt && cd plain-wt && GIT_WORK_TREE=$(pwd) git init @@ -48,7 +48,7 @@ test_expect_success 'plain with GIT_WORK_TREE' ' test_expect_success 'plain bare' ' ( - unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && mkdir plain-bare-1 && cd plain-bare-1 && git --bare init @@ -58,7 +58,7 @@ test_expect_success 'plain bare' ' test_expect_success 'plain bare with GIT_WORK_TREE' ' if ( - unset GIT_DIR GIT_CONFIG + sane_unset GIT_DIR GIT_CONFIG && mkdir plain-bare-2 && cd plain-bare-2 && GIT_WORK_TREE=$(pwd) git --bare init @@ -72,7 +72,7 @@ test_expect_success 'plain bare with GIT_WORK_TREE' ' test_expect_success 'GIT_DIR bare' ' ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir git-dir-bare.git && GIT_DIR=git-dir-bare.git git init ) && @@ -82,7 +82,7 @@ test_expect_success 'GIT_DIR bare' ' test_expect_success 'init --bare' ' ( - unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + sane_unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && mkdir init-bare.git && cd init-bare.git && git init --bare @@ -93,7 +93,7 @@ test_expect_success 'init --bare' ' test_expect_success 'GIT_DIR non-bare' ' ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir non-bare && cd non-bare && GIT_DIR=.git git init @@ -104,7 +104,7 @@ test_expect_success 'GIT_DIR non-bare' ' test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir git-dir-wt-1.git && GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init ) && @@ -114,7 +114,7 @@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' ' if ( - unset GIT_CONFIG + sane_unset GIT_CONFIG && mkdir git-dir-wt-2.git && GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init ) @@ -127,7 +127,7 @@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' ' test_expect_success 'reinit' ' ( - unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG + sane_unset GIT_CONFIG GIT_WORK_TREE GIT_CONFIG && mkdir again && cd again && @@ -175,8 +175,8 @@ test_expect_success 'init with init.templatedir set' ' git config -f "$test_config" init.templatedir "${HOME}/templatedir-source" && mkdir templatedir-set && cd templatedir-set && - unset GIT_CONFIG_NOGLOBAL && - unset GIT_TEMPLATE_DIR && + sane_unset GIT_CONFIG_NOGLOBAL && + sane_unset GIT_TEMPLATE_DIR && NO_SET_GIT_TEMPLATE_DIR=t && export NO_SET_GIT_TEMPLATE_DIR && git init @@ -187,7 +187,7 @@ test_expect_success 'init with init.templatedir set' ' test_expect_success 'init --bare/--shared overrides system/global config' ' ( test_config="$HOME"/.gitconfig && - unset GIT_CONFIG_NOGLOBAL && + sane_unset GIT_CONFIG_NOGLOBAL && git config -f "$test_config" core.bare false && git config -f "$test_config" core.sharedRepository 0640 && mkdir init-bare-shared-override && @@ -202,7 +202,7 @@ test_expect_success 'init --bare/--shared overrides system/global config' ' test_expect_success 'init honors global core.sharedRepository' ' ( test_config="$HOME"/.gitconfig && - unset GIT_CONFIG_NOGLOBAL && + sane_unset GIT_CONFIG_NOGLOBAL && git config -f "$test_config" core.sharedRepository 0666 && mkdir shared-honor-global && cd shared-honor-global && diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index e75153bdea..ebbc7554a7 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -72,7 +72,7 @@ test_expect_success 'core.attributesfile' ' test_expect_success 'attribute test: read paths from stdin' ' - cat <<EOF > expect + cat <<EOF > expect && f: test: f a/f: test: f a/c/f: test: f diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 234a94f3e6..1a8f44c44c 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -439,7 +439,7 @@ test_expect_success 'checkout when deleting .gitattributes' ' git rm .gitattributes && echo "contentsQ" | q_to_cr > .file2 && git add .file2 && - git commit -m third + git commit -m third && git checkout master~1 && git checkout master && diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh index c7d0324374..ec6c1b3f8a 100755 --- a/t/t0024-crlf-archive.sh +++ b/t/t0024-crlf-archive.sh @@ -7,7 +7,7 @@ UNZIP=${UNZIP:-unzip} test_expect_success setup ' - git config core.autocrlf true + git config core.autocrlf true && printf "CRLF line ending\r\nAnd another\r\n" > sample && git add sample && @@ -20,7 +20,7 @@ test_expect_success setup ' test_expect_success 'tar archive' ' git archive --format=tar HEAD | - ( mkdir untarred && cd untarred && "$TAR" -xf - ) + ( mkdir untarred && cd untarred && "$TAR" -xf - ) && test_cmp sample untarred/sample diff --git a/t/t0026-eol-config.sh b/t/t0026-eol-config.sh index f37ac8fa0b..fe0164be62 100755 --- a/t/t0026-eol-config.sh +++ b/t/t0026-eol-config.sh @@ -12,7 +12,7 @@ test_expect_success setup ' git config core.autocrlf false && - echo "one text" > .gitattributes + echo "one text" > .gitattributes && for w in Hello world how are you; do echo $w; done >one && for w in I am very very fine thank you; do echo $w; done >two && diff --git a/t/t0050-filesystem.sh b/t/t0050-filesystem.sh index 41df6bcf27..057c97c49f 100755 --- a/t/t0050-filesystem.sh +++ b/t/t0050-filesystem.sh @@ -12,14 +12,14 @@ unibad= no_symlinks= test_expect_success 'see what we expect' ' - test_case=test_expect_success - test_unicode=test_expect_success + test_case=test_expect_success && + test_unicode=test_expect_success && mkdir junk && echo good >junk/CamelCase && echo bad >junk/camelcase && if test "$(cat junk/CamelCase)" != good then - test_case=test_expect_failure + test_case=test_expect_failure && case_insensitive=t fi && rm -fr junk && @@ -27,7 +27,7 @@ test_expect_success 'see what we expect' ' >junk/"$auml" && case "$(cd junk && echo *)" in "$aumlcdiar") - test_unicode=test_expect_failure + test_unicode=test_expect_failure && unibad=t ;; *) ;; @@ -36,7 +36,7 @@ test_expect_success 'see what we expect' ' { ln -s x y 2> /dev/null && test -h y 2> /dev/null || - no_symlinks=1 + no_symlinks=1 && rm -f y } ' @@ -128,7 +128,7 @@ test_expect_success "setup unicode normalization tests" ' cd unicode && touch "$aumlcdiar" && git add "$aumlcdiar" && - git commit -m initial + git commit -m initial && git tag initial && git checkout -b topic && git mv $aumlcdiar tmp && diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh index 4f171722d9..ca8a4098fa 100755 --- a/t/t1000-read-tree-m-3way.sh +++ b/t/t1000-read-tree-m-3way.sh @@ -309,7 +309,7 @@ test_expect_success \ test_expect_success \ '6 - must not exist in O && !A && !B case' " rm -f .git/index DD && - echo DD >DD + echo DD >DD && git update-index --add DD && test_must_fail git read-tree -m $tree_O $tree_A $tree_B " diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 93ca84f9e6..680d992f22 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -98,8 +98,8 @@ test_expect_success \ git checkout-index -u -f -q -a && git update-index --add yomin && read_tree_twoway $treeH $treeM && - git ls-files --stage >4.out || return 1 - git diff --no-index M.out 4.out >4diff.out + git ls-files --stage >4.out && + test_must_fail git diff --no-index M.out 4.out >4diff.out && compare_change 4diff.out expected && check_cache_at yomin clean' @@ -112,8 +112,8 @@ test_expect_success \ git update-index --add yomin && echo yomin yomin >yomin && read_tree_twoway $treeH $treeM && - git ls-files --stage >5.out || return 1 - git diff --no-index M.out 5.out >5diff.out + git ls-files --stage >5.out && + test_must_fail git diff --no-index M.out 5.out >5diff.out && compare_change 5diff.out expected && check_cache_at yomin dirty' @@ -213,8 +213,8 @@ test_expect_success \ echo nitfol nitfol >nitfol && git update-index --add nitfol && read_tree_twoway $treeH $treeM && - git ls-files --stage >14.out || return 1 - git diff --no-index M.out 14.out >14diff.out + git ls-files --stage >14.out && + test_must_fail git diff --no-index M.out 14.out >14diff.out && compare_change 14diff.out expected && check_cache_at nitfol clean' @@ -227,8 +227,8 @@ test_expect_success \ git update-index --add nitfol && echo nitfol nitfol nitfol >nitfol && read_tree_twoway $treeH $treeM && - git ls-files --stage >15.out || return 1 - git diff --no-index M.out 15.out >15diff.out + git ls-files --stage >15.out && + test_must_fail git diff --no-index M.out 15.out >15diff.out && compare_change 15diff.out expected && check_cache_at nitfol dirty' @@ -377,7 +377,7 @@ test_expect_success \ git ls-files --stage >treeM.out && rm -f a && - mkdir a + mkdir a && : >a/b && git update-index --add --remove a a/b && treeH=`git write-tree` && @@ -394,7 +394,7 @@ test_expect_success '-m references the correct modified tree' ' echo >file-a && echo >file-b && git add file-a file-b && - git commit -a -m "test for correct modified tree" + git commit -a -m "test for correct modified tree" && git branch initial-mod && echo b >file-b && git commit -a -m "B" && diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index 0241329a08..a4a17e0017 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -205,8 +205,8 @@ test_expect_success \ echo nitfol nitfol >nitfol && git update-index --add nitfol && git read-tree -m -u $treeH $treeM && - git ls-files --stage >14.out || return 1 - git diff -U0 --no-index M.out 14.out >14diff.out + git ls-files --stage >14.out && + test_must_fail git diff -U0 --no-index M.out 14.out >14diff.out && compare_change 14diff.out expected && sum bozbar frotz >actual14.sum && grep -v nitfol M.sum > expected14.sum && @@ -226,8 +226,8 @@ test_expect_success \ git update-index --add nitfol && echo nitfol nitfol nitfol >nitfol && git read-tree -m -u $treeH $treeM && - git ls-files --stage >15.out || return 1 - git diff -U0 --no-index M.out 15.out >15diff.out + git ls-files --stage >15.out && + test_must_fail git diff -U0 --no-index M.out 15.out >15diff.out && compare_change 15diff.out expected && check_cache_at nitfol dirty && sum bozbar frotz >actual15.sum && @@ -314,7 +314,7 @@ test_expect_success \ # Also make sure we did not break DF vs DF/DF case. test_expect_success \ 'DF vs DF/DF case setup.' \ - 'rm -f .git/index + 'rm -f .git/index && echo DF >DF && git update-index --add DF && treeDF=`git write-tree` && diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index 8008fa2d89..0ef11bccb4 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -49,7 +49,7 @@ test_expect_success 'read-tree without .git/info/sparse-checkout' ' ' test_expect_success 'read-tree with .git/info/sparse-checkout but disabled' ' - echo >.git/info/sparse-checkout + echo >.git/info/sparse-checkout && git read-tree -m -u HEAD && git ls-files -t >result && test_cmp expected.swt result && diff --git a/t/t1200-tutorial.sh b/t/t1200-tutorial.sh index ab55eda158..bfa2c2190d 100755 --- a/t/t1200-tutorial.sh +++ b/t/t1200-tutorial.sh @@ -42,7 +42,7 @@ test_expect_success 'git diff' ' ' test_expect_success 'tree' ' - tree=$(git write-tree 2>/dev/null) + tree=$(git write-tree 2>/dev/null) && test 8988da15d077d4829fc51d8544c097def6644dbb = $tree ' diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh index a6bf1bf4d6..0e47662406 100755 --- a/t/t1302-repo-version.sh +++ b/t/t1302-repo-version.sh @@ -39,7 +39,7 @@ test_expect_success 'gitdir selection on unsupported repo' ' ( cd test2 && git config core.repositoryformatversion >../actual - ) + ) && test_cmp expect actual ' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 54ba3df95f..ff747f8229 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -52,9 +52,8 @@ rm -f .git/$m test_expect_success \ "fail to create $n" \ - "touch .git/$n_dir - git update-ref $n $A >out 2>err"' - test $? != 0' + "touch .git/$n_dir && + test_must_fail git update-ref $n $A >out 2>err" rm -f .git/$n_dir out err test_expect_success \ @@ -185,55 +184,55 @@ gd="Thu, 26 May 2005 18:33:00 -0500" ld="Thu, 26 May 2005 18:43:00 -0500" test_expect_success \ 'Query "master@{May 25 2005}" (before history)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{May 25 2005}" >o 2>e && test '"$C"' = $(cat o) && test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"' test_expect_success \ "Query master@{2005-05-25} (before history)" \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify master@{2005-05-25} >o 2>e && test '"$C"' = $(cat o) && echo test "warning: Log for '\'master\'' only goes back to $ed." = "$(cat e)"' test_expect_success \ 'Query "master@{May 26 2005 23:31:59}" (1 second before history)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e && test '"$C"' = $(cat o) && test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)"' test_expect_success \ 'Query "master@{May 26 2005 23:32:00}" (exactly history start)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e && test '"$C"' = $(cat o) && test "" = "$(cat e)"' test_expect_success \ 'Query "master@{May 26 2005 23:32:30}" (first non-creation change)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{May 26 2005 23:32:30}" >o 2>e && test '"$A"' = $(cat o) && test "" = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e && test '"$B"' = $(cat o) && test "warning: Log .git/logs/'"$m has gap after $gd"'." = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-26 23:38:00}" (middle of history)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e && test '"$Z"' = $(cat o) && test "" = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-26 23:43:00}" (exact end of history)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e && test '"$E"' = $(cat o) && test "" = "$(cat e)"' test_expect_success \ 'Query "master@{2005-05-28}" (past end of history)' \ - 'rm -f o e + 'rm -f o e && git rev-parse --verify "master@{2005-05-28}" >o 2>e && test '"$D"' = $(cat o) && test "warning: Log .git/logs/'"$m unexpectedly ended on $ld"'." = "$(cat e)"' @@ -247,7 +246,7 @@ test_expect_success \ git add F && GIT_AUTHOR_DATE="2005-05-26 23:30" \ GIT_COMMITTER_DATE="2005-05-26 23:30" git commit -m add -a && - h_TEST=$(git rev-parse --verify HEAD) + h_TEST=$(git rev-parse --verify HEAD) && echo The other day this did not work. >M && echo And then Bob told me how to fix it. >>M && echo OTHER >F && diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 7fa5f5b22a..2c96551ed0 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -28,7 +28,7 @@ test_expect_success 'symbolic-ref refuses non-ref for HEAD' ' reset_to_sane test_expect_success 'symbolic-ref refuses bare sha1' ' - echo content >file && git add file && git commit -m one + echo content >file && git add file && git commit -m one && test_must_fail git symbolic-ref HEAD `git rev-parse HEAD` ' reset_to_sane diff --git a/t/t1402-check-ref-format.sh b/t/t1402-check-ref-format.sh index 782e75d000..1b0f82fa4c 100755 --- a/t/t1402-check-ref-format.sh +++ b/t/t1402-check-ref-format.sh @@ -32,7 +32,7 @@ test_expect_success "check-ref-format --branch @{-1}" ' T=$(git write-tree) && sha1=$(echo A | git commit-tree $T) && git update-ref refs/heads/master $sha1 && - git update-ref refs/remotes/origin/master $sha1 + git update-ref refs/remotes/origin/master $sha1 && git checkout master && git checkout origin/master && git checkout master && @@ -47,7 +47,7 @@ test_expect_success 'check-ref-format --branch from subdir' ' T=$(git write-tree) && sha1=$(echo A | git commit-tree $T) && git update-ref refs/heads/master $sha1 && - git update-ref refs/remotes/origin/master $sha1 + git update-ref refs/remotes/origin/master $sha1 && git checkout master && git checkout origin/master && git checkout master && diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 25046c4208..252fc82837 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -186,8 +186,8 @@ test_expect_success 'delete' ' test_tick && git commit -m tiger C && - HEAD_entry_count=$(git reflog | wc -l) - master_entry_count=$(git reflog show master | wc -l) + HEAD_entry_count=$(git reflog | wc -l) && + master_entry_count=$(git reflog show master | wc -l) && test $HEAD_entry_count = 5 && test $master_entry_count = 5 && @@ -199,13 +199,13 @@ test_expect_success 'delete' ' test $HEAD_entry_count = $(git reflog | wc -l) && ! grep ox < output && - master_entry_count=$(wc -l < output) + master_entry_count=$(wc -l < output) && git reflog delete HEAD@{1} && test $(($HEAD_entry_count -1)) = $(git reflog | wc -l) && test $master_entry_count = $(git reflog show master | wc -l) && - HEAD_entry_count=$(git reflog | wc -l) + HEAD_entry_count=$(git reflog | wc -l) && git reflog delete master@{07.04.2005.15:15:00.-0700} && git reflog show master > output && diff --git a/t/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh new file mode 100755 index 0000000000..7f519e5ebe --- /dev/null +++ b/t/t1412-reflog-loop.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +test_description='reflog walk shows repeated commits again' +. ./test-lib.sh + +test_expect_success 'setup commits' ' + test_tick && + echo content >file && git add file && git commit -m one && + git tag one && + echo content >>file && git add file && git commit -m two && + git tag two +' + +test_expect_success 'setup reflog with alternating commits' ' + git checkout -b topic && + git reset one && + git reset two && + git reset one && + git reset two +' + +test_expect_success 'reflog shows all entries' ' + cat >expect <<-\EOF + topic@{0} two: updating HEAD + topic@{1} one: updating HEAD + topic@{2} two: updating HEAD + topic@{3} one: updating HEAD + topic@{4} branch: Created from HEAD + EOF + git log -g --format="%gd %gs" topic >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 1be415e334..bb01d5ab8f 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -61,7 +61,7 @@ test_expect_success 'object with bad sha1' ' sha=$(echo blob | git hash-object -w --stdin) && old=$(echo $sha | sed "s+^..+&/+") && new=$(dirname $old)/ffffffffffffffffffffffffffffffffffffff && - sha="$(dirname $new)$(basename $new)" + sha="$(dirname $new)$(basename $new)" && mv .git/objects/$old .git/objects/$new && test_when_finished "remove_object $sha" && git update-index --add --cacheinfo 100644 $sha foo && @@ -111,7 +111,7 @@ test_expect_success 'email with embedded > is not okay' ' ' test_expect_success 'tag pointing to nonexistent' ' - cat >invalid-tag <<-\EOF + cat >invalid-tag <<-\EOF && object ffffffffffffffffffffffffffffffffffffffff type commit tag invalid diff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh index b3195c4707..1efd7f76dd 100755 --- a/t/t1502-rev-parse-parseopt.sh +++ b/t/t1502-rev-parse-parseopt.sh @@ -40,7 +40,7 @@ extra1 line above used to cause a segfault but no longer does EOF test_expect_success 'test --parseopt help output' ' - git rev-parse --parseopt -- -h > output < optionspec + test_expect_code 129 git rev-parse --parseopt -- -h > output < optionspec && test_cmp expect output ' diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh index df5ad8c686..cce87a5ab5 100755 --- a/t/t1504-ceiling-dirs.sh +++ b/t/t1504-ceiling-dirs.sh @@ -9,8 +9,9 @@ test_prefix() { } test_fail() { - test_expect_code 128 "$1: prefix" \ - "git rev-parse --show-prefix" + test_expect_success "$1: prefix" ' + test_expect_code 128 git rev-parse --show-prefix + ' } TRASH_ROOT="$PWD" diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index 8c8dfdaf9f..a4555510c3 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -85,7 +85,7 @@ test_expect_success 'merge my-side@{u} records the correct name' ' git branch -t new my-side@{u} && git merge -s ours new@{u} && git show -s --pretty=format:%s >actual && - echo "Merge remote branch ${sq}origin/side${sq}" >expect && + echo "Merge remote-tracking branch ${sq}origin/side${sq}" >expect && test_cmp expect actual ) ' diff --git a/t/t2006-checkout-index-basic.sh b/t/t2006-checkout-index-basic.sh new file mode 100755 index 0000000000..b8559838b1 --- /dev/null +++ b/t/t2006-checkout-index-basic.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +test_description='basic checkout-index tests +' + +. ./test-lib.sh + +test_expect_success 'checkout-index --gobbledegook' ' + test_expect_code 129 git checkout-index --gobbledegook 2>err && + grep "[Uu]sage" err +' + +test_expect_success 'checkout-index -h in broken repository' ' + mkdir broken && + ( + cd broken && + git init && + >.git/index && + test_expect_code 129 git checkout-index -h >usage 2>&1 + ) && + grep "[Uu]sage" broken/usage +' + +test_done diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh index a74ee227b8..e6f59f1914 100755 --- a/t/t2007-checkout-symlink.sh +++ b/t/t2007-checkout-symlink.sh @@ -17,7 +17,7 @@ test_expect_success SYMLINKS setup ' git branch side && echo goodbye >nitfol && - git add nitfol + git add nitfol && test_tick && git commit -m "master adds file nitfol" && diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh index a463b13b27..9cd0ac4ba3 100755 --- a/t/t2016-checkout-patch.sh +++ b/t/t2016-checkout-patch.sh @@ -32,7 +32,7 @@ test_expect_success PERL 'git checkout -p' ' ' test_expect_success PERL 'git checkout -p with staged changes' ' - set_state dir/foo work index + set_state dir/foo work index && (echo n; echo y) | git checkout -p && verify_saved_state bar && verify_state dir/foo index index diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh index 2d2f63f22e..0e3b8582f2 100755 --- a/t/t2017-checkout-orphan.sh +++ b/t/t2017-checkout-orphan.sh @@ -14,7 +14,7 @@ TEST_FILE=foo test_expect_success 'Setup' ' echo "Initial" >"$TEST_FILE" && git add "$TEST_FILE" && - git commit -m "First Commit" + git commit -m "First Commit" && test_tick && echo "State 1" >>"$TEST_FILE" && git add "$TEST_FILE" && diff --git a/t/t2050-git-dir-relative.sh b/t/t2050-git-dir-relative.sh index b7131d8c08..21f4659a9d 100755 --- a/t/t2050-git-dir-relative.sh +++ b/t/t2050-git-dir-relative.sh @@ -26,7 +26,7 @@ chmod +x .git/hooks/post-commit' test_expect_success 'post-commit hook used ordinarily' ' echo initial >top && -git add top +git add top && git commit -m initial && test -r "${COMMIT_FILE}" ' @@ -45,7 +45,7 @@ test -r "${COMMIT_FILE}" rm -rf "${COMMIT_FILE}" test_expect_success 'post-commit-hook from sub dir' ' -echo changed again >top +echo changed again >top && cd subdir && git --git-dir .git --work-tree .. add ../top && git --git-dir .git --work-tree .. commit -m subcommit && diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh index 76ad7c344c..c8bce8c2e4 100755 --- a/t/t2101-update-index-reupdate.sh +++ b/t/t2101-update-index-reupdate.sh @@ -51,7 +51,7 @@ test_expect_success 'update-index again' \ echo hello world >dir1/file3 && echo goodbye people >file2 && git update-index --add file2 dir1/file3 && - echo hello everybody >file2 + echo hello everybody >file2 && echo happy >dir1/file3 && git update-index --again && git ls-files -s >current && diff --git a/t/t2107-update-index-basic.sh b/t/t2107-update-index-basic.sh new file mode 100755 index 0000000000..33f8be0cd7 --- /dev/null +++ b/t/t2107-update-index-basic.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +test_description='basic update-index tests + +Tests for command-line parsing and basic operation. +' + +. ./test-lib.sh + +test_expect_success 'update-index --nonsense fails' ' + test_must_fail git update-index --nonsense 2>msg && + cat msg && + test -s msg +' + +test_expect_failure 'update-index --nonsense dumps usage' ' + test_expect_code 129 git update-index --nonsense 2>err && + grep "[Uu]sage: git update-index" err +' + +test_expect_success 'update-index -h with corrupt index' ' + mkdir broken && + ( + cd broken && + git init && + >.git/index && + test_expect_code 129 git update-index -h >usage 2>&1 + ) && + grep "[Uu]sage: git update-index" broken/usage +' + +test_done diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 2ad2819a34..0692427cb6 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -25,7 +25,7 @@ test_expect_success setup ' echo initial >dir1/sub2 && echo initial >dir2/sub3 && git add check dir1 dir2 top foo && - test_tick + test_tick && git commit -m initial && echo changed >check && diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index 6d2f2b67ee..c8fe978267 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -156,7 +156,7 @@ test_expect_success 'trailing slash in exclude allows directory match (2)' ' test_expect_success 'trailing slash in exclude forces directory match (1)' ' - >two + >two && git ls-files --others --exclude=two/ >output && grep "^two" output diff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh new file mode 100755 index 0000000000..490e052875 --- /dev/null +++ b/t/t3004-ls-files-basic.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +test_description='basic ls-files tests + +This test runs git ls-files with various unusual or malformed +command-line arguments. +' + +. ./test-lib.sh + +>empty + +test_expect_success 'ls-files in empty repository' ' + git ls-files >actual && + test_cmp empty actual +' + +test_expect_success 'ls-files with nonexistent path' ' + git ls-files doesnotexist >actual && + test_cmp empty actual +' + +test_expect_success 'ls-files with nonsense option' ' + test_expect_code 129 git ls-files --nonsense 2>actual && + grep "[Uu]sage: git ls-files" actual +' + +test_expect_success 'ls-files -h in corrupt repository' ' + mkdir broken && + ( + cd broken && + git init && + >.git/index && + test_expect_code 129 git ls-files -h >usage 2>&1 + ) && + grep "[Uu]sage: git ls-files " broken/usage +' + +test_done diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index e66e550b24..34794f8a70 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -25,6 +25,10 @@ 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 && echo hello >>a && cp a d/e && @@ -255,7 +259,16 @@ test_expect_success 'setup 8' ' git mv a e && git add e && test_tick && - git commit -m "rename a->e" + 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" + fi ' test_expect_success 'setup 9' ' @@ -544,7 +557,7 @@ test_expect_success 'reset and bind merge' ' echo "100644 $o0 0 c" echo "100644 $o1 0 d/e" ) >expected && - test_cmp expected actual + test_cmp expected actual && git read-tree --prefix=z/ master && git ls-files -s >actual && @@ -615,4 +628,26 @@ test_expect_success 'merge-recursive copy vs. rename' ' test_cmp expected actual ' +if test_have_prereq SYMLINKS +then + test_expect_success '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 "100644 blob $o0 b" + echo "100644 blob $o0 c" + echo "100644 blob $o0 d/e" + echo "100644 blob $o0 e" + 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_done diff --git a/t/t3050-subprojects-fetch.sh b/t/t3050-subprojects-fetch.sh index 4261e9641e..2f5f41a012 100755 --- a/t/t3050-subprojects-fetch.sh +++ b/t/t3050-subprojects-fetch.sh @@ -10,10 +10,10 @@ test_expect_success setup ' cd sub && git init && >subfile && - git add subfile + git add subfile && git commit -m "subproject commit #1" ) && - >mainfile + >mainfile && git add sub mainfile && test_tick && git commit -m "superproject commit #1" diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index f54a533456..f308235f5d 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -26,6 +26,17 @@ test_expect_success \ ! test -f .git/refs/heads/--help ' +test_expect_success 'branch -h in broken repository' ' + mkdir broken && + ( + cd broken && + git init && + >.git/refs/heads/master && + test_expect_code 129 git branch -h >usage 2>&1 + ) && + grep "[Uu]sage" broken/usage +' + test_expect_success \ 'git branch abc should create a branch' \ 'git branch abc && test -f .git/refs/heads/abc' diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 809d1c4ed4..6028748c6c 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -12,13 +12,13 @@ test_expect_success 'make commits' ' ' test_expect_success 'make branches' ' - git branch branch-one + git branch branch-one && git branch branch-two HEAD^ ' test_expect_success 'make remote branches' ' - git update-ref refs/remotes/origin/branch-one branch-one - git update-ref refs/remotes/origin/branch-two branch-two + git update-ref refs/remotes/origin/branch-one branch-one && + git update-ref refs/remotes/origin/branch-two branch-two && git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/branch-one ' diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index f39a261d80..5e29a05259 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -43,8 +43,8 @@ test_expect_success TABS_IN_FILENAMES 'git ls-files no-funny' \ test_cmp expected current' test_expect_success TABS_IN_FILENAMES 'setup expect' ' -t0=`git write-tree` -echo "$t0" >t0 +t0=`git write-tree` && +echo "$t0" >t0 && cat > expected <<\EOF just space @@ -69,8 +69,8 @@ test_expect_success TABS_IN_FILENAMES 'git ls-files -z with-funny' \ test_cmp expected current' test_expect_success TABS_IN_FILENAMES 'setup expect' ' -t1=`git write-tree` -echo "$t1" >t1 +t1=`git write-tree` && +echo "$t1" >t1 && cat > expected <<\EOF just space diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index a2b79a0430..dc2e04a016 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -52,7 +52,7 @@ test_expect_success 'refusing to edit notes in refs/remotes/' ' # 1 indicates caught gracefully by die, 128 means git-show barked test_expect_success 'handle empty notes gracefully' ' - git notes show ; test 1 = $? + test_expect_code 1 git notes show ' test_expect_success 'show non-existent notes entry with %N' ' @@ -627,16 +627,16 @@ test_expect_success '--show-notes=ref accumulates' ' test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' ' git config core.notesRef refs/notes/other && - echo "Note on a tree" > expect + echo "Note on a tree" > expect && git notes add -m "Note on a tree" HEAD: && git notes show HEAD: > actual && test_cmp expect actual && - echo "Note on a blob" > expect + echo "Note on a blob" > expect && filename=$(git ls-tree --name-only HEAD | head -n1) && git notes add -m "Note on a blob" HEAD:$filename && git notes show HEAD:$filename > actual && test_cmp expect actual && - echo "Note on a tag" > expect + echo "Note on a tag" > expect && git tag -a -m "This is an annotated tag" foobar HEAD^ && git notes add -m "Note on a tag" foobar && git notes show foobar > actual && @@ -962,6 +962,7 @@ Date: Thu Apr 7 15:27:13 2005 -0700 Notes (other): a fresh note +$whitespace another fresh note EOF @@ -983,8 +984,11 @@ Date: Thu Apr 7 15:27:13 2005 -0700 Notes (other): a fresh note +$whitespace another fresh note +$whitespace append 1 +$whitespace append 2 EOF @@ -1061,4 +1065,23 @@ test_expect_success 'git notes copy diagnoses too many or too few parameters' ' test_must_fail git notes copy one two three ' +test_expect_success 'git notes get-ref (no overrides)' ' + git config --unset core.notesRef && + unset GIT_NOTES_REF && + test "$(git notes get-ref)" = "refs/notes/commits" +' + +test_expect_success 'git notes get-ref (core.notesRef)' ' + git config core.notesRef refs/notes/foo && + test "$(git notes get-ref)" = "refs/notes/foo" +' + +test_expect_success 'git notes get-ref (GIT_NOTES_REF)' ' + test "$(GIT_NOTES_REF=refs/notes/bar git notes get-ref)" = "refs/notes/bar" +' + +test_expect_success 'git notes get-ref (--ref)' ' + test "$(GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref)" = "refs/notes/baz" +' + test_done diff --git a/t/t3303-notes-subtrees.sh b/t/t3303-notes-subtrees.sh index 75ec18778e..704aee81ef 100755 --- a/t/t3303-notes-subtrees.sh +++ b/t/t3303-notes-subtrees.sh @@ -168,15 +168,16 @@ INPUT_END } verify_concatenated_notes () { - git log | grep "^ " > output && - i=$number_of_commits && - while [ $i -gt 0 ]; do - echo " commit #$i" && - echo " first note for commit #$i" && - echo " second note for commit #$i" && - i=$(($i-1)); - done > expect && - test_cmp expect output + git log | grep "^ " > output && + i=$number_of_commits && + while [ $i -gt 0 ]; do + echo " commit #$i" && + echo " first note for commit #$i" && + echo " " && + echo " second note for commit #$i" && + i=$(($i-1)); + done > expect && + test_cmp expect output } test_expect_success 'test notes in no fanout concatenated with 2/38-fanout' 'test_concatenated_notes "s|^..|&/|" ""' diff --git a/t/t3307-notes-man.sh b/t/t3307-notes-man.sh index 3269f2eebd..2ea3be6546 100755 --- a/t/t3307-notes-man.sh +++ b/t/t3307-notes-man.sh @@ -26,7 +26,7 @@ test_expect_success 'example 1: notes to add an Acked-by line' ' ' test_expect_success 'example 2: binary notes' ' - cp "$TEST_DIRECTORY"/test4012.png . + cp "$TEST_DIRECTORY"/test4012.png . && git checkout B && blob=$(git hash-object -w test4012.png) && git notes --ref=logo add -C "$blob" && diff --git a/t/t3308-notes-merge.sh b/t/t3308-notes-merge.sh new file mode 100755 index 0000000000..24d82b49bb --- /dev/null +++ b/t/t3308-notes-merge.sh @@ -0,0 +1,368 @@ +#!/bin/sh +# +# Copyright (c) 2010 Johan Herland +# + +test_description='Test merging of notes trees' + +. ./test-lib.sh + +test_expect_success setup ' + test_commit 1st && + test_commit 2nd && + test_commit 3rd && + test_commit 4th && + test_commit 5th && + # Create notes on 4 first commits + git config core.notesRef refs/notes/x && + git notes add -m "Notes on 1st commit" 1st && + git notes add -m "Notes on 2nd commit" 2nd && + git notes add -m "Notes on 3rd commit" 3rd && + git notes add -m "Notes on 4th commit" 4th +' + +commit_sha1=$(git rev-parse 1st^{commit}) +commit_sha2=$(git rev-parse 2nd^{commit}) +commit_sha3=$(git rev-parse 3rd^{commit}) +commit_sha4=$(git rev-parse 4th^{commit}) +commit_sha5=$(git rev-parse 5th^{commit}) + +verify_notes () { + notes_ref="$1" + git -c core.notesRef="refs/notes/$notes_ref" notes | + sort >"output_notes_$notes_ref" && + test_cmp "expect_notes_$notes_ref" "output_notes_$notes_ref" && + git -c core.notesRef="refs/notes/$notes_ref" log --format="%H %s%n%N" \ + >"output_log_$notes_ref" && + test_cmp "expect_log_$notes_ref" "output_log_$notes_ref" +} + +cat <<EOF | sort >expect_notes_x +5e93d24084d32e1cb61f7070505b9d2530cca987 $commit_sha4 +8366731eeee53787d2bdf8fc1eff7d94757e8da0 $commit_sha3 +eede89064cd42441590d6afec6c37b321ada3389 $commit_sha2 +daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1 +EOF + +cat >expect_log_x <<EOF +$commit_sha5 5th + +$commit_sha4 4th +Notes on 4th commit + +$commit_sha3 3rd +Notes on 3rd commit + +$commit_sha2 2nd +Notes on 2nd commit + +$commit_sha1 1st +Notes on 1st commit + +EOF + +test_expect_success 'verify initial notes (x)' ' + verify_notes x +' + +cp expect_notes_x expect_notes_y +cp expect_log_x expect_log_y + +test_expect_success 'fail to merge empty notes ref into empty notes ref (z => y)' ' + test_must_fail git -c "core.notesRef=refs/notes/y" notes merge z +' + +test_expect_success 'fail to merge into various non-notes refs' ' + test_must_fail git -c "core.notesRef=refs/notes" notes merge x && + test_must_fail git -c "core.notesRef=refs/notes/" notes merge x && + mkdir -p .git/refs/notes/dir && + test_must_fail git -c "core.notesRef=refs/notes/dir" notes merge x && + test_must_fail git -c "core.notesRef=refs/notes/dir/" notes merge x && + test_must_fail git -c "core.notesRef=refs/heads/master" notes merge x && + test_must_fail git -c "core.notesRef=refs/notes/y:" notes merge x && + test_must_fail git -c "core.notesRef=refs/notes/y:foo" notes merge x && + test_must_fail git -c "core.notesRef=refs/notes/foo^{bar" notes merge x +' + +test_expect_success 'fail to merge various non-note-trees' ' + git config core.notesRef refs/notes/y && + test_must_fail git notes merge refs/notes && + test_must_fail git notes merge refs/notes/ && + test_must_fail git notes merge refs/notes/dir && + test_must_fail git notes merge refs/notes/dir/ && + test_must_fail git notes merge refs/heads/master && + test_must_fail git notes merge x: && + test_must_fail git notes merge x:foo && + test_must_fail git notes merge foo^{bar +' + +test_expect_success 'merge notes into empty notes ref (x => y)' ' + git config core.notesRef refs/notes/y && + git notes merge x && + verify_notes y && + # x and y should point to the same notes commit + test "$(git rev-parse refs/notes/x)" = "$(git rev-parse refs/notes/y)" +' + +test_expect_success 'merge empty notes ref (z => y)' ' + git notes merge z && + # y should not change (still == x) + test "$(git rev-parse refs/notes/x)" = "$(git rev-parse refs/notes/y)" +' + +test_expect_success 'change notes on other notes ref (y)' ' + # Not touching notes to 1st commit + git notes remove 2nd && + git notes append -m "More notes on 3rd commit" 3rd && + git notes add -f -m "New notes on 4th commit" 4th && + git notes add -m "Notes on 5th commit" 5th +' + +test_expect_success 'merge previous notes commit (y^ => y) => No-op' ' + pre_state="$(git rev-parse refs/notes/y)" && + git notes merge y^ && + # y should not move + test "$pre_state" = "$(git rev-parse refs/notes/y)" +' + +cat <<EOF | sort >expect_notes_y +0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 +dec2502dac3ea161543f71930044deff93fa945c $commit_sha4 +4069cdb399fd45463ec6eef8e051a16a03592d91 $commit_sha3 +daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1 +EOF + +cat >expect_log_y <<EOF +$commit_sha5 5th +Notes on 5th commit + +$commit_sha4 4th +New notes on 4th commit + +$commit_sha3 3rd +Notes on 3rd commit + +More notes on 3rd commit + +$commit_sha2 2nd + +$commit_sha1 1st +Notes on 1st commit + +EOF + +test_expect_success 'verify changed notes on other notes ref (y)' ' + verify_notes y +' + +test_expect_success 'verify unchanged notes on original notes ref (x)' ' + verify_notes x +' + +test_expect_success 'merge original notes (x) into changed notes (y) => No-op' ' + git notes merge -vvv x && + verify_notes y && + verify_notes x +' + +cp expect_notes_y expect_notes_x +cp expect_log_y expect_log_x + +test_expect_success 'merge changed (y) into original (x) => Fast-forward' ' + git config core.notesRef refs/notes/x && + git notes merge y && + verify_notes x && + verify_notes y && + # x and y should point to same the notes commit + test "$(git rev-parse refs/notes/x)" = "$(git rev-parse refs/notes/y)" +' + +test_expect_success 'merge empty notes ref (z => y)' ' + # Prepare empty (but valid) notes ref (z) + git config core.notesRef refs/notes/z && + git notes add -m "foo" && + git notes remove && + git notes >output_notes_z && + test_cmp /dev/null output_notes_z && + # Do the merge (z => y) + git config core.notesRef refs/notes/y && + git notes merge z && + verify_notes y && + # y should no longer point to the same notes commit as x + test "$(git rev-parse refs/notes/x)" != "$(git rev-parse refs/notes/y)" +' + +cat <<EOF | sort >expect_notes_y +0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 +dec2502dac3ea161543f71930044deff93fa945c $commit_sha4 +4069cdb399fd45463ec6eef8e051a16a03592d91 $commit_sha3 +d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 +43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1 +EOF + +cat >expect_log_y <<EOF +$commit_sha5 5th +Notes on 5th commit + +$commit_sha4 4th +New notes on 4th commit + +$commit_sha3 3rd +Notes on 3rd commit + +More notes on 3rd commit + +$commit_sha2 2nd +New notes on 2nd commit + +$commit_sha1 1st +Notes on 1st commit + +More notes on 1st commit + +EOF + +test_expect_success 'change notes on other notes ref (y)' ' + # Append to 1st commit notes + git notes append -m "More notes on 1st commit" 1st && + # Add new notes to 2nd commit + git notes add -m "New notes on 2nd commit" 2nd && + verify_notes y +' + +cat <<EOF | sort >expect_notes_x +0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 +1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4 +daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1 +EOF + +cat >expect_log_x <<EOF +$commit_sha5 5th +Notes on 5th commit + +$commit_sha4 4th +New notes on 4th commit + +More notes on 4th commit + +$commit_sha3 3rd + +$commit_sha2 2nd + +$commit_sha1 1st +Notes on 1st commit + +EOF + +test_expect_success 'change notes on notes ref (x)' ' + git config core.notesRef refs/notes/x && + git notes remove 3rd && + git notes append -m "More notes on 4th commit" 4th && + verify_notes x +' + +cat <<EOF | sort >expect_notes_x +0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 +1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4 +d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 +43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1 +EOF + +cat >expect_log_x <<EOF +$commit_sha5 5th +Notes on 5th commit + +$commit_sha4 4th +New notes on 4th commit + +More notes on 4th commit + +$commit_sha3 3rd + +$commit_sha2 2nd +New notes on 2nd commit + +$commit_sha1 1st +Notes on 1st commit + +More notes on 1st commit + +EOF + +test_expect_success 'merge y into x => Non-conflicting 3-way merge' ' + git notes merge y && + verify_notes x && + verify_notes y +' + +cat <<EOF | sort >expect_notes_w +05a4927951bcef347f51486575b878b2b60137f2 $commit_sha3 +d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 +EOF + +cat >expect_log_w <<EOF +$commit_sha5 5th + +$commit_sha4 4th + +$commit_sha3 3rd +New notes on 3rd commit + +$commit_sha2 2nd +New notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'create notes on new, separate notes ref (w)' ' + git config core.notesRef refs/notes/w && + # Add same note as refs/notes/y on 2nd commit + git notes add -m "New notes on 2nd commit" 2nd && + # Add new note on 3rd commit (non-conflicting) + git notes add -m "New notes on 3rd commit" 3rd && + # Verify state of notes on new, separate notes ref (w) + verify_notes w +' + +cat <<EOF | sort >expect_notes_x +0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 +1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4 +05a4927951bcef347f51486575b878b2b60137f2 $commit_sha3 +d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 +43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1 +EOF + +cat >expect_log_x <<EOF +$commit_sha5 5th +Notes on 5th commit + +$commit_sha4 4th +New notes on 4th commit + +More notes on 4th commit + +$commit_sha3 3rd +New notes on 3rd commit + +$commit_sha2 2nd +New notes on 2nd commit + +$commit_sha1 1st +Notes on 1st commit + +More notes on 1st commit + +EOF + +test_expect_success 'merge w into x => Non-conflicting history-less merge' ' + git config core.notesRef refs/notes/x && + git notes merge w && + # Verify new state of notes on other notes ref (x) + verify_notes x && + # Also verify that nothing changed on other notes refs (y and w) + verify_notes y && + verify_notes w +' + +test_done diff --git a/t/t3309-notes-merge-auto-resolve.sh b/t/t3309-notes-merge-auto-resolve.sh new file mode 100755 index 0000000000..461fd84755 --- /dev/null +++ b/t/t3309-notes-merge-auto-resolve.sh @@ -0,0 +1,647 @@ +#!/bin/sh +# +# Copyright (c) 2010 Johan Herland +# + +test_description='Test notes merging with auto-resolving strategies' + +. ./test-lib.sh + +# Set up a notes merge scenario with all kinds of potential conflicts +test_expect_success 'setup commits' ' + test_commit 1st && + test_commit 2nd && + test_commit 3rd && + test_commit 4th && + test_commit 5th && + test_commit 6th && + test_commit 7th && + test_commit 8th && + test_commit 9th && + test_commit 10th && + test_commit 11th && + test_commit 12th && + test_commit 13th && + test_commit 14th && + test_commit 15th +' + +commit_sha1=$(git rev-parse 1st^{commit}) +commit_sha2=$(git rev-parse 2nd^{commit}) +commit_sha3=$(git rev-parse 3rd^{commit}) +commit_sha4=$(git rev-parse 4th^{commit}) +commit_sha5=$(git rev-parse 5th^{commit}) +commit_sha6=$(git rev-parse 6th^{commit}) +commit_sha7=$(git rev-parse 7th^{commit}) +commit_sha8=$(git rev-parse 8th^{commit}) +commit_sha9=$(git rev-parse 9th^{commit}) +commit_sha10=$(git rev-parse 10th^{commit}) +commit_sha11=$(git rev-parse 11th^{commit}) +commit_sha12=$(git rev-parse 12th^{commit}) +commit_sha13=$(git rev-parse 13th^{commit}) +commit_sha14=$(git rev-parse 14th^{commit}) +commit_sha15=$(git rev-parse 15th^{commit}) + +verify_notes () { + notes_ref="$1" + suffix="$2" + git -c core.notesRef="refs/notes/$notes_ref" notes | + sort >"output_notes_$suffix" && + test_cmp "expect_notes_$suffix" "output_notes_$suffix" && + git -c core.notesRef="refs/notes/$notes_ref" log --format="%H %s%n%N" \ + >"output_log_$suffix" && + test_cmp "expect_log_$suffix" "output_log_$suffix" +} + +test_expect_success 'setup merge base (x)' ' + git config core.notesRef refs/notes/x && + git notes add -m "x notes on 6th commit" 6th && + git notes add -m "x notes on 7th commit" 7th && + git notes add -m "x notes on 8th commit" 8th && + git notes add -m "x notes on 9th commit" 9th && + git notes add -m "x notes on 10th commit" 10th && + git notes add -m "x notes on 11th commit" 11th && + git notes add -m "x notes on 12th commit" 12th && + git notes add -m "x notes on 13th commit" 13th && + git notes add -m "x notes on 14th commit" 14th && + git notes add -m "x notes on 15th commit" 15th +' + +cat <<EOF | sort >expect_notes_x +457a85d6c814ea208550f15fcc48f804ac8dc023 $commit_sha15 +b0c95b954301d69da2bc3723f4cb1680d355937c $commit_sha14 +5d30216a129eeffa97d9694ffe8c74317a560315 $commit_sha13 +dd161bc149470fd890dd4ab52a4cbd79bbd18c36 $commit_sha12 +7abbc45126d680336fb24294f013a7cdfa3ed545 $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +20c613c835011c48a5abe29170a2402ca6354910 $commit_sha9 +a3daf8a1e4e5dc3409a303ad8481d57bfea7f5d6 $commit_sha8 +897003322b53bc6ca098e9324ee508362347e734 $commit_sha7 +11d97fdebfa5ceee540a3da07bce6fa0222bc082 $commit_sha6 +EOF + +cat >expect_log_x <<EOF +$commit_sha15 15th +x notes on 15th commit + +$commit_sha14 14th +x notes on 14th commit + +$commit_sha13 13th +x notes on 13th commit + +$commit_sha12 12th +x notes on 12th commit + +$commit_sha11 11th +x notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th +x notes on 9th commit + +$commit_sha8 8th +x notes on 8th commit + +$commit_sha7 7th +x notes on 7th commit + +$commit_sha6 6th +x notes on 6th commit + +$commit_sha5 5th + +$commit_sha4 4th + +$commit_sha3 3rd + +$commit_sha2 2nd + +$commit_sha1 1st + +EOF + +test_expect_success 'verify state of merge base (x)' 'verify_notes x x' + +test_expect_success 'setup local branch (y)' ' + git update-ref refs/notes/y refs/notes/x && + git config core.notesRef refs/notes/y && + git notes add -f -m "y notes on 3rd commit" 3rd && + git notes add -f -m "y notes on 4th commit" 4th && + git notes add -f -m "y notes on 5th commit" 5th && + git notes remove 6th && + git notes remove 7th && + git notes remove 8th && + git notes add -f -m "y notes on 12th commit" 12th && + git notes add -f -m "y notes on 13th commit" 13th && + git notes add -f -m "y notes on 14th commit" 14th && + git notes add -f -m "y notes on 15th commit" 15th +' + +cat <<EOF | sort >expect_notes_y +68b8630d25516028bed862719855b3d6768d7833 $commit_sha15 +5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 +3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 +a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 +7abbc45126d680336fb24294f013a7cdfa3ed545 $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +20c613c835011c48a5abe29170a2402ca6354910 $commit_sha9 +154508c7a0bcad82b6fe4b472bc4c26b3bf0825b $commit_sha5 +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +EOF + +cat >expect_log_y <<EOF +$commit_sha15 15th +y notes on 15th commit + +$commit_sha14 14th +y notes on 14th commit + +$commit_sha13 13th +y notes on 13th commit + +$commit_sha12 12th +y notes on 12th commit + +$commit_sha11 11th +x notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th +x notes on 9th commit + +$commit_sha8 8th + +$commit_sha7 7th + +$commit_sha6 6th + +$commit_sha5 5th +y notes on 5th commit + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd + +$commit_sha1 1st + +EOF + +test_expect_success 'verify state of local branch (y)' 'verify_notes y y' + +test_expect_success 'setup remote branch (z)' ' + git update-ref refs/notes/z refs/notes/x && + git config core.notesRef refs/notes/z && + git notes add -f -m "z notes on 2nd commit" 2nd && + git notes add -f -m "y notes on 4th commit" 4th && + git notes add -f -m "z notes on 5th commit" 5th && + git notes remove 6th && + git notes add -f -m "z notes on 8th commit" 8th && + git notes remove 9th && + git notes add -f -m "z notes on 11th commit" 11th && + git notes remove 12th && + git notes add -f -m "y notes on 14th commit" 14th && + git notes add -f -m "z notes on 15th commit" 15th +' + +cat <<EOF | sort >expect_notes_z +9b4b2c61f0615412da3c10f98ff85b57c04ec765 $commit_sha15 +5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 +5d30216a129eeffa97d9694ffe8c74317a560315 $commit_sha13 +7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 +897003322b53bc6ca098e9324ee508362347e734 $commit_sha7 +99fc34adfc400b95c67b013115e37e31aa9a6d23 $commit_sha5 +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +EOF + +cat >expect_log_z <<EOF +$commit_sha15 15th +z notes on 15th commit + +$commit_sha14 14th +y notes on 14th commit + +$commit_sha13 13th +x notes on 13th commit + +$commit_sha12 12th + +$commit_sha11 11th +z notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th + +$commit_sha8 8th +z notes on 8th commit + +$commit_sha7 7th +x notes on 7th commit + +$commit_sha6 6th + +$commit_sha5 5th +z notes on 5th commit + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'verify state of remote branch (z)' 'verify_notes z z' + +# At this point, before merging z into y, we have the following status: +# +# commit | base/x | local/y | remote/z | diff from x to y/z | result +# -------|---------|---------|----------|----------------------------|------- +# 1st | [none] | [none] | [none] | unchanged / unchanged | [none] +# 2nd | [none] | [none] | 283b482 | unchanged / added | 283b482 +# 3rd | [none] | 5772f42 | [none] | added / unchanged | 5772f42 +# 4th | [none] | e2bfd06 | e2bfd06 | added / added (same) | e2bfd06 +# 5th | [none] | 154508c | 99fc34a | added / added (diff) | ??? +# 6th | 11d97fd | [none] | [none] | removed / removed | [none] +# 7th | 8970033 | [none] | 8970033 | removed / unchanged | [none] +# 8th | a3daf8a | [none] | 851e163 | removed / changed | ??? +# 9th | 20c613c | 20c613c | [none] | unchanged / removed | [none] +# 10th | b8d03e1 | b8d03e1 | b8d03e1 | unchanged / unchanged | b8d03e1 +# 11th | 7abbc45 | 7abbc45 | 7e3c535 | unchanged / changed | 7e3c535 +# 12th | dd161bc | a66055f | [none] | changed / removed | ??? +# 13th | 5d30216 | 3a631fd | 5d30216 | changed / unchanged | 3a631fd +# 14th | b0c95b9 | 5de7ea7 | 5de7ea7 | changed / changed (same) | 5de7ea7 +# 15th | 457a85d | 68b8630 | 9b4b2c6 | changed / changed (diff) | ??? + +test_expect_success 'merge z into y with invalid strategy => Fail/No changes' ' + git config core.notesRef refs/notes/y && + test_must_fail git notes merge --strategy=foo z && + # Verify no changes (y) + verify_notes y y +' + +cat <<EOF | sort >expect_notes_ours +68b8630d25516028bed862719855b3d6768d7833 $commit_sha15 +5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 +3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 +a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 +7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +154508c7a0bcad82b6fe4b472bc4c26b3bf0825b $commit_sha5 +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +EOF + +cat >expect_log_ours <<EOF +$commit_sha15 15th +y notes on 15th commit + +$commit_sha14 14th +y notes on 14th commit + +$commit_sha13 13th +y notes on 13th commit + +$commit_sha12 12th +y notes on 12th commit + +$commit_sha11 11th +z notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th + +$commit_sha8 8th + +$commit_sha7 7th + +$commit_sha6 6th + +$commit_sha5 5th +y notes on 5th commit + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'merge z into y with "ours" strategy => Non-conflicting 3-way merge' ' + git notes merge --strategy=ours z && + verify_notes y ours +' + +test_expect_success 'reset to pre-merge state (y)' ' + git update-ref refs/notes/y refs/notes/y^1 && + # Verify pre-merge state + verify_notes y y +' + +cat <<EOF | sort >expect_notes_theirs +9b4b2c61f0615412da3c10f98ff85b57c04ec765 $commit_sha15 +5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 +3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 +7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 +99fc34adfc400b95c67b013115e37e31aa9a6d23 $commit_sha5 +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +EOF + +cat >expect_log_theirs <<EOF +$commit_sha15 15th +z notes on 15th commit + +$commit_sha14 14th +y notes on 14th commit + +$commit_sha13 13th +y notes on 13th commit + +$commit_sha12 12th + +$commit_sha11 11th +z notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th + +$commit_sha8 8th +z notes on 8th commit + +$commit_sha7 7th + +$commit_sha6 6th + +$commit_sha5 5th +z notes on 5th commit + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'merge z into y with "theirs" strategy => Non-conflicting 3-way merge' ' + git notes merge --strategy=theirs z && + verify_notes y theirs +' + +test_expect_success 'reset to pre-merge state (y)' ' + git update-ref refs/notes/y refs/notes/y^1 && + # Verify pre-merge state + verify_notes y y +' + +cat <<EOF | sort >expect_notes_union +7c4e546efd0fe939f876beb262ece02797880b54 $commit_sha15 +5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 +3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 +a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 +7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 +6c841cc36ea496027290967ca96bd2bef54dbb47 $commit_sha5 +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +EOF + +cat >expect_log_union <<EOF +$commit_sha15 15th +y notes on 15th commit + +z notes on 15th commit + +$commit_sha14 14th +y notes on 14th commit + +$commit_sha13 13th +y notes on 13th commit + +$commit_sha12 12th +y notes on 12th commit + +$commit_sha11 11th +z notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th + +$commit_sha8 8th +z notes on 8th commit + +$commit_sha7 7th + +$commit_sha6 6th + +$commit_sha5 5th +y notes on 5th commit + +z notes on 5th commit + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'merge z into y with "union" strategy => Non-conflicting 3-way merge' ' + git notes merge --strategy=union z && + verify_notes y union +' + +test_expect_success 'reset to pre-merge state (y)' ' + git update-ref refs/notes/y refs/notes/y^1 && + # Verify pre-merge state + verify_notes y y +' + +cat <<EOF | sort >expect_notes_union2 +d682107b8bf7a7aea1e537a8d5cb6a12b60135f1 $commit_sha15 +5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 +3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 +a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 +7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 +357b6ca14c7afd59b7f8b8aaaa6b8b723771135b $commit_sha5 +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +EOF + +cat >expect_log_union2 <<EOF +$commit_sha15 15th +z notes on 15th commit + +y notes on 15th commit + +$commit_sha14 14th +y notes on 14th commit + +$commit_sha13 13th +y notes on 13th commit + +$commit_sha12 12th +y notes on 12th commit + +$commit_sha11 11th +z notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th + +$commit_sha8 8th +z notes on 8th commit + +$commit_sha7 7th + +$commit_sha6 6th + +$commit_sha5 5th +z notes on 5th commit + +y notes on 5th commit + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'merge y into z with "union" strategy => Non-conflicting 3-way merge' ' + git config core.notesRef refs/notes/z && + git notes merge --strategy=union y && + verify_notes z union2 +' + +test_expect_success 'reset to pre-merge state (z)' ' + git update-ref refs/notes/z refs/notes/z^1 && + # Verify pre-merge state + verify_notes z z +' + +cat <<EOF | sort >expect_notes_cat_sort_uniq +6be90240b5f54594203e25d9f2f64b7567175aee $commit_sha15 +5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 +3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 +a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 +7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 +b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 +851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 +660311d7f78dc53db12ac373a43fca7465381a7e $commit_sha5 +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +EOF + +cat >expect_log_cat_sort_uniq <<EOF +$commit_sha15 15th +y notes on 15th commit +z notes on 15th commit + +$commit_sha14 14th +y notes on 14th commit + +$commit_sha13 13th +y notes on 13th commit + +$commit_sha12 12th +y notes on 12th commit + +$commit_sha11 11th +z notes on 11th commit + +$commit_sha10 10th +x notes on 10th commit + +$commit_sha9 9th + +$commit_sha8 8th +z notes on 8th commit + +$commit_sha7 7th + +$commit_sha6 6th + +$commit_sha5 5th +y notes on 5th commit +z notes on 5th commit + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'merge y into z with "cat_sort_uniq" strategy => Non-conflicting 3-way merge' ' + git notes merge --strategy=cat_sort_uniq y && + verify_notes z cat_sort_uniq +' + +test_done diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh new file mode 100755 index 0000000000..4ec4d11450 --- /dev/null +++ b/t/t3310-notes-merge-manual-resolve.sh @@ -0,0 +1,556 @@ +#!/bin/sh +# +# Copyright (c) 2010 Johan Herland +# + +test_description='Test notes merging with manual conflict resolution' + +. ./test-lib.sh + +# Set up a notes merge scenario with different kinds of conflicts +test_expect_success 'setup commits' ' + test_commit 1st && + test_commit 2nd && + test_commit 3rd && + test_commit 4th && + test_commit 5th +' + +commit_sha1=$(git rev-parse 1st^{commit}) +commit_sha2=$(git rev-parse 2nd^{commit}) +commit_sha3=$(git rev-parse 3rd^{commit}) +commit_sha4=$(git rev-parse 4th^{commit}) +commit_sha5=$(git rev-parse 5th^{commit}) + +verify_notes () { + notes_ref="$1" + git -c core.notesRef="refs/notes/$notes_ref" notes | + sort >"output_notes_$notes_ref" && + test_cmp "expect_notes_$notes_ref" "output_notes_$notes_ref" && + git -c core.notesRef="refs/notes/$notes_ref" log --format="%H %s%n%N" \ + >"output_log_$notes_ref" && + test_cmp "expect_log_$notes_ref" "output_log_$notes_ref" +} + +cat <<EOF | sort >expect_notes_x +6e8e3febca3c2bb896704335cc4d0c34cb2f8715 $commit_sha4 +e5388c10860456ee60673025345fe2e153eb8cf8 $commit_sha3 +ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2 +EOF + +cat >expect_log_x <<EOF +$commit_sha5 5th + +$commit_sha4 4th +x notes on 4th commit + +$commit_sha3 3rd +x notes on 3rd commit + +$commit_sha2 2nd +x notes on 2nd commit + +$commit_sha1 1st + +EOF + +test_expect_success 'setup merge base (x)' ' + git config core.notesRef refs/notes/x && + git notes add -m "x notes on 2nd commit" 2nd && + git notes add -m "x notes on 3rd commit" 3rd && + git notes add -m "x notes on 4th commit" 4th && + verify_notes x +' + +cat <<EOF | sort >expect_notes_y +e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +b0a6021ec006d07e80e9b20ec9b444cbd9d560d3 $commit_sha1 +EOF + +cat >expect_log_y <<EOF +$commit_sha5 5th + +$commit_sha4 4th +y notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd + +$commit_sha1 1st +y notes on 1st commit + +EOF + +test_expect_success 'setup local branch (y)' ' + git update-ref refs/notes/y refs/notes/x && + git config core.notesRef refs/notes/y && + git notes add -f -m "y notes on 1st commit" 1st && + git notes remove 2nd && + git notes add -f -m "y notes on 3rd commit" 3rd && + git notes add -f -m "y notes on 4th commit" 4th && + verify_notes y +' + +cat <<EOF | sort >expect_notes_z +cff59c793c20bb49a4e01bc06fb06bad642e0d54 $commit_sha4 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +0a81da8956346e19bcb27a906f04af327e03e31b $commit_sha1 +EOF + +cat >expect_log_z <<EOF +$commit_sha5 5th + +$commit_sha4 4th +z notes on 4th commit + +$commit_sha3 3rd + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st +z notes on 1st commit + +EOF + +test_expect_success 'setup remote branch (z)' ' + git update-ref refs/notes/z refs/notes/x && + git config core.notesRef refs/notes/z && + git notes add -f -m "z notes on 1st commit" 1st && + git notes add -f -m "z notes on 2nd commit" 2nd && + git notes remove 3rd && + git notes add -f -m "z notes on 4th commit" 4th && + verify_notes z +' + +# At this point, before merging z into y, we have the following status: +# +# commit | base/x | local/y | remote/z | diff from x to y/z +# -------|---------|---------|----------|--------------------------- +# 1st | [none] | b0a6021 | 0a81da8 | added / added (diff) +# 2nd | ceefa67 | [none] | 283b482 | removed / changed +# 3rd | e5388c1 | 5772f42 | [none] | changed / removed +# 4th | 6e8e3fe | e2bfd06 | cff59c7 | changed / changed (diff) +# 5th | [none] | [none] | [none] | [none] + +cat <<EOF | sort >expect_conflicts +$commit_sha1 +$commit_sha2 +$commit_sha3 +$commit_sha4 +EOF + +cat >expect_conflict_$commit_sha1 <<EOF +<<<<<<< refs/notes/m +y notes on 1st commit +======= +z notes on 1st commit +>>>>>>> refs/notes/z +EOF + +cat >expect_conflict_$commit_sha2 <<EOF +z notes on 2nd commit +EOF + +cat >expect_conflict_$commit_sha3 <<EOF +y notes on 3rd commit +EOF + +cat >expect_conflict_$commit_sha4 <<EOF +<<<<<<< refs/notes/m +y notes on 4th commit +======= +z notes on 4th commit +>>>>>>> refs/notes/z +EOF + +cp expect_notes_y expect_notes_m +cp expect_log_y expect_log_m + +git rev-parse refs/notes/y > pre_merge_y +git rev-parse refs/notes/z > pre_merge_z + +test_expect_success 'merge z into m (== y) with default ("manual") resolver => Conflicting 3-way merge' ' + git update-ref refs/notes/m refs/notes/y && + git config core.notesRef refs/notes/m && + test_must_fail git notes merge z >output && + # Output should point to where to resolve conflicts + grep -q "\\.git/NOTES_MERGE_WORKTREE" output && + # Inspect merge conflicts + ls .git/NOTES_MERGE_WORKTREE >output_conflicts && + test_cmp expect_conflicts output_conflicts && + ( for f in $(cat expect_conflicts); do + test_cmp "expect_conflict_$f" ".git/NOTES_MERGE_WORKTREE/$f" || + exit 1 + done ) && + # Verify that current notes tree (pre-merge) has not changed (m == y) + verify_notes y && + verify_notes m && + test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" +' + +cat <<EOF | sort >expect_notes_z +00494adecf2d9635a02fa431308d67993f853968 $commit_sha4 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +0a81da8956346e19bcb27a906f04af327e03e31b $commit_sha1 +EOF + +cat >expect_log_z <<EOF +$commit_sha5 5th + +$commit_sha4 4th +z notes on 4th commit + +More z notes on 4th commit + +$commit_sha3 3rd + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st +z notes on 1st commit + +EOF + +test_expect_success 'change notes in z' ' + git notes --ref z append -m "More z notes on 4th commit" 4th && + verify_notes z +' + +test_expect_success 'cannot do merge w/conflicts when previous merge is unfinished' ' + test -d .git/NOTES_MERGE_WORKTREE && + test_must_fail git notes merge z >output 2>&1 && + # Output should indicate what is wrong + grep -q "\\.git/NOTES_MERGE_\\* exists" output +' + +# Setup non-conflicting merge between x and new notes ref w + +cat <<EOF | sort >expect_notes_w +ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2 +f75d1df88cbfe4258d49852f26cfc83f2ad4494b $commit_sha1 +EOF + +cat >expect_log_w <<EOF +$commit_sha5 5th + +$commit_sha4 4th + +$commit_sha3 3rd + +$commit_sha2 2nd +x notes on 2nd commit + +$commit_sha1 1st +w notes on 1st commit + +EOF + +test_expect_success 'setup unrelated notes ref (w)' ' + git config core.notesRef refs/notes/w && + git notes add -m "w notes on 1st commit" 1st && + git notes add -m "x notes on 2nd commit" 2nd && + verify_notes w +' + +cat <<EOF | sort >expect_notes_w +6e8e3febca3c2bb896704335cc4d0c34cb2f8715 $commit_sha4 +e5388c10860456ee60673025345fe2e153eb8cf8 $commit_sha3 +ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2 +f75d1df88cbfe4258d49852f26cfc83f2ad4494b $commit_sha1 +EOF + +cat >expect_log_w <<EOF +$commit_sha5 5th + +$commit_sha4 4th +x notes on 4th commit + +$commit_sha3 3rd +x notes on 3rd commit + +$commit_sha2 2nd +x notes on 2nd commit + +$commit_sha1 1st +w notes on 1st commit + +EOF + +test_expect_success 'can do merge without conflicts even if previous merge is unfinished (x => w)' ' + test -d .git/NOTES_MERGE_WORKTREE && + git notes merge x && + verify_notes w && + # Verify that other notes refs has not changed (x and y) + verify_notes x && + verify_notes y +' + +cat <<EOF | sort >expect_notes_m +021faa20e931fb48986ffc6282b4bb05553ac946 $commit_sha4 +5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +0a59e787e6d688aa6309e56e8c1b89431a0fc1c1 $commit_sha1 +EOF + +cat >expect_log_m <<EOF +$commit_sha5 5th + +$commit_sha4 4th +y and z notes on 4th commit + +$commit_sha3 3rd +y notes on 3rd commit + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st +y and z notes on 1st commit + +EOF + +test_expect_success 'finalize conflicting merge (z => m)' ' + # Resolve conflicts and finalize merge + cat >.git/NOTES_MERGE_WORKTREE/$commit_sha1 <<EOF && +y and z notes on 1st commit +EOF + cat >.git/NOTES_MERGE_WORKTREE/$commit_sha4 <<EOF && +y and z notes on 4th commit +EOF + git notes merge --commit && + # No .git/NOTES_MERGE_* files left + test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && + test_cmp /dev/null output && + # Merge commit has pre-merge y and pre-merge z as parents + test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" && + test "$(git rev-parse refs/notes/m^2)" = "$(cat pre_merge_z)" && + # Merge commit mentions the notes refs merged + git log -1 --format=%B refs/notes/m > merge_commit_msg && + grep -q refs/notes/m merge_commit_msg && + grep -q refs/notes/z merge_commit_msg && + # Merge commit mentions conflicting notes + grep -q "Conflicts" merge_commit_msg && + ( for sha1 in $(cat expect_conflicts); do + grep -q "$sha1" merge_commit_msg || + exit 1 + done ) && + # Verify contents of merge result + verify_notes m && + # Verify that other notes refs has not changed (w, x, y and z) + verify_notes w && + verify_notes x && + verify_notes y && + verify_notes z +' + +cat >expect_conflict_$commit_sha4 <<EOF +<<<<<<< refs/notes/m +y notes on 4th commit +======= +z notes on 4th commit + +More z notes on 4th commit +>>>>>>> refs/notes/z +EOF + +cp expect_notes_y expect_notes_m +cp expect_log_y expect_log_m + +git rev-parse refs/notes/y > pre_merge_y +git rev-parse refs/notes/z > pre_merge_z + +test_expect_success 'redo merge of z into m (== y) with default ("manual") resolver => Conflicting 3-way merge' ' + git update-ref refs/notes/m refs/notes/y && + git config core.notesRef refs/notes/m && + test_must_fail git notes merge z >output && + # Output should point to where to resolve conflicts + grep -q "\\.git/NOTES_MERGE_WORKTREE" output && + # Inspect merge conflicts + ls .git/NOTES_MERGE_WORKTREE >output_conflicts && + test_cmp expect_conflicts output_conflicts && + ( for f in $(cat expect_conflicts); do + test_cmp "expect_conflict_$f" ".git/NOTES_MERGE_WORKTREE/$f" || + exit 1 + done ) && + # Verify that current notes tree (pre-merge) has not changed (m == y) + verify_notes y && + verify_notes m && + test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" +' + +test_expect_success 'abort notes merge' ' + git notes merge --abort && + # No .git/NOTES_MERGE_* files left + test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && + test_cmp /dev/null output && + # m has not moved (still == y) + test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" + # Verify that other notes refs has not changed (w, x, y and z) + verify_notes w && + verify_notes x && + verify_notes y && + verify_notes z +' + +git rev-parse refs/notes/y > pre_merge_y +git rev-parse refs/notes/z > pre_merge_z + +test_expect_success 'redo merge of z into m (== y) with default ("manual") resolver => Conflicting 3-way merge' ' + test_must_fail git notes merge z >output && + # Output should point to where to resolve conflicts + grep -q "\\.git/NOTES_MERGE_WORKTREE" output && + # Inspect merge conflicts + ls .git/NOTES_MERGE_WORKTREE >output_conflicts && + test_cmp expect_conflicts output_conflicts && + ( for f in $(cat expect_conflicts); do + test_cmp "expect_conflict_$f" ".git/NOTES_MERGE_WORKTREE/$f" || + exit 1 + done ) && + # Verify that current notes tree (pre-merge) has not changed (m == y) + verify_notes y && + verify_notes m && + test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" +' + +cat <<EOF | sort >expect_notes_m +304dfb4325cf243025b9957486eb605a9b51c199 $commit_sha5 +283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +0a59e787e6d688aa6309e56e8c1b89431a0fc1c1 $commit_sha1 +EOF + +cat >expect_log_m <<EOF +$commit_sha5 5th +new note on 5th commit + +$commit_sha4 4th + +$commit_sha3 3rd + +$commit_sha2 2nd +z notes on 2nd commit + +$commit_sha1 1st +y and z notes on 1st commit + +EOF + +test_expect_success 'add + remove notes in finalized merge (z => m)' ' + # Resolve one conflict + cat >.git/NOTES_MERGE_WORKTREE/$commit_sha1 <<EOF && +y and z notes on 1st commit +EOF + # Remove another conflict + rm .git/NOTES_MERGE_WORKTREE/$commit_sha4 && + # Remove a D/F conflict + rm .git/NOTES_MERGE_WORKTREE/$commit_sha3 && + # Add a new note + echo "new note on 5th commit" > .git/NOTES_MERGE_WORKTREE/$commit_sha5 && + # Finalize merge + git notes merge --commit && + # No .git/NOTES_MERGE_* files left + test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && + test_cmp /dev/null output && + # Merge commit has pre-merge y and pre-merge z as parents + test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" && + test "$(git rev-parse refs/notes/m^2)" = "$(cat pre_merge_z)" && + # Merge commit mentions the notes refs merged + git log -1 --format=%B refs/notes/m > merge_commit_msg && + grep -q refs/notes/m merge_commit_msg && + grep -q refs/notes/z merge_commit_msg && + # Merge commit mentions conflicting notes + grep -q "Conflicts" merge_commit_msg && + ( for sha1 in $(cat expect_conflicts); do + grep -q "$sha1" merge_commit_msg || + exit 1 + done ) && + # Verify contents of merge result + verify_notes m && + # Verify that other notes refs has not changed (w, x, y and z) + verify_notes w && + verify_notes x && + verify_notes y && + verify_notes z +' + +cp expect_notes_y expect_notes_m +cp expect_log_y expect_log_m + +test_expect_success 'redo merge of z into m (== y) with default ("manual") resolver => Conflicting 3-way merge' ' + git update-ref refs/notes/m refs/notes/y && + test_must_fail git notes merge z >output && + # Output should point to where to resolve conflicts + grep -q "\\.git/NOTES_MERGE_WORKTREE" output && + # Inspect merge conflicts + ls .git/NOTES_MERGE_WORKTREE >output_conflicts && + test_cmp expect_conflicts output_conflicts && + ( for f in $(cat expect_conflicts); do + test_cmp "expect_conflict_$f" ".git/NOTES_MERGE_WORKTREE/$f" || + exit 1 + done ) && + # Verify that current notes tree (pre-merge) has not changed (m == y) + verify_notes y && + verify_notes m && + test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" +' + +cp expect_notes_w expect_notes_m +cp expect_log_w expect_log_m + +test_expect_success 'reset notes ref m to somewhere else (w)' ' + git update-ref refs/notes/m refs/notes/w && + verify_notes m && + test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" +' + +test_expect_success 'fail to finalize conflicting merge if underlying ref has moved in the meantime (m != NOTES_MERGE_PARTIAL^1)' ' + # Resolve conflicts + cat >.git/NOTES_MERGE_WORKTREE/$commit_sha1 <<EOF && +y and z notes on 1st commit +EOF + cat >.git/NOTES_MERGE_WORKTREE/$commit_sha4 <<EOF && +y and z notes on 4th commit +EOF + # Fail to finalize merge + test_must_fail git notes merge --commit >output 2>&1 && + # .git/NOTES_MERGE_* must remain + test -f .git/NOTES_MERGE_PARTIAL && + test -f .git/NOTES_MERGE_REF && + test -f .git/NOTES_MERGE_WORKTREE/$commit_sha1 && + test -f .git/NOTES_MERGE_WORKTREE/$commit_sha2 && + test -f .git/NOTES_MERGE_WORKTREE/$commit_sha3 && + test -f .git/NOTES_MERGE_WORKTREE/$commit_sha4 && + # Refs are unchanged + test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" + test "$(git rev-parse refs/notes/y)" = "$(git rev-parse NOTES_MERGE_PARTIAL^1)" + test "$(git rev-parse refs/notes/m)" != "$(git rev-parse NOTES_MERGE_PARTIAL^1)" + # Mention refs/notes/m, and its current and expected value in output + grep -q "refs/notes/m" output && + grep -q "$(git rev-parse refs/notes/m)" output && + grep -q "$(git rev-parse NOTES_MERGE_PARTIAL^1)" output && + # Verify that other notes refs has not changed (w, x, y and z) + verify_notes w && + verify_notes x && + verify_notes y && + verify_notes z +' + +test_expect_success 'resolve situation by aborting the notes merge' ' + git notes merge --abort && + # No .git/NOTES_MERGE_* files left + test_must_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && + test_cmp /dev/null output && + # m has not moved (still == w) + test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" + # Verify that other notes refs has not changed (w, x, y and z) + verify_notes w && + verify_notes x && + verify_notes y && + verify_notes z +' + +test_done diff --git a/t/t3311-notes-merge-fanout.sh b/t/t3311-notes-merge-fanout.sh new file mode 100755 index 0000000000..93516ef67c --- /dev/null +++ b/t/t3311-notes-merge-fanout.sh @@ -0,0 +1,436 @@ +#!/bin/sh +# +# Copyright (c) 2010 Johan Herland +# + +test_description='Test notes merging at various fanout levels' + +. ./test-lib.sh + +verify_notes () { + notes_ref="$1" + commit="$2" + if test -f "expect_notes_$notes_ref" + then + git -c core.notesRef="refs/notes/$notes_ref" notes | + sort >"output_notes_$notes_ref" && + test_cmp "expect_notes_$notes_ref" "output_notes_$notes_ref" || + return 1 + fi && + git -c core.notesRef="refs/notes/$notes_ref" log --format="%H %s%n%N" \ + "$commit" >"output_log_$notes_ref" && + test_cmp "expect_log_$notes_ref" "output_log_$notes_ref" +} + +verify_fanout () { + notes_ref="$1" + # Expect entire notes tree to have a fanout == 1 + git rev-parse --quiet --verify "refs/notes/$notes_ref" >/dev/null && + git ls-tree -r --name-only "refs/notes/$notes_ref" | + while read path + do + case "$path" in + ??/??????????????????????????????????????) + : true + ;; + *) + echo "Invalid path \"$path\"" && + return 1 + ;; + esac + done +} + +verify_no_fanout () { + notes_ref="$1" + # Expect entire notes tree to have a fanout == 0 + git rev-parse --quiet --verify "refs/notes/$notes_ref" >/dev/null && + git ls-tree -r --name-only "refs/notes/$notes_ref" | + while read path + do + case "$path" in + ????????????????????????????????????????) + : true + ;; + *) + echo "Invalid path \"$path\"" && + return 1 + ;; + esac + done +} + +# Set up a notes merge scenario with different kinds of conflicts +test_expect_success 'setup a few initial commits with notes (notes ref: x)' ' + git config core.notesRef refs/notes/x && + for i in 1 2 3 4 5 + do + test_commit "commit$i" >/dev/null && + git notes add -m "notes for commit$i" || return 1 + done +' + +commit_sha1=$(git rev-parse commit1^{commit}) +commit_sha2=$(git rev-parse commit2^{commit}) +commit_sha3=$(git rev-parse commit3^{commit}) +commit_sha4=$(git rev-parse commit4^{commit}) +commit_sha5=$(git rev-parse commit5^{commit}) + +cat <<EOF | sort >expect_notes_x +aed91155c7a72c2188e781fdf40e0f3761b299db $commit_sha5 +99fab268f9d7ee7b011e091a436c78def8eeee69 $commit_sha4 +953c20ae26c7aa0b428c20693fe38bc687f9d1a9 $commit_sha3 +6358796131b8916eaa2dde6902642942a1cb37e1 $commit_sha2 +b02d459c32f0e68f2fe0981033bb34f38776ba47 $commit_sha1 +EOF + +cat >expect_log_x <<EOF +$commit_sha5 commit5 +notes for commit5 + +$commit_sha4 commit4 +notes for commit4 + +$commit_sha3 commit3 +notes for commit3 + +$commit_sha2 commit2 +notes for commit2 + +$commit_sha1 commit1 +notes for commit1 + +EOF + +test_expect_success 'sanity check (x)' ' + verify_notes x commit5 && + verify_no_fanout x +' + +num=300 + +cp expect_log_x expect_log_y + +test_expect_success 'Add a few hundred commits w/notes to trigger fanout (x -> y)' ' + git update-ref refs/notes/y refs/notes/x && + git config core.notesRef refs/notes/y && + i=5 && + while test $i -lt $num + do + i=$(($i + 1)) && + test_commit "commit$i" >/dev/null && + git notes add -m "notes for commit$i" || return 1 + done && + test "$(git rev-parse refs/notes/y)" != "$(git rev-parse refs/notes/x)" && + # Expected number of commits and notes + test $(git rev-list HEAD | wc -l) = $num && + test $(git notes list | wc -l) = $num && + # 5 first notes unchanged + verify_notes y commit5 +' + +test_expect_success 'notes tree has fanout (y)' 'verify_fanout y' + +test_expect_success 'No-op merge (already included) (x => y)' ' + git update-ref refs/notes/m refs/notes/y && + git config core.notesRef refs/notes/m && + git notes merge x && + test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/y)" +' + +test_expect_success 'Fast-forward merge (y => x)' ' + git update-ref refs/notes/m refs/notes/x && + git notes merge y && + test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/y)" +' + +cat <<EOF | sort >expect_notes_z +9f506ee70e20379d7f78204c77b334f43d77410d $commit_sha3 +23a47d6ea7d589895faf800752054818e1e7627b $commit_sha2 +b02d459c32f0e68f2fe0981033bb34f38776ba47 $commit_sha1 +EOF + +cat >expect_log_z <<EOF +$commit_sha5 commit5 + +$commit_sha4 commit4 + +$commit_sha3 commit3 +notes for commit3 + +appended notes for commit3 + +$commit_sha2 commit2 +new notes for commit2 + +$commit_sha1 commit1 +notes for commit1 + +EOF + +test_expect_success 'change some of the initial 5 notes (x -> z)' ' + git update-ref refs/notes/z refs/notes/x && + git config core.notesRef refs/notes/z && + git notes add -f -m "new notes for commit2" commit2 && + git notes append -m "appended notes for commit3" commit3 && + git notes remove commit4 && + git notes remove commit5 && + verify_notes z commit5 +' + +test_expect_success 'notes tree has no fanout (z)' 'verify_no_fanout z' + +cp expect_log_z expect_log_m + +test_expect_success 'successful merge without conflicts (y => z)' ' + git update-ref refs/notes/m refs/notes/z && + git config core.notesRef refs/notes/m && + git notes merge y && + verify_notes m commit5 && + # x/y/z unchanged + verify_notes x commit5 && + verify_notes y commit5 && + verify_notes z commit5 +' + +test_expect_success 'notes tree still has fanout after merge (m)' 'verify_fanout m' + +cat >expect_log_w <<EOF +$commit_sha5 commit5 + +$commit_sha4 commit4 +other notes for commit4 + +$commit_sha3 commit3 +other notes for commit3 + +$commit_sha2 commit2 +notes for commit2 + +$commit_sha1 commit1 +other notes for commit1 + +EOF + +test_expect_success 'introduce conflicting changes (y -> w)' ' + git update-ref refs/notes/w refs/notes/y && + git config core.notesRef refs/notes/w && + git notes add -f -m "other notes for commit1" commit1 && + git notes add -f -m "other notes for commit3" commit3 && + git notes add -f -m "other notes for commit4" commit4 && + git notes remove commit5 && + verify_notes w commit5 +' + +cat >expect_log_m <<EOF +$commit_sha5 commit5 + +$commit_sha4 commit4 +other notes for commit4 + +$commit_sha3 commit3 +other notes for commit3 + +$commit_sha2 commit2 +new notes for commit2 + +$commit_sha1 commit1 +other notes for commit1 + +EOF + +test_expect_success 'successful merge using "ours" strategy (z => w)' ' + git update-ref refs/notes/m refs/notes/w && + git config core.notesRef refs/notes/m && + git notes merge -s ours z && + verify_notes m commit5 && + # w/x/y/z unchanged + verify_notes w commit5 && + verify_notes x commit5 && + verify_notes y commit5 && + verify_notes z commit5 +' + +test_expect_success 'notes tree still has fanout after merge (m)' 'verify_fanout m' + +cat >expect_log_m <<EOF +$commit_sha5 commit5 + +$commit_sha4 commit4 + +$commit_sha3 commit3 +notes for commit3 + +appended notes for commit3 + +$commit_sha2 commit2 +new notes for commit2 + +$commit_sha1 commit1 +other notes for commit1 + +EOF + +test_expect_success 'successful merge using "theirs" strategy (z => w)' ' + git update-ref refs/notes/m refs/notes/w && + git notes merge -s theirs z && + verify_notes m commit5 && + # w/x/y/z unchanged + verify_notes w commit5 && + verify_notes x commit5 && + verify_notes y commit5 && + verify_notes z commit5 +' + +test_expect_success 'notes tree still has fanout after merge (m)' 'verify_fanout m' + +cat >expect_log_m <<EOF +$commit_sha5 commit5 + +$commit_sha4 commit4 +other notes for commit4 + +$commit_sha3 commit3 +other notes for commit3 + +notes for commit3 + +appended notes for commit3 + +$commit_sha2 commit2 +new notes for commit2 + +$commit_sha1 commit1 +other notes for commit1 + +EOF + +test_expect_success 'successful merge using "union" strategy (z => w)' ' + git update-ref refs/notes/m refs/notes/w && + git notes merge -s union z && + verify_notes m commit5 && + # w/x/y/z unchanged + verify_notes w commit5 && + verify_notes x commit5 && + verify_notes y commit5 && + verify_notes z commit5 +' + +test_expect_success 'notes tree still has fanout after merge (m)' 'verify_fanout m' + +cat >expect_log_m <<EOF +$commit_sha5 commit5 + +$commit_sha4 commit4 +other notes for commit4 + +$commit_sha3 commit3 +appended notes for commit3 +notes for commit3 +other notes for commit3 + +$commit_sha2 commit2 +new notes for commit2 + +$commit_sha1 commit1 +other notes for commit1 + +EOF + +test_expect_success 'successful merge using "cat_sort_uniq" strategy (z => w)' ' + git update-ref refs/notes/m refs/notes/w && + git notes merge -s cat_sort_uniq z && + verify_notes m commit5 && + # w/x/y/z unchanged + verify_notes w commit5 && + verify_notes x commit5 && + verify_notes y commit5 && + verify_notes z commit5 +' + +test_expect_success 'notes tree still has fanout after merge (m)' 'verify_fanout m' + +# We're merging z into w. Here are the conflicts we expect: +# +# commit | x -> w | x -> z | conflict? +# -------|-----------|-----------|---------- +# 1 | changed | unchanged | no, use w +# 2 | unchanged | changed | no, use z +# 3 | changed | changed | yes (w, then z in conflict markers) +# 4 | changed | deleted | yes (w) +# 5 | deleted | deleted | no, deleted + +test_expect_success 'fails to merge using "manual" strategy (z => w)' ' + git update-ref refs/notes/m refs/notes/w && + test_must_fail git notes merge z +' + +test_expect_success 'notes tree still has fanout after merge (m)' 'verify_fanout m' + +cat <<EOF | sort >expect_conflicts +$commit_sha3 +$commit_sha4 +EOF + +cat >expect_conflict_$commit_sha3 <<EOF +<<<<<<< refs/notes/m +other notes for commit3 +======= +notes for commit3 + +appended notes for commit3 +>>>>>>> refs/notes/z +EOF + +cat >expect_conflict_$commit_sha4 <<EOF +other notes for commit4 +EOF + +test_expect_success 'verify conflict entries (with no fanout)' ' + ls .git/NOTES_MERGE_WORKTREE >output_conflicts && + test_cmp expect_conflicts output_conflicts && + ( for f in $(cat expect_conflicts); do + test_cmp "expect_conflict_$f" ".git/NOTES_MERGE_WORKTREE/$f" || + exit 1 + done ) && + # Verify that current notes tree (pre-merge) has not changed (m == w) + test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" +' + +cat >expect_log_m <<EOF +$commit_sha5 commit5 + +$commit_sha4 commit4 +other notes for commit4 + +$commit_sha3 commit3 +other notes for commit3 + +appended notes for commit3 + +$commit_sha2 commit2 +new notes for commit2 + +$commit_sha1 commit1 +other notes for commit1 + +EOF + +test_expect_success 'resolve and finalize merge (z => w)' ' + cat >.git/NOTES_MERGE_WORKTREE/$commit_sha3 <<EOF && +other notes for commit3 + +appended notes for commit3 +EOF + git notes merge --commit && + verify_notes m commit5 && + # w/x/y/z unchanged + verify_notes w commit5 && + verify_notes x commit5 && + verify_notes y commit5 && + verify_notes z commit5 +' + +test_expect_success 'notes tree still has fanout after merge (m)' 'verify_fanout m' + +test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 7d20a74c5c..d3a3bd2679 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -7,34 +7,39 @@ test_description='git rebase interactive This test runs git rebase "interactively", by faking an edit, and verifies that the result still makes sense. + +Initial setup: + + one - two - three - four (conflict-branch) + / + A - B - C - D - E (master) + | \ + | F - G - H (branch1) + | \ + |\ I (branch2) + | \ + | J - K - L - M (no-conflict-branch) + \ + N - O - P (no-ff-branch) + + where A, B, D and G all touch file1, and one, two, three, four all + touch file "conflict". ' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh +test_cmp_rev () { + git rev-parse --verify "$1" >expect.rev && + git rev-parse --verify "$2" >actual.rev && + test_cmp expect.rev actual.rev +} + set_fake_editor -# Set up the repository like this: -# -# one - two - three - four (conflict-branch) -# / -# A - B - C - D - E (master) -# | \ -# | F - G - H (branch1) -# | \ -# |\ I (branch2) -# | \ -# | J - K - L - M (no-conflict-branch) -# \ -# N - O - P (no-ff-branch) -# -# where A, B, D and G all touch file1, and one, two, three, four all -# touch file "conflict". -# # WARNING: Modifications to the initial repository can change the SHA ID used # in the expect2 file for the 'stop on conflicting pick' test. - test_expect_success 'setup' ' test_commit A file1 && test_commit B file1 && @@ -46,22 +51,21 @@ test_expect_success 'setup' ' test_commit G file1 && test_commit H file5 && git checkout -b branch2 F && - test_commit I file6 + test_commit I file6 && git checkout -b conflict-branch A && - for n in one two three four - do - test_commit $n conflict - done && + test_commit one conflict && + test_commit two conflict && + test_commit three conflict && + test_commit four conflict && git checkout -b no-conflict-branch A && - for n in J K L M - do - test_commit $n file$n - done && + test_commit J fileJ && + test_commit K fileK && + test_commit L fileL && + test_commit M fileM && git checkout -b no-ff-branch A && - for n in N O P - do - test_commit $n file$n - done + test_commit N fileN && + test_commit O fileO && + test_commit P fileP ' # "exec" commands are ran with the user shell by default, but this may @@ -82,20 +86,12 @@ test_expect_success 'rebase -i with the exec command' ' test_path_is_file touch-one && test_path_is_file touch-two && test_path_is_missing touch-three " (should have stopped before)" && - test $(git rev-parse C) = $(git rev-parse HEAD) || { - echo "Stopped at wrong revision:" - echo "($(git describe --tags HEAD) instead of C)" - false - } && + test_cmp_rev C HEAD && git rebase --continue && test_path_is_file touch-three && test_path_is_file "touch-file name with spaces" && test_path_is_file touch-after-semicolon && - test $(git rev-parse master) = $(git rev-parse HEAD) || { - echo "Stopped at wrong revision:" - echo "($(git describe --tags HEAD) instead of master)" - false - } && + test_cmp_rev master HEAD && rm -f touch-* ' @@ -116,11 +112,7 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' ' export FAKE_LINES && test_must_fail git rebase -i HEAD^ ) && - test $(git rev-parse master^) = $(git rev-parse HEAD) || { - echo "Stopped at wrong revision:" - echo "($(git describe --tags HEAD) instead of master^)" - false - } && + test_cmp_rev master^ HEAD && git reset --hard && git rebase --continue ' @@ -584,7 +576,7 @@ test_expect_success 'do "noop" when there is nothing to cherry-pick' ' git checkout -b branch4 HEAD && GIT_EDITOR=: git commit --amend \ - --author="Somebody else <somebody@else.com>" + --author="Somebody else <somebody@else.com>" && test $(git rev-parse branch3) != $(git rev-parse branch4) && git rebase -i branch3 && test $(git rev-parse branch3) = $(git rev-parse branch4) @@ -599,7 +591,7 @@ test_expect_success 'submodule rebase setup' ' git add elif && git commit -m "submodule initial" ) && echo 1 >file1 && - git add file1 sub + git add file1 sub && test_tick && git commit -m "One" && echo 2 >file1 && @@ -655,6 +647,7 @@ test_expect_success 'rebase -i can copy notes' ' cat >expect <<EOF an earlier note + a note EOF diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index 85fc7c4af8..fe5f936988 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -43,20 +43,20 @@ test_expect_success 'rebase -m' ' ' test_expect_success 'rebase --stat' ' - git reset --hard start + git reset --hard start && git rebase --stat master >diffstat.txt && grep "^ fileX | *1 +$" diffstat.txt ' test_expect_success 'rebase w/config rebase.stat' ' - git reset --hard start + git reset --hard start && git config rebase.stat true && git rebase master >diffstat.txt && grep "^ fileX | *1 +$" diffstat.txt ' test_expect_success 'rebase -n overrides config rebase.stat config' ' - git reset --hard start + git reset --hard start && git config rebase.stat true && git rebase -n master >diffstat.txt && ! grep "^ fileX | *1 +$" diffstat.txt diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh index fbb3f2e0df..e573dc845b 100755 --- a/t/t3407-rebase-abort.sh +++ b/t/t3407-rebase-abort.sh @@ -72,6 +72,18 @@ testrebase() { test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) && test ! -d "$dotest" ' + + test_expect_success "rebase$type --abort does not update reflog" ' + cd "$work_dir" && + # Clean up the state from the previous one + git reset --hard pre-rebase && + git reflog show to-rebase > reflog_before && + test_must_fail git rebase$type master && + git rebase --abort && + git reflog show to-rebase > reflog_after && + test_cmp reflog_before reflog_after && + rm reflog_before reflog_after + ' } testrebase "" .git/rebase-apply diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh index 2062b858bb..6b84e6042a 100755 --- a/t/t3408-rebase-multi-line.sh +++ b/t/t3408-rebase-multi-line.sh @@ -16,7 +16,7 @@ test_expect_success setup ' git commit -a -m "A sample commit log message that has a long summary that spills over multiple lines. -But otherwise with a sane description." +But otherwise with a sane description." && git branch side && diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh index 74161a42ec..19341e5ca1 100755 --- a/t/t3409-rebase-preserve-merges.sh +++ b/t/t3409-rebase-preserve-merges.sh @@ -72,7 +72,7 @@ test_expect_success 'rebase -p fakes interactive rebase' ' 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 branch " | wc -l) + test 1 = $(git rev-list --all --pretty=oneline | grep "Merge remote-tracking branch " | wc -l) ) ' diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh index 5869061c5b..086c91c7b4 100755 --- a/t/t3412-rebase-root.sh +++ b/t/t3412-rebase-root.sh @@ -173,14 +173,14 @@ EOF test_expect_success 'pre-rebase hook stops rebase' ' git checkout -b stops1 other && test_must_fail git rebase --root --onto master && - test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1 + test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops1 && test 0 = $(git rev-list other...stops1 | wc -l) ' test_expect_success 'pre-rebase hook stops rebase -i' ' git checkout -b stops2 other && test_must_fail git rebase --root --onto master && - test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops2 + test "z$(git symbolic-ref HEAD)" = zrefs/heads/stops2 && test 0 = $(git rev-list other...stops2 | wc -l) ' diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index fd2184ce71..b38be8e937 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -14,6 +14,7 @@ test_expect_success setup ' git add . && test_tick && git commit -m "first commit" && + git tag first-commit && echo 3 >file3 && git add . && test_tick && @@ -21,7 +22,7 @@ test_expect_success setup ' git tag base ' -test_auto_fixup() { +test_auto_fixup () { git reset --hard base && echo 1 >file1 && git add -u && @@ -50,7 +51,7 @@ test_expect_success 'auto fixup (config)' ' test_must_fail test_auto_fixup final-fixup-config-false ' -test_auto_squash() { +test_auto_squash () { git reset --hard base && echo 1 >file1 && git add -u && @@ -94,4 +95,102 @@ test_expect_success 'misspelled auto squash' ' test 0 = $(git rev-list final-missquash...HEAD | wc -l) ' +test_expect_success 'auto squash that matches 2 commits' ' + git reset --hard base && + echo 4 >file4 && + git add file4 && + test_tick && + git commit -m "first new commit" && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "squash! first" && + git tag final-multisquash && + test_tick && + git rebase --autosquash -i HEAD~4 && + git log --oneline >actual && + test 4 = $(wc -l <actual) && + git diff --exit-code final-multisquash && + test 1 = "$(git cat-file blob HEAD^^:file1)" && + test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) && + test 1 = $(git cat-file commit HEAD | grep first | wc -l) +' + +test_expect_success 'auto squash that matches a commit after the squash' ' + git reset --hard base && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "squash! third" && + echo 4 >file4 && + git add file4 && + test_tick && + git commit -m "third commit" && + git tag final-presquash && + test_tick && + git rebase --autosquash -i HEAD~4 && + git log --oneline >actual && + test 5 = $(wc -l <actual) && + git diff --exit-code final-presquash && + test 0 = "$(git cat-file blob HEAD^^:file1)" && + test 1 = "$(git cat-file blob HEAD^:file1)" && + test 1 = $(git cat-file commit HEAD | grep third | wc -l) && + test 1 = $(git cat-file commit HEAD^ | grep third | wc -l) +' +test_expect_success 'auto squash that matches a sha1' ' + git reset --hard base && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "squash! $(git rev-parse --short HEAD^)" && + git tag final-shasquash && + test_tick && + git rebase --autosquash -i HEAD^^^ && + git log --oneline >actual && + test 3 = $(wc -l <actual) && + git diff --exit-code final-shasquash && + test 1 = "$(git cat-file blob HEAD^:file1)" && + test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l) +' + +test_expect_success 'auto squash that matches longer sha1' ' + git reset --hard base && + echo 1 >file1 && + git add -u && + test_tick && + git commit -m "squash! $(git rev-parse --short=11 HEAD^)" && + git tag final-longshasquash && + test_tick && + git rebase --autosquash -i HEAD^^^ && + git log --oneline >actual && + test 3 = $(wc -l <actual) && + git diff --exit-code final-longshasquash && + test 1 = "$(git cat-file blob HEAD^:file1)" && + test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l) +' + +test_auto_commit_flags () { + git reset --hard base && + echo 1 >file1 && + git add -u && + test_tick && + git commit --$1 first-commit && + git tag final-commit-$1 && + test_tick && + git rebase --autosquash -i HEAD^^^ && + git log --oneline >actual && + test 3 = $(wc -l <actual) && + git diff --exit-code final-commit-$1 && + test 1 = "$(git cat-file blob HEAD^:file1)" && + test $2 = $(git cat-file commit HEAD^ | grep first | wc -l) +} + +test_expect_success 'use commit --fixup' ' + test_auto_commit_flags fixup 1 +' + +test_expect_success 'use commit --squash' ' + test_auto_commit_flags squash 2 +' + test_done diff --git a/t/t3417-rebase-whitespace-fix.sh b/t/t3417-rebase-whitespace-fix.sh index 220a740ee8..1fb3e499b4 100755 --- a/t/t3417-rebase-whitespace-fix.sh +++ b/t/t3417-rebase-whitespace-fix.sh @@ -89,7 +89,7 @@ test_expect_success 'same, but do not remove trailing spaces' ' git config core.whitespace "-blank-at-eol" && git reset --hard HEAD^ && cp third file && git add file && git commit -m third && - git rebase --whitespace=fix HEAD^^ + git rebase --whitespace=fix HEAD^^ && git diff --exit-code HEAD^:file expect-second && test_cmp file third ' diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index bc7aedd048..043954422c 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -81,6 +81,16 @@ test_expect_success 'revert after renaming branch' ' ' +test_expect_success 'cherry-pick on stat-dirty working tree' ' + git clone . copy && + ( + cd copy && + git checkout initial && + test-chmtime +40 oops && + git cherry-pick added + ) +' + test_expect_success 'revert forbidden on dirty working tree' ' echo content >extra_file && diff --git a/t/t3504-cherry-pick-rerere.sh b/t/t3504-cherry-pick-rerere.sh index f7b3518a32..e6a64816ef 100755 --- a/t/t3504-cherry-pick-rerere.sh +++ b/t/t3504-cherry-pick-rerere.sh @@ -23,7 +23,7 @@ test_expect_success 'conflicting merge' ' test_expect_success 'fixup' ' echo foo-dev >foo && git add foo && test_tick && git commit -q -m 4 && - git reset --hard HEAD^ + git reset --hard HEAD^ && echo foo-dev >expect ' @@ -33,7 +33,7 @@ test_expect_success 'cherry-pick conflict' ' ' test_expect_success 'reconfigure' ' - git config rerere.enabled false + git config rerere.enabled false && git reset --hard ' diff --git a/t/t3509-cherry-pick-merge-df.sh b/t/t3509-cherry-pick-merge-df.sh index a5ccdbf8fc..948ca1bce6 100755 --- a/t/t3509-cherry-pick-merge-df.sh +++ b/t/t3509-cherry-pick-merge-df.sh @@ -32,4 +32,70 @@ test_expect_success SYMLINKS 'Cherry-pick succeeds with rename across D/F confli git cherry-pick branch ' +test_expect_success 'Setup rename with file on one side matching directory name on other' ' + git checkout --orphan nick-testcase && + git rm -rf . && + + >empty && + git add empty && + git commit -m "Empty file" && + + git checkout -b simple && + mv empty file && + mkdir empty && + mv file empty && + git add empty/file && + git commit -m "Empty file under empty dir" && + + echo content >newfile && + git add newfile && + git commit -m "New file" +' + +test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (resolve)' ' + git reset --hard && + git checkout -q nick-testcase^0 && + git cherry-pick --strategy=resolve simple +' + +test_expect_success 'Cherry-pick succeeds with was_a_dir/file -> was_a_dir (recursive)' ' + git reset --hard && + git checkout -q nick-testcase^0 && + git cherry-pick --strategy=recursive simple +' + +test_expect_success 'Setup rename with file on one side matching different dirname on other' ' + git reset --hard && + git checkout --orphan mergeme && + git rm -rf . && + + mkdir sub && + mkdir othersub && + echo content > sub/file && + echo foo > othersub/whatever && + git add -A && + git commit -m "Common commmit" && + + git rm -rf othersub && + git mv sub/file othersub && + git commit -m "Commit to merge" && + + git checkout -b newhead mergeme~1 && + >independent-change && + git add independent-change && + git commit -m "Completely unrelated change" +' + +test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds (resolve)' ' + git reset --hard && + git checkout -q newhead^0 && + git cherry-pick --strategy=resolve mergeme +' + +test_expect_success 'Cherry-pick with rename to different D/F conflict succeeds (recursive)' ' + git reset --hard && + git checkout -q newhead^0 && + git cherry-pick --strategy=recursive mergeme +' + test_done diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index 256c4c9701..c06a5ee766 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -133,4 +133,33 @@ do ' done +test_commit_autosquash_flags () { + H=$1 + flag=$2 + test_expect_success "commit --$flag with $H encoding" ' + git config i18n.commitencoding $H && + git checkout -b $H-$flag C0 && + echo $H >>F && + git commit -a -F "$TEST_DIRECTORY"/t3900/$H.txt && + test_tick && + echo intermediate stuff >>G && + git add G && + git commit -a -m "intermediate commit" && + test_tick && + echo $H $flag >>F && + git commit -a --$flag HEAD~1 $3 && + E=$(git cat-file commit '$H-$flag' | + sed -ne "s/^encoding //p") && + test "z$E" = "z$H" && + git config --unset-all i18n.commitencoding && + git rebase --autosquash -i HEAD^^^ && + git log --oneline >actual && + test 3 = $(wc -l <actual) + ' +} + +test_commit_autosquash_flags eucJP fixup + +test_commit_autosquash_flags ISO-2022-JP squash '-m "squash message"' + test_done diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh index 7d49469841..da82b655b3 100755 --- a/t/t3902-quoted.sh +++ b/t/t3902-quoted.sh @@ -36,19 +36,19 @@ for_each_name () { test_expect_success TABS_IN_FILENAMES 'setup' ' mkdir "$FN" && - for_each_name "echo initial >\"\$name\"" + for_each_name "echo initial >\"\$name\"" && git add . && git commit -q -m Initial && for_each_name "echo second >\"\$name\"" && - git commit -a -m Second + git commit -a -m Second && for_each_name "echo modified >\"\$name\"" ' test_expect_success TABS_IN_FILENAMES 'setup expected files' ' -cat >expect.quoted <<\EOF +cat >expect.quoted <<\EOF && Name "Name and a\nLF" "Name and an\tHT" diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 903a122efe..6fd560ccf1 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -157,7 +157,7 @@ EOF test_expect_success 'stash branch' ' echo foo > file && - git commit file -m first + git commit file -m first && echo bar > file && echo bar2 > file2 && git add file2 && @@ -255,7 +255,7 @@ test_expect_success 'stash rm and ignore' ' echo file >.gitignore && git stash save "rm and ignore" && test bar = "$(cat file)" && - test file = "$(cat .gitignore)" + test file = "$(cat .gitignore)" && git stash apply && ! test -r file && test file = "$(cat .gitignore)" @@ -268,7 +268,7 @@ test_expect_success 'stash rm and ignore (stage .gitignore)' ' git add .gitignore && git stash save "rm and ignore (stage .gitignore)" && test bar = "$(cat file)" && - ! test -r .gitignore + ! test -r .gitignore && git stash apply && ! test -r file && test file = "$(cat .gitignore)" diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh index d1819ca23a..1e7193ac0b 100755 --- a/t/t3904-stash-patch.sh +++ b/t/t3904-stash-patch.sh @@ -20,7 +20,7 @@ test_expect_success PERL 'setup' ' # note: bar sorts before dir, so the first 'n' is always to skip 'bar' test_expect_success PERL 'saying "n" does nothing' ' - set_state dir/foo work index + set_state dir/foo work index && (echo n; echo n) | test_must_fail git stash save -p && verify_state dir/foo work index && verify_saved_state bar diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index 73441a5165..9fb8ca06a8 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -205,8 +205,8 @@ test_expect_success \ 'rm -fr Z [A-Z][A-Z] && git read-tree $tree_A && git checkout-index -f -a && - git read-tree --reset $tree_O || return 1 - git update-index --refresh >/dev/null ;# this can exit non-zero + git read-tree --reset $tree_O && + test_must_fail git update-index --refresh -q && git diff-files >.test-a && cmp_diff_files_output .test-a .test-recursive-OA' @@ -215,8 +215,8 @@ test_expect_success \ 'rm -fr Z [A-Z][A-Z] && git read-tree $tree_B && git checkout-index -f -a && - git read-tree --reset $tree_O || return 1 - git update-index --refresh >/dev/null ;# this can exit non-zero + git read-tree --reset $tree_O && + test_must_fail git update-index --refresh -q && git diff-files >.test-a && cmp_diff_files_output .test-a .test-recursive-OB' @@ -225,8 +225,8 @@ test_expect_success \ 'rm -fr Z [A-Z][A-Z] && git read-tree $tree_B && git checkout-index -f -a && - git read-tree --reset $tree_A || return 1 - git update-index --refresh >/dev/null ;# this can exit non-zero + git read-tree --reset $tree_A && + test_must_fail git update-index --refresh -q && git diff-files >.test-a && cmp_diff_files_output .test-a .test-recursive-AB' diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh index e19ca65885..d79d9e1e71 100755 --- a/t/t4008-diff-break-rewrite.sh +++ b/t/t4008-diff-break-rewrite.sh @@ -155,7 +155,7 @@ test_expect_success \ git checkout-index -f -u -a && sed -e "s/git/GIT/" file0 >file1 && sed -e "s/git/GET/" file0 >file2 && - rm -f file0 + rm -f file0 && git update-index --add --remove file0 file1 file2' test_expect_success \ diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index a8736f7cbe..8622eb51c7 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -330,7 +330,7 @@ test_expect_success 'check space before tab in indent (space-before-tab: on)' ' test_expect_success 'check spaces as indentation (indent-with-non-tab: off)' ' - git config core.whitespace "-indent-with-non-tab" + git config core.whitespace "-indent-with-non-tab" && echo " foo ();" > x && git diff --check diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh index 61589853df..95a7ca7070 100755 --- a/t/t4017-diff-retval.sh +++ b/t/t4017-diff-retval.sh @@ -29,66 +29,49 @@ test_expect_success 'git diff --quiet -w HEAD^ HEAD' ' ' test_expect_success 'git diff-tree HEAD^ HEAD' ' - git diff-tree --exit-code HEAD^ HEAD - test $? = 1 + test_expect_code 1 git diff-tree --exit-code HEAD^ HEAD ' test_expect_success 'git diff-tree HEAD^ HEAD -- a' ' git diff-tree --exit-code HEAD^ HEAD -- a - test $? = 0 ' test_expect_success 'git diff-tree HEAD^ HEAD -- b' ' - git diff-tree --exit-code HEAD^ HEAD -- b - test $? = 1 + test_expect_code 1 git diff-tree --exit-code HEAD^ HEAD -- b ' test_expect_success 'echo HEAD | git diff-tree --stdin' ' - echo $(git rev-parse HEAD) | git diff-tree --exit-code --stdin - test $? = 1 + echo $(git rev-parse HEAD) | test_expect_code 1 git diff-tree --exit-code --stdin ' test_expect_success 'git diff-tree HEAD HEAD' ' git diff-tree --exit-code HEAD HEAD - test $? = 0 ' test_expect_success 'git diff-files' ' git diff-files --exit-code - test $? = 0 ' test_expect_success 'git diff-index --cached HEAD' ' git diff-index --exit-code --cached HEAD - test $? = 0 ' test_expect_success 'git diff-index --cached HEAD^' ' - git diff-index --exit-code --cached HEAD^ - test $? = 1 + test_expect_code 1 git diff-index --exit-code --cached HEAD^ ' test_expect_success 'git diff-index --cached HEAD^' ' echo text >>b && echo 3 >c && - git add . && { - git diff-index --exit-code --cached HEAD^ - test $? = 1 - } + git add . && + test_expect_code 1 git diff-index --exit-code --cached HEAD^ ' test_expect_success 'git diff-tree -Stext HEAD^ HEAD -- b' ' - git commit -m "text in b" && { - git diff-tree -p --exit-code -Stext HEAD^ HEAD -- b - test $? = 1 - } + git commit -m "text in b" && + test_expect_code 1 git diff-tree -p --exit-code -Stext HEAD^ HEAD -- b ' test_expect_success 'git diff-tree -Snot-found HEAD^ HEAD -- b' ' git diff-tree -p --exit-code -Snot-found HEAD^ HEAD -- b - test $? = 0 ' test_expect_success 'git diff-files' ' - echo 3 >>c && { - git diff-files --exit-code - test $? = 1 - } + echo 3 >>c && + test_expect_code 1 git diff-files --exit-code ' test_expect_success 'git diff-index --cached HEAD' ' - git update-index c && { - git diff-index --exit-code --cached HEAD - test $? = 1 - } + git update-index c && + test_expect_code 1 git diff-index --exit-code --cached HEAD ' test_expect_success '--check --exit-code returns 0 for no difference' ' @@ -100,30 +83,26 @@ test_expect_success '--check --exit-code returns 0 for no difference' ' test_expect_success '--check --exit-code returns 1 for a clean difference' ' echo "good" > a && - git diff --check --exit-code - test $? = 1 + test_expect_code 1 git diff --check --exit-code ' test_expect_success '--check --exit-code returns 3 for a dirty difference' ' echo "bad " >> a && - git diff --check --exit-code - test $? = 3 + test_expect_code 3 git diff --check --exit-code ' test_expect_success '--check with --no-pager returns 2 for dirty difference' ' - git --no-pager diff --check - test $? = 2 + test_expect_code 2 git --no-pager diff --check ' test_expect_success 'check should test not just the last line' ' echo "" >>a && - git --no-pager diff --check - test $? = 2 + test_expect_code 2 git --no-pager diff --check ' @@ -133,10 +112,8 @@ test_expect_success 'check detects leftover conflict markers' ' echo binary >>b && git commit -m "side" b && test_must_fail git merge master && - git add b && ( - git --no-pager diff --cached --check >test.out - test $? = 2 - ) && + git add b && + test_expect_code 2 git --no-pager diff --cached --check >test.out && test 3 = $(grep "conflict marker" test.out | wc -l) && git reset --hard ' @@ -146,19 +123,13 @@ test_expect_success 'check honors conflict marker length' ' echo ">>>>>>> boo" >>b && echo "======" >>a && git diff --check a && - ( - git diff --check b - test $? = 2 - ) && + test_expect_code 2 git diff --check b && git reset --hard && echo ">>>>>>>> boo" >>b && echo "========" >>a && git diff --check && echo "b conflict-marker-size=8" >.gitattributes && - ( - git diff --check b - test $? = 2 - ) && + test_expect_code 2 git diff --check b && git diff --check a && git reset --hard ' diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index f6d1f1ebab..3fa836f9d3 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -36,11 +36,12 @@ prepare_output () { git diff --color >output $grep_a "$blue_grep" output >error $grep_a -v "$blue_grep" output >normal + return 0 } test_expect_success default ' - prepare_output + prepare_output && grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -52,8 +53,8 @@ test_expect_success default ' test_expect_success 'without -trail' ' - git config core.whitespace -trail - prepare_output + git config core.whitespace -trail && + prepare_output && grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -65,9 +66,9 @@ test_expect_success 'without -trail' ' test_expect_success 'without -trail (attribute)' ' - git config --unset core.whitespace - echo "F whitespace=-trail" >.gitattributes - prepare_output + test_might_fail git config --unset core.whitespace && + echo "F whitespace=-trail" >.gitattributes && + prepare_output && grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -79,9 +80,9 @@ test_expect_success 'without -trail (attribute)' ' test_expect_success 'without -space' ' - rm -f .gitattributes - git config core.whitespace -space - prepare_output + rm -f .gitattributes && + git config core.whitespace -space && + prepare_output && grep Eight normal >/dev/null && grep HT normal >/dev/null && @@ -93,9 +94,9 @@ test_expect_success 'without -space' ' test_expect_success 'without -space (attribute)' ' - git config --unset core.whitespace - echo "F whitespace=-space" >.gitattributes - prepare_output + test_might_fail git config --unset core.whitespace && + echo "F whitespace=-space" >.gitattributes && + prepare_output && grep Eight normal >/dev/null && grep HT normal >/dev/null && @@ -107,9 +108,9 @@ test_expect_success 'without -space (attribute)' ' test_expect_success 'with indent-non-tab only' ' - rm -f .gitattributes - git config core.whitespace indent,-trailing,-space - prepare_output + rm -f .gitattributes && + git config core.whitespace indent,-trailing,-space && + prepare_output && grep Eight error >/dev/null && grep HT normal >/dev/null && @@ -121,9 +122,9 @@ test_expect_success 'with indent-non-tab only' ' test_expect_success 'with indent-non-tab only (attribute)' ' - git config --unset core.whitespace - echo "F whitespace=indent,-trailing,-space" >.gitattributes - prepare_output + test_might_fail git config --unset core.whitespace && + echo "F whitespace=indent,-trailing,-space" >.gitattributes && + prepare_output && grep Eight error >/dev/null && grep HT normal >/dev/null && @@ -135,9 +136,9 @@ test_expect_success 'with indent-non-tab only (attribute)' ' test_expect_success 'with cr-at-eol' ' - rm -f .gitattributes - git config core.whitespace cr-at-eol - prepare_output + rm -f .gitattributes && + git config core.whitespace cr-at-eol && + prepare_output && grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -149,9 +150,9 @@ test_expect_success 'with cr-at-eol' ' test_expect_success 'with cr-at-eol (attribute)' ' - git config --unset core.whitespace - echo "F whitespace=trailing,cr-at-eol" >.gitattributes - prepare_output + test_might_fail git config --unset core.whitespace && + echo "F whitespace=trailing,cr-at-eol" >.gitattributes && + prepare_output && grep Eight normal >/dev/null && grep HT error >/dev/null && @@ -178,12 +179,21 @@ test_expect_success 'trailing empty lines (2)' ' ' +test_expect_success 'checkdiff shows correct line number for trailing blank lines' ' + + printf "a\nb\n" > G && + git add G && + printf "x\nx\nx\na\nb\nc\n\n" > G && + [ "$(git diff --check -- G)" = "G:7: new blank line at EOF." ] + +' + test_expect_success 'do not color trailing cr in context' ' - git config --unset core.whitespace + test_might_fail git config --unset core.whitespace && rm -f .gitattributes && echo AAAQ | tr Q "\015" >G && git add G && - echo BBBQ | tr Q "\015" >>G + echo BBBQ | tr Q "\015" >>G && git diff --color G | tr "\015" Q >output && grep "BBB.*${blue_grep}Q" output && grep "AAA.*\[mQ" output diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh index 709b3231ca..886494b58f 100755 --- a/t/t4021-format-patch-numbered.sh +++ b/t/t4021-format-patch-numbered.sh @@ -95,7 +95,7 @@ test_expect_success 'format.numbered && --keep-subject' ' test_expect_success 'format.numbered = auto' ' - git config format.numbered auto + git config format.numbered auto && git format-patch --stdout HEAD~2 > patch5 && test_numbered patch5 diff --git a/t/t4026-color.sh b/t/t4026-color.sh index d5ccdd0cf8..3726a0e201 100755 --- a/t/t4026-color.sh +++ b/t/t4026-color.sh @@ -74,7 +74,6 @@ test_expect_success 'extra character after attribute' ' ' test_expect_success 'unknown color slots are ignored (diff)' ' - git config --unset diff.color.new git config color.diff.nosuchslotwilleverbedefined white && git diff --color ' diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index d99814ac64..241a74d2a2 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -316,11 +316,11 @@ test_expect_success 'git diff (empty submodule dir)' ' test_expect_success 'conflicted submodule setup' ' # 39 efs - c=fffffffffffffffffffffffffffffffffffffff + c=fffffffffffffffffffffffffffffffffffffff && ( - echo "000000 $_z40 0 sub" - echo "160000 1$c 1 sub" - echo "160000 2$c 2 sub" + echo "000000 $_z40 0 sub" && + echo "160000 1$c 1 sub" && + echo "160000 2$c 2 sub" && echo "160000 3$c 3 sub" ) | git update-index --index-info && echo >expect.nosub '\''diff --cc sub diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 3f3c7577ca..8096d8a337 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -6,8 +6,8 @@ test_description='word diff colors' test_expect_success setup ' - git config diff.color.old red - git config diff.color.new green + git config diff.color.old red && + git config diff.color.new green && git config diff.color.func magenta ' diff --git a/t/t4103-apply-binary.sh b/t/t4103-apply-binary.sh index 08ad6d8b9e..dbbf56cba9 100755 --- a/t/t4103-apply-binary.sh +++ b/t/t4103-apply-binary.sh @@ -50,11 +50,11 @@ test_expect_success 'setup' " " test_expect_success 'stat binary diff -- should not fail.' \ - 'git checkout master + 'git checkout master && git apply --stat --summary B.diff' test_expect_success 'stat binary diff (copy) -- should not fail.' \ - 'git checkout master + 'git checkout master && git apply --stat --summary C.diff' test_expect_success 'check binary diff -- should fail.' \ @@ -78,11 +78,11 @@ test_expect_success \ ' test_expect_success 'check binary diff with replacement.' \ - 'git checkout master + 'git checkout master && git apply --check --allow-binary-replacement BF.diff' test_expect_success 'check binary diff with replacement (copy).' \ - 'git checkout master + 'git checkout master && git apply --check --allow-binary-replacement CF.diff' # Now we start applying them. diff --git a/t/t4111-apply-subdir.sh b/t/t4111-apply-subdir.sh index a52d94ae21..7c398432ba 100755 --- a/t/t4111-apply-subdir.sh +++ b/t/t4111-apply-subdir.sh @@ -89,7 +89,7 @@ test_expect_success 'apply --index from subdir of toplevel' ' test_expect_success 'apply from .git dir' ' cp postimage expected && cp preimage .git/file && - cp preimage .git/objects/file + cp preimage .git/objects/file && ( cd .git && git apply "$patch" @@ -100,7 +100,7 @@ test_expect_success 'apply from .git dir' ' test_expect_success 'apply from subdir of .git dir' ' cp postimage expected && cp preimage .git/file && - cp preimage .git/objects/file + cp preimage .git/objects/file && ( cd .git/objects && git apply "$patch" diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh index 3c73a783a7..3d0384daa8 100755 --- a/t/t4119-apply-config.sh +++ b/t/t4119-apply-config.sh @@ -73,7 +73,7 @@ D=`pwd` test_expect_success 'apply --whitespace=strip in subdir' ' cd "$D" && - git config --unset-all apply.whitespace + git config --unset-all apply.whitespace && rm -f sub/file1 && cp saved sub/file1 && git update-index --refresh && diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh index 2b2d00b334..579c9e6105 100755 --- a/t/t4120-apply-popt.sh +++ b/t/t4120-apply-popt.sh @@ -56,4 +56,30 @@ test_expect_success 'apply with too large -p and fancy filename' ' grep "removing 3 leading" err ' +test_expect_success 'apply (-p2) diff, mode change only' ' + cat >patch.chmod <<-\EOF && + diff --git a/sub/file1 b/sub/file1 + old mode 100644 + new mode 100755 + EOF + chmod 644 file1 && + git apply -p2 patch.chmod && + test -x file1 +' + +test_expect_success 'apply (-p2) diff, rename' ' + cat >patch.rename <<-\EOF && + diff --git a/sub/file1 b/sub/file2 + similarity index 100% + rename from sub/file1 + rename to sub/file2 + EOF + echo A >expected && + + cp file1.saved file1 && + rm -f file2 && + git apply -p2 patch.rename && + test_cmp expected file2 +' + test_done diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index 8a676a5dcd..61bfc569c3 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -176,9 +176,8 @@ test_expect_success 'trailing whitespace & no newline at the end of file' ' ' test_expect_success 'blank at EOF with --whitespace=fix (1)' ' - : these can fail depending on what we did before - git config --unset core.whitespace - rm -f .gitattributes + test_might_fail git config --unset core.whitespace && + rm -f .gitattributes && { echo a; echo b; echo c; } >one && git add one && @@ -368,7 +367,7 @@ test_expect_success 'missing blanks at EOF must only match blank lines' ' git diff -- one >patch && echo a >one && - test_must_fail git apply patch + test_must_fail git apply patch && test_must_fail git apply --whitespace=fix patch && test_must_fail git apply --ignore-space-change --whitespace=fix patch ' @@ -419,7 +418,7 @@ test_expect_success 'same, but with CR-LF line endings && cr-at-eol set' ' printf "b\r\n" >>one && printf "c\r\n" >>one && cp one save-one && - printf " \r\n" >>one + printf " \r\n" >>one && git add one && printf "d\r\n" >>one && cp one expect && @@ -436,7 +435,7 @@ test_expect_success 'same, but with CR-LF line endings && cr-at-eol unset' ' printf "b\r\n" >>one && printf "c\r\n" >>one && cp one save-one && - printf " \r\n" >>one + printf " \r\n" >>one && git add one && cp one expect && printf "d\r\n" >>one && diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh index 77200c0b2d..972946c174 100755 --- a/t/t4127-apply-same-fn.sh +++ b/t/t4127-apply-same-fn.sh @@ -31,7 +31,7 @@ test_expect_success 'apply same filename with independent changes' ' ' test_expect_success 'apply same filename with overlapping changes' ' - git reset --hard + git reset --hard && modify "s/^d/z/" same_fn && git diff > patch0 && git add same_fn && @@ -44,8 +44,8 @@ test_expect_success 'apply same filename with overlapping changes' ' ' test_expect_success 'apply same new filename after rename' ' - git reset --hard - git mv same_fn new_fn + git reset --hard && + git mv same_fn new_fn && modify "s/^d/z/" new_fn && git add new_fn && git diff -M --cached > patch1 && @@ -58,12 +58,12 @@ test_expect_success 'apply same new filename after rename' ' ' test_expect_success 'apply same old filename after rename -- should fail.' ' - git reset --hard - git mv same_fn new_fn + git reset --hard && + git mv same_fn new_fn && modify "s/^d/z/" new_fn && git add new_fn && git diff -M --cached > patch1 && - git mv new_fn same_fn + git mv new_fn same_fn && modify "s/^e/y/" same_fn && git diff >> patch1 && git reset --hard && @@ -71,13 +71,13 @@ test_expect_success 'apply same old filename after rename -- should fail.' ' ' test_expect_success 'apply A->B (rename), C->A (rename), A->A -- should pass.' ' - git reset --hard - git mv same_fn new_fn + git reset --hard && + git mv same_fn new_fn && modify "s/^d/z/" new_fn && git add new_fn && git diff -M --cached > patch1 && git commit -m "a rename" && - git mv other_fn same_fn + git mv other_fn same_fn && modify "s/^e/y/" same_fn && git add same_fn && git diff -M --cached >> patch1 && diff --git a/t/t4130-apply-criss-cross-rename.sh b/t/t4130-apply-criss-cross-rename.sh index 7cfa2d6287..d173acde0f 100755 --- a/t/t4130-apply-criss-cross-rename.sh +++ b/t/t4130-apply-criss-cross-rename.sh @@ -44,7 +44,7 @@ test_expect_success 'criss-cross rename' ' git reset --hard && mv file1 tmp && mv file2 file1 && - mv file3 file2 + mv file3 file2 && mv tmp file3 && cp file1 file1-swapped && cp file2 file2-swapped && diff --git a/t/t4132-apply-removal.sh b/t/t4132-apply-removal.sh index bb1ffe3b6c..a2bc1cd37d 100755 --- a/t/t4132-apply-removal.sh +++ b/t/t4132-apply-removal.sh @@ -30,6 +30,7 @@ test_expect_success setup ' epocWest="1969-12-31 16:00:00.000000000 -0800" && epocGMT="1970-01-01 00:00:00.000000000 +0000" && epocEast="1970-01-01 09:00:00.000000000 +0900" && + epocWest2="1969-12-31 16:00:00 -08:00" && sed -e "s/TS0/$epocWest/" -e "s/TS1/$timeWest/" <c >createWest.patch && sed -e "s/TS0/$epocEast/" -e "s/TS1/$timeEast/" <c >createEast.patch && @@ -46,6 +47,7 @@ test_expect_success setup ' sed -e "s/TS0/$timeWest/" -e "s/TS1/$epocWest/" <d >removeWest.patch && sed -e "s/TS0/$timeEast/" -e "s/TS1/$epocEast/" <d >removeEast.patch && sed -e "s/TS0/$timeGMT/" -e "s/TS1/$epocGMT/" <d >removeGMT.patch && + sed -e "s/TS0/$timeWest/" -e "s/TS1/$epocWest2/" <d >removeWest2.patch && echo something >something && >empty diff --git a/t/t4133-apply-filenames.sh b/t/t4133-apply-filenames.sh index 34218071b6..94da99075c 100755 --- a/t/t4133-apply-filenames.sh +++ b/t/t4133-apply-filenames.sh @@ -8,7 +8,7 @@ test_description='git apply filename consistency check' . ./test-lib.sh test_expect_success setup ' - cat > bad1.patch <<EOF + cat > bad1.patch <<EOF && diff --git a/f b/f new file mode 100644 index 0000000..d00491f @@ -29,9 +29,9 @@ EOF ' test_expect_success 'apply diff with inconsistent filenames in headers' ' - test_must_fail git apply bad1.patch 2>err - grep "inconsistent new filename" err - test_must_fail git apply bad2.patch 2>err + test_must_fail git apply bad1.patch 2>err && + grep "inconsistent new filename" err && + test_must_fail git apply bad2.patch 2>err && grep "inconsistent old filename" err ' diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh index 1b82f93cff..0043930ca6 100755 --- a/t/t4134-apply-submodule.sh +++ b/t/t4134-apply-submodule.sh @@ -8,7 +8,7 @@ test_description='git apply submodule tests' . ./test-lib.sh test_expect_success setup ' - cat > create-sm.patch <<EOF + cat > create-sm.patch <<EOF && diff --git a/dir/sm b/dir/sm new file mode 160000 index 0000000..0123456 diff --git a/t/t4135-apply-weird-filenames.sh b/t/t4135-apply-weird-filenames.sh index 1e5aad57ab..bf5dc57286 100755 --- a/t/t4135-apply-weird-filenames.sh +++ b/t/t4135-apply-weird-filenames.sh @@ -72,4 +72,20 @@ test_expect_success 'whitespace-damaged traditional patch' ' test_cmp expected postimage.txt ' +test_expect_success 'traditional patch with colon in timezone' ' + echo postimage >expected && + reset_preimage && + rm -f "post image.txt" && + git apply "$vector/funny-tz.diff" && + test_cmp expected "post image.txt" +' + +test_expect_success 'traditional, whitespace-damaged, colon in timezone' ' + echo postimage >expected && + reset_preimage && + rm -f "post image.txt" && + git apply "$vector/damaged-tz.diff" && + test_cmp expected "post image.txt" +' + test_done diff --git a/t/t4135/damaged-tz.diff b/t/t4135/damaged-tz.diff new file mode 100644 index 0000000000..07aaf08370 --- /dev/null +++ b/t/t4135/damaged-tz.diff @@ -0,0 +1,5 @@ +diff -urN -X /usr/people/jes/exclude-linux linux-2.6.12-rc2-mm3-vanilla/post image.txt linux-2.6.12-rc2-mm3/post image.txt +--- linux-2.6.12-rc2-mm3-vanilla/post image.txt 1969-12-31 16:00:00 -08:00 ++++ linux-2.6.12-rc2-mm3/post image.txt 2005-04-12 02:14:06 -07:00 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4135/funny-tz.diff b/t/t4135/funny-tz.diff new file mode 100644 index 0000000000..998e3a867e --- /dev/null +++ b/t/t4135/funny-tz.diff @@ -0,0 +1,5 @@ +diff -urN -X /usr/people/jes/exclude-linux linux-2.6.12-rc2-mm3-vanilla/post image.txt linux-2.6.12-rc2-mm3/post image.txt +--- linux-2.6.12-rc2-mm3-vanilla/post image.txt 1969-12-31 16:00:00 -08:00 ++++ linux-2.6.12-rc2-mm3/post image.txt 2005-04-12 02:14:06 -07:00 +@@ -0,0 +1 @@ ++postimage diff --git a/t/t4150-am.sh b/t/t4150-am.sh index 1c3d8ed548..850fc96d1f 100755 --- a/t/t4150-am.sh +++ b/t/t4150-am.sh @@ -219,7 +219,7 @@ test_expect_success 'am stays in branch' ' test_expect_success 'am --signoff does not add Signed-off-by: line if already there' ' git format-patch --stdout HEAD^ >patch3 && - sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4 + sed -e "/^Subject/ s,\[PATCH,Re: Re: Re: & 1/5 v2," patch3 >patch4 && rm -fr .git/rebase-apply && git reset --hard && git checkout HEAD^ && diff --git a/t/t4201-shortlog.sh b/t/t4201-shortlog.sh index cdb70b4b33..6872ba1a42 100755 --- a/t/t4201-shortlog.sh +++ b/t/t4201-shortlog.sh @@ -35,7 +35,7 @@ test_expect_success 'setup' ' tr 1234 "\370\235\204\236")" a1 && echo 5 >a1 && - git commit --quiet -m "a 12 34 56 78" a1 + git commit --quiet -m "a 12 34 56 78" a1 && echo 6 >a1 && git commit --quiet -m "Commit by someone else" \ diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 2e51356947..2fcc31a6f3 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -191,7 +191,7 @@ test_expect_success 'git show <commits> leaves list of commits as given' ' test_expect_success 'setup case sensitivity tests' ' echo case >one && test_tick && - git add one + git add one && git commit -a -m Second ' @@ -341,7 +341,7 @@ test_expect_success 'set up more tangled history' ' test_commit octopus-b && git checkout master && test_commit seventh && - git merge octopus-a octopus-b + git merge octopus-a octopus-b && git merge reach ' @@ -393,7 +393,7 @@ test_expect_success 'log --graph with merge' ' ' test_expect_success 'log.decorate configuration' ' - git config --unset-all log.decorate || : + test_might_fail git config --unset-all log.decorate && git log --oneline >expect.none && git log --oneline --decorate >expect.short && @@ -422,6 +422,15 @@ test_expect_success 'log.decorate configuration' ' test_cmp expect.full actual && git config --unset-all log.decorate && + git config log.decorate 1 && + git log --oneline >actual && + test_cmp expect.short actual && + git log --oneline --decorate=full >actual && + test_cmp expect.full actual && + git log --oneline --decorate=no >actual && + test_cmp expect.none actual && + + git config --unset-all log.decorate && git config log.decorate short && git log --oneline >actual && test_cmp expect.short actual && diff --git a/t/t4252-am-options.sh b/t/t4252-am-options.sh index f603c1b133..e758e634a3 100755 --- a/t/t4252-am-options.sh +++ b/t/t4252-am-options.sh @@ -59,7 +59,7 @@ test_expect_success 'interrupted am --directory="frotz nitfol"' ' ' test_expect_success 'apply to a funny path' ' - with_sq="with'\''sq" + with_sq="with'\''sq" && rm -fr .git/rebase-apply && git reset --hard initial && git am --directory="$with_sq" "$tm"/am-test-5-2 && diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index bbb9c1251d..602806d09c 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -12,7 +12,7 @@ TRASH=`pwd` test_expect_success \ 'setup' \ - 'rm -f .git/index* + 'rm -f .git/index* && perl -e "print \"a\" x 4096;" > a && perl -e "print \"b\" x 4096;" > b && perl -e "print \"c\" x 4096;" > c && diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 0a24e61ff9..2fc5af6007 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -8,7 +8,7 @@ test_description='mmap sliding window tests' test_expect_success \ 'setup' \ - 'rm -f .git/index* + 'rm -f .git/index* && for i in a b c do echo $i >$i && @@ -48,7 +48,7 @@ test_expect_success \ git repack -a -d && test "`git count-objects`" = "0 objects, 0 kilobytes" && pack2=`ls .git/objects/pack/*.pack` && - test -f "$pack2" + test -f "$pack2" && test "$pack1" \!= "$pack2"' test_expect_success \ diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index fb3a270822..b34ea93a80 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -8,7 +8,7 @@ test_description='pack index with 64-bit offsets and object CRC' test_expect_success \ 'setup' \ - 'rm -rf .git + 'rm -rf .git && git init && git config pack.threads 1 && i=1 && diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index 5bcf0b867a..b0b2684a1f 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -129,7 +129,7 @@ test_expect_success 'denyNonFastforwards trumps --force' ' test "$victim_orig" = "$victim_head" ' -test_expect_success 'push --all excludes remote tracking hierarchy' ' +test_expect_success 'push --all excludes remote-tracking hierarchy' ' mkdir parent && ( cd parent && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 18376d6608..bafcca765e 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -91,7 +91,7 @@ test_expect_success 'setup' ' prev=$cur && cur=$(($cur+1)) done && - add B1 $A1 + add B1 $A1 && echo $ATIP > .git/refs/heads/A && echo $BTIP > .git/refs/heads/B && git symbolic-ref HEAD refs/heads/B diff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh index 1037a723fe..7a46cbdbe6 100755 --- a/t/t5502-quickfetch.sh +++ b/t/t5502-quickfetch.sh @@ -57,7 +57,7 @@ test_expect_success 'copy commit and tree but not blob by hand' ' cd cloned && git count-objects | sed -e "s/ *objects,.*//" ) ) && - test $cnt -eq 6 + test $cnt -eq 6 && blob=$(git rev-parse HEAD:file | sed -e "s|..|&/|") && test -f "cloned/.git/objects/$blob" && diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh index aa0ada0147..60de2d6ede 100755 --- a/t/t5503-tagfollow.sh +++ b/t/t5503-tagfollow.sh @@ -49,7 +49,7 @@ EOF ' test_expect_success NOT_MINGW 'fetch A (new commit : 1 connection)' ' - rm -f $U + rm -f $U && ( cd cloned && GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && @@ -82,7 +82,7 @@ EOF ' test_expect_success NOT_MINGW 'fetch C, T (new branch, tag : 1 connection)' ' - rm -f $U + rm -f $U && ( cd cloned && GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && @@ -121,7 +121,7 @@ EOF ' test_expect_success NOT_MINGW 'fetch B, S (commit and tag : 1 connection)' ' - rm -f $U + rm -f $U && ( cd cloned && GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 5d1c66ea71..d189add2d0 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -107,16 +107,18 @@ test_expect_success 'remove remote' ' ) ' -test_expect_success 'remove remote protects non-remote branches' ' +test_expect_success 'remove remote protects local branches' ' ( cd test && { cat >expect1 <<EOF -Note: A non-remote branch was not removed; to delete it, use: +Note: A branch outside the refs/remotes/ hierarchy was not removed; +to delete it, use: git branch -d master EOF } && { cat >expect2 <<EOF -Note: Non-remote branches were not removed; to delete them, use: +Note: Some branches outside the refs/remotes/ hierarchy were not removed; +to delete them, use: git branch -d foobranch git branch -d master EOF diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 9a884751ec..7e433b179f 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -119,7 +119,7 @@ test_expect_success 'fetch must not resolve short tag name' ' test_expect_success 'fetch must not resolve short remote name' ' cd "$D" && - git update-ref refs/remotes/six/HEAD HEAD + git update-ref refs/remotes/six/HEAD HEAD && mkdir six && cd six && diff --git a/t/t5513-fetch-track.sh b/t/t5513-fetch-track.sh index 9e7486274b..65d1e05bd6 100755 --- a/t/t5513-fetch-track.sh +++ b/t/t5513-fetch-track.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='fetch follows remote tracking branches correctly' +test_description='fetch follows remote-tracking branches correctly' . ./test-lib.sh diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh index b73733219d..227dd56137 100755 --- a/t/t5514-fetch-multiple.sh +++ b/t/t5514-fetch-multiple.sh @@ -27,7 +27,7 @@ test_expect_success setup ' ( cd two && git branch another ) && - git clone --mirror two three + git clone --mirror two three && git clone one test ' diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index b11da79c9c..d73731e644 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -586,7 +586,7 @@ test_expect_success 'push --delete refuses src:dest refspecs' ' ' test_expect_success 'warn on push to HEAD of non-bare repository' ' - mk_test heads/master + mk_test heads/master && ( cd testrepo && git checkout master && @@ -597,7 +597,7 @@ test_expect_success 'warn on push to HEAD of non-bare repository' ' ' test_expect_success 'deny push to HEAD of non-bare repository' ' - mk_test heads/master + mk_test heads/master && ( cd testrepo && git checkout master && @@ -607,7 +607,7 @@ test_expect_success 'deny push to HEAD of non-bare repository' ' ' test_expect_success 'allow push to HEAD of bare repository (bare)' ' - mk_test heads/master + mk_test heads/master && ( cd testrepo && git checkout master && @@ -619,7 +619,7 @@ test_expect_success 'allow push to HEAD of bare repository (bare)' ' ' test_expect_success 'allow push to HEAD of non-bare repository (config)' ' - mk_test heads/master + mk_test heads/master && ( cd testrepo && git checkout master && diff --git a/t/t5519-push-alternates.sh b/t/t5519-push-alternates.sh index 96be5236a2..c00c9b071d 100755 --- a/t/t5519-push-alternates.sh +++ b/t/t5519-push-alternates.sh @@ -123,7 +123,7 @@ test_expect_success 'bob works and pushes again' ' ( cd alice-pub && git cat-file commit master >../bob-work/commit - ) + ) && ( # This time Bob does not pull from Alice, and # the master branch at her public repository points diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 0b489f5b12..0470a81be0 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -222,4 +222,11 @@ test_expect_success 'git pull --rebase does not reapply old patches' ' ) ' +test_expect_success 'git pull --rebase against local branch' ' + git checkout -b copy2 to-rebase-orig && + git pull --rebase . to-rebase && + test "conflicting modification" = "$(cat file)" && + test file = "$(cat file2)" +' + test_done diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index 65d8d474bc..faa2e96337 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -6,7 +6,7 @@ test_description='unpack-objects' test_expect_success setup ' mkdir pub.git && - GIT_DIR=pub.git git init --bare + GIT_DIR=pub.git git init --bare && GIT_DIR=pub.git git config receive.fsckobjects true && mkdir work && ( diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh index 2fb48d09ed..8c2ac353b7 100755 --- a/t/t5550-http-fetch.sh +++ b/t/t5550-http-fetch.sh @@ -34,6 +34,13 @@ test_expect_success 'clone http repository' ' test_cmp file clone/file ' +test_expect_success 'clone http repository with authentication' ' + mkdir "$HTTPD_DOCUMENT_ROOT_PATH/auth/" && + cp -Rf "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" "$HTTPD_DOCUMENT_ROOT_PATH/auth/repo.git" && + git clone $AUTH_HTTPD_URL/auth/repo.git clone-auth && + test_cmp file clone-auth/file +' + test_expect_success 'fetch changes via http' ' echo content >>file && git commit -a -m two && diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh index fd19121372..26d355725f 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@ -101,5 +101,13 @@ test_expect_success 'used upload-pack service' ' test_cmp exp act ' +test_expect_success 'follow redirects (301)' ' + git clone $HTTPD_URL/smart-redir-perm/repo.git --quiet repo-p +' + +test_expect_success 'follow redirects (302)' ' + git clone $HTTPD_URL/smart-redir-temp/repo.git --quiet repo-t +' + stop_httpd test_done diff --git a/t/t556x_common b/t/t556x_common index 51287d89d8..82926cfdb7 100755 --- a/t/t556x_common +++ b/t/t556x_common @@ -52,21 +52,21 @@ get_static_files() { SMART=smart GIT_HTTP_EXPORT_ALL=1 && export GIT_HTTP_EXPORT_ALL test_expect_success 'direct refs/heads/master not found' ' - log_div "refs/heads/master" + log_div "refs/heads/master" && GET refs/heads/master "404 Not Found" ' test_expect_success 'static file is ok' ' - log_div "getanyfile default" + log_div "getanyfile default" && get_static_files "200 OK" ' SMART=smart_noexport unset GIT_HTTP_EXPORT_ALL test_expect_success 'no export by default' ' - log_div "no git-daemon-export-ok" + log_div "no git-daemon-export-ok" && get_static_files "404 Not Found" ' test_expect_success 'export if git-daemon-export-ok' ' - log_div "git-daemon-export-ok" + log_div "git-daemon-export-ok" && (cd "$HTTPD_DOCUMENT_ROOT_PATH/repo.git" && touch git-daemon-export-ok ) && @@ -75,47 +75,47 @@ test_expect_success 'export if git-daemon-export-ok' ' SMART=smart GIT_HTTP_EXPORT_ALL=1 && export GIT_HTTP_EXPORT_ALL test_expect_success 'static file if http.getanyfile true is ok' ' - log_div "getanyfile true" + log_div "getanyfile true" && config http.getanyfile true && get_static_files "200 OK" ' test_expect_success 'static file if http.getanyfile false fails' ' - log_div "getanyfile false" + log_div "getanyfile false" && config http.getanyfile false && get_static_files "403 Forbidden" ' test_expect_success 'http.uploadpack default enabled' ' - log_div "uploadpack default" + log_div "uploadpack default" && GET info/refs?service=git-upload-pack "200 OK" && POST git-upload-pack 0000 "200 OK" ' test_expect_success 'http.uploadpack true' ' - log_div "uploadpack true" + log_div "uploadpack true" && config http.uploadpack true && GET info/refs?service=git-upload-pack "200 OK" && POST git-upload-pack 0000 "200 OK" ' test_expect_success 'http.uploadpack false' ' - log_div "uploadpack false" + log_div "uploadpack false" && config http.uploadpack false && GET info/refs?service=git-upload-pack "403 Forbidden" && POST git-upload-pack 0000 "403 Forbidden" ' test_expect_success 'http.receivepack default disabled' ' - log_div "receivepack default" + log_div "receivepack default" && GET info/refs?service=git-receive-pack "403 Forbidden" && POST git-receive-pack 0000 "403 Forbidden" ' test_expect_success 'http.receivepack true' ' - log_div "receivepack true" + log_div "receivepack true" && config http.receivepack true && GET info/refs?service=git-receive-pack "200 OK" && POST git-receive-pack 0000 "200 OK" ' test_expect_success 'http.receivepack false' ' - log_div "receivepack false" + log_div "receivepack false" && config http.receivepack false && GET info/refs?service=git-receive-pack "403 Forbidden" && POST git-receive-pack 0000 "403 Forbidden" diff --git a/t/t5602-clone-remote-exec.sh b/t/t5602-clone-remote-exec.sh index deffdaee49..3f353d99e8 100755 --- a/t/t5602-clone-remote-exec.sh +++ b/t/t5602-clone-remote-exec.sh @@ -5,21 +5,29 @@ test_description=clone . ./test-lib.sh test_expect_success setup ' - echo "#!/bin/sh" > not_ssh - echo "echo \"\$*\" > not_ssh_output" >> not_ssh - echo "exit 1" >> not_ssh + echo "#!/bin/sh" > not_ssh && + echo "echo \"\$*\" > not_ssh_output" >> not_ssh && + echo "exit 1" >> not_ssh && chmod +x not_ssh ' test_expect_success 'clone calls git upload-pack unqualified with no -u option' ' - GIT_SSH=./not_ssh git clone localhost:/path/to/repo junk - echo "localhost git-upload-pack '\''/path/to/repo'\''" >expected + ( + GIT_SSH=./not_ssh && + export GIT_SSH && + test_must_fail git clone localhost:/path/to/repo junk + ) && + echo "localhost git-upload-pack '\''/path/to/repo'\''" >expected && test_cmp expected not_ssh_output ' test_expect_success 'clone calls specified git upload-pack with -u option' ' - GIT_SSH=./not_ssh git clone -u ./something/bin/git-upload-pack localhost:/path/to/repo junk - echo "localhost ./something/bin/git-upload-pack '\''/path/to/repo'\''" >expected + ( + GIT_SSH=./not_ssh && + export GIT_SSH && + test_must_fail git clone -u ./something/bin/git-upload-pack localhost:/path/to/repo junk + ) && + echo "localhost ./something/bin/git-upload-pack '\''/path/to/repo'\''" >expected && test_cmp expected not_ssh_output ' diff --git a/t/t5701-clone-local.sh b/t/t5701-clone-local.sh index 8b4c356cd2..0f4d487be3 100755 --- a/t/t5701-clone-local.sh +++ b/t/t5701-clone-local.sh @@ -10,11 +10,11 @@ test_expect_success 'preparing origin repository' ' git clone --bare . a.git && git clone --bare . x && test "$(GIT_CONFIG=a.git/config git config --bool core.bare)" = true && - test "$(GIT_CONFIG=x/config git config --bool core.bare)" = true + test "$(GIT_CONFIG=x/config git config --bool core.bare)" = true && git bundle create b1.bundle --all && git bundle create b2.bundle master && mkdir dir && - cp b1.bundle dir/b3 + cp b1.bundle dir/b3 && cp b1.bundle b4 ' @@ -112,7 +112,7 @@ test_expect_success 'bundle clone with nonexistent HEAD' ' cd "$D" && git clone b2.bundle b2 && cd b2 && - git fetch + git fetch && test ! -e .git/refs/heads/master ' diff --git a/t/t6001-rev-list-graft.sh b/t/t6001-rev-list-graft.sh index fc57e7d3fd..8efcd13079 100755 --- a/t/t6001-rev-list-graft.sh +++ b/t/t6001-rev-list-graft.sh @@ -90,22 +90,22 @@ check () { for type in basic parents parents-raw do test_expect_success 'without grafts' " - rm -f .git/info/grafts + rm -f .git/info/grafts && check $type $B2 -- $B2 $B1 $B0 " test_expect_success 'with grafts' " - echo '$B0 $A2' >.git/info/grafts + echo '$B0 $A2' >.git/info/grafts && check $type $B2 -- $B2 $B1 $B0 $A2 $A1 $A0 " test_expect_success 'without grafts, with pathlimit' " - rm -f .git/info/grafts + rm -f .git/info/grafts && check $type $B2 subdir -- $B2 $B0 " test_expect_success 'with grafts, with pathlimit' " - echo '$B0 $A2' >.git/info/grafts + echo '$B0 $A2' >.git/info/grafts && check $type $B2 subdir -- $B2 $B0 $A2 $A0 " diff --git a/t/t6009-rev-list-parent.sh b/t/t6009-rev-list-parent.sh index c8a96a9a99..52f7b277ce 100755 --- a/t/t6009-rev-list-parent.sh +++ b/t/t6009-rev-list-parent.sh @@ -18,7 +18,7 @@ test_expect_success setup ' commit one && - test_tick=$(($test_tick - 2400)) + test_tick=$(($test_tick - 2400)) && commit two && commit three && diff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh index 62197a3d35..082032edc3 100755 --- a/t/t6010-merge-base.sh +++ b/t/t6010-merge-base.sh @@ -131,7 +131,7 @@ test_expect_success 'unsynchronized clocks' ' R2=$(doit 3 R2 $R1) && PL=$(doit 4 PL $L2 $C2) && - PR=$(doit 4 PR $C2 $R2) + PR=$(doit 4 PR $C2 $R2) && git name-rev $C2 >expected && diff --git a/t/t6016-rev-list-graph-simplify-history.sh b/t/t6016-rev-list-graph-simplify-history.sh index 27fd52b7be..f7181d1d6a 100755 --- a/t/t6016-rev-list-graph-simplify-history.sh +++ b/t/t6016-rev-list-graph-simplify-history.sh @@ -29,7 +29,7 @@ test_expect_success 'set up rev-list --graph test' ' # Octopus merge B and C into branch A git checkout A && git merge B C && - git tag A4 + git tag A4 && test_commit A5 bar.txt && @@ -39,7 +39,7 @@ test_expect_success 'set up rev-list --graph test' ' test_commit C4 bar.txt && git checkout A && git merge -s ours C && - git tag A6 + git tag A6 && test_commit A7 bar.txt && @@ -90,7 +90,7 @@ test_expect_success '--graph --all' ' # that undecorated merges are interesting, even with --simplify-by-decoration test_expect_success '--graph --simplify-by-decoration' ' rm -f expected && - git tag -d A4 + git tag -d A4 && echo "* $A7" >> expected && echo "* $A6" >> expected && echo "|\\ " >> expected && @@ -116,12 +116,15 @@ test_expect_success '--graph --simplify-by-decoration' ' test_cmp expected actual ' -# Get rid of all decorations on branch B, and graph with it simplified away +test_expect_success 'setup: get rid of decorations on B' ' + git tag -d B2 && + git tag -d B1 && + git branch -d B +' + +# Graph with branch B simplified away test_expect_success '--graph --simplify-by-decoration prune branch B' ' rm -f expected && - git tag -d B2 - git tag -d B1 - git branch -d B echo "* $A7" >> expected && echo "* $A6" >> expected && echo "|\\ " >> expected && @@ -143,9 +146,6 @@ test_expect_success '--graph --simplify-by-decoration prune branch B' ' test_expect_success '--graph --full-history -- bar.txt' ' rm -f expected && - git tag -d B2 - git tag -d B1 - git branch -d B echo "* $A7" >> expected && echo "* $A6" >> expected && echo "|\\ " >> expected && @@ -163,9 +163,6 @@ test_expect_success '--graph --full-history -- bar.txt' ' test_expect_success '--graph --full-history --simplify-merges -- bar.txt' ' rm -f expected && - git tag -d B2 - git tag -d B1 - git branch -d B echo "* $A7" >> expected && echo "* $A6" >> expected && echo "|\\ " >> expected && @@ -181,9 +178,6 @@ test_expect_success '--graph --full-history --simplify-merges -- bar.txt' ' test_expect_success '--graph -- bar.txt' ' rm -f expected && - git tag -d B2 - git tag -d B1 - git branch -d B echo "* $A7" >> expected && echo "* $A5" >> expected && echo "* $A3" >> expected && @@ -196,9 +190,6 @@ test_expect_success '--graph -- bar.txt' ' test_expect_success '--graph --sparse -- bar.txt' ' rm -f expected && - git tag -d B2 - git tag -d B1 - git branch -d B echo "* $A7" >> expected && echo "* $A6" >> expected && echo "* $A5" >> expected && diff --git a/t/t6020-merge-df.sh b/t/t6020-merge-df.sh index 490d397114..eec8f4e3ed 100755 --- a/t/t6020-merge-df.sh +++ b/t/t6020-merge-df.sh @@ -6,21 +6,26 @@ test_description='Test merge with directory/file conflicts' . ./test-lib.sh -test_expect_success 'prepare repository' \ -'echo "Hello" > init && -git add init && -git commit -m "Initial commit" && -git branch B && -mkdir dir && -echo "foo" > dir/foo && -git add dir/foo && -git commit -m "File: dir/foo" && -git checkout B && -echo "file dir" > dir && -git add dir && -git commit -m "File: dir"' - -test_expect_code 1 'Merge with d/f conflicts' 'git merge "merge msg" B master' +test_expect_success 'prepare repository' ' + echo Hello >init && + git add init && + git commit -m initial && + + git branch B && + mkdir dir && + echo foo >dir/foo && + git add dir/foo && + git commit -m "File: dir/foo" && + + git checkout B && + echo file dir >dir && + git add dir && + git commit -m "File: dir" +' + +test_expect_success 'Merge with d/f conflicts' ' + test_expect_code 1 git merge "merge msg" B master +' test_expect_success 'F/D conflict' ' git reset --hard && @@ -45,4 +50,51 @@ test_expect_success 'F/D conflict' ' git merge master ' +test_expect_success 'setup modify/delete + directory/file conflict' ' + git checkout --orphan modify && + git rm -rf . && + git clean -fdqx && + + printf "a\nb\nc\nd\ne\nf\ng\nh\n" >letters && + git add letters && + git commit -m initial && + + echo i >>letters && + git add letters && + git commit -m modified && + + git checkout -b delete HEAD^ && + git rm letters && + mkdir letters && + >letters/file && + git add letters && + git commit -m deleted +' + +test_expect_success 'modify/delete + directory/file conflict' ' + git checkout delete^0 && + test_must_fail git merge modify && + + test 3 = $(git ls-files -s | wc -l) && + test 2 = $(git ls-files -u | wc -l) && + test 1 = $(git ls-files -o | wc -l) && + + test -f letters/file && + test -f letters~modify +' + +test_expect_success 'modify/delete + directory/file conflict; other way' ' + git reset --hard && + git clean -f && + git checkout modify^0 && + test_must_fail git merge delete && + + test 3 = $(git ls-files -s | wc -l) && + test 2 = $(git ls-files -u | wc -l) && + test 1 = $(git ls-files -o | wc -l) && + + test -f letters/file && + test -f letters~HEAD +' + test_done diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index b66544b76d..1ed259d864 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -3,6 +3,11 @@ test_description='Merge-recursive merging renames' . ./test-lib.sh +modify () { + sed -e "$1" <"$2" >"$2.x" && + mv "$2.x" "$2" +} + test_expect_success setup \ ' cat >A <<\EOF && @@ -94,245 +99,147 @@ git checkout master' test_expect_success 'pull renaming branch into unrenaming one' \ ' - git show-branch - git pull . white && { - echo "BAD: should have conflicted" - return 1 - } - git ls-files -s - test "$(git ls-files -u B | wc -l)" -eq 3 || { - echo "BAD: should have left stages for B" - return 1 - } - test "$(git ls-files -s N | wc -l)" -eq 1 || { - echo "BAD: should have merged N" - return 1 - } + git show-branch && + test_expect_code 1 git pull . white && + git ls-files -s && + git ls-files -u B >b.stages && + test_line_count = 3 b.stages && + git ls-files -s N >n.stages && + test_line_count = 1 n.stages && sed -ne "/^g/{ p q - }" B | grep master || { - echo "BAD: should have listed our change first" - return 1 - } - test "$(git diff white N | wc -l)" -eq 0 || { - echo "BAD: should have taken colored branch" - return 1 - } + }" B | grep master && + git diff --exit-code white N ' test_expect_success 'pull renaming branch into another renaming one' \ ' - rm -f B - git reset --hard - git checkout red - git pull . white && { - echo "BAD: should have conflicted" - return 1 - } - test "$(git ls-files -u B | wc -l)" -eq 3 || { - echo "BAD: should have left stages" - return 1 - } - test "$(git ls-files -s N | wc -l)" -eq 1 || { - echo "BAD: should have merged N" - return 1 - } + rm -f B && + git reset --hard && + git checkout red && + test_expect_code 1 git pull . white && + git ls-files -u B >b.stages && + test_line_count = 3 b.stages && + git ls-files -s N >n.stages && + test_line_count = 1 n.stages && sed -ne "/^g/{ p q - }" B | grep red || { - echo "BAD: should have listed our change first" - return 1 - } - test "$(git diff white N | wc -l)" -eq 0 || { - echo "BAD: should have taken colored branch" - return 1 - } + }" B | grep red && + git diff --exit-code white N ' test_expect_success 'pull unrenaming branch into renaming one' \ ' - git reset --hard - git show-branch - git pull . master && { - echo "BAD: should have conflicted" - return 1 - } - test "$(git ls-files -u B | wc -l)" -eq 3 || { - echo "BAD: should have left stages" - return 1 - } - test "$(git ls-files -s N | wc -l)" -eq 1 || { - echo "BAD: should have merged N" - return 1 - } + git reset --hard && + git show-branch && + test_expect_code 1 git pull . master && + git ls-files -u B >b.stages && + test_line_count = 3 b.stages && + git ls-files -s N >n.stages && + test_line_count = 1 n.stages && sed -ne "/^g/{ p q - }" B | grep red || { - echo "BAD: should have listed our change first" - return 1 - } - test "$(git diff white N | wc -l)" -eq 0 || { - echo "BAD: should have taken colored branch" - return 1 - } + }" B | grep red && + git diff --exit-code white N ' test_expect_success 'pull conflicting renames' \ ' - git reset --hard - git show-branch - git pull . blue && { - echo "BAD: should have conflicted" - return 1 - } - test "$(git ls-files -u A | wc -l)" -eq 1 || { - echo "BAD: should have left a stage" - return 1 - } - test "$(git ls-files -u B | wc -l)" -eq 1 || { - echo "BAD: should have left a stage" - return 1 - } - test "$(git ls-files -u C | wc -l)" -eq 1 || { - echo "BAD: should have left a stage" - return 1 - } - test "$(git ls-files -s N | wc -l)" -eq 1 || { - echo "BAD: should have merged N" - return 1 - } + git reset --hard && + git show-branch && + test_expect_code 1 git pull . blue && + git ls-files -u A >a.stages && + test_line_count = 1 a.stages && + git ls-files -u B >b.stages && + test_line_count = 1 b.stages && + git ls-files -u C >c.stages && + test_line_count = 1 c.stages && + git ls-files -s N >n.stages && + test_line_count = 1 n.stages && sed -ne "/^g/{ p q - }" B | grep red || { - echo "BAD: should have listed our change first" - return 1 - } - test "$(git diff white N | wc -l)" -eq 0 || { - echo "BAD: should have taken colored branch" - return 1 - } + }" B | grep red && + git diff --exit-code white N ' test_expect_success 'interference with untracked working tree file' ' - - git reset --hard - git show-branch - echo >A this file should not matter - git pull . white && { - echo "BAD: should have conflicted" - return 1 - } - test -f A || { - echo "BAD: should have left A intact" - return 1 - } + git reset --hard && + git show-branch && + echo >A this file should not matter && + test_expect_code 1 git pull . white && + test_path_is_file A ' test_expect_success 'interference with untracked working tree file' ' - - git reset --hard - git checkout white - git show-branch - rm -f A - echo >A this file should not matter - git pull . red && { - echo "BAD: should have conflicted" - return 1 - } - test -f A || { - echo "BAD: should have left A intact" - return 1 - } + git reset --hard && + git checkout white && + git show-branch && + rm -f A && + echo >A this file should not matter && + test_expect_code 1 git pull . red && + test_path_is_file A ' test_expect_success 'interference with untracked working tree file' ' - - git reset --hard - rm -f A M - git checkout -f master - git tag -f anchor - git show-branch - git pull . yellow || { - echo "BAD: should have cleanly merged" - return 1 - } - test -f M && { - echo "BAD: should have removed M" - return 1 - } + git reset --hard && + rm -f A M && + git checkout -f master && + git tag -f anchor && + git show-branch && + git pull . yellow && + test_path_is_missing M && git reset --hard anchor ' test_expect_success 'updated working tree file should prevent the merge' ' - - git reset --hard - rm -f A M - git checkout -f master - git tag -f anchor - git show-branch - echo >>M one line addition - cat M >M.saved - git pull . yellow && { - echo "BAD: should have complained" - return 1 - } - test_cmp M M.saved || { - echo "BAD: should have left M intact" - return 1 - } + git reset --hard && + rm -f A M && + git checkout -f master && + git tag -f anchor && + git show-branch && + echo >>M one line addition && + cat M >M.saved && + test_expect_code 128 git pull . yellow && + test_cmp M M.saved && rm -f M.saved ' test_expect_success 'updated working tree file should prevent the merge' ' - - git reset --hard - rm -f A M - git checkout -f master - git tag -f anchor - git show-branch - echo >>M one line addition - cat M >M.saved - git update-index M - git pull . yellow && { - echo "BAD: should have complained" - return 1 - } - test_cmp M M.saved || { - echo "BAD: should have left M intact" - return 1 - } + git reset --hard && + rm -f A M && + git checkout -f master && + git tag -f anchor && + git show-branch && + echo >>M one line addition && + cat M >M.saved && + git update-index M && + test_expect_code 128 git pull . yellow && + test_cmp M M.saved && rm -f M.saved ' test_expect_success 'interference with untracked working tree file' ' - - git reset --hard - rm -f A M - git checkout -f yellow - git tag -f anchor - git show-branch - echo >M this file should not matter - git pull . master || { - echo "BAD: should have cleanly merged" - return 1 - } - test -f M || { - echo "BAD: should have left M intact" - return 1 - } - git ls-files -s | grep M && { - echo "BAD: M must be untracked in the result" - return 1 - } + git reset --hard && + rm -f A M && + git checkout -f yellow && + git tag -f anchor && + git show-branch && + echo >M this file should not matter && + git pull . master && + test_path_is_file M && + ! { + git ls-files -s | + grep M + } && git reset --hard anchor ' test_expect_success 'merge of identical changes in a renamed file' ' - rm -f A M N + rm -f A M N && git reset --hard && git checkout change+rename && GIT_MERGE_VERBOSITY=3 git merge change | grep "^Skipped B" && @@ -341,4 +248,365 @@ test_expect_success 'merge of identical changes in a renamed file' ' GIT_MERGE_VERBOSITY=3 git merge change+rename | grep "^Skipped B" ' +test_expect_success 'setup for rename + d/f conflicts' ' + git reset --hard && + git checkout --orphan dir-in-way && + git rm -rf . && + + mkdir sub && + mkdir dir && + printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >sub/file && + echo foo >dir/file-in-the-way && + git add -A && + git commit -m "Common commmit" && + + echo 11 >>sub/file && + echo more >>dir/file-in-the-way && + git add -u && + git commit -m "Commit to merge, with dir in the way" && + + git checkout -b dir-not-in-way && + git reset --soft HEAD^ && + git rm -rf dir && + git commit -m "Commit to merge, with dir removed" -- dir sub/file && + + git checkout -b renamed-file-has-no-conflicts dir-in-way~1 && + git rm -rf dir && + git rm sub/file && + printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n" >dir && + git add dir && + git commit -m "Independent change" && + + git checkout -b renamed-file-has-conflicts dir-in-way~1 && + git rm -rf dir && + git mv sub/file dir && + echo 12 >>dir && + git add dir && + git commit -m "Conflicting change" +' + +printf "1\n2\n3\n4\n5555\n6\n7\n8\n9\n10\n11\n" >expected + +test_expect_success 'Rename+D/F conflict; renamed file merges + dir not in way' ' + git reset --hard && + git checkout -q renamed-file-has-no-conflicts^0 && + git merge --strategy=recursive dir-not-in-way && + git diff --quiet && + test -f dir && + test_cmp expected dir +' + +test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q renamed-file-has-no-conflicts^0 && + test_must_fail git merge --strategy=recursive dir-in-way >output && + + grep "CONFLICT (delete/modify): dir/file-in-the-way" output && + grep "Auto-merging dir" output && + grep "Adding as dir~HEAD instead" output && + + test 2 -eq "$(git ls-files -u | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~HEAD && + test_cmp expected dir~HEAD +' + +test_expect_success 'Same as previous, but merged other way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q dir-in-way^0 && + test_must_fail git merge --strategy=recursive renamed-file-has-no-conflicts >output 2>errors && + + ! grep "error: refusing to lose untracked file at" errors && + grep "CONFLICT (delete/modify): dir/file-in-the-way" output && + grep "Auto-merging dir" output && + grep "Adding as dir~renamed-file-has-no-conflicts instead" output && + + test 2 -eq "$(git ls-files -u | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~renamed-file-has-no-conflicts && + test_cmp expected dir~renamed-file-has-no-conflicts +' + +cat >expected <<\EOF && +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +<<<<<<< HEAD +12 +======= +11 +>>>>>>> dir-not-in-way +EOF + +test_expect_success 'Rename+D/F conflict; renamed file cannot merge, dir not in way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q renamed-file-has-conflicts^0 && + test_must_fail git merge --strategy=recursive dir-not-in-way && + + test 3 -eq "$(git ls-files -u | wc -l)" && + test 3 -eq "$(git ls-files -u dir | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir && + test_cmp expected dir +' + +test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in the way' ' + modify s/dir-not-in-way/dir-in-way/ expected && + + git reset --hard && + rm -rf dir~* && + git checkout -q renamed-file-has-conflicts^0 && + test_must_fail git merge --strategy=recursive dir-in-way && + + test 5 -eq "$(git ls-files -u | wc -l)" && + test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~HEAD && + test_cmp expected dir~HEAD +' + +cat >expected <<\EOF && +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +<<<<<<< HEAD +11 +======= +12 +>>>>>>> renamed-file-has-conflicts +EOF + +test_expect_success 'Same as previous, but merged other way' ' + git reset --hard && + rm -rf dir~* && + git checkout -q dir-in-way^0 && + test_must_fail git merge --strategy=recursive renamed-file-has-conflicts && + + test 5 -eq "$(git ls-files -u | wc -l)" && + test 3 -eq "$(git ls-files -u dir | grep -v file-in-the-way | wc -l)" && + test 2 -eq "$(git ls-files -u dir/file-in-the-way | wc -l)" && + + test_must_fail git diff --quiet && + test_must_fail git diff --cached --quiet && + + test -f dir/file-in-the-way && + test -f dir~renamed-file-has-conflicts && + test_cmp expected dir~renamed-file-has-conflicts +' + +test_expect_success 'setup both rename source and destination involved in D/F conflict' ' + git reset --hard && + git checkout --orphan rename-dest && + git rm -rf . && + git clean -fdqx && + + mkdir one && + echo stuff >one/file && + git add -A && + git commit -m "Common commmit" && + + git mv one/file destdir && + git commit -m "Renamed to destdir" && + + git checkout -b source-conflict HEAD~1 && + git rm -rf one && + mkdir destdir && + touch one destdir/foo && + git add -A && + git commit -m "Conflicts in the way" +' + +test_expect_success 'both rename source and destination involved in D/F conflict' ' + git reset --hard && + rm -rf dir~* && + git checkout -q rename-dest^0 && + test_must_fail git merge --strategy=recursive source-conflict && + + test 1 -eq "$(git ls-files -u | wc -l)" && + + test_must_fail git diff --quiet && + + test -f destdir/foo && + test -f one && + test -f destdir~HEAD && + test "stuff" = "$(cat destdir~HEAD)" +' + +test_expect_success 'setup pair rename to parent of other (D/F conflicts)' ' + git reset --hard && + git checkout --orphan rename-two && + git rm -rf . && + git clean -fdqx && + + mkdir one && + mkdir two && + echo stuff >one/file && + echo other >two/file && + git add -A && + git commit -m "Common commmit" && + + git rm -rf one && + git mv two/file one && + git commit -m "Rename two/file -> one" && + + git checkout -b rename-one HEAD~1 && + git rm -rf two && + git mv one/file two && + rm -r one && + git commit -m "Rename one/file -> two" +' + +test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' ' + git checkout -q rename-one^0 && + mkdir one && + test_must_fail git merge --strategy=recursive rename-two && + + test 2 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && + + test_must_fail git diff --quiet && + + test 4 -eq $(find . | grep -v .git | wc -l) && + + test -d one && + test -f one~rename-two && + test -f two && + test "other" = $(cat one~rename-two) && + test "stuff" = $(cat two) +' + +test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' ' + git reset --hard && + git clean -fdqx && + test_must_fail git merge --strategy=recursive rename-two && + + test 2 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && + + test_must_fail git diff --quiet && + + test 3 -eq $(find . | grep -v .git | wc -l) && + + test -f one && + test -f two && + test "other" = $(cat one) && + test "stuff" = $(cat two) +' + +test_expect_success 'setup rename of one file to two, with directories in the way' ' + git reset --hard && + git checkout --orphan first-rename && + git rm -rf . && + git clean -fdqx && + + echo stuff >original && + git add -A && + git commit -m "Common commmit" && + + mkdir two && + >two/file && + git add two/file && + git mv original one && + git commit -m "Put two/file in the way, rename to one" && + + git checkout -b second-rename HEAD~1 && + mkdir one && + >one/file && + git add one/file && + git mv original two && + git commit -m "Put one/file in the way, rename to two" +' + +test_expect_success 'check handling of differently renamed file with D/F conflicts' ' + git checkout -q first-rename^0 && + test_must_fail git merge --strategy=recursive second-rename && + + test 5 -eq "$(git ls-files -s | wc -l)" && + test 3 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && + test 1 -eq "$(git ls-files -u original | wc -l)" && + test 2 -eq "$(git ls-files -o | wc -l)" && + + test -f one/file && + test -f two/file && + test -f one~HEAD && + test -f two~second-rename && + ! test -f original +' + +test_expect_success 'setup rename one file to two; directories moving out of the way' ' + git reset --hard && + git checkout --orphan first-rename-redo && + git rm -rf . && + git clean -fdqx && + + echo stuff >original && + mkdir one two && + touch one/file two/file && + git add -A && + git commit -m "Common commmit" && + + git rm -rf one && + git mv original one && + git commit -m "Rename to one" && + + git checkout -b second-rename-redo HEAD~1 && + git rm -rf two && + git mv original two && + git commit -m "Rename to two" +' + +test_expect_success 'check handling of differently renamed file with D/F conflicts' ' + git checkout -q first-rename-redo^0 && + test_must_fail git merge --strategy=recursive second-rename-redo && + + test 3 -eq "$(git ls-files -u | wc -l)" && + test 1 -eq "$(git ls-files -u one | wc -l)" && + test 1 -eq "$(git ls-files -u two | wc -l)" && + test 1 -eq "$(git ls-files -u original | wc -l)" && + test 0 -eq "$(git ls-files -o | wc -l)" && + + test -f one && + test -f two && + ! test -f original +' + test_done diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh index b3fbf659c0..755d30ce2a 100755 --- a/t/t6024-recursive-merge.sh +++ b/t/t6024-recursive-merge.sh @@ -104,7 +104,7 @@ test_expect_success 'mark rename/delete as unmerged' ' test_tick && git commit -m delete && git checkout -b rename HEAD^ && - git mv a1 a2 + git mv a1 a2 && test_tick && git commit -m rename && test_must_fail git merge delete && diff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh index 3900d9f61f..73fc240e85 100755 --- a/t/t6029-merge-subtree.sh +++ b/t/t6029-merge-subtree.sh @@ -6,7 +6,7 @@ test_description='subtree merge strategy' test_expect_success setup ' - s="1 2 3 4 5 6 7 8" + s="1 2 3 4 5 6 7 8" && for i in $s; do echo $i; done >hello && git add hello && git commit -m initial && diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 3b042aacd6..b5063b6fe6 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -517,13 +517,13 @@ test_expect_success '"parallel" side branch creation' ' add_line_into_file "2(para): line 2 on parallel branch" dir2/file2 && PARA_HASH2=$(git rev-parse --verify HEAD) && add_line_into_file "3(para): line 3 on parallel branch" dir2/file3 && - PARA_HASH3=$(git rev-parse --verify HEAD) + PARA_HASH3=$(git rev-parse --verify HEAD) && git merge -m "merge HASH4 and PARA_HASH3" "$HASH4" && - PARA_HASH4=$(git rev-parse --verify HEAD) + PARA_HASH4=$(git rev-parse --verify HEAD) && add_line_into_file "5(para): add line on parallel branch" dir1/file1 && - PARA_HASH5=$(git rev-parse --verify HEAD) + PARA_HASH5=$(git rev-parse --verify HEAD) && add_line_into_file "6(para): add line on parallel branch" dir2/file2 && - PARA_HASH6=$(git rev-parse --verify HEAD) + PARA_HASH6=$(git rev-parse --verify HEAD) && git merge -m "merge HASH7 and PARA_HASH6" "$HASH7" && PARA_HASH7=$(git rev-parse --verify HEAD) ' diff --git a/t/t6032-merge-large-rename.sh b/t/t6032-merge-large-rename.sh index eac5ebac24..fdb6c25371 100755 --- a/t/t6032-merge-large-rename.sh +++ b/t/t6032-merge-large-rename.sh @@ -70,4 +70,34 @@ test_expect_success 'set merge.renamelimit to 5' ' test_rename 5 ok test_rename 6 fail +test_expect_success 'setup large simple rename' ' + git config --unset merge.renamelimit && + git config --unset diff.renamelimit && + + git reset --hard initial && + for i in $(count 200); do + make_text foo bar baz >$i + done && + git add . && + git commit -m create-files && + + git branch simple-change && + git checkout -b simple-rename && + + mkdir builtin && + git mv [0-9]* builtin/ && + git commit -m renamed && + + git checkout simple-change && + >unrelated-change && + git add unrelated-change && + git commit -m unrelated-change +' + +test_expect_success 'massive simple rename does not spam added files' ' + unset GIT_MERGE_VERBOSITY && + git merge --no-stat simple-rename | grep -v Removing >output && + test 5 -gt "$(wc -l < output)" +' + test_done diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index b874141658..871577d90c 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -14,7 +14,80 @@ test_description='recursive merge corner cases' # R1 R2 # -test_expect_success setup ' +test_expect_success 'setup basic criss-cross + rename with no modifications' ' + ten="0 1 2 3 4 5 6 7 8 9" && + for i in $ten + do + echo line $i in a sample file + done >one && + for i in $ten + do + echo line $i in another sample file + done >two && + git add one two && + test_tick && git commit -m initial && + + git branch L1 && + git checkout -b R1 && + git mv one three && + test_tick && git commit -m R1 && + + git checkout L1 && + git mv two three && + test_tick && git commit -m L1 && + + git checkout L1^0 && + test_tick && git merge -s ours R1 && + git tag L2 && + + git checkout R1^0 && + test_tick && git merge -s ours L1 && + git tag R2 +' + +test_expect_success 'merge simple rename+criss-cross with no modifications' ' + git reset --hard && + git checkout L2^0 && + + test_must_fail git merge -s recursive R2^0 && + + test 5 = $(git ls-files -s | wc -l) && + test 3 = $(git ls-files -u | wc -l) && + test 0 = $(git ls-files -o | wc -l) && + + test $(git rev-parse :0:one) = $(git rev-parse L2:one) && + test $(git rev-parse :0:two) = $(git rev-parse R2:two) && + test $(git rev-parse :2:three) = $(git rev-parse L2:three) && + test $(git rev-parse :3:three) = $(git rev-parse R2:three) && + + cp two merged && + >empty && + test_must_fail git merge-file \ + -L "Temporary merge branch 2" \ + -L "" \ + -L "Temporary merge branch 1" \ + merged empty one && + test $(git rev-parse :1:three) = $(git hash-object merged) +' + +# +# Same as before, but modify L1 slightly: +# +# L1m L2 +# o---o +# / \ / \ +# o X ? +# \ / \ / +# o---o +# R1 R2 +# + +test_expect_success 'setup criss-cross + rename merges with basic modification' ' + git rm -rf . && + git clean -fdqx && + rm -rf .git && + git init && + ten="0 1 2 3 4 5 6 7 8 9" for i in $ten do @@ -30,6 +103,8 @@ test_expect_success setup ' git branch L1 && git checkout -b R1 && git mv one three && + echo more >>two && + git add two && test_tick && git commit -m R1 && git checkout L1 && @@ -45,11 +120,115 @@ test_expect_success setup ' git tag R2 ' -test_expect_success merge ' +test_expect_success 'merge criss-cross + rename merges with basic modification' ' git reset --hard && git checkout L2^0 && - test_must_fail git merge -s recursive R2^0 + test_must_fail git merge -s recursive R2^0 && + + test 5 = $(git ls-files -s | wc -l) && + test 3 = $(git ls-files -u | wc -l) && + test 0 = $(git ls-files -o | wc -l) && + + test $(git rev-parse :0:one) = $(git rev-parse L2:one) && + test $(git rev-parse :0:two) = $(git rev-parse R2:two) && + test $(git rev-parse :2:three) = $(git rev-parse L2:three) && + test $(git rev-parse :3:three) = $(git rev-parse R2:three) && + + head -n 10 two >merged && + cp one merge-me && + >empty && + test_must_fail git merge-file \ + -L "Temporary merge branch 2" \ + -L "" \ + -L "Temporary merge branch 1" \ + merged empty merge-me && + test $(git rev-parse :1:three) = $(git hash-object merged) +' + +# +# For the next test, we start with three commits in two lines of development +# which setup a rename/add conflict: +# Commit A: File 'a' exists +# Commit B: Rename 'a' -> 'new_a' +# Commit C: Modify 'a', create different 'new_a' +# Later, two different people merge and resolve differently: +# Commit D: Merge B & C, ignoring separately created 'new_a' +# Commit E: Merge B & C making use of some piece of secondary 'new_a' +# Finally, someone goes to merge D & E. Does git detect the conflict? +# +# B D +# o---o +# / \ / \ +# A o X ? F +# \ / \ / +# o---o +# C E +# + +test_expect_success 'setup differently handled merges of rename/add conflict' ' + git rm -rf . && + git clean -fdqx && + rm -rf .git && + git init && + + printf "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n" >a && + git add a && + test_tick && git commit -m A && + + git branch B && + git checkout -b C && + echo 10 >>a && + echo "other content" >>new_a && + git add a new_a && + test_tick && git commit -m C && + + git checkout B && + git mv a new_a && + test_tick && git commit -m B && + + git checkout B^0 && + test_must_fail git merge C && + git clean -f && + test_tick && git commit -m D && + git tag D && + + git checkout C^0 && + test_must_fail git merge B && + rm new_a~HEAD new_a && + printf "Incorrectly merged content" >>new_a && + git add -u && + test_tick && git commit -m E && + git tag E +' + +test_expect_success 'git detects differently handled merges conflict' ' + git reset --hard && + git checkout D^0 && + + git merge -s recursive E^0 && { + echo "BAD: should have conflicted" + test "Incorrectly merged content" = "$(cat new_a)" && + echo "BAD: Silently accepted wrong content" + return 1 + } + + test 3 = $(git ls-files -s | wc -l) && + test 3 = $(git ls-files -u | wc -l) && + test 0 = $(git ls-files -o | wc -l) && + + test $(git rev-parse :2:new_a) = $(git rev-parse D:new_a) && + test $(git rev-parse :3:new_a) = $(git rev-parse E:new_a) && + + git cat-file -p B:new_a >>merged && + git cat-file -p C:new_a >>merge-me && + >empty && + test_must_fail git merge-file \ + -L "Temporary merge branch 2" \ + -L "" \ + -L "Temporary merge branch 1" \ + merged empty merge-me && + test $(git rev-parse :1:new_a) = $(git hash-object merged) ' test_done diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh index 1785e178a4..1e0447f615 100755 --- a/t/t6040-tracking-info.sh +++ b/t/t6040-tracking-info.sh @@ -60,7 +60,7 @@ test_expect_success 'checkout' ' test_expect_success 'checkout with local tracked branch' ' git checkout master && - git checkout follower >actual + git checkout follower >actual && grep "is ahead of" actual ' diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index 95b180f469..ae2194e07d 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -53,7 +53,7 @@ test_expect_success 'set up buggy branch' ' echo "line 12" >> hello && echo "line 13" >> hello && add_and_commit_file hello "2 more lines" && - HASH6=$(git rev-parse --verify HEAD) + HASH6=$(git rev-parse --verify HEAD) && echo "line 14" >> hello && echo "line 15" >> hello && echo "line 16" >> hello && diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh new file mode 100755 index 0000000000..82f3639937 --- /dev/null +++ b/t/t6500-gc.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +test_description='basic git gc tests +' + +. ./test-lib.sh + +test_expect_success 'gc empty repository' ' + git gc +' + +test_expect_success 'gc --gobbledegook' ' + test_expect_code 129 git gc --nonsense 2>err && + grep "[Uu]sage: git gc" err +' + +test_expect_success 'gc -h with invalid configuration' ' + mkdir broken && + ( + cd broken && + git init && + echo "[gc] pruneexpire = CORRUPT" >>.git/config && + test_expect_code 129 git gc -h >usage 2>&1 + ) && + grep "[Uu]sage" broken/usage +' + +test_done diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 65a35d94a0..a845b154e4 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -61,7 +61,7 @@ test_expect_success \ test_expect_success \ 'checking -f on untracked file with existing target' \ 'touch path0/untracked1 && - git mv -f untracked1 path0 + test_must_fail git mv -f untracked1 path0 && test ! -f .git/index.lock && test -f untracked1 && test -f path0/untracked1' @@ -207,7 +207,7 @@ test_expect_success 'git mv should not change sha1 of moved cache entry' ' git init && echo 1 >dirty && git add dirty && - entry="$(git ls-files --stage dirty | cut -f 1)" + entry="$(git ls-files --stage dirty | cut -f 1)" && git mv dirty dirty2 && [ "$entry" = "$(git ls-files --stage dirty2 | cut -f 1)" ] && echo 2 >dirty2 && diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 700b556fe8..3e7baaf89f 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1030,6 +1030,72 @@ test_expect_success GPG \ test_cmp expect actual ' +# usage with rfc1991 signatures +echo "rfc1991" > gpghome/gpg.conf +get_tag_header rfc1991-signed-tag $commit commit $time >expect +echo "RFC1991 signed tag" >>expect +echo '-----BEGIN PGP MESSAGE-----' >>expect +test_expect_success GPG \ + 'creating a signed tag with rfc1991' ' + git tag -s -m "RFC1991 signed tag" rfc1991-signed-tag $commit && + get_tag_msg rfc1991-signed-tag >actual && + test_cmp expect actual +' + +cat >fakeeditor <<'EOF' +#!/bin/sh +cp "$1" actual +EOF +chmod +x fakeeditor + +test_expect_success GPG \ + 'reediting a signed tag body omits signature' ' + echo "RFC1991 signed tag" >expect && + GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit && + test_cmp expect actual +' + +test_expect_success GPG \ + 'verifying rfc1991 signature' ' + git tag -v rfc1991-signed-tag +' + +test_expect_success GPG \ + 'list tag with rfc1991 signature' ' + echo "rfc1991-signed-tag RFC1991 signed tag" >expect && + git tag -l -n1 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n2 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n999 rfc1991-signed-tag >actual && + test_cmp expect actual +' + +rm -f gpghome/gpg.conf + +test_expect_success GPG \ + 'verifying rfc1991 signature without --rfc1991' ' + git tag -v rfc1991-signed-tag +' + +test_expect_success GPG \ + 'list tag with rfc1991 signature without --rfc1991' ' + echo "rfc1991-signed-tag RFC1991 signed tag" >expect && + git tag -l -n1 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n2 rfc1991-signed-tag >actual && + test_cmp expect actual && + git tag -l -n999 rfc1991-signed-tag >actual && + test_cmp expect actual +' + +test_expect_success GPG \ + 'reediting a signed tag body omits signature' ' + echo "RFC1991 signed tag" >expect && + GIT_EDITOR=./fakeeditor git tag -f -s rfc1991-signed-tag $commit && + test_cmp expect actual +' + # try to sign with bad user.signingkey git config user.signingkey BobTheMouse test_expect_success GPG \ @@ -1107,7 +1173,7 @@ hash1=$(git rev-parse HEAD) test_expect_success 'creating second commit and tag' ' echo foo-2.0 >foo && git add foo && - git commit -m second + git commit -m second && git tag v2.0 ' @@ -1132,18 +1198,18 @@ v2.0 EOF test_expect_success 'checking that first commit is in all tags (hash)' " - git tag -l --contains $hash1 v* >actual + git tag -l --contains $hash1 v* >actual && test_cmp expected actual " # other ways of specifying the commit test_expect_success 'checking that first commit is in all tags (tag)' " - git tag -l --contains v1.0 v* >actual + git tag -l --contains v1.0 v* >actual && test_cmp expected actual " test_expect_success 'checking that first commit is in all tags (relative)' " - git tag -l --contains HEAD~2 v* >actual + git tag -l --contains HEAD~2 v* >actual && test_cmp expected actual " @@ -1152,7 +1218,7 @@ v2.0 EOF test_expect_success 'checking that second commit only has one tag' " - git tag -l --contains $hash2 v* >actual + git tag -l --contains $hash2 v* >actual && test_cmp expected actual " @@ -1161,7 +1227,7 @@ cat > expected <<EOF EOF test_expect_success 'checking that third commit has no tags' " - git tag -l --contains $hash3 v* >actual + git tag -l --contains $hash3 v* >actual && test_cmp expected actual " @@ -1171,7 +1237,7 @@ test_expect_success 'creating simple branch' ' git branch stable v2.0 && git checkout stable && echo foo-3.0 > foo && - git commit foo -m fourth + git commit foo -m fourth && git tag v3.0 ' @@ -1182,7 +1248,7 @@ v3.0 EOF test_expect_success 'checking that branch head only has one tag' " - git tag -l --contains $hash4 v* >actual + git tag -l --contains $hash4 v* >actual && test_cmp expected actual " @@ -1196,7 +1262,7 @@ v4.0 EOF test_expect_success 'checking that original branch head has one tag now' " - git tag -l --contains $hash3 v* >actual + git tag -l --contains $hash3 v* >actual && test_cmp expected actual " @@ -1211,18 +1277,18 @@ v4.0 EOF test_expect_success 'checking that initial commit is in all tags' " - git tag -l --contains $hash1 v* >actual + git tag -l --contains $hash1 v* >actual && test_cmp expected actual " # mixing modes and options: test_expect_success 'mixing incompatibles modes and options is forbidden' ' - test_must_fail git tag -a - test_must_fail git tag -l -v - test_must_fail git tag -n 100 - test_must_fail git tag -l -m msg - test_must_fail git tag -l -F some file + test_must_fail git tag -a && + test_must_fail git tag -l -v && + test_must_fail git tag -n 100 && + test_must_fail git tag -l -m msg && + test_must_fail git tag -l -F some file && test_must_fail git tag -v -s ' diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index 5641b59559..ed7575d0fd 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -12,7 +12,7 @@ cleanup_fail() { } test_expect_success 'setup' ' - unset GIT_PAGER GIT_PAGER_IN_USE; + sane_unset GIT_PAGER GIT_PAGER_IN_USE && test_might_fail git config --unset core.pager && PAGER="cat >paginated.out" && @@ -220,7 +220,7 @@ test_default_pager() { parse_args "$@" $test_expectation SIMPLEPAGER,TTY "$cmd - default pager is used by default" " - unset PAGER GIT_PAGER; + sane_unset PAGER GIT_PAGER && test_might_fail git config --unset core.pager && rm -f default_pager_used || cleanup_fail && @@ -243,7 +243,7 @@ test_PAGER_overrides() { parse_args "$@" $test_expectation TTY "$cmd - PAGER overrides default pager" " - unset GIT_PAGER; + sane_unset GIT_PAGER && test_might_fail git config --unset core.pager && rm -f PAGER_used || cleanup_fail && @@ -271,7 +271,7 @@ test_core_pager() { parse_args "$@" $test_expectation TTY "$cmd - repository-local core.pager setting $used_if_wanted" " - unset GIT_PAGER; + sane_unset GIT_PAGER && rm -f core.pager_used || cleanup_fail && @@ -299,7 +299,7 @@ test_pager_subdir_helper() { parse_args "$@" $test_expectation TTY "$cmd - core.pager $used_if_wanted from subdirectory" " - unset GIT_PAGER; + sane_unset GIT_PAGER && rm -f core.pager_used && rm -fr sub || cleanup_fail && @@ -401,4 +401,33 @@ test_core_pager_subdir expect_success 'git -p shortlog' test_core_pager_subdir expect_success test_must_fail \ 'git -p apply </dev/null' +test_expect_success TTY 'command-specific pager' ' + unset PAGER GIT_PAGER; + echo "foo:initial" >expect && + >actual && + git config --unset core.pager && + git config pager.log "sed s/^/foo:/ >actual" && + test_terminal git log --format=%s -1 && + test_cmp expect actual +' + +test_expect_success TTY 'command-specific pager overrides core.pager' ' + unset PAGER GIT_PAGER; + echo "foo:initial" >expect && + >actual && + git config core.pager "exit 1" + git config pager.log "sed s/^/foo:/ >actual" && + test_terminal git log --format=%s -1 && + test_cmp expect actual +' + +test_expect_success TTY 'command-specific pager overridden by environment' ' + GIT_PAGER="sed s/^/foo:/ >actual" && export GIT_PAGER && + >actual && + echo "foo:initial" >expect && + git config pager.log "exit 1" && + test_terminal git log --format=%s -1 && + test_cmp expect actual +' + test_done diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh index 9891e2c1f5..95fab20361 100755 --- a/t/t7105-reset-patch.sh +++ b/t/t7105-reset-patch.sh @@ -18,7 +18,7 @@ test_expect_success PERL 'setup' ' # note: bar sorts before foo, so the first 'n' is always to skip 'bar' test_expect_success PERL 'saying "n" does nothing' ' - set_and_save_state dir/foo work work + set_and_save_state dir/foo work work && (echo n; echo n) | git reset -p && verify_saved_state dir/foo && verify_saved_state bar @@ -42,14 +42,14 @@ test_expect_success PERL 'git reset -p HEAD^' ' # the failure case (and thus get out of the loop). test_expect_success PERL 'git reset -p dir' ' - set_state dir/foo work work + set_state dir/foo work work && (echo y; echo n) | git reset -p dir && verify_state dir/foo work head && verify_saved_state bar ' test_expect_success PERL 'git reset -p -- foo (inside dir)' ' - set_state dir/foo work work + set_state dir/foo work work && (echo y; echo n) | (cd dir && git reset -p -- foo) && verify_state dir/foo work head && verify_saved_state bar diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 6c776e9bec..02f67b73b7 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -179,11 +179,11 @@ test_expect_success 'git clean -d with prefix and path' ' ' -test_expect_success 'git clean symbolic link' ' +test_expect_success SYMLINKS 'git clean symbolic link' ' mkdir -p build docs && touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && - ln -s docs/manual.txt src/part4.c + ln -s docs/manual.txt src/part4.c && git clean && test -f Makefile && test -f README && diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index aa9c577e9e..162527c211 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -215,4 +215,84 @@ test_expect_success 'Commit a message with --allow-empty-message' ' commit_msg_is "hello there" ' +commit_for_rebase_autosquash_setup () { + echo "first content line" >>foo && + git add foo && + cat >log <<EOF && +target message subject line + +target message body line 1 +target message body line 2 +EOF + git commit -F log && + echo "second content line" >>foo && + git add foo && + git commit -m "intermediate commit" && + echo "third content line" >>foo && + git add foo +} + +test_expect_success 'commit --fixup provides correct one-line commit message' ' + commit_for_rebase_autosquash_setup && + git commit --fixup HEAD~1 && + commit_msg_is "fixup! target message subject line" +' + +test_expect_success 'commit --squash works with -F' ' + commit_for_rebase_autosquash_setup && + echo "log message from file" >msgfile && + git commit --squash HEAD~1 -F msgfile && + commit_msg_is "squash! target message subject linelog message from file" +' + +test_expect_success 'commit --squash works with -m' ' + commit_for_rebase_autosquash_setup && + git commit --squash HEAD~1 -m "foo bar\nbaz" && + commit_msg_is "squash! target message subject linefoo bar\nbaz" +' + +test_expect_success 'commit --squash works with -C' ' + commit_for_rebase_autosquash_setup && + git commit --squash HEAD~1 -C HEAD && + commit_msg_is "squash! target message subject lineintermediate commit" +' + +test_expect_success 'commit --squash works with -c' ' + commit_for_rebase_autosquash_setup && + test_set_editor "$TEST_DIRECTORY"/t7500/edit-content && + git commit --squash HEAD~1 -c HEAD && + commit_msg_is "squash! target message subject lineedited commit" +' + +test_expect_success 'commit --squash works with -C for same commit' ' + commit_for_rebase_autosquash_setup && + git commit --squash HEAD -C HEAD && + commit_msg_is "squash! intermediate commit" +' + +test_expect_success 'commit --squash works with -c for same commit' ' + commit_for_rebase_autosquash_setup && + test_set_editor "$TEST_DIRECTORY"/t7500/edit-content && + git commit --squash HEAD -c HEAD && + commit_msg_is "squash! edited commit" +' + +test_expect_success 'commit --squash works with editor' ' + commit_for_rebase_autosquash_setup && + test_set_editor "$TEST_DIRECTORY"/t7500/add-content && + git commit --squash HEAD~1 && + commit_msg_is "squash! target message subject linecommit message" +' + +test_expect_success 'invalid message options when using --fixup' ' + echo changes >>foo && + echo "message" >log && + git add foo && + test_must_fail git commit --fixup HEAD~1 --squash HEAD~2 && + test_must_fail git commit --fixup HEAD~1 -C HEAD~2 && + test_must_fail git commit --fixup HEAD~1 -c HEAD~2 && + test_must_fail git commit --fixup HEAD~1 -m "cmdline message" && + test_must_fail git commit --fixup HEAD~1 -F log +' + test_done diff --git a/t/t7500/edit-content b/t/t7500/edit-content new file mode 100755 index 0000000000..08db9fdd2e --- /dev/null +++ b/t/t7500/edit-content @@ -0,0 +1,4 @@ +#!/bin/sh +sed -e "s/intermediate/edited/g" <"$1" >"$1-" +mv "$1-" "$1" +exit 0 diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index ac2e187a57..50da034cd3 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -252,8 +252,8 @@ test_expect_success 'committer is automatic' ' echo >>negative && ( - unset GIT_COMMITTER_EMAIL - unset GIT_COMMITTER_NAME + sane_unset GIT_COMMITTER_EMAIL && + sane_unset GIT_COMMITTER_NAME && # must fail because there is no change test_must_fail git commit -e -m "sample" ) && @@ -390,7 +390,7 @@ try_commit_status_combo () { test_expect_success 'commit --no-status' ' clear_config commit.status && - try_commit --no-status + try_commit --no-status && ! grep "^# Changes to be committed:" .git/COMMIT_EDITMSG ' diff --git a/t/t7508-status.sh b/t/t7508-status.sh index c9300f3c8b..b73ab42936 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -7,6 +7,30 @@ test_description='git status' . ./test-lib.sh +test_expect_success 'status -h in broken repository' ' + mkdir broken && + test_when_finished "rm -fr broken" && + ( + cd broken && + git init && + echo "[status] showuntrackedfiles = CORRUPT" >>.git/config && + test_expect_code 129 git status -h >usage 2>&1 + ) && + grep "[Uu]sage" broken/usage +' + +test_expect_success 'commit -h in broken repository' ' + mkdir broken && + test_when_finished "rm -fr broken" && + ( + cd broken && + git init && + echo "[status] showuntrackedfiles = CORRUPT" >>.git/config && + test_expect_code 129 git commit -h >usage 2>&1 + ) && + grep "[Uu]sage" broken/usage +' + test_expect_success 'setup' ' : >tracked && : >modified && @@ -44,7 +68,7 @@ cat >expect <<\EOF # # new file: dir2/added # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -73,7 +97,7 @@ cat >expect <<\EOF # Changes to be committed: # new file: dir2/added # -# Changed but not updated: +# Changes not staged for commit: # modified: dir1/modified # # Untracked files: @@ -140,7 +164,7 @@ cat >expect <<EOF # # new file: dir2/added # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -167,7 +191,7 @@ cat >expect <<EOF # Changes to be committed: # new file: dir2/added # -# Changed but not updated: +# Changes not staged for commit: # modified: dir1/modified # # Untracked files not listed @@ -202,7 +226,7 @@ cat >expect <<EOF # # new file: dir2/added # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -260,7 +284,7 @@ cat >expect <<EOF # # new file: dir2/added # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -320,7 +344,7 @@ cat >expect <<\EOF # # new file: ../dir2/added # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -392,7 +416,7 @@ cat >expect <<\EOF # # <GREEN>new file: dir2/added<RESET> # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -521,7 +545,7 @@ cat >expect <<\EOF # # new file: dir2/added # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -614,7 +638,7 @@ cat >expect <<EOF # new file: dir2/added # new file: sm # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -673,7 +697,7 @@ cat >expect <<EOF # new file: dir2/added # new file: sm # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -718,7 +742,7 @@ test_expect_success 'status -s submodule summary' ' cat >expect <<EOF # On branch master -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -766,7 +790,7 @@ cat >expect <<EOF # new file: dir2/added # new file: sm # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -819,7 +843,7 @@ cat > expect << EOF # # modified: sm # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -931,7 +955,7 @@ cat > expect << EOF # # modified: sm # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # (commit or discard the untracked or modified content in submodules) @@ -989,7 +1013,7 @@ cat > expect << EOF # # modified: sm # -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # @@ -1067,7 +1091,7 @@ test_expect_success ".git/config ignore=dirty doesn't suppress submodule summary cat > expect << EOF # On branch master -# Changed but not updated: +# Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # diff --git a/t/t7509-commit.sh b/t/t7509-commit.sh index 643ab03f99..77b6920029 100755 --- a/t/t7509-commit.sh +++ b/t/t7509-commit.sh @@ -40,7 +40,7 @@ test_expect_success '-C option copies only the message with --reset-author' ' test_tick && git commit -a -C Initial --reset-author && echo "author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE" >expect && - author_header HEAD >actual + author_header HEAD >actual && test_cmp expect actual && message_body Initial >expect && diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index b4f40e4c3a..b147a1bd69 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -144,6 +144,17 @@ test_expect_success 'test option parsing' ' test_must_fail git merge ' +test_expect_success 'merge -h with invalid index' ' + mkdir broken && + ( + cd broken && + git init && + >.git/index && + test_expect_code 129 git merge -h 2>usage + ) && + grep "[Uu]sage: git merge" broken/usage +' + test_expect_success 'reject non-strategy with a git-merge-foo name' ' test_must_fail git merge -s index c1 ' diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 7ba94ea99b..b44b293950 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -114,13 +114,13 @@ test_expect_success 'setup conflicted merge' ' test_expect_success 'merge picks up the best result' ' git config --unset-all pull.twohead && git reset --hard c5 && - git merge -s resolve c6 + test_must_fail git merge -s resolve c6 && resolve_count=$(conflict_count) && git reset --hard c5 && - git merge -s recursive c6 + test_must_fail git merge -s recursive c6 && recursive_count=$(conflict_count) && git reset --hard c5 && - git merge -s recursive -s resolve c6 + test_must_fail git merge -s recursive -s resolve c6 && auto_count=$(conflict_count) && test $auto_count = $recursive_count && test $auto_count != $resolve_count @@ -129,13 +129,13 @@ test_expect_success 'merge picks up the best result' ' test_expect_success 'merge picks up the best result (from config)' ' git config pull.twohead "recursive resolve" && git reset --hard c5 && - git merge -s resolve c6 + test_must_fail git merge -s resolve c6 && resolve_count=$(conflict_count) && git reset --hard c5 && - git merge -s recursive c6 + test_must_fail git merge -s recursive c6 && recursive_count=$(conflict_count) && git reset --hard c5 && - git merge c6 + test_must_fail git merge c6 && auto_count=$(conflict_count) && test $auto_count = $recursive_count && test $auto_count != $resolve_count diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh index 2746169514..0a46795ae7 100755 --- a/t/t7602-merge-octopus-many.sh +++ b/t/t7602-merge-octopus-many.sh @@ -31,7 +31,7 @@ test_expect_success 'merge c1 with c2, c3, c4, ... c29' ' do refs="$refs c$i" i=`expr $i + 1` - done + done && git merge $refs && test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && i=1 && diff --git a/t/t7607-merge-overwrite.sh b/t/t7607-merge-overwrite.sh index d82349a6a8..4d5ce4e682 100755 --- a/t/t7607-merge-overwrite.sh +++ b/t/t7607-merge-overwrite.sh @@ -7,48 +7,54 @@ Do not overwrite changes.' . ./test-lib.sh test_expect_success 'setup' ' - echo c0 > c0.c && - git add c0.c && - git commit -m c0 && - git tag c0 && - echo c1 > c1.c && - git add c1.c && - git commit -m c1 && - git tag c1 && + test_commit c0 c0.c && + test_commit c1 c1.c && + test_commit c1a c1.c "c1 a" && git reset --hard c0 && - echo c2 > c2.c && - git add c2.c && - git commit -m c2 && - git tag c2 && - git reset --hard c1 && - echo "c1 a" > c1.c && - git add c1.c && - git commit -m "c1 a" && - git tag c1a && + test_commit c2 c2.c && + git reset --hard c0 && + mkdir sub && + echo "sub/f" > sub/f && + mkdir sub2 && + echo "sub2/f" > sub2/f && + git add sub/f sub2/f && + git commit -m sub && + git tag sub && echo "VERY IMPORTANT CHANGES" > important ' test_expect_success 'will not overwrite untracked file' ' git reset --hard c1 && - cat important > c2.c && + cp important c2.c && test_must_fail git merge c2 && + test_path_is_missing .git/MERGE_HEAD && test_cmp important c2.c ' +test_expect_success 'will overwrite tracked file' ' + git reset --hard c1 && + cp important c2.c && + git add c2.c && + git commit -m important && + git checkout c2 +' + test_expect_success 'will not overwrite new file' ' git reset --hard c1 && - cat important > c2.c && + cp important c2.c && git add c2.c && test_must_fail git merge c2 && + test_path_is_missing .git/MERGE_HEAD && test_cmp important c2.c ' test_expect_success 'will not overwrite staged changes' ' git reset --hard c1 && - cat important > c2.c && + cp important c2.c && git add c2.c && rm c2.c && test_must_fail git merge c2 && + test_path_is_missing .git/MERGE_HEAD && git checkout c2.c && test_cmp important c2.c ' @@ -57,7 +63,7 @@ test_expect_success 'will not overwrite removed file' ' git reset --hard c1 && git rm c1.c && git commit -m "rm c1.c" && - cat important > c1.c && + cp important c1.c && test_must_fail git merge c1a && test_cmp important c1.c ' @@ -66,9 +72,10 @@ test_expect_success 'will not overwrite re-added file' ' git reset --hard c1 && git rm c1.c && git commit -m "rm c1.c" && - cat important > c1.c && + cp important c1.c && git add c1.c && test_must_fail git merge c1a && + test_path_is_missing .git/MERGE_HEAD && test_cmp important c1.c ' @@ -76,12 +83,77 @@ test_expect_success 'will not overwrite removed file with staged changes' ' git reset --hard c1 && git rm c1.c && git commit -m "rm c1.c" && - cat important > c1.c && + cp important c1.c && git add c1.c && rm c1.c && test_must_fail git merge c1a && + test_path_is_missing .git/MERGE_HEAD && git checkout c1.c && test_cmp important c1.c ' +test_expect_success 'will not overwrite untracked subtree' ' + git reset --hard c0 && + rm -rf sub && + mkdir -p sub/f && + cp important sub/f/important && + test_must_fail git merge sub && + test_path_is_missing .git/MERGE_HEAD && + test_cmp important sub/f/important +' + +cat >expect <<\EOF +error: The following untracked working tree files would be overwritten by merge: + sub + sub2 +Please move or remove them before you can merge. +EOF + +test_expect_success 'will not overwrite untracked file in leading path' ' + git reset --hard c0 && + rm -rf sub && + cp important sub && + cp important sub2 && + test_must_fail git merge sub 2>out && + test_cmp out expect && + test_path_is_missing .git/MERGE_HEAD && + test_cmp important sub && + test_cmp important sub2 && + rm -f sub sub2 +' + +test_expect_failure SYMLINKS 'will not overwrite untracked symlink in leading path' ' + git reset --hard c0 && + rm -rf sub && + mkdir sub2 && + ln -s sub2 sub && + test_must_fail git merge sub && + test_path_is_missing .git/MERGE_HEAD +' + +test_expect_success SYMLINKS 'will not be confused by symlink in leading path' ' + git reset --hard c0 && + rm -rf sub && + ln -s sub2 sub && + git add sub && + git commit -m ln && + git checkout sub +' + +cat >expect <<\EOF +error: Untracked working tree file 'c0.c' would be overwritten by merge. +fatal: read-tree failed +EOF + +test_expect_success 'will not overwrite untracked file on unborn branch' ' + git reset --hard c0 && + git rm -fr . && + git checkout --orphan new && + cp important c0.c && + test_must_fail git merge c0 2>out && + test_cmp out expect && + test_path_is_missing .git/MERGE_HEAD && + test_cmp important c0.c +' + test_done diff --git a/t/t7608-merge-messages.sh b/t/t7608-merge-messages.sh index 28d56797b1..9225fa6f02 100755 --- a/t/t7608-merge-messages.sh +++ b/t/t7608-merge-messages.sh @@ -47,14 +47,14 @@ test_expect_success 'ambiguous tag' ' check_oneline "Merge commit QambiguousQ" ' -test_expect_success 'remote branch' ' +test_expect_success 'remote-tracking branch' ' git checkout -b remote master && test_commit remote-1 && git update-ref refs/remotes/origin/master remote && git checkout master && test_commit master-5 && git merge origin/master && - check_oneline "Merge remote branch Qorigin/masterQ" + check_oneline "Merge remote-tracking branch Qorigin/masterQ" ' test_done diff --git a/t/t7609-merge-abort.sh b/t/t7609-merge-abort.sh new file mode 100755 index 0000000000..61890bc892 --- /dev/null +++ b/t/t7609-merge-abort.sh @@ -0,0 +1,313 @@ +#!/bin/sh + +test_description='test aborting in-progress merges + +Set up repo with conflicting and non-conflicting branches: + +There are three files foo/bar/baz, and the following graph illustrates the +content of these files in each commit: + +# foo/bar/baz --- foo/bar/bazz <-- master +# \ +# --- foo/barf/bazf <-- conflict_branch +# \ +# --- foo/bart/baz <-- clean_branch + +Next, test git merge --abort with the following variables: +- before/after successful merge (should fail when not in merge context) +- with/without conflicts +- clean/dirty index before merge +- clean/dirty worktree before merge +- dirty index before merge matches contents on remote branch +- changed/unchanged worktree after merge +- changed/unchanged index after merge +' +. ./test-lib.sh + +test_expect_success 'setup' ' + # Create the above repo + echo foo > foo && + echo bar > bar && + echo baz > baz && + git add foo bar baz && + git commit -m initial && + echo bazz > baz && + git commit -a -m "second" && + git checkout -b conflict_branch HEAD^ && + echo barf > bar && + echo bazf > baz && + git commit -a -m "conflict" && + git checkout -b clean_branch HEAD^ && + echo bart > bar && + git commit -a -m "clean" && + git checkout master +' + +pre_merge_head="$(git rev-parse HEAD)" + +test_expect_success 'fails without MERGE_HEAD (unstarted merge)' ' + test_must_fail git merge --abort 2>output && + grep -q MERGE_HEAD output && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" +' + +test_expect_success 'fails without MERGE_HEAD (completed merge)' ' + git merge clean_branch && + test ! -f .git/MERGE_HEAD && + # Merge successfully completed + post_merge_head="$(git rev-parse HEAD)" && + test_must_fail git merge --abort 2>output && + grep -q MERGE_HEAD output && + test ! -f .git/MERGE_HEAD && + test "$post_merge_head" = "$(git rev-parse HEAD)" +' + +test_expect_success 'Forget previous merge' ' + git reset --hard "$pre_merge_head" +' + +test_expect_success 'Abort after --no-commit' ' + # Redo merge, but stop before creating merge commit + git merge --no-commit clean_branch && + test -f .git/MERGE_HEAD && + # Abort non-conflicting merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff)" && + test -z "$(git diff --staged)" +' + +test_expect_success 'Abort after conflicts' ' + # Create conflicting merge + test_must_fail git merge conflict_branch && + test -f .git/MERGE_HEAD && + # Abort conflicting merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff)" && + test -z "$(git diff --staged)" +' + +test_expect_success 'Clean merge with dirty index fails' ' + echo xyzzy >> foo && + git add foo && + git diff --staged > expect && + test_must_fail git merge clean_branch && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff)" && + git diff --staged > actual && + test_cmp expect actual +' + +test_expect_success 'Conflicting merge with dirty index fails' ' + test_must_fail git merge conflict_branch && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff)" && + git diff --staged > actual && + test_cmp expect actual +' + +test_expect_success 'Reset index (but preserve worktree changes)' ' + git reset "$pre_merge_head" && + git diff > actual && + test_cmp expect actual +' + +test_expect_success 'Abort clean merge with non-conflicting dirty worktree' ' + git merge --no-commit clean_branch && + test -f .git/MERGE_HEAD && + # Abort merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff --staged)" && + git diff > actual && + test_cmp expect actual +' + +test_expect_success 'Abort conflicting merge with non-conflicting dirty worktree' ' + test_must_fail git merge conflict_branch && + test -f .git/MERGE_HEAD && + # Abort merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff --staged)" && + git diff > actual && + test_cmp expect actual +' + +test_expect_success 'Reset worktree changes' ' + git reset --hard "$pre_merge_head" +' + +test_expect_success 'Fail clean merge with conflicting dirty worktree' ' + echo xyzzy >> bar && + git diff > expect && + test_must_fail git merge --no-commit clean_branch && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff --staged)" && + git diff > actual && + test_cmp expect actual +' + +test_expect_success 'Fail conflicting merge with conflicting dirty worktree' ' + test_must_fail git merge conflict_branch && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff --staged)" && + git diff > actual && + test_cmp expect actual +' + +test_expect_success 'Reset worktree changes' ' + git reset --hard "$pre_merge_head" +' + +test_expect_success 'Fail clean merge with matching dirty worktree' ' + echo bart > bar && + git diff > expect && + test_must_fail git merge --no-commit clean_branch && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff --staged)" && + git diff > actual && + test_cmp expect actual +' + +test_expect_success 'Abort clean merge with matching dirty index' ' + git add bar && + git diff --staged > expect && + git merge --no-commit clean_branch && + test -f .git/MERGE_HEAD && + ### When aborting the merge, git will discard all staged changes, + ### including those that were staged pre-merge. In other words, + ### --abort will LOSE any staged changes (the staged changes that + ### are lost must match the merge result, or the merge would not + ### have been allowed to start). Change expectations accordingly: + rm expect && + touch expect && + # Abort merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + git diff --staged > actual && + test_cmp expect actual && + test -z "$(git diff)" +' + +test_expect_success 'Reset worktree changes' ' + git reset --hard "$pre_merge_head" +' + +test_expect_success 'Fail conflicting merge with matching dirty worktree' ' + echo barf > bar && + git diff > expect && + test_must_fail git merge conflict_branch && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + test -z "$(git diff --staged)" && + git diff > actual && + test_cmp expect actual +' + +test_expect_success 'Abort conflicting merge with matching dirty index' ' + git add bar && + git diff --staged > expect && + test_must_fail git merge conflict_branch && + test -f .git/MERGE_HEAD && + ### When aborting the merge, git will discard all staged changes, + ### including those that were staged pre-merge. In other words, + ### --abort will LOSE any staged changes (the staged changes that + ### are lost must match the merge result, or the merge would not + ### have been allowed to start). Change expectations accordingly: + rm expect && + touch expect && + # Abort merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + git diff --staged > actual && + test_cmp expect actual && + test -z "$(git diff)" +' + +test_expect_success 'Reset worktree changes' ' + git reset --hard "$pre_merge_head" +' + +test_expect_success 'Abort merge with pre- and post-merge worktree changes' ' + # Pre-merge worktree changes + echo xyzzy > foo && + echo barf > bar && + git add bar && + git diff > expect && + git diff --staged > expect-staged && + # Perform merge + test_must_fail git merge conflict_branch && + test -f .git/MERGE_HEAD && + # Post-merge worktree changes + echo yzxxz > foo && + echo blech > baz && + ### When aborting the merge, git will discard staged changes (bar) + ### and unmerged changes (baz). Other changes that are neither + ### staged nor marked as unmerged (foo), will be preserved. For + ### these changed, git cannot tell pre-merge changes apart from + ### post-merge changes, so the post-merge changes will be + ### preserved. Change expectations accordingly: + git diff -- foo > expect && + rm expect-staged && + touch expect-staged && + # Abort merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + git diff > actual && + test_cmp expect actual && + git diff --staged > actual-staged && + test_cmp expect-staged actual-staged +' + +test_expect_success 'Reset worktree changes' ' + git reset --hard "$pre_merge_head" +' + +test_expect_success 'Abort merge with pre- and post-merge index changes' ' + # Pre-merge worktree changes + echo xyzzy > foo && + echo barf > bar && + git add bar && + git diff > expect && + git diff --staged > expect-staged && + # Perform merge + test_must_fail git merge conflict_branch && + test -f .git/MERGE_HEAD && + # Post-merge worktree changes + echo yzxxz > foo && + echo blech > baz && + git add foo bar && + ### When aborting the merge, git will discard all staged changes + ### (foo, bar and baz), and no changes will be preserved. Whether + ### the changes were staged pre- or post-merge does not matter + ### (except for not preventing starting the merge). + ### Change expectations accordingly: + rm expect expect-staged && + touch expect && + touch expect-staged && + # Abort merge + git merge --abort && + test ! -f .git/MERGE_HEAD && + test "$pre_merge_head" = "$(git rev-parse HEAD)" && + git diff > actual && + test_cmp expect actual && + git diff --staged > actual-staged && + test_cmp expect-staged actual-staged +' + +test_done diff --git a/t/t7609-merge-co-error-msgs.sh b/t/t7609-merge-co-error-msgs.sh index 114d2bd785..c994836c53 100755 --- a/t/t7609-merge-co-error-msgs.sh +++ b/t/t7609-merge-co-error-msgs.sh @@ -27,10 +27,10 @@ test_expect_success 'setup' ' cat >expect <<\EOF error: The following untracked working tree files would be overwritten by merge: - two - three - four five + four + three + two Please move or remove them before you can merge. EOF @@ -49,9 +49,9 @@ test_expect_success 'untracked files overwritten by merge (fast and non-fast for cat >expect <<\EOF error: Your local changes to the following files would be overwritten by merge: - two - three four + three + two Please, commit your changes or stash them before you can merge. error: The following untracked working tree files would be overwritten by merge: five @@ -68,8 +68,8 @@ test_expect_success 'untracked files or local changes ovewritten by merge' ' cat >expect <<\EOF error: Your local changes to the following files would be overwritten by checkout: - rep/two rep/one + rep/two Please, commit your changes or stash them before you can switch branches. EOF @@ -89,8 +89,8 @@ test_expect_success 'cannot switch branches because of local changes' ' cat >expect <<\EOF error: Your local changes to the following files would be overwritten by checkout: - rep/two rep/one + rep/two Please, commit your changes or stash them before you can switch branches. EOF @@ -102,8 +102,8 @@ test_expect_success 'not uptodate file porcelain checkout error' ' cat >expect <<\EOF error: Updating the following directories would lose untracked files in it: - rep2 rep + rep2 EOF diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index 3bd74042ef..d78bdec330 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -54,7 +54,7 @@ test_expect_success 'custom mergetool' ' test_expect_success 'mergetool crlf' ' git config core.autocrlf true && - git checkout -b test2 branch1 + git checkout -b test2 branch1 && test_must_fail git merge master >/dev/null 2>&1 && ( yes "" | git mergetool file1 >/dev/null 2>&1 ) && ( yes "" | git mergetool file2 >/dev/null 2>&1 ) && diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index c2f66ff170..d954b846a1 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -56,7 +56,7 @@ test_expect_success 'loose objects in alternate ODB are not repacked' ' ' test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' ' - mkdir alt_objects/pack + mkdir alt_objects/pack && mv .git/objects/pack/* alt_objects/pack && git repack -a && myidx=$(ls -1 .git/objects/pack/*.idx) && @@ -95,14 +95,14 @@ test_expect_success 'packed obs in alternate ODB kept pack are repacked' ' # swap the .keep so the commit object is in the pack with .keep for p in alt_objects/pack/*.pack do - base_name=$(basename $p .pack) + base_name=$(basename $p .pack) && if test -f alt_objects/pack/$base_name.keep then rm alt_objects/pack/$base_name.keep else touch alt_objects/pack/$base_name.keep fi - done + done && git repack -a -d && myidx=$(ls -1 .git/objects/pack/*.idx) && test -f "$myidx" && diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 58dc6f6452..4048d106d4 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -98,7 +98,7 @@ test_expect_success PERL 'difftool --gui works without configured diff.guitool' # Specify the diff tool using $GIT_DIFF_TOOL test_expect_success PERL 'GIT_DIFF_TOOL variable' ' - git config --unset diff.tool + test_might_fail git config --unset diff.tool && GIT_DIFF_TOOL=test-tool && export GIT_DIFF_TOOL && @@ -166,7 +166,7 @@ test_expect_success PERL 'difftool.prompt config variable is false' ' # Test that we don't have to pass --no-prompt when mergetool.prompt is false test_expect_success PERL 'difftool merge.prompt = false' ' - git config --unset difftool.prompt + test_might_fail git config --unset difftool.prompt && git config mergetool.prompt false && diff=$(git difftool branch) && @@ -211,7 +211,7 @@ test_expect_success PERL 'difftool last flag wins' ' # git-difftool falls back to git-mergetool config variables # so test that behavior here test_expect_success PERL 'difftool + mergetool config variables' ' - remove_config_vars + remove_config_vars && git config merge.tool test-tool && git config mergetool.test-tool.cmd "cat \$LOCAL" && @@ -254,17 +254,17 @@ test_expect_success PERL 'difftool -x cat' ' ' test_expect_success PERL 'difftool --extcmd echo arg1' ' - diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"echo\ \$1\" branch) + diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"echo\ \$1\" branch) && test "$diff" = file ' test_expect_success PERL 'difftool --extcmd cat arg1' ' - diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$1\" branch) + diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$1\" branch) && test "$diff" = master ' test_expect_success PERL 'difftool --extcmd cat arg2' ' - diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$2\" branch) + diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$2\" branch) && test "$diff" = branch ' diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 50658845ca..c8777589ca 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -479,7 +479,7 @@ test_expect_success 'outside of git repository' ' echo file1:hello && echo sub/file2:world } >non/expect.full && - echo file2:world >non/expect.sub + echo file2:world >non/expect.sub && ( GIT_CEILING_DIRECTORIES="$(pwd)/non/git" && export GIT_CEILING_DIRECTORIES && @@ -505,7 +505,7 @@ test_expect_success 'inside git repository but with --no-index' ' echo sub/file2:world } >is/expect.full && : >is/expect.empty && - echo file2:world >is/expect.sub + echo file2:world >is/expect.sub && ( cd is/git && git init && diff --git a/t/t8002-blame.sh b/t/t8002-blame.sh index 597cf0486f..d3a51e1269 100755 --- a/t/t8002-blame.sh +++ b/t/t8002-blame.sh @@ -6,4 +6,9 @@ test_description='git blame' PROG='git blame -c' . "$TEST_DIRECTORY"/annotate-tests.sh +PROG='git blame -c -e' +test_expect_success 'Blame --show-email works' ' + check_count "<A@test.git>" 1 "<B@test.git>" 1 "<B1@test.git>" 1 "<B2@test.git>" 1 "<author@example.com>" 1 "<C@test.git>" 1 "<D@test.git>" 1 +' + test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index d1ba25205b..5e48318013 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -313,6 +313,49 @@ test_expect_success $PREREQ 'Valid In-Reply-To when prompting' ' ! grep "^In-Reply-To: < *>" msgtxt1 ' +test_expect_success $PREREQ 'In-Reply-To without --chain-reply-to' ' + clean_fake_sendmail && + echo "<unique-message-id@example.com>" >expect && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --no-chain-reply-to \ + --in-reply-to="$(cat expect)" \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches $patches $patches \ + 2>errors && + # The first message is a reply to --in-reply-to + sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual && + test_cmp expect actual && + # Second and subsequent messages are replies to the first one + sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect && + sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual && + test_cmp expect actual && + sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual && + test_cmp expect actual +' + +test_expect_success $PREREQ 'In-Reply-To with --chain-reply-to' ' + clean_fake_sendmail && + echo "<unique-message-id@example.com>" >expect && + git send-email \ + --from="Example <nobody@example.com>" \ + --to=nobody@example.com \ + --chain-reply-to \ + --in-reply-to="$(cat expect)" \ + --smtp-server="$(pwd)/fake.sendmail" \ + $patches $patches $patches \ + 2>errors && + sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt1 >actual && + test_cmp expect actual && + sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt1 >expect && + sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt2 >actual && + test_cmp expect actual && + sed -n -e "s/^Message-Id: *\(.*\)/\1/p" msgtxt2 >expect && + sed -n -e "s/^In-Reply-To: *\(.*\)/\1/p" msgtxt3 >actual && + test_cmp expect actual +' + test_expect_success $PREREQ 'setup fake editor' ' (echo "#!$SHELL_PATH" && echo "echo fake edit >>\"\$1\"" diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index f7f3c5ab8e..13b179e721 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -190,7 +190,7 @@ test_expect_success "follow-parent is atomic" ' git svn init --minimize-url -i stunk "$svnrepo"/stunk && git svn fetch -i stunk && git svn init --minimize-url -i flunked "$svnrepo"/flunked && - git svn fetch -i flunked + git svn fetch -i flunked && test "`git rev-parse --verify refs/remotes/flunk@18`" \ = "`git rev-parse --verify refs/remotes/stunk`" && test "`git rev-parse --verify refs/remotes/flunk~1`" \ diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh index 0ed90d982d..fd8184787f 100755 --- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -16,7 +16,7 @@ rm -rf import test_expect_success 'init, fetch and checkout repository' ' git svn init --rewrite-root=http://invalid.invalid/ "$svnrepo" && - git svn fetch + git svn fetch && git checkout -b mybranch ${remotes_git_svn} ' diff --git a/t/t9124-git-svn-dcommit-auto-props.sh b/t/t9124-git-svn-dcommit-auto-props.sh index d6b076f6b7..aa841e1299 100755 --- a/t/t9124-git-svn-dcommit-auto-props.sh +++ b/t/t9124-git-svn-dcommit-auto-props.sh @@ -24,7 +24,7 @@ test_expect_success 'initialize git svn' ' svn_cmd import -m "import for git svn" . "$svnrepo" ) && rm -rf import && - git svn init "$svnrepo" + git svn init "$svnrepo" && git svn fetch ' diff --git a/t/t9143-git-svn-gc.sh b/t/t9143-git-svn-gc.sh index 337ea59711..4594e1ae2f 100755 --- a/t/t9143-git-svn-gc.sh +++ b/t/t9143-git-svn-gc.sh @@ -37,13 +37,11 @@ test_expect_success 'git svn gc runs' 'git svn gc' test_expect_success 'git svn index removed' '! test -f .git/svn/refs/remotes/git-svn/index' -if perl -MCompress::Zlib -e 0 2>/dev/null +if test -r .git/svn/refs/remotes/git-svn/unhandled.log.gz then test_expect_success 'git svn gc produces a valid gzip file' ' gunzip .git/svn/refs/remotes/git-svn/unhandled.log.gz ' -else - say "# Perl Compress::Zlib unavailable, skipping gunzip test" fi test_expect_success 'git svn gc does not change unhandled.log files' ' diff --git a/t/t9146-git-svn-empty-dirs.sh b/t/t9146-git-svn-empty-dirs.sh index 565365cbd3..158c8e33ef 100755 --- a/t/t9146-git-svn-empty-dirs.sh +++ b/t/t9146-git-svn-empty-dirs.sh @@ -33,7 +33,7 @@ test_expect_success 'more emptiness' ' ' test_expect_success 'git svn rebase creates empty directory' ' - ( cd cloned && git svn rebase ) + ( cd cloned && git svn rebase ) && test -d cloned/"! !" ' diff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh index 250c651eae..4f6c06ecb2 100755 --- a/t/t9151-svn-mergeinfo.sh +++ b/t/t9151-svn-mergeinfo.sh @@ -18,39 +18,39 @@ test_expect_success 'load svn dump' " test_expect_success 'all svn merges became git merge commits' ' unmarked=$(git rev-list --parents --all --grep=Merge | - grep -v " .* " | cut -f1 -d" ") + grep -v " .* " | cut -f1 -d" ") && [ -z "$unmarked" ] ' test_expect_success 'cherry picks did not become git merge commits' ' bad_cherries=$(git rev-list --parents --all --grep=Cherry | - grep " .* " | cut -f1 -d" ") + grep " .* " | cut -f1 -d" ") && [ -z "$bad_cherries" ] ' test_expect_success 'svn non-merge merge commits did not become git merge commits' ' bad_non_merges=$(git rev-list --parents --all --grep=non-merge | - grep " .* " | cut -f1 -d" ") + grep " .* " | cut -f1 -d" ") && [ -z "$bad_non_merges" ] ' test_expect_success 'commit made to merged branch is reachable from the merge' ' - before_commit=$(git rev-list --all --grep="trunk commit before merging trunk to b2") - merge_commit=$(git rev-list --all --grep="Merge trunk to b2") - not_reachable=$(git rev-list -1 $before_commit --not $merge_commit) + before_commit=$(git rev-list --all --grep="trunk commit before merging trunk to b2") && + merge_commit=$(git rev-list --all --grep="Merge trunk to b2") && + not_reachable=$(git rev-list -1 $before_commit --not $merge_commit) && [ -z "$not_reachable" ] ' test_expect_success 'merging two branches in one commit is detected correctly' ' - f1_commit=$(git rev-list --all --grep="make f1 branch from trunk") - f2_commit=$(git rev-list --all --grep="make f2 branch from trunk") - merge_commit=$(git rev-list --all --grep="Merge f1 and f2 to trunk") - not_reachable=$(git rev-list -1 $f1_commit $f2_commit --not $merge_commit) + f1_commit=$(git rev-list --all --grep="make f1 branch from trunk") && + f2_commit=$(git rev-list --all --grep="make f2 branch from trunk") && + merge_commit=$(git rev-list --all --grep="Merge f1 and f2 to trunk") && + not_reachable=$(git rev-list -1 $f1_commit $f2_commit --not $merge_commit) && [ -z "$not_reachable" ] ' test_expect_failure 'everything got merged in the end' ' - unmerged=$(git rev-list --all --not master) + unmerged=$(git rev-list --all --not master) && [ -z "$unmerged" ] ' diff --git a/t/t9158-git-svn-mergeinfo.sh b/t/t9158-git-svn-mergeinfo.sh new file mode 100644 index 0000000000..3ab43902b3 --- /dev/null +++ b/t/t9158-git-svn-mergeinfo.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# +# Copyright (c) 2010 Steven Walter +# + +test_description='git svn mergeinfo propagation' + +. ./lib-git-svn.sh + +say 'define NO_SVN_TESTS to skip git svn tests' + +test_expect_success 'initialize source svn repo' ' + svn_cmd mkdir -m x "$svnrepo"/trunk && + svn_cmd co "$svnrepo"/trunk "$SVN_TREE" && + ( + cd "$SVN_TREE" && + touch foo && + svn_cmd add foo && + svn_cmd commit -m "initial commit" + ) && + rm -rf "$SVN_TREE" +' + +test_expect_success 'clone svn repo' ' + git svn init "$svnrepo"/trunk && + git svn fetch +' + +test_expect_success 'change svn:mergeinfo' ' + touch bar && + git add bar && + git commit -m "bar" && + git svn dcommit --mergeinfo="/branches/foo:1-10" +' + +test_expect_success 'verify svn:mergeinfo' ' + mergeinfo=$(svn_cmd propget svn:mergeinfo "$svnrepo"/trunk) + test "$mergeinfo" = "/branches/foo:1-10" +' + +test_done diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 3c0cf0509d..e8034d410f 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -321,7 +321,7 @@ test_expect_success \ 'for p in .git/objects/pack/*.pack;do git verify-pack $p||exit;done' test_expect_success \ 'C: validate reuse existing blob' \ - 'test $newf = `git rev-parse --verify branch:file2/newf` + 'test $newf = `git rev-parse --verify branch:file2/newf` && test $oldf = `git rev-parse --verify branch:file2/oldf`' cat >expect <<EOF @@ -928,6 +928,114 @@ test_expect_success \ git diff-tree -C --find-copies-harder -r N5^^ N5 >actual && compare_diff_raw expect actual' +test_expect_success \ + 'N: reject foo/ syntax' \ + 'subdir=$(git rev-parse refs/heads/branch^0:file2) && + test_must_fail git fast-import <<-INPUT_END + commit refs/heads/N5B + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + copy with invalid syntax + COMMIT + + from refs/heads/branch^0 + M 040000 $subdir file3/ + INPUT_END' + +test_expect_success \ + 'N: copy to root by id and modify' \ + 'echo "hello, world" >expect.foo && + echo hello >expect.bar && + git fast-import <<-SETUP_END && + commit refs/heads/N7 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + hello, tree + COMMIT + + deleteall + M 644 inline foo/bar + data <<EOF + hello + EOF + SETUP_END + + tree=$(git rev-parse --verify N7:) && + git fast-import <<-INPUT_END && + commit refs/heads/N8 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + copy to root by id and modify + COMMIT + + M 040000 $tree "" + M 644 inline foo/foo + data <<EOF + hello, world + EOF + INPUT_END + git show N8:foo/foo >actual.foo && + git show N8:foo/bar >actual.bar && + test_cmp expect.foo actual.foo && + test_cmp expect.bar actual.bar' + +test_expect_success \ + 'N: extract subtree' \ + 'branch=$(git rev-parse --verify refs/heads/branch^{tree}) && + cat >input <<-INPUT_END && + commit refs/heads/N9 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + extract subtree branch:newdir + COMMIT + + M 040000 $branch "" + C "newdir" "" + INPUT_END + git fast-import <input && + git diff --exit-code branch:newdir N9' + +test_expect_success \ + 'N: modify subtree, extract it, and modify again' \ + 'echo hello >expect.baz && + echo hello, world >expect.qux && + git fast-import <<-SETUP_END && + commit refs/heads/N10 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + hello, tree + COMMIT + + deleteall + M 644 inline foo/bar/baz + data <<EOF + hello + EOF + SETUP_END + + tree=$(git rev-parse --verify N10:) && + git fast-import <<-INPUT_END && + commit refs/heads/N11 + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE + data <<COMMIT + copy to root by id and modify + COMMIT + + M 040000 $tree "" + M 100644 inline foo/bar/qux + data <<EOF + hello, world + EOF + R "foo" "" + C "bar/qux" "bar/quux" + INPUT_END + git show N11:bar/baz >actual.baz && + git show N11:bar/qux >actual.qux && + git show N11:bar/quux >actual.quux && + test_cmp expect.baz actual.baz && + test_cmp expect.qux actual.qux && + test_cmp expect.qux actual.quux' + ### ### series O ### diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh index a5c99d8507..7cf8cd8a2f 100755 --- a/t/t9301-fast-import-notes.sh +++ b/t/t9301-fast-import-notes.sh @@ -255,13 +255,18 @@ EOF INPUT_END +whitespace=" " + cat >expect <<EXPECT_END fourth commit pre-prefix of note for fourth commit +$whitespace prefix of note for fourth commit +$whitespace third note for fourth commit third commit prefix of note for third commit +$whitespace third note for third commit second commit third note for second commit diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 8c8e679468..f823c05305 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -26,7 +26,7 @@ test_expect_success 'setup' ' test_tick && git tag rein && git checkout -b wer HEAD^ && - echo lange > file2 + echo lange > file2 && test_tick && git commit -m sitzt file2 && test_tick && diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 36c457e7f2..9199550ef4 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -57,7 +57,7 @@ test_expect_success 'setup' ' # as argument to co -d test_expect_success 'basic checkout' \ 'GIT_CONFIG="$git_config" cvs -Q co -d cvswork master && - test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | head -n 1))" = "empty/1.1/" + test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | head -n 1))" = "empty/1.1/" && test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | sed -ne \$p))" = "secondrootfile/1.1/"' #------------------------ diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index 1bbfd824e5..ff6d6fb473 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -70,7 +70,7 @@ test_expect_success 'setup' ' mkdir subdir && echo "Another text file" > subdir/file.h && echo "Another binary: Q (this time CR)" | q_to_cr > subdir/withCr.bin && - echo "Mixed up NUL, but marked text: Q <- there" | q_to_nul > mixedUp.c + echo "Mixed up NUL, but marked text: Q <- there" | q_to_nul > mixedUp.c && echo "Unspecified" > subdir/unspecified.other && echo "/*.bin -crlf" > .gitattributes && echo "/*.c crlf" >> .gitattributes && diff --git a/t/test-lib.sh b/t/test-lib.sh index 38e5a59ff7..48fa516004 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -305,6 +305,17 @@ remove_cr () { tr '\015' Q | sed -e 's/Q$//' } +# In some bourne shell implementations, the "unset" builtin returns +# nonzero status when a variable to be unset was not set in the first +# place. +# +# Use sane_unset when that should not be considered an error. + +sane_unset () { + unset "$@" + return 0 +} + test_tick () { if test -z "${test_tick+set}" then @@ -521,24 +532,6 @@ test_expect_success () { echo >&3 "" } -test_expect_code () { - test "$#" = 4 && { prereq=$1; shift; } || prereq= - test "$#" = 3 || - error "bug in the test script: not 3 or 4 parameters to test-expect-code" - if ! test_skip "$@" - then - say >&3 "expecting exit code $1: $3" - test_run_ "$3" - if [ "$?" = 0 -a "$eval_ret" = "$1" ] - then - test_ok_ "$2" - else - test_failure_ "$@" - fi - fi - echo >&3 "" -} - # test_external runs external test scripts that provide continuous # test output about their progress, and succeeds/fails on # zero/non-zero exit code. It outputs the test output on stdout even @@ -654,6 +647,28 @@ test_path_is_missing () { fi } +# test_line_count checks that a file has the number of lines it +# ought to. For example: +# +# test_expect_success 'produce exactly one line of output' ' +# do something >output && +# test_line_count = 1 output +# ' +# +# is like "test $(wc -l <output) = 1" except that it passes the +# output through when the number of lines is wrong. + +test_line_count () { + if test $# != 3 + then + error "bug in the test script: not 3 parameters to test_line_count" + elif ! test $(wc -l <"$3") "$1" "$2" + then + echo "test_line_count: line count for $3 !$1 $2" + cat "$3" + return 1 + fi +} # This is not among top-level (test_expect_success | test_expect_failure) # but is a prefix that can be used in the test script, like: @@ -707,6 +722,28 @@ test_might_fail () { return 0 } +# Similar to test_must_fail and test_might_fail, but check that a +# given command exited with a given exit code. Meant to be used as: +# +# test_expect_success 'Merge with d/f conflicts' ' +# test_expect_code 1 git merge "merge msg" B master +# ' + +test_expect_code () { + want_code=$1 + shift + "$@" + exit_code=$? + if test $exit_code = $want_code + then + echo >&2 "test_expect_code: command exited with $exit_code: $*" + return 0 + else + echo >&2 "test_expect_code: command exited with $exit_code, we wanted $want_code $*" + return 1 + fi +} + # test_cmp is a helper function to compare actual and expected output. # You can use it like: # |