diff options
Diffstat (limited to 't')
46 files changed, 1382 insertions, 176 deletions
@@ -1,7 +1,7 @@ -Core GIT Tests +Core Git Tests ============== -This directory holds many test scripts for core GIT tools. The +This directory holds many test scripts for core Git tools. The first part of this short document describes how to run the tests and read their output. @@ -1117,21 +1117,21 @@ Tips for Writing Tests As with any programming projects, existing programs are the best source of the information. However, do _not_ emulate t0000-basic.sh when writing your tests. The test is special in -that it tries to validate the very core of GIT. For example, it +that it tries to validate the very core of Git. For example, it knows that there will be 256 subdirectories under .git/objects/, and it knows that the object ID of an empty tree is a certain 40-byte string. This is deliberately done so in t0000-basic.sh because the things the very basic core test tries to achieve is -to serve as a basis for people who are changing the GIT internal +to serve as a basis for people who are changing the Git internals drastically. For these people, after making certain changes, not seeing failures from the basic test _is_ a failure. And -such drastic changes to the core GIT that even changes these +such drastic changes to the core Git that even changes these otherwise supposedly stable object IDs should be accompanied by an update to t0000-basic.sh. However, other tests that simply rely on basic parts of the core -GIT working properly should not have that level of intimate -knowledge of the core GIT internals. If all the test scripts +Git working properly should not have that level of intimate +knowledge of the core Git internals. If all the test scripts hardcoded the object IDs like t0000-basic.sh does, that defeats the purpose of t0000-basic.sh, which is to isolate that level of validation in one place. Your test also ends up needing diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c index 12ca698e17..69152958e5 100644 --- a/t/helper/test-pkt-line.c +++ b/t/helper/test-pkt-line.c @@ -46,6 +46,9 @@ static void unpack(void) case PACKET_READ_DELIM: printf("0001\n"); break; + case PACKET_READ_RESPONSE_END: + printf("0002\n"); + break; } } } @@ -75,6 +78,7 @@ static void unpack_sideband(void) case PACKET_READ_FLUSH: return; case PACKET_READ_DELIM: + case PACKET_READ_RESPONSE_END: break; } } diff --git a/t/helper/test-regex.c b/t/helper/test-regex.c index 10284cc56f..d6f28ca8d1 100644 --- a/t/helper/test-regex.c +++ b/t/helper/test-regex.c @@ -1,5 +1,4 @@ #include "test-tool.h" -#include "git-compat-util.h" #include "gettext.h" struct reg_flag { @@ -8,12 +7,13 @@ struct reg_flag { }; static struct reg_flag reg_flags[] = { - { "EXTENDED", REG_EXTENDED }, - { "NEWLINE", REG_NEWLINE }, - { "ICASE", REG_ICASE }, - { "NOTBOL", REG_NOTBOL }, + { "EXTENDED", REG_EXTENDED }, + { "NEWLINE", REG_NEWLINE }, + { "ICASE", REG_ICASE }, + { "NOTBOL", REG_NOTBOL }, + { "NOTEOL", REG_NOTEOL }, #ifdef REG_STARTEND - { "STARTEND", REG_STARTEND }, + { "STARTEND", REG_STARTEND }, #endif { NULL, 0 } }; @@ -41,36 +41,74 @@ int cmd__regex(int argc, const char **argv) { const char *pat; const char *str; - int flags = 0; + int ret, silent = 0, flags = 0; regex_t r; regmatch_t m[1]; - - if (argc == 2 && !strcmp(argv[1], "--bug")) - return test_regex_bug(); - else if (argc < 3) - usage("test-tool regex --bug\n" - "test-tool regex <pattern> <string> [<options>]"); + char errbuf[64]; argv++; - pat = *argv++; - str = *argv++; - while (*argv) { - struct reg_flag *rf; - for (rf = reg_flags; rf->name; rf++) - if (!strcmp(*argv, rf->name)) { - flags |= rf->flag; - break; - } - if (!rf->name) - die("do not recognize %s", *argv); + argc--; + + if (!argc) + goto usage; + + if (!strcmp(*argv, "--bug")) { + if (argc == 1) + return test_regex_bug(); + else + goto usage; + } + if (!strcmp(*argv, "--silent")) { + silent = 1; argv++; + argc--; + } + if (!argc) + goto usage; + + pat = *argv++; + if (argc == 1) + str = NULL; + else { + str = *argv++; + while (*argv) { + struct reg_flag *rf; + for (rf = reg_flags; rf->name; rf++) + if (!strcmp(*argv, rf->name)) { + flags |= rf->flag; + break; + } + if (!rf->name) + die("do not recognize flag %s", *argv); + argv++; + } } git_setup_gettext(); - if (regcomp(&r, pat, flags)) - die("failed regcomp() for pattern '%s'", pat); - if (regexec(&r, str, 1, m, 0)) - return 1; + ret = regcomp(&r, pat, flags); + if (ret) { + if (silent) + return ret; + + regerror(ret, &r, errbuf, sizeof(errbuf)); + die("failed regcomp() for pattern '%s' (%s)", pat, errbuf); + } + if (!str) + return 0; + + ret = regexec(&r, str, 1, m, 0); + if (ret) { + if (silent || ret == REG_NOMATCH) + return ret; + + regerror(ret, &r, errbuf, sizeof(errbuf)); + die("failed regexec() for subject '%s' (%s)", str, errbuf); + } return 0; +usage: + usage("\ttest-tool regex --bug\n" + "\ttest-tool regex [--silent] <pattern>\n" + "\ttest-tool regex [--silent] <pattern> <string> [<options>]"); + return -1; } diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 1449ee95e9..d2edfa4c50 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -129,6 +129,8 @@ install_script () { prepare_httpd() { mkdir -p "$HTTPD_DOCUMENT_ROOT_PATH" cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH" + install_script incomplete-length-upload-pack-v2-http.sh + install_script incomplete-body-upload-pack-v2-http.sh install_script broken-smart-http.sh install_script error-smart-http.sh install_script error.sh diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 994e5290d6..afa91e38b0 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -117,6 +117,8 @@ Alias /auth/dumb/ www/auth/dumb/ SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} SetEnv GIT_HTTP_EXPORT_ALL </LocationMatch> +ScriptAlias /smart/incomplete_length/git-upload-pack incomplete-length-upload-pack-v2-http.sh/ +ScriptAlias /smart/incomplete_body/git-upload-pack incomplete-body-upload-pack-v2-http.sh/ ScriptAliasMatch /error_git_upload_pack/(.*)/git-upload-pack error.sh/ ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 ScriptAlias /broken_smart/ broken-smart-http.sh/ @@ -126,6 +128,12 @@ ScriptAliasMatch /one_time_perl/(.*) apply-one-time-perl.sh/$1 <Directory ${GIT_EXEC_PATH}> Options FollowSymlinks </Directory> +<Files incomplete-length-upload-pack-v2-http.sh> + Options ExecCGI +</Files> +<Files incomplete-body-upload-pack-v2-http.sh> + Options ExecCGI +</Files> <Files broken-smart-http.sh> Options ExecCGI </Files> diff --git a/t/lib-httpd/incomplete-body-upload-pack-v2-http.sh b/t/lib-httpd/incomplete-body-upload-pack-v2-http.sh new file mode 100644 index 0000000000..90e73ef8d5 --- /dev/null +++ b/t/lib-httpd/incomplete-body-upload-pack-v2-http.sh @@ -0,0 +1,3 @@ +printf "Content-Type: text/%s\n" "application/x-git-upload-pack-result" +echo +printf "%s%s" "0079" "45" diff --git a/t/lib-httpd/incomplete-length-upload-pack-v2-http.sh b/t/lib-httpd/incomplete-length-upload-pack-v2-http.sh new file mode 100644 index 0000000000..dce552e348 --- /dev/null +++ b/t/lib-httpd/incomplete-length-upload-pack-v2-http.sh @@ -0,0 +1,3 @@ +printf "Content-Type: text/%s\n" "application/x-git-upload-pack-result" +echo +printf "%s" "00" diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index 0aa9908ea1..960ed150cb 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -62,7 +62,7 @@ test_expect_success 'check commit-tree' ' ' test_expect_success 'check rev-list' ' - echo $SHA >"$REAL/HEAD" && + git update-ref "HEAD" "$SHA" && test "$SHA" = "$(git rev-list HEAD)" ' diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 88cdde255c..7cd45fc139 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -100,6 +100,28 @@ test_expect_success 'clone --sparse' ' check_files clone a ' +test_expect_success 'interaction with clone --no-checkout (unborn index)' ' + git clone --no-checkout "file://$(pwd)/repo" clone_no_checkout && + git -C clone_no_checkout sparse-checkout init --cone && + git -C clone_no_checkout sparse-checkout set folder1 && + + git -C clone_no_checkout sparse-checkout list >actual && + cat >expect <<-\EOF && + folder1 + EOF + test_cmp expect actual && + + # nothing checked out, expect "No such file or directory" + ! ls clone_no_checkout/* >actual && + test_must_be_empty actual && + test_path_is_missing clone_no_checkout/.git/index && + + # No branch is checked out until we manually switch to one + git -C clone_no_checkout switch master && + test_path_is_file clone_no_checkout/.git/index && + check_files clone_no_checkout a folder1 +' + test_expect_success 'set enables config' ' git init empty-config && ( diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index e1197ac818..27171f8261 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -37,15 +37,15 @@ test_expect_success setup ' test_expect_success "create $m" ' git update-ref $m $A && - test $A = $(cat .git/$m) + test $A = $(git show-ref -s --verify $m) ' test_expect_success "create $m with oldvalue verification" ' git update-ref $m $B $A && - test $B = $(cat .git/$m) + test $B = $(git show-ref -s --verify $m) ' test_expect_success "fail to delete $m with stale ref" ' test_must_fail git update-ref -d $m $A && - test $B = "$(cat .git/$m)" + test $B = "$(git show-ref -s --verify $m)" ' test_expect_success "delete $m" ' test_when_finished "rm -f .git/$m" && @@ -56,7 +56,7 @@ test_expect_success "delete $m" ' test_expect_success "delete $m without oldvalue verification" ' test_when_finished "rm -f .git/$m" && git update-ref $m $A && - test $A = $(cat .git/$m) && + test $A = $(git show-ref -s --verify $m) && git update-ref -d $m && test_path_is_missing .git/$m ' @@ -69,15 +69,15 @@ test_expect_success "fail to create $n" ' test_expect_success "create $m (by HEAD)" ' git update-ref HEAD $A && - test $A = $(cat .git/$m) + test $A = $(git show-ref -s --verify $m) ' test_expect_success "create $m (by HEAD) with oldvalue verification" ' git update-ref HEAD $B $A && - test $B = $(cat .git/$m) + test $B = $(git show-ref -s --verify $m) ' test_expect_success "fail to delete $m (by HEAD) with stale ref" ' test_must_fail git update-ref -d HEAD $A && - test $B = $(cat .git/$m) + test $B = $(git show-ref -s --verify $m) ' test_expect_success "delete $m (by HEAD)" ' test_when_finished "rm -f .git/$m" && @@ -178,14 +178,14 @@ test_expect_success '--no-create-reflog overrides core.logAllRefUpdates=always' test_expect_success "create $m (by HEAD)" ' git update-ref HEAD $A && - test $A = $(cat .git/$m) + test $A = $(git show-ref -s --verify $m) ' test_expect_success 'pack refs' ' git pack-refs --all ' test_expect_success "move $m (by HEAD)" ' git update-ref HEAD $B $A && - test $B = $(cat .git/$m) + test $B = $(git show-ref -s --verify $m) ' test_expect_success "delete $m (by HEAD) should remove both packed and loose $m" ' test_when_finished "rm -f .git/$m" && @@ -255,7 +255,7 @@ test_expect_success '(not) change HEAD with wrong SHA1' ' ' test_expect_success "(not) changed .git/$m" ' test_when_finished "rm -f .git/$m" && - ! test $B = $(cat .git/$m) + ! test $B = $(git show-ref -s --verify $m) ' rm -f .git/logs/refs/heads/master @@ -263,19 +263,19 @@ test_expect_success "create $m (logged by touch)" ' test_config core.logAllRefUpdates false && GIT_COMMITTER_DATE="2005-05-26 23:30" \ git update-ref --create-reflog HEAD $A -m "Initial Creation" && - test $A = $(cat .git/$m) + test $A = $(git show-ref -s --verify $m) ' test_expect_success "update $m (logged by touch)" ' test_config core.logAllRefUpdates false && GIT_COMMITTER_DATE="2005-05-26 23:31" \ git update-ref HEAD $B $A -m "Switch" && - test $B = $(cat .git/$m) + test $B = $(git show-ref -s --verify $m) ' test_expect_success "set $m (logged by touch)" ' test_config core.logAllRefUpdates false && GIT_COMMITTER_DATE="2005-05-26 23:41" \ git update-ref HEAD $A && - test $A = $(cat .git/$m) + test $A = $(git show-ref -s --verify $m) ' test_expect_success 'empty directory removal' ' @@ -319,19 +319,19 @@ test_expect_success "create $m (logged by config)" ' test_config core.logAllRefUpdates true && GIT_COMMITTER_DATE="2005-05-26 23:32" \ git update-ref HEAD $A -m "Initial Creation" && - test $A = $(cat .git/$m) + test $A = $(git show-ref -s --verify $m) ' test_expect_success "update $m (logged by config)" ' test_config core.logAllRefUpdates true && GIT_COMMITTER_DATE="2005-05-26 23:33" \ git update-ref HEAD'" $B $A "'-m "Switch" && - test $B = $(cat .git/$m) + test $B = $(git show-ref -s --verify $m) ' test_expect_success "set $m (logged by config)" ' test_config core.logAllRefUpdates true && GIT_COMMITTER_DATE="2005-05-26 23:43" \ git update-ref HEAD $A && - test $A = $(cat .git/$m) + test $A = $(git show-ref -s --verify $m) ' cat >expect <<EOF diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 91a6e34f38..344a2aad82 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -257,21 +257,34 @@ test_expect_success 'tree object with duplicate entries' ' test_i18ngrep "error in tree .*contains duplicate file entries" out ' -test_expect_success 'tree object with dublicate names' ' - test_when_finished "remove_object \$blob" && - test_when_finished "remove_object \$tree" && - test_when_finished "remove_object \$badtree" && - blob=$(echo blob | git hash-object -w --stdin) && - printf "100644 blob %s\t%s\n" $blob x.2 >tree && - tree=$(git mktree <tree) && - printf "100644 blob %s\t%s\n" $blob x.1 >badtree && - printf "100644 blob %s\t%s\n" $blob x >>badtree && - printf "040000 tree %s\t%s\n" $tree x >>badtree && - badtree=$(git mktree <badtree) && - test_must_fail git fsck 2>out && - test_i18ngrep "$badtree" out && - test_i18ngrep "error in tree .*contains duplicate file entries" out -' +check_duplicate_names () { + expect=$1 && + shift && + names=$@ && + test_expect_$expect "tree object with duplicate names: $names" ' + test_when_finished "remove_object \$blob" && + test_when_finished "remove_object \$tree" && + test_when_finished "remove_object \$badtree" && + blob=$(echo blob | git hash-object -w --stdin) && + printf "100644 blob %s\t%s\n" $blob x.2 >tree && + tree=$(git mktree <tree) && + for name in $names + do + case "$name" in + */) printf "040000 tree %s\t%s\n" $tree "${name%/}" ;; + *) printf "100644 blob %s\t%s\n" $blob "$name" ;; + esac + done >badtree && + badtree=$(git mktree <badtree) && + test_must_fail git fsck 2>out && + test_i18ngrep "$badtree" out && + test_i18ngrep "error in tree .*contains duplicate file entries" out + ' +} + +check_duplicate_names success x x.1 x/ +check_duplicate_names success x x.1.2 x.1/ x/ +check_duplicate_names success x x.1 x.1.2 x/ test_expect_success 'unparseable tree object' ' test_oid_cache <<-\EOF && diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index 52edcbdcc3..dbf690b9c1 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -207,7 +207,7 @@ test_expect_success 'arg before dashdash must be a revision (ambiguous)' ' { # we do not want to use rev-parse here, because # we are testing it - cat .git/refs/heads/foobar && + git show-ref -s refs/heads/foobar && printf "%s\n" -- } >expect && git rev-parse foobar -- >actual && diff --git a/t/t1509-root-work-tree.sh b/t/t1509-root-work-tree.sh index 553a3f601b..fd2f7abf1c 100755 --- a/t/t1509-root-work-tree.sh +++ b/t/t1509-root-work-tree.sh @@ -221,7 +221,7 @@ test_expect_success 'setup' ' rm -rf /.git && echo "Initialized empty Git repository in /.git/" > expected && git init > result && - test_cmp expected result + test_i18ncmp expected result ' test_vars 'auto gitdir, root' ".git" "/" "" @@ -246,7 +246,7 @@ test_expect_success 'setup' ' cd / && echo "Initialized empty Git repository in /" > expected && git init --bare > result && - test_cmp expected result + test_i18ncmp expected result ' test_vars 'auto gitdir, root' "." "" "" diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index 21583154d8..5f761bc616 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -260,4 +260,14 @@ test_expect_success 'checkout -b to a new branch preserves mergeable changes des test_cmp expect actual ' +test_expect_success 'checkout -b rejects an invalid start point' ' + test_must_fail git checkout -b branch4 file1 2>err && + test_i18ngrep "is not a commit" err +' + +test_expect_success 'checkout -b rejects an extra path argument' ' + test_must_fail git checkout -b branch5 branch1 file1 2>err && + test_i18ngrep "Cannot update paths and switch to branch" err +' + test_done diff --git a/t/t2027-checkout-track.sh b/t/t2027-checkout-track.sh new file mode 100755 index 0000000000..bcba1bf90c --- /dev/null +++ b/t/t2027-checkout-track.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +test_description='tests for git branch --track' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit one && + test_commit two +' + +test_expect_success 'checkout --track -b creates a new tracking branch' ' + git checkout --track -b branch1 master && + test $(git rev-parse --abbrev-ref HEAD) = branch1 && + test $(git config --get branch.branch1.remote) = . && + test $(git config --get branch.branch1.merge) = refs/heads/master +' + +test_expect_success 'checkout --track -b rejects an extra path argument' ' + test_must_fail git checkout --track -b branch2 master one.t 2>err && + test_i18ngrep "cannot be used with updating paths" err +' + +test_done diff --git a/t/t2060-switch.sh b/t/t2060-switch.sh index f9efa29dfb..2c1b8c0d6d 100755 --- a/t/t2060-switch.sh +++ b/t/t2060-switch.sh @@ -68,6 +68,14 @@ test_expect_success 'new orphan branch from empty' ' test_cmp expected tracked-files ' +test_expect_success 'orphan branch works with --discard-changes' ' + test_when_finished git switch master && + echo foo >foo.txt && + git switch --discard-changes --orphan new-orphan2 && + git ls-files >tracked-files && + test_must_be_empty tracked-files +' + test_expect_success 'switching ignores file of same branch name' ' test_when_finished git switch master && : >first-branch && diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh index b7d6d5d45a..a6ce7f590b 100755 --- a/t/t2401-worktree-prune.sh +++ b/t/t2401-worktree-prune.sh @@ -92,4 +92,28 @@ test_expect_success 'not prune proper checkouts' ' test -d .git/worktrees/nop ' +test_expect_success 'prune duplicate (linked/linked)' ' + test_when_finished rm -fr .git/worktrees w1 w2 && + git worktree add --detach w1 && + git worktree add --detach w2 && + sed "s/w2/w1/" .git/worktrees/w2/gitdir >.git/worktrees/w2/gitdir.new && + mv .git/worktrees/w2/gitdir.new .git/worktrees/w2/gitdir && + git worktree prune --verbose >actual && + test_i18ngrep "duplicate entry" actual && + test -d .git/worktrees/w1 && + ! test -d .git/worktrees/w2 +' + +test_expect_success 'prune duplicate (main/linked)' ' + test_when_finished rm -fr repo wt && + test_create_repo repo && + test_commit -C repo x && + git -C repo worktree add --detach ../wt && + rm -fr wt && + mv repo wt && + git -C wt worktree prune --verbose >actual && + test_i18ngrep "duplicate entry" actual && + ! test -d .git/worktrees/wt +' + test_done diff --git a/t/t2403-worktree-move.sh b/t/t2403-worktree-move.sh index 939d18d728..a4e1a178e0 100755 --- a/t/t2403-worktree-move.sh +++ b/t/t2403-worktree-move.sh @@ -112,6 +112,27 @@ test_expect_success 'move locked worktree (force)' ' git worktree move --force --force flump ploof ' +test_expect_success 'refuse to move worktree atop existing path' ' + >bobble && + git worktree add --detach beeble && + test_must_fail git worktree move beeble bobble +' + +test_expect_success 'move atop existing but missing worktree' ' + git worktree add --detach gnoo && + git worktree add --detach pneu && + rm -fr pneu && + test_must_fail git worktree move gnoo pneu && + git worktree move --force gnoo pneu && + + git worktree add --detach nu && + git worktree lock nu && + rm -fr nu && + test_must_fail git worktree move pneu nu && + test_must_fail git worktree --force move pneu nu && + git worktree move --force --force pneu nu +' + test_expect_success 'move a repo with uninitialized submodule' ' git init withsub && ( diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 411a70b0ce..1fd03cae80 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -323,11 +323,11 @@ test_expect_success 'git branch --list -v with --abbrev' ' test_expect_success 'git branch --column' ' COLUMNS=81 git branch --column=column >actual && - cat >expected <<\EOF && + cat >expect <<\EOF && a/b/c bam foo l * master mb o/o q abc bar j/k m/m master2 n o/p r EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'git branch --column with an extremely long branch name' ' @@ -336,7 +336,7 @@ test_expect_success 'git branch --column with an extremely long branch name' ' test_when_finished "git branch -d $long" && git branch $long && COLUMNS=80 git branch --column=column >actual && - cat >expected <<EOF && + cat >expect <<EOF && a/b/c abc bam @@ -355,7 +355,7 @@ test_expect_success 'git branch --column with an extremely long branch name' ' r $long EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'git branch with column.*' ' @@ -364,11 +364,11 @@ test_expect_success 'git branch with column.*' ' COLUMNS=80 git branch >actual && git config --unset column.branch && git config --unset column.ui && - cat >expected <<\EOF && + cat >expect <<\EOF && a/b/c bam foo l * master mb o/o q abc bar j/k m/m master2 n o/p r EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'git branch --column -v should fail' ' @@ -379,7 +379,7 @@ test_expect_success 'git branch -v with column.ui ignored' ' git config column.ui column && COLUMNS=80 git branch -v | cut -c -10 | sed "s/ *$//" >actual && git config --unset column.ui && - cat >expected <<\EOF && + cat >expect <<\EOF && a/b/c abc bam @@ -397,7 +397,7 @@ test_expect_success 'git branch -v with column.ui ignored' ' q r EOF - test_cmp expected actual + test_cmp expect actual ' mv .git/config .git/config-saved @@ -835,32 +835,42 @@ test_expect_success 'branch from tag w/--track causes failure' ' ' test_expect_success '--set-upstream-to fails on multiple branches' ' - test_must_fail git branch --set-upstream-to master a b c + echo "fatal: too many arguments to set new upstream" >expect && + test_must_fail git branch --set-upstream-to master a b c 2>err && + test_i18ncmp expect err ' test_expect_success '--set-upstream-to fails on detached HEAD' ' git checkout HEAD^{} && - test_must_fail git branch --set-upstream-to master && - git checkout - + test_when_finished git checkout - && + echo "fatal: could not set upstream of HEAD to master when it does not point to any branch." >expect && + test_must_fail git branch --set-upstream-to master 2>err && + test_i18ncmp expect err ' test_expect_success '--set-upstream-to fails on a missing dst branch' ' - test_must_fail git branch --set-upstream-to master does-not-exist + echo "fatal: branch '"'"'does-not-exist'"'"' does not exist" >expect && + test_must_fail git branch --set-upstream-to master does-not-exist 2>err && + test_i18ncmp expect err ' test_expect_success '--set-upstream-to fails on a missing src branch' ' - test_must_fail git branch --set-upstream-to does-not-exist master + test_must_fail git branch --set-upstream-to does-not-exist master 2>err && + test_i18ngrep "the requested upstream branch '"'"'does-not-exist'"'"' does not exist" err ' test_expect_success '--set-upstream-to fails on a non-ref' ' - test_must_fail git branch --set-upstream-to HEAD^{} + echo "fatal: Cannot setup tracking information; starting point '"'"'HEAD^{}'"'"' is not a branch." >expect && + test_must_fail git branch --set-upstream-to HEAD^{} 2>err && + test_i18ncmp expect err ' test_expect_success '--set-upstream-to fails on locked config' ' test_when_finished "rm -f .git/config.lock" && >.git/config.lock && git branch locked && - test_must_fail git branch --set-upstream-to locked + test_must_fail git branch --set-upstream-to locked 2>err && + test_i18ngrep "could not lock config file .git/config: File exists" err ' test_expect_success 'use --set-upstream-to modify HEAD' ' @@ -881,14 +891,17 @@ test_expect_success 'use --set-upstream-to modify a particular branch' ' ' test_expect_success '--unset-upstream should fail if given a non-existent branch' ' - test_must_fail git branch --unset-upstream i-dont-exist + echo "fatal: Branch '"'"'i-dont-exist'"'"' has no upstream information" >expect && + test_must_fail git branch --unset-upstream i-dont-exist 2>err && + test_i18ncmp expect err ' test_expect_success '--unset-upstream should fail if config is locked' ' test_when_finished "rm -f .git/config.lock" && git branch --set-upstream-to locked && >.git/config.lock && - test_must_fail git branch --unset-upstream + test_must_fail git branch --unset-upstream 2>err && + test_i18ngrep "could not lock config file .git/config: File exists" err ' test_expect_success 'test --unset-upstream on HEAD' ' @@ -900,17 +913,23 @@ test_expect_success 'test --unset-upstream on HEAD' ' test_must_fail git config branch.master.remote && test_must_fail git config branch.master.merge && # fail for a branch without upstream set - test_must_fail git branch --unset-upstream + echo "fatal: Branch '"'"'master'"'"' has no upstream information" >expect && + test_must_fail git branch --unset-upstream 2>err && + test_i18ncmp expect err ' test_expect_success '--unset-upstream should fail on multiple branches' ' - test_must_fail git branch --unset-upstream a b c + echo "fatal: too many arguments to unset upstream" >expect && + test_must_fail git branch --unset-upstream a b c 2>err && + test_i18ncmp expect err ' test_expect_success '--unset-upstream should fail on detached HEAD' ' git checkout HEAD^{} && - test_must_fail git branch --unset-upstream && - git checkout - + test_when_finished git checkout - && + echo "fatal: could not unset upstream of HEAD when it does not point to any branch." >expect && + test_must_fail git branch --unset-upstream 2>err && + test_i18ncmp expect err ' test_expect_success 'test --unset-upstream on a particular branch' ' @@ -922,17 +941,17 @@ test_expect_success 'test --unset-upstream on a particular branch' ' ' test_expect_success 'disabled option --set-upstream fails' ' - test_must_fail git branch --set-upstream origin/master + test_must_fail git branch --set-upstream origin/master ' test_expect_success '--set-upstream-to notices an error to set branch as own upstream' ' git branch --set-upstream-to refs/heads/my13 my13 2>actual && - cat >expected <<-\EOF && + cat >expect <<-\EOF && warning: Not setting branch my13 as its own upstream. EOF test_expect_code 1 git config branch.my13.remote && test_expect_code 1 git config branch.my13.merge && - test_i18ncmp expected actual + test_i18ncmp expect actual ' # Keep this test last, as it changes the current branch diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index a1bc3e2001..b454f400eb 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -420,7 +420,7 @@ test_expect_success 'with --autosquash and --exec' ' git commit --fixup B B.t && write_script show.sh <<-\EOF && subject="$(git show -s --format=%s HEAD)" - content="$(git diff HEAD^! | tail -n 1)" + content="$(git diff HEAD^ HEAD | tail -n 1)" echo "$subject: $content" EOF test_tick && diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b3d8bb7577..49decbac71 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -412,6 +412,25 @@ test_expect_success 'deleting an empty file' ' diff_cmp expected diff ' +test_expect_success 'adding an empty file' ' + git init added && + ( + cd added && + test_commit initial && + >empty && + git add empty && + test_tick && + git commit -m empty && + git tag added-file && + git reset --hard HEAD^ && + test_path_is_missing empty && + + echo y | git checkout -p added-file -- >actual && + test_path_is_file empty && + test_i18ngrep "Apply addition to index and worktree" actual + ) +' + test_expect_success 'split hunk setup' ' git reset --hard && test_write_lines 10 20 30 40 50 60 >test && diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index db7e733af9..575e079cc2 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1602,6 +1602,19 @@ test_expect_success 'format patch ignores color.ui' ' test_cmp expect actual ' +test_expect_success 'format patch respects diff.relative' ' + rm -rf subdir && + mkdir subdir && + echo other content >subdir/file2 && + git add subdir/file2 && + git commit -F msg && + test_unconfig diff.relative && + git format-patch --relative=subdir --stdout -1 >expect && + test_config diff.relative true && + git -C subdir format-patch --stdout -1 >actual && + test_cmp expect actual +' + test_expect_success 'cover letter with invalid --cover-from-description and config' ' test_config branch.rebuild-1.description "config subject diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh index 258808708e..7be1de736d 100755 --- a/t/t4045-diff-relative.sh +++ b/t/t4045-diff-relative.sh @@ -8,7 +8,8 @@ test_expect_success 'setup' ' echo content >file1 && mkdir subdir && echo other content >subdir/file2 && - blob=$(git hash-object subdir/file2) && + blob_file1=$(git hash-object file1) && + blob_file2=$(git hash-object subdir/file2) && git add . && git commit -m one ' @@ -18,7 +19,7 @@ check_diff () { shift expect=$1 shift - short_blob=$(git rev-parse --short $blob) + short_blob=$(git rev-parse --short $blob_file2) cat >expected <<-EOF diff --git a/$expect b/$expect new file mode 100644 @@ -70,7 +71,7 @@ check_raw () { expect=$1 shift cat >expected <<-EOF - :000000 100644 $ZERO_OID $blob A $expect + :000000 100644 $ZERO_OID $blob_file2 A $expect EOF test_expect_success "--raw $*" " git -C '$dir' diff --no-abbrev --raw $* HEAD^ >actual && @@ -86,4 +87,79 @@ do check_$type . dir/file2 --relative=sub done +check_diff_relative_option () { + dir=$1 + shift + expect=$1 + shift + relative_opt=$1 + shift + test_expect_success "config diff.relative $relative_opt -p $*" " + short_blob=\$(git rev-parse --short $blob_file2) && + cat >expected <<-EOF && + diff --git a/$expect b/$expect + new file mode 100644 + index 0000000..\$short_blob + --- /dev/null + +++ b/$expect + @@ -0,0 +1 @@ + +other content + EOF + test_config -C $dir diff.relative $relative_opt && + git -C '$dir' diff -p $* HEAD^ >actual && + test_cmp expected actual + " +} + +check_diff_no_relative_option () { + dir=$1 + shift + expect=$1 + shift + relative_opt=$1 + shift + test_expect_success "config diff.relative $relative_opt -p $*" " + short_blob_file1=\$(git rev-parse --short $blob_file1) && + short_blob_file2=\$(git rev-parse --short $blob_file2) && + cat >expected <<-EOF && + diff --git a/file1 b/file1 + new file mode 100644 + index 0000000..\$short_blob_file1 + --- /dev/null + +++ b/file1 + @@ -0,0 +1 @@ + +content + diff --git a/$expect b/$expect + new file mode 100644 + index 0000000..\$short_blob_file2 + --- /dev/null + +++ b/$expect + @@ -0,0 +1 @@ + +other content + EOF + test_config -C $dir diff.relative $relative_opt && + git -C '$dir' diff -p $* HEAD^ >actual && + test_cmp expected actual + " +} + +check_diff_no_relative_option . subdir/file2 false +check_diff_no_relative_option . subdir/file2 true --no-relative +check_diff_no_relative_option . subdir/file2 false --no-relative +check_diff_no_relative_option subdir subdir/file2 false +check_diff_no_relative_option subdir subdir/file2 true --no-relative +check_diff_no_relative_option subdir subdir/file2 false --no-relative + +check_diff_relative_option . file2 false --relative=subdir/ +check_diff_relative_option . file2 false --relative=subdir +check_diff_relative_option . file2 true --relative=subdir/ +check_diff_relative_option . file2 true --relative=subdir +check_diff_relative_option subdir file2 false --relative +check_diff_relative_option subdir file2 true --relative +check_diff_relative_option subdir file2 true +check_diff_relative_option subdir file2 false --no-relative --relative +check_diff_relative_option subdir file2 true --no-relative --relative +check_diff_relative_option . file2 false --no-relative --relative=subdir +check_diff_relative_option . file2 true --no-relative --relative=subdir + test_done diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh index c1ed1c2fc4..ef8e0e9cb0 100755 --- a/t/t4067-diff-partial-clone.sh +++ b/t/t4067-diff-partial-clone.sh @@ -125,8 +125,8 @@ test_expect_success 'diff with rename detection batches blobs' ' # Ensure that there is exactly 1 negotiation by checking that there is # only 1 "done" line sent. ("done" marks the end of negotiation.) - GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff -M HEAD^ HEAD >out && - grep "similarity index" out && + GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD >out && + grep ":100644 100644.*R[0-9][0-9][0-9].*b.*c" out && grep "git> done" trace >done_lines && test_line_count = 1 done_lines ' diff --git a/t/t4068-diff-symmetric.sh b/t/t4068-diff-symmetric.sh new file mode 100755 index 0000000000..31d17a5af0 --- /dev/null +++ b/t/t4068-diff-symmetric.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +test_description='behavior of diff with symmetric-diff setups' + +. ./test-lib.sh + +# build these situations: +# - normal merge with one merge base (br1...b2r); +# - criss-cross merge ie 2 merge bases (br1...master); +# - disjoint subgraph (orphan branch, br3...master). +# +# B---E <-- master +# / \ / +# A X +# \ / \ +# C---D--G <-- br1 +# \ / +# ---F <-- br2 +# +# H <-- br3 +# +# We put files into a few commits so that we can verify the +# output as well. + +test_expect_success setup ' + git commit --allow-empty -m A && + echo b >b && + git add b && + git commit -m B && + git checkout -b br1 HEAD^ && + echo c >c && + git add c && + git commit -m C && + git tag commit-C && + git merge -m D master && + git tag commit-D && + git checkout master && + git merge -m E commit-C && + git checkout -b br2 commit-C && + echo f >f && + git add f && + git commit -m F && + git checkout br1 && + git merge -m G br2 && + git checkout --orphan br3 && + git commit -m H +' + +test_expect_success 'diff with one merge base' ' + git diff commit-D...br1 >tmp && + tail -n 1 tmp >actual && + echo +f >expect && + test_cmp expect actual +' + +# The output (in tmp) can have +b or +c depending +# on which merge base (commit B or C) is picked. +# It should have one of those two, which comes out +# to seven lines. +test_expect_success 'diff with two merge bases' ' + git diff br1...master >tmp 2>err && + test_line_count = 7 tmp && + test_line_count = 1 err +' + +test_expect_success 'diff with no merge bases' ' + test_must_fail git diff br2...br3 >tmp 2>err && + test_i18ngrep "fatal: br2...br3: no merge base" err +' + +test_expect_success 'diff with too many symmetric differences' ' + test_must_fail git diff br1...master br2...br3 >tmp 2>err && + test_i18ngrep "usage" err +' + +test_expect_success 'diff with symmetric difference and extraneous arg' ' + test_must_fail git diff master br1...master >tmp 2>err && + test_i18ngrep "usage" err +' + +test_expect_success 'diff with two ranges' ' + test_must_fail git diff master br1..master br2..br3 >tmp 2>err && + test_i18ngrep "usage" err +' + +test_expect_success 'diff with ranges and extra arg' ' + test_must_fail git diff master br1..master commit-D >tmp 2>err && + test_i18ngrep "usage" err +' + +test_done diff --git a/t/t4202-log.sh b/t/t4202-log.sh index f1ea7d97f5..a0930599aa 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -1692,7 +1692,7 @@ test_expect_success GPG 'log --graph --show-signature for merged tag with missin GNUPGHOME=. git log --graph --show-signature -n1 plain-nokey >actual && grep "^|\\\ merged tag" actual && grep "^| | gpg: Signature made" actual && - grep "^| | gpg: Can'"'"'t check signature: \(public key not found\|No public key\)" actual + grep -E "^| | gpg: Can'"'"'t check signature: (public key not found|No public key)" actual ' test_expect_success GPG 'log --graph --show-signature for merged tag with bad signature' ' diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index c3792081e6..d2dfcf164e 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -10,6 +10,13 @@ latin1_e=$(printf '\351') # invalid UTF-8 invalid_e=$(printf '\303\50)') # ")" at end to close opening "(" +have_reg_illseq= +if test_have_prereq GETTEXT_LOCALE && + ! LC_ALL=$is_IS_locale test-tool regex --silent $latin1_e +then + have_reg_illseq=1 +fi + test_expect_success 'create commits in different encodings' ' test_tick && cat >msg <<-EOF && @@ -51,43 +58,77 @@ test_expect_success !MINGW 'log --grep does not find non-reencoded values (utf8) test_must_be_empty actual ' -test_expect_success !MINGW 'log --grep does not find non-reencoded values (latin1)' ' +test_expect_success 'log --grep does not find non-reencoded values (latin1)' ' git log --encoding=ISO-8859-1 --format=%s --grep=$utf8_e >actual && test_must_be_empty actual ' +triggers_undefined_behaviour () { + local engine=$1 + + case $engine in + fixed) + if test -n "$have_reg_illseq" && + ! test_have_prereq LIBPCRE2 + then + return 0 + fi + ;; + basic|extended) + if test -n "$have_reg_illseq" + then + return 0 + fi + ;; + esac + return 1 +} + +mismatched_git_log () { + local pattern=$1 + + LC_ALL=$is_IS_locale git log --encoding=ISO-8859-1 --format=%s \ + --grep=$pattern +} + for engine in fixed basic extended perl do prereq= if test $engine = "perl" then - prereq="PCRE" - else - prereq="" + prereq=PCRE fi force_regex= if test $engine != "fixed" then - force_regex=.* + force_regex='.*' fi - test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " - cat >expect <<-\EOF && - latin1 - utf8 - EOF - LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$latin1_e\" >actual && - test_cmp expect actual - " - test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " - LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$utf8_e\" >actual && - test_must_be_empty actual + test_expect_success $prereq "config grep.patternType=$engine" " + git config grep.patternType $engine " - test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" " - LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$invalid_e\" >actual && + test_expect_success GETTEXT_LOCALE,$prereq "log --grep does not find non-reencoded values (latin1 + locale)" " + mismatched_git_log '$force_regex$utf8_e' >actual && test_must_be_empty actual " + + if ! triggers_undefined_behaviour $engine + then + test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "log --grep searches in log output encoding (latin1 + locale)" " + cat >expect <<-\EOF && + latin1 + utf8 + EOF + mismatched_git_log '$force_regex$latin1_e' >actual && + test_cmp expect actual + " + + test_expect_success GETTEXT_LOCALE,$prereq "log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" " + mismatched_git_log '$force_regex$invalid_e' >actual && + test_must_be_empty actual + " + fi done test_done diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index cda58186c2..1428eae262 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -215,4 +215,72 @@ test_expect_success 'fancy rename following #2' ' test_cmp expect actual ' +# Create the following linear history, where each commit does what its +# subject line promises: +# +# * 66c6410 Modify func2() in file.c +# * 50834e5 Modify other-file +# * fe5851c Modify func1() in file.c +# * 8c7c7dd Add other-file +# * d5f4417 Add func1() and func2() in file.c +test_expect_success 'setup for checking line-log and parent oids' ' + git checkout --orphan parent-oids && + git reset --hard && + + cat >file.c <<-\EOF && + int func1() + { + return F1; + } + + int func2() + { + return F2; + } + EOF + git add file.c && + test_tick && + git commit -m "Add func1() and func2() in file.c" && + + echo 1 >other-file && + git add other-file && + git commit -m "Add other-file" && + + sed -e "s/F1/F1 + 1/" file.c >tmp && + mv tmp file.c && + git commit -a -m "Modify func1() in file.c" && + + echo 2 >other-file && + git commit -a -m "Modify other-file" && + + sed -e "s/F2/F2 + 2/" file.c >tmp && + mv tmp file.c && + git commit -a -m "Modify func2() in file.c" && + + head_oid=$(git rev-parse --short HEAD) && + prev_oid=$(git rev-parse --short HEAD^) && + root_oid=$(git rev-parse --short HEAD~4) +' + +# Parent oid should be from immediate parent. +test_expect_success 'parent oids without parent rewriting' ' + cat >expect <<-EOF && + $head_oid $prev_oid Modify func2() in file.c + $root_oid Add func1() and func2() in file.c + EOF + git log --format="%h %p %s" --no-patch -L:func2:file.c >actual && + test_cmp expect actual +' + +# Parent oid should be from the most recent ancestor touching func2(), +# i.e. in this case from the root commit. +test_expect_success 'parent oids with parent rewriting' ' + cat >expect <<-EOF && + $head_oid $root_oid Modify func2() in file.c + $root_oid Add func1() and func2() in file.c + EOF + git log --format="%h %p %s" --no-patch -L:func2:file.c --parents >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh index 21b68dd6c8..c855bcd3e7 100755 --- a/t/t4216-log-bloom.sh +++ b/t/t4216-log-bloom.sh @@ -70,7 +70,7 @@ test_bloom_filters_used () { test_bloom_filters_not_used () { log_args=$1 setup "$log_args" && - !(grep -q "statistics:{\"filter_not_present\":" "$TRASH_DIRECTORY/trace.perf") && + ! grep -q "statistics:{\"filter_not_present\":" "$TRASH_DIRECTORY/trace.perf" && test_cmp log_wo_bloom log_w_bloom } diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 424599959c..26f332d6a3 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -46,15 +46,6 @@ test_expect_success 'create commits and repack' ' git repack ' -test_expect_success 'exit with correct error on bad input to --stdin-commits' ' - cd "$TRASH_DIRECTORY/full" && - echo HEAD | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr && - test_i18ngrep "unexpected non-hex object ID: HEAD" stderr && - # valid tree OID, but not a commit OID - git rev-parse HEAD^{tree} | test_expect_code 1 git commit-graph write --stdin-commits 2>stderr && - test_i18ngrep "invalid commit object id" stderr -' - graph_git_two_modes() { git -c core.commitGraph=true $1 >output git -c core.commitGraph=false $1 >expect @@ -95,6 +86,22 @@ graph_read_expect() { test_cmp expect output } +test_expect_success 'exit with correct error on bad input to --stdin-commits' ' + cd "$TRASH_DIRECTORY/full" && + # invalid, non-hex OID + echo HEAD >in && + test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr && + test_i18ngrep "unexpected non-hex object ID: HEAD" stderr && + # non-existent OID + echo $ZERO_OID >in && + test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr && + test_i18ngrep "invalid object" stderr && + # valid commit and tree OID + git rev-parse HEAD HEAD^{tree} >in && + git commit-graph write --stdin-commits <in && + graph_read_expect 3 +' + test_expect_success 'write graph' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write && @@ -140,7 +147,7 @@ test_expect_success 'Add more commits' ' test_expect_success 'commit-graph write progress off for redirected stderr' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write 2>err && - test_line_count = 0 err + test_must_be_empty err ' test_expect_success 'commit-graph write force progress on for stderr' ' @@ -152,13 +159,34 @@ test_expect_success 'commit-graph write force progress on for stderr' ' test_expect_success 'commit-graph write with the --no-progress option' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write --no-progress 2>err && - test_line_count = 0 err + test_must_be_empty err +' + +test_expect_success 'commit-graph write --stdin-commits progress off for redirected stderr' ' + cd "$TRASH_DIRECTORY/full" && + git rev-parse commits/5 >in && + git commit-graph write --stdin-commits <in 2>err && + test_must_be_empty err +' + +test_expect_success 'commit-graph write --stdin-commits force progress on for stderr' ' + cd "$TRASH_DIRECTORY/full" && + git rev-parse commits/5 >in && + GIT_PROGRESS_DELAY=0 git commit-graph write --stdin-commits --progress <in 2>err && + test_i18ngrep "Collecting commits from input" err +' + +test_expect_success 'commit-graph write --stdin-commits with the --no-progress option' ' + cd "$TRASH_DIRECTORY/full" && + git rev-parse commits/5 >in && + git commit-graph write --stdin-commits --no-progress <in 2>err && + test_must_be_empty err ' test_expect_success 'commit-graph verify progress off for redirected stderr' ' cd "$TRASH_DIRECTORY/full" && git commit-graph verify 2>err && - test_line_count = 0 err + test_must_be_empty err ' test_expect_success 'commit-graph verify force progress on for stderr' ' @@ -170,7 +198,7 @@ test_expect_success 'commit-graph verify force progress on for stderr' ' test_expect_success 'commit-graph verify with the --no-progress option' ' cd "$TRASH_DIRECTORY/full" && git commit-graph verify --no-progress 2>err && - test_line_count = 0 err + test_must_be_empty err ' # Current graph structure: diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 37535d63a9..9fae07cdfa 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -28,7 +28,7 @@ test_pull_autostash_fail () { echo dirty >new_file && git add new_file && test_must_fail git pull "$@" . copy 2>err && - test_i18ngrep "\(uncommitted changes.\)\|\(overwritten by merge:\)" err + test_i18ngrep -E "uncommitted changes.|overwritten by merge:" err } test_expect_success setup ' diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index afc680d5e3..463d0f12e5 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -464,6 +464,21 @@ test_expect_success 'push status output scrubs password' ' grep "^To $HTTPD_URL/smart/test_repo.git" status ' +test_expect_success 'clone/fetch scrubs password from reflogs' ' + cd "$ROOT_PATH" && + git clone "$HTTPD_URL_USER_PASS/smart/test_repo.git" \ + reflog-test && + cd reflog-test && + test_commit prepare-for-force-fetch && + git switch -c away && + git fetch "$HTTPD_URL_USER_PASS/smart/test_repo.git" \ + +master:master && + # should have been scrubbed down to vanilla URL + git log -g master >reflog && + grep "$HTTPD_URL" reflog && + ! grep "$HTTPD_URL_USER_PASS" reflog +' + test_expect_success 'colorize errors/hints' ' cd "$ROOT_PATH"/test_repo_clone && test_must_fail git -c color.transport=always -c color.advice=always \ diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index 6788aeface..e40e9ed52f 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -185,6 +185,40 @@ test_expect_success 'redirects send auth to new location' ' expect_askpass both user@host auth/smart/repo.git ' +test_expect_success 'GIT_TRACE_CURL redacts auth details' ' + rm -rf redact-auth trace && + set_askpass user@host pass@host && + GIT_TRACE_CURL="$(pwd)/trace" git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth && + expect_askpass both user@host && + + # Ensure that there is no "Basic" followed by a base64 string, but that + # the auth details are redacted + ! grep "Authorization: Basic [0-9a-zA-Z+/]" trace && + grep "Authorization: Basic <redacted>" trace +' + +test_expect_success 'GIT_CURL_VERBOSE redacts auth details' ' + rm -rf redact-auth trace && + set_askpass user@host pass@host && + GIT_CURL_VERBOSE=1 git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth 2>trace && + expect_askpass both user@host && + + # Ensure that there is no "Basic" followed by a base64 string, but that + # the auth details are redacted + ! grep "Authorization: Basic [0-9a-zA-Z+/]" trace && + grep "Authorization: Basic <redacted>" trace +' + +test_expect_success 'GIT_TRACE_CURL does not redact auth details if GIT_TRACE_REDACT=0' ' + rm -rf redact-auth trace && + set_askpass user@host pass@host && + GIT_TRACE_REDACT=0 GIT_TRACE_CURL="$(pwd)/trace" \ + git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth && + expect_askpass both user@host && + + grep "Authorization: Basic [0-9a-zA-Z+/]" trace +' + test_expect_success 'disable dumb http on server' ' git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ config http.getanyfile false @@ -430,27 +464,39 @@ test_expect_success 'fetch by SHA-1 without tag following' ' --no-tags origin $(cat bar_hash) ' -test_expect_success 'GIT_REDACT_COOKIES redacts cookies' ' +test_expect_success 'cookies are redacted by default' ' rm -rf clone && echo "Set-Cookie: Foo=1" >cookies && echo "Set-Cookie: Bar=2" >>cookies && - GIT_TRACE_CURL=true GIT_REDACT_COOKIES=Bar,Baz \ + GIT_TRACE_CURL=true \ git -c "http.cookieFile=$(pwd)/cookies" clone \ $HTTPD_URL/smart/repo.git clone 2>err && - grep "Cookie:.*Foo=1" err && + grep "Cookie:.*Foo=<redacted>" err && grep "Cookie:.*Bar=<redacted>" err && + ! grep "Cookie:.*Foo=1" err && ! grep "Cookie:.*Bar=2" err ' -test_expect_success 'GIT_REDACT_COOKIES handles empty values' ' +test_expect_success 'empty values of cookies are also redacted' ' rm -rf clone && echo "Set-Cookie: Foo=" >cookies && - GIT_TRACE_CURL=true GIT_REDACT_COOKIES=Foo \ + GIT_TRACE_CURL=true \ git -c "http.cookieFile=$(pwd)/cookies" clone \ $HTTPD_URL/smart/repo.git clone 2>err && grep "Cookie:.*Foo=<redacted>" err ' +test_expect_success 'GIT_TRACE_REDACT=0 disables cookie redaction' ' + rm -rf clone && + echo "Set-Cookie: Foo=1" >cookies && + echo "Set-Cookie: Bar=2" >>cookies && + GIT_TRACE_REDACT=0 GIT_TRACE_CURL=true \ + git -c "http.cookieFile=$(pwd)/cookies" clone \ + $HTTPD_URL/smart/repo.git clone 2>err && + grep "Cookie:.*Foo=1" err && + grep "Cookie:.*Bar=2" err +' + test_expect_success 'GIT_TRACE_CURL_NO_DATA prevents data from being traced' ' rm -rf clone && GIT_TRACE_CURL=true \ diff --git a/t/t5581-http-curl-verbose.sh b/t/t5581-http-curl-verbose.sh index 5129b0724f..927aad0820 100755 --- a/t/t5581-http-curl-verbose.sh +++ b/t/t5581-http-curl-verbose.sh @@ -20,7 +20,7 @@ test_expect_success 'failure in git-upload-pack is shown' ' test_might_fail env GIT_CURL_VERBOSE=1 \ git clone "$HTTPD_URL/error_git_upload_pack/smart/repo.git" \ 2>curl_log && - grep "< HTTP/1.1 500 Intentional Breakage" curl_log + grep "<= Recv header: HTTP/1.1 500 Intentional Breakage" curl_log ' test_done diff --git a/t/t5608-clone-2gb.sh b/t/t5608-clone-2gb.sh index eee0842888..4c476d2fa1 100755 --- a/t/t5608-clone-2gb.sh +++ b/t/t5608-clone-2gb.sh @@ -5,12 +5,11 @@ test_description='Test cloning a repository larger than 2 gigabyte' if ! test_bool_env GIT_TEST_CLONE_2GB false then - say 'Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t' -else - test_set_prereq CLONE_2GB + skip_all='expensive 2GB clone test; enable with GIT_TEST_CLONE_2GB=true' + test_done fi -test_expect_success CLONE_2GB 'setup' ' +test_expect_success 'setup' ' git config pack.compression 0 && git config pack.depth 0 && @@ -38,13 +37,13 @@ test_expect_success CLONE_2GB 'setup' ' ' -test_expect_success CLONE_2GB 'clone - bare' ' +test_expect_success 'clone - bare' ' git clone --bare --no-hardlinks . clone-bare ' -test_expect_success CLONE_2GB 'clone - with worktree, file:// protocol' ' +test_expect_success 'clone - with worktree, file:// protocol' ' git clone "file://$(pwd)" clone-wt diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 53bda39fb7..7ab0217fb3 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -586,6 +586,53 @@ test_expect_success 'clone with http:// using protocol v2' ' ! grep "Send header: Transfer-Encoding: chunked" log ' +test_expect_success 'clone repository with http:// using protocol v2 with incomplete pktline length' ' + test_when_finished "rm -f log" && + + git init "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_length" && + test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_length" file && + + test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ + clone "$HTTPD_URL/smart/incomplete_length" incomplete_length_child 2>err && + + # Client requested to use protocol v2 + grep "Git-Protocol: version=2" log && + # Server responded using protocol v2 + grep "git< version 2" log && + # Client reported appropriate failure + test_i18ngrep "bytes of length header were received" err +' + +test_expect_success 'clone repository with http:// using protocol v2 with incomplete pktline body' ' + test_when_finished "rm -f log" && + + git init "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_body" && + test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/incomplete_body" file && + + test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ + clone "$HTTPD_URL/smart/incomplete_body" incomplete_body_child 2>err && + + # Client requested to use protocol v2 + grep "Git-Protocol: version=2" log && + # Server responded using protocol v2 + grep "git< version 2" log && + # Client reported appropriate failure + test_i18ngrep "bytes of body are still expected" err +' + +test_expect_success 'clone with http:// using protocol v2 and invalid parameters' ' + test_when_finished "rm -f log" && + + test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" \ + git -c protocol.version=2 \ + clone --shallow-since=20151012 "$HTTPD_URL/smart/http_parent" http_child_invalid && + + # Client requested to use protocol v2 + grep "Git-Protocol: version=2" log && + # Server responded using protocol v2 + grep "git< version 2" log +' + test_expect_success 'clone big repository with http:// using protocol v2' ' test_when_finished "rm -f log" && diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index a34460f7d8..92ad5eeec0 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -49,15 +49,18 @@ test_expect_success 'setup repository' ' test_expect_success 'config controls ref-in-want advertisement' ' test-tool serve-v2 --advertise-capabilities >out && - ! grep -a ref-in-want out && + perl -ne "/ref-in-want/ and print" out >out.filter && + test_must_be_empty out.filter && git config uploadpack.allowRefInWant false && test-tool serve-v2 --advertise-capabilities >out && - ! grep -a ref-in-want out && + perl -ne "/ref-in-want/ and print" out >out.filter && + test_must_be_empty out.filter && git config uploadpack.allowRefInWant true && test-tool serve-v2 --advertise-capabilities >out && - grep -a ref-in-want out + perl -ne "/ref-in-want/ and print" out >out.filter && + test_file_not_empty out.filter ' test_expect_success 'invalid want-ref line' ' diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index ac31faefa1..36d9b2b2e4 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -866,7 +866,9 @@ test_expect_success 'bisect cannot mix terms' ' test_expect_success 'bisect terms rejects invalid terms' ' git bisect reset && + test_must_fail git bisect start --term-good && test_must_fail git bisect start --term-good invalid..term && + test_must_fail git bisect start --term-bad && test_must_fail git bisect terms --term-bad invalid..term && test_must_fail git bisect terms --term-good bad && test_must_fail git bisect terms --term-good old && diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh index b047cf1c1c..f163893ff9 100755 --- a/t/t6042-merge-rename-corner-cases.sh +++ b/t/t6042-merge-rename-corner-cases.sh @@ -1379,4 +1379,59 @@ test_expect_success 'check nested conflicts from rename/rename(2to1)' ' ) ' +# Testcase rename/rename(1to2) of a binary file +# Commit O: orig +# Commit A: orig-A +# Commit B: orig-B +# Expected: CONFLICT(rename/rename) message, three unstaged entries in the +# index, and contents of orig-[AB] at path orig-[AB] +test_setup_rename_rename_1_to_2_binary () { + test_create_repo rename_rename_1_to_2_binary && + ( + cd rename_rename_1_to_2_binary && + + echo '* binary' >.gitattributes && + git add .gitattributes && + + test_seq 1 10 >orig && + git add orig && + git commit -m orig && + + git branch A && + git branch B && + + git checkout A && + git mv orig orig-A && + test_seq 1 11 >orig-A && + git add orig-A && + git commit -m orig-A && + + git checkout B && + git mv orig orig-B && + test_seq 0 10 >orig-B && + git add orig-B && + git commit -m orig-B + + ) +} + +test_expect_success 'rename/rename(1to2) with a binary file' ' + test_setup_rename_rename_1_to_2_binary && + ( + cd rename_rename_1_to_2_binary && + + git checkout A^0 && + + test_must_fail git merge -s recursive B^0 && + + # Make sure the index has the right number of entries + git ls-files -s >actual && + test_line_count = 4 actual && + + git rev-parse A:orig-A B:orig-B >expect && + git hash-object orig-A orig-B >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index e7e64e085d..c80dc10b8f 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -135,7 +135,7 @@ test_expect_success 'tag replaced commit' ' test_expect_success '"git fsck" works' ' git fsck master >fsck_master.out && test_i18ngrep "dangling commit $R" fsck_master.out && - test_i18ngrep "dangling tag $(cat .git/refs/tags/mytag)" fsck_master.out && + test_i18ngrep "dangling tag $(git show-ref -s refs/tags/mytag)" fsck_master.out && test -z "$(git fsck)" ' diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh index 2462b19ddd..30328b87f0 100755 --- a/t/t6132-pathspec-exclude.sh +++ b/t/t6132-pathspec-exclude.sh @@ -211,4 +211,37 @@ test_expect_success 't_e_i() exclude case #8' ' ) ' +test_expect_success 'grep --untracked PATTERN' ' + # This test is not an actual test of exclude patterns, rather it + # is here solely to ensure that if any tests are inserted, deleted, or + # changed above, that we still have untracked files with the expected + # contents for the NEXT two tests. + cat <<-\EOF >expect-grep && + actual + expect + sub/actual + sub/expect + EOF + git grep -l --untracked file -- >actual-grep && + test_cmp expect-grep actual-grep +' + +test_expect_success 'grep --untracked PATTERN :(exclude)DIR' ' + cat <<-\EOF >expect-grep && + actual + expect + EOF + git grep -l --untracked file -- ":(exclude)sub" >actual-grep && + test_cmp expect-grep actual-grep +' + +test_expect_success 'grep --untracked PATTERN :(exclude)*FILE' ' + cat <<-\EOF >expect-grep && + actual + sub/actual + EOF + git grep -l --untracked file -- ":(exclude)*expect" >actual-grep && + test_cmp expect-grep actual-grep +' + test_done diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index b15582a7a2..e4c2a6eca4 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -103,7 +103,7 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' ' GNUPGHOME=. git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 && grep "^Merge tag ${apos}signed-good-tag${apos}" actual && grep "^# gpg: Signature made" actual && - grep "^# gpg: Can${apos}t check signature: \(public key not found\|No public key\)" actual + grep -E "^# gpg: Can${apos}t check signature: (public key not found|No public key)" actual ' test_expect_success 'message for merging external branch' ' diff --git a/t/t9020-remote-svn.sh b/t/t9020-remote-svn.sh index 6fca08e5e3..9fcfa969a9 100755 --- a/t/t9020-remote-svn.sh +++ b/t/t9020-remote-svn.sh @@ -48,8 +48,8 @@ test_expect_success REMOTE_SVN 'simple fetch' ' ' test_debug ' - cat .git/refs/svn/svnsim/master - cat .git/refs/remotes/svnsim/master + git show-ref -s refs/svn/svnsim/master + git show-ref -s refs/remotes/svnsim/master ' test_expect_success REMOTE_SVN 'repeated fetch, nothing shall change' ' diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 768257b29e..e151df81c0 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -410,6 +410,34 @@ test_expect_success 'B: accept empty committer' ' test -z "$out" ' +test_expect_success 'B: reject invalid timezone' ' + cat >input <<-INPUT_END && + commit refs/heads/invalid-timezone + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1234567890 +051800 + data <<COMMIT + empty commit + COMMIT + INPUT_END + + test_when_finished "git update-ref -d refs/heads/invalid-timezone" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: accept invalid timezone with raw-permissive' ' + cat >input <<-INPUT_END && + commit refs/heads/invalid-timezone + committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1234567890 +051800 + data <<COMMIT + empty commit + COMMIT + INPUT_END + + git init invalid-timezone && + git -C invalid-timezone fast-import --date-format=raw-permissive <input && + git -C invalid-timezone cat-file -p invalid-timezone >out && + grep "1234567890 [+]051800" out +' + test_expect_success 'B: accept and fixup committer with no name' ' cat >input <<-INPUT_END && commit refs/heads/empty-committer-2 diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 3c44af6940..8f434a0931 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1240,6 +1240,461 @@ test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' ' test_cmp expected out ' +test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' ' + test_completion "git switch " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' ' + test_completion "git checkout " <<-\EOF + HEAD Z + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with --no-guess, complete only local branches' ' + test_completion "git switch --no-guess " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete only local branches' ' + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' ' + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' ' + test_completion "git switch --no-guess --guess " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - a later --no-guess overrides previous --guess, complete only local branches' ' + test_completion "git switch --guess --no-guess " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only completes refs' ' + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' ' + GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF + HEAD Z + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with --no-guess, only completes refs' ' + test_completion "git checkout --no-guess " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' ' + test_completion "git checkout --no-guess --guess " <<-\EOF + HEAD Z + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - a later --no-guess overrides previous --guess, complete only refs' ' + test_completion "git checkout --guess --no-guess " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with --detach, complete all references' ' + test_completion "git switch --detach " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with --detach, complete only references' ' + test_completion "git checkout --detach " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with -d, complete all references' ' + test_completion "git switch -d " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with -d, complete only references' ' + test_completion "git checkout -d " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with --track, complete only remote branches' ' + test_completion "git switch --track " <<-\EOF + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with --track, complete only remote branches' ' + test_completion "git checkout --track " <<-\EOF + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with --no-track, complete only local branch names' ' + test_completion "git switch --no-track " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - with --no-track, complete only local references' ' + test_completion "git checkout --no-track " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with -c, complete all references' ' + test_completion "git switch -c new-branch " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with -C, complete all references' ' + test_completion "git switch -C new-branch " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with -c and --track, complete all references' ' + test_completion "git switch -c new-branch --track " <<-EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with -C and --track, complete all references' ' + test_completion "git switch -C new-branch --track " <<-EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with -c and --no-track, complete all references' ' + test_completion "git switch -c new-branch --no-track " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - with -C and --no-track, complete all references' ' + test_completion "git switch -C new-branch --no-track " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with -b, complete all references' ' + test_completion "git checkout -b new-branch " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with -B, complete all references' ' + test_completion "git checkout -B new-branch " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with -b and --track, complete all references' ' + test_completion "git checkout -b new-branch --track " <<-EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with -B and --track, complete all references' ' + test_completion "git checkout -B new-branch --track " <<-EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with -b and --no-track, complete all references' ' + test_completion "git checkout -b new-branch --no-track " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git checkout - with -B and --no-track, complete all references' ' + test_completion "git checkout -B new-branch --no-track " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + +test_expect_success 'git switch - for -c, complete local branches and unique remote branches' ' + test_completion "git switch -c " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - for -C, complete local branches and unique remote branches' ' + test_completion "git switch -C " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - for -c with --no-guess, complete local branches only' ' + test_completion "git switch --no-guess -c " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - for -C with --no-guess, complete local branches only' ' + test_completion "git switch --no-guess -C " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - for -c with --no-track, complete local branches only' ' + test_completion "git switch --no-track -c " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - for -C with --no-track, complete local branches only' ' + test_completion "git switch --no-track -C " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' ' + test_completion "git checkout -b " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' ' + test_completion "git checkout -B " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - for -b with --no-guess, complete local branches only' ' + test_completion "git checkout --no-guess -b " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - for -B with --no-guess, complete local branches only' ' + test_completion "git checkout --no-guess -B " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - for -b with --no-track, complete local branches only' ' + test_completion "git checkout --no-track -b " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - for -B with --no-track, complete local branches only' ' + test_completion "git checkout --no-track -B " <<-\EOF + master Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' ' + test_completion "git switch --orphan " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git switch - --orphan with branch already provided completes nothing else' ' + test_completion "git switch --orphan master " <<-\EOF + + EOF +' + +test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' ' + test_completion "git checkout --orphan " <<-\EOF + branch-in-other Z + master Z + master-in-other Z + matching-branch Z + EOF +' + +test_expect_success 'git checkout - --orphan with branch already provided completes local refs for a start-point' ' + test_completion "git checkout --orphan master " <<-\EOF + HEAD Z + master Z + matching-branch Z + matching-tag Z + other/branch-in-other Z + other/master-in-other Z + EOF +' + test_expect_success 'teardown after ref completion' ' git branch -d matching-branch && git tag -d matching-tag && diff --git a/t/test-lib.sh b/t/test-lib.sh index baf94546da..dbc027ff26 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -675,20 +675,6 @@ die () { fi } -file_lineno () { - test -z "$GIT_TEST_FRAMEWORK_SELFTEST" && test -n "$BASH" || return 0 - eval ' - local i - for i in ${!BASH_SOURCE[*]} - do - case $i,"${BASH_SOURCE[$i]##*/}" in - 0,t[0-9]*.sh) echo "t/${BASH_SOURCE[$i]}:$LINENO: ${1+$1: }"; return;; - *,t[0-9]*.sh) echo "t/${BASH_SOURCE[$i]}:${BASH_LINENO[$(($i-1))]}: ${1+$1: }"; return;; - esac - done - ' -} - GIT_EXIT_OK= trap 'die' EXIT # Disable '-x' tracing, because with some shells, notably dash, it @@ -734,7 +720,7 @@ test_failure_ () { write_junit_xml_testcase "$1" " $junit_insert" fi test_failure=$(($test_failure + 1)) - say_color error "$(file_lineno error)not ok $test_count - $1" + say_color error "not ok $test_count - $1" shift printf '%s\n' "$*" | sed -e 's/^/# /' test "$immediate" = "" || { finalize_junit_xml; GIT_EXIT_OK=t; exit 1; } @@ -1503,12 +1489,6 @@ case $uname_s in test_set_prereq SED_STRIPS_CR test_set_prereq GREP_STRIPS_CR ;; -FreeBSD) - test_set_prereq REGEX_ILLSEQ - test_set_prereq POSIXPERM - test_set_prereq BSLASHPSPEC - test_set_prereq EXECKEEPSPID - ;; *) test_set_prereq POSIXPERM test_set_prereq BSLASHPSPEC @@ -1516,6 +1496,14 @@ FreeBSD) ;; esac +# Detect arches where a few things don't work +uname_m=$(uname -m) +case $uname_m in +parisc* | hppa*) + test_set_prereq HPPA + ;; +esac + ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PTHREADS" && test_set_prereq PTHREADS @@ -1655,7 +1643,7 @@ run_with_limited_cmdline () { } test_lazy_prereq CMDLINE_LIMIT ' - test_have_prereq !MINGW,!CYGWIN && + test_have_prereq !HPPA,!MINGW,!CYGWIN && run_with_limited_cmdline true ' @@ -1664,7 +1652,7 @@ run_with_limited_stack () { } test_lazy_prereq ULIMIT_STACK_SIZE ' - test_have_prereq !MINGW,!CYGWIN && + test_have_prereq !HPPA,!MINGW,!CYGWIN && run_with_limited_stack true ' |