diff options
Diffstat (limited to 't')
65 files changed, 1926 insertions, 195 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-bloom.c b/t/helper/test-bloom.c index 77eb27adac..f0aa80b98e 100644 --- a/t/helper/test-bloom.c +++ b/t/helper/test-bloom.c @@ -3,7 +3,7 @@ #include "test-tool.h" #include "commit.h" -struct bloom_filter_settings settings = DEFAULT_BLOOM_FILTER_SETTINGS; +static struct bloom_filter_settings settings = DEFAULT_BLOOM_FILTER_SETTINGS; static void add_string_to_filter(const char *data, struct bloom_filter *filter) { struct bloom_key key; @@ -44,7 +44,7 @@ static void get_bloom_filter_for_commit(const struct object_id *commit_oid) } static const char *bloom_usage = "\n" -" test-tool bloom get_murmer3 <string>\n" +" test-tool bloom get_murmur3 <string>\n" " test-tool bloom generate_filter <string> [<string>...]\n" " test-tool get_filter_for_commit <commit-hex>\n"; 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-reach.c b/t/helper/test-reach.c index a0272178b7..ccf837cb33 100644 --- a/t/helper/test-reach.c +++ b/t/helper/test-reach.c @@ -67,7 +67,7 @@ int cmd__reach(int ac, const char **av) die("failed to load commit for input %s resulting in oid %s\n", buf.buf, oid_to_hex(&oid)); - c = object_as_type(r, peeled, OBJ_COMMIT, 0); + c = object_as_type(peeled, OBJ_COMMIT, 0); if (!c) die("failed to load commit for input %s resulting in oid %s\n", 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/perf/p1400-update-ref.sh b/t/perf/p1400-update-ref.sh new file mode 100755 index 0000000000..d275a81248 --- /dev/null +++ b/t/perf/p1400-update-ref.sh @@ -0,0 +1,32 @@ +#!/bin/sh + +test_description="Tests performance of update-ref" + +. ./perf-lib.sh + +test_perf_fresh_repo + +test_expect_success "setup" ' + test_commit PRE && + test_commit POST && + printf "create refs/heads/%d PRE\n" $(test_seq 1000) >create && + printf "update refs/heads/%d POST PRE\n" $(test_seq 1000) >update && + printf "delete refs/heads/%d POST\n" $(test_seq 1000) >delete +' + +test_perf "update-ref" ' + for i in $(test_seq 1000) + do + git update-ref refs/heads/branch PRE && + git update-ref refs/heads/branch POST PRE && + git update-ref -d refs/heads/branch + done +' + +test_perf "update-ref --stdin" ' + git update-ref --stdin <create && + git update-ref --stdin <update && + git update-ref --stdin <delete +' + +test_done diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh index 80c53edca7..b3e725f031 100755 --- a/t/perf/p5310-pack-bitmaps.sh +++ b/t/perf/p5310-pack-bitmaps.sh @@ -53,6 +53,11 @@ test_perf 'rev-list count with blob:limit=1k' ' --filter=blob:limit=1k >/dev/null ' +test_perf 'rev-list count with tree:0' ' + git rev-list --use-bitmap-index --count --objects --all \ + --filter=tree:0 >/dev/null +' + test_perf 'simulated partial clone' ' git pack-objects --stdout --all --filter=blob:none </dev/null >/dev/null ' @@ -86,4 +91,9 @@ test_perf 'pack to file (partial bitmap)' ' git pack-objects --use-bitmap-index --all pack2b </dev/null >/dev/null ' +test_perf 'rev-list with tree filter (partial bitmap)' ' + git rev-list --use-bitmap-index --count --objects --all \ + --filter=tree:0 >/dev/null +' + test_done 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/t0091-bugreport.sh b/t/t0091-bugreport.sh index 2e73658a5c..526304ff95 100755 --- a/t/t0091-bugreport.sh +++ b/t/t0091-bugreport.sh @@ -57,5 +57,20 @@ test_expect_success 'can create leading directories outside of a git dir' ' nongit git bugreport -o foo/bar/baz ' +test_expect_success 'indicates populated hooks' ' + test_when_finished rm git-bugreport-hooks.txt && + test_when_finished rm -fr .git/hooks && + rm -fr .git/hooks && + mkdir .git/hooks && + for hook in applypatch-msg prepare-commit-msg.sample + do + write_script ".git/hooks/$hook" <<-EOF || return 1 + echo "hook $hook exists" + EOF + done && + git bugreport -s hooks && + grep applypatch-msg git-bugreport-hooks.txt && + ! grep prepare-commit-msg git-bugreport-hooks.txt +' test_done diff --git a/t/t0095-bloom.sh b/t/t0095-bloom.sh index 8f9eef116d..232ba2c485 100755 --- a/t/t0095-bloom.sh +++ b/t/t0095-bloom.sh @@ -89,8 +89,8 @@ test_expect_success 'get bloom filter for commit with 10 changes' ' git add smallDir && git commit -m "commit with 10 changes" && cat >expect <<-\EOF && - Filter_Length:25 - Filter_Data:82|a0|65|47|0c|92|90|c0|a1|40|02|a0|e2|40|e0|04|0a|9a|66|cf|80|19|85|42|23| + Filter_Length:14 + Filter_Data:02|b3|c4|a0|34|e7|fe|eb|cb|47|fe|a0|e8|72| EOF test-tool bloom get_filter_for_commit "$(git rev-parse HEAD)" >actual && test_cmp expect actual @@ -100,7 +100,7 @@ test_expect_success EXPENSIVE 'get bloom filter for commit with 513 changes' ' rm actual && rm expect && mkdir bigDir && - for i in $(test_seq 0 512) + for i in $(test_seq 0 511) do echo $i >bigDir/$i done && @@ -114,4 +114,4 @@ test_expect_success EXPENSIVE 'get bloom filter for commit with 513 changes' ' test_cmp expect actual ' -test_done
\ No newline at end of file +test_done diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index a3988bd4b8..463dc3a8be 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -30,6 +30,29 @@ test_expect_success 'extensions.partialclone without filter' ' git -C client fetch origin ' +test_expect_success 'convert shallow clone to partial clone' ' + rm -fr server client && + test_create_repo server && + test_commit -C server my_commit 1 && + test_commit -C server my_commit2 1 && + git clone --depth=1 "file://$(pwd)/server" client && + git -C client fetch --unshallow --filter="blob:none" && + test_cmp_config -C client true remote.origin.promisor && + test_cmp_config -C client blob:none remote.origin.partialclonefilter && + test_cmp_config -C client 1 core.repositoryformatversion +' + +test_expect_success 'convert shallow clone to partial clone must fail with any extension' ' + rm -fr server client && + test_create_repo server && + test_commit -C server my_commit 1 && + test_commit -C server my_commit2 1 && + git clone --depth=1 "file://$(pwd)/server" client && + test_cmp_config -C client 0 core.repositoryformatversion && + git -C client config extensions.partialclone origin && + test_must_fail git -C client fetch --unshallow --filter="blob:none" +' + test_expect_success 'missing reflog object, but promised by a commit, passes fsck' ' rm -rf repo && test_create_repo repo && diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh index d2d088d9a0..1ed1df351c 100755 --- a/t/t0500-progress-display.sh +++ b/t/t0500-progress-display.sh @@ -283,4 +283,30 @@ test_expect_success 'cover up after throughput shortens a lot' ' test_i18ncmp expect out ' +test_expect_success 'progress generates traces' ' + cat >in <<-\EOF && + throughput 102400 1000 + update + progress 10 + throughput 204800 2000 + update + progress 20 + throughput 307200 3000 + update + progress 30 + throughput 409600 4000 + update + progress 40 + EOF + + GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool progress --total=40 \ + "Working hard" <in 2>stderr && + + # t0212/parse_events.perl intentionally omits regions and data. + grep -e "region_enter" -e "\"category\":\"progress\"" trace.event && + grep -e "region_leave" -e "\"category\":\"progress\"" trace.event && + grep "\"key\":\"total_objects\",\"value\":\"40\"" trace.event && + grep "\"key\":\"total_bytes\",\"value\":\"409600\"" trace.event +' + test_done diff --git a/t/t1090-sparse-checkout-scope.sh b/t/t1090-sparse-checkout-scope.sh index 40cc004326..f35a73dd20 100755 --- a/t/t1090-sparse-checkout-scope.sh +++ b/t/t1090-sparse-checkout-scope.sh @@ -63,7 +63,6 @@ test_expect_success 'in partial clone, sparse checkout only fetches needed blobs git -C server commit -m message && test_config -C client core.sparsecheckout 1 && - test_config -C client extensions.partialclone origin && echo "!/*" >client/.git/info/sparse-checkout && echo "/a" >>client/.git/info/sparse-checkout && git -C client fetch --filter=blob:none origin && 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/t1416-ref-transaction-hooks.sh b/t/t1416-ref-transaction-hooks.sh new file mode 100755 index 0000000000..da58d867a5 --- /dev/null +++ b/t/t1416-ref-transaction-hooks.sh @@ -0,0 +1,109 @@ +#!/bin/sh + +test_description='reference transaction hooks' + +. ./test-lib.sh + +test_expect_success setup ' + mkdir -p .git/hooks && + test_commit PRE && + test_commit POST && + POST_OID=$(git rev-parse POST) +' + +test_expect_success 'hook allows updating ref if successful' ' + test_when_finished "rm .git/hooks/reference-transaction" && + git reset --hard PRE && + write_script .git/hooks/reference-transaction <<-\EOF && + echo "$*" >>actual + EOF + cat >expect <<-EOF && + prepared + committed + EOF + git update-ref HEAD POST && + test_cmp expect actual +' + +test_expect_success 'hook aborts updating ref in prepared state' ' + test_when_finished "rm .git/hooks/reference-transaction" && + git reset --hard PRE && + write_script .git/hooks/reference-transaction <<-\EOF && + if test "$1" = prepared + then + exit 1 + fi + EOF + test_must_fail git update-ref HEAD POST 2>err && + test_i18ngrep "ref updates aborted by hook" err +' + +test_expect_success 'hook gets all queued updates in prepared state' ' + test_when_finished "rm .git/hooks/reference-transaction actual" && + git reset --hard PRE && + write_script .git/hooks/reference-transaction <<-\EOF && + if test "$1" = prepared + then + while read -r line + do + printf "%s\n" "$line" + done >actual + fi + EOF + cat >expect <<-EOF && + $ZERO_OID $POST_OID HEAD + $ZERO_OID $POST_OID refs/heads/master + EOF + git update-ref HEAD POST <<-EOF && + update HEAD $ZERO_OID $POST_OID + update refs/heads/master $ZERO_OID $POST_OID + EOF + test_cmp expect actual +' + +test_expect_success 'hook gets all queued updates in committed state' ' + test_when_finished "rm .git/hooks/reference-transaction actual" && + git reset --hard PRE && + write_script .git/hooks/reference-transaction <<-\EOF && + if test "$1" = committed + then + while read -r line + do + printf "%s\n" "$line" + done >actual + fi + EOF + cat >expect <<-EOF && + $ZERO_OID $POST_OID HEAD + $ZERO_OID $POST_OID refs/heads/master + EOF + git update-ref HEAD POST && + test_cmp expect actual +' + +test_expect_success 'hook gets all queued updates in aborted state' ' + test_when_finished "rm .git/hooks/reference-transaction actual" && + git reset --hard PRE && + write_script .git/hooks/reference-transaction <<-\EOF && + if test "$1" = aborted + then + while read -r line + do + printf "%s\n" "$line" + done >actual + fi + EOF + cat >expect <<-EOF && + $ZERO_OID $POST_OID HEAD + $ZERO_OID $POST_OID refs/heads/master + EOF + git update-ref --stdin <<-EOF && + start + update HEAD POST $ZERO_OID + update refs/heads/master POST $ZERO_OID + abort + EOF + test_cmp expect actual +' + +test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 449ebc5657..344a2aad82 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -257,6 +257,35 @@ test_expect_success 'tree object with duplicate entries' ' 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 && junk sha1:twenty-bytes-of-junk 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/t2203-add-intent.sh b/t/t2203-add-intent.sh index 5bbe8dcce4..8a5d55054f 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -232,17 +232,54 @@ test_expect_success 'double rename detection in status' ' ) ' -test_expect_success 'diff-files/diff-cached shows ita as new/not-new files' ' +test_expect_success 'i-t-a files shown as new for "diff", "diff-files"; not-new for "diff --cached"' ' git reset --hard && - echo new >new-ita && - git add -N new-ita && + : >empty && + content="foo" && + echo "$content" >not-empty && + + hash_e=$(git hash-object empty) && + hash_n=$(git hash-object not-empty) && + hash_t=$(git hash-object -t tree /dev/null) && + + cat >expect.diff_p <<-EOF && + diff --git a/empty b/empty + new file mode 100644 + index 0000000..$(git rev-parse --short $hash_e) + diff --git a/not-empty b/not-empty + new file mode 100644 + index 0000000..$(git rev-parse --short $hash_n) + --- /dev/null + +++ b/not-empty + @@ -0,0 +1 @@ + +$content + EOF + cat >expect.diff_s <<-EOF && + create mode 100644 empty + create mode 100644 not-empty + EOF + cat >expect.diff_a <<-EOF && + :000000 100644 0000000 $(git rev-parse --short $hash_t) A$(printf "\t")empty + :000000 100644 0000000 $(git rev-parse --short $hash_t) A$(printf "\t")not-empty + EOF + + git add -N empty not-empty && + + git diff >actual && + test_cmp expect.diff_p actual && + git diff --summary >actual && - echo " create mode 100644 new-ita" >expected && - test_cmp expected actual && - git diff --cached --summary >actual2 && - test_must_be_empty actual2 -' + test_cmp expect.diff_s actual && + + git diff-files -p >actual && + test_cmp expect.diff_p actual && + git diff-files --abbrev >actual && + test_cmp expect.diff_a actual && + + git diff --cached >actual && + test_must_be_empty actual +' test_expect_success '"diff HEAD" includes ita as new files' ' git reset --hard && 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/t2404-worktree-config.sh b/t/t2404-worktree-config.sh index 286121d8de..9536d10919 100755 --- a/t/t2404-worktree-config.sh +++ b/t/t2404-worktree-config.sh @@ -23,8 +23,10 @@ test_expect_success 'config --worktree without extension' ' ' test_expect_success 'enable worktreeConfig extension' ' + git config core.repositoryformatversion 1 && git config extensions.worktreeConfig true && - test_cmp_config true extensions.worktreeConfig + test_cmp_config true extensions.worktreeConfig && + test_cmp_config 1 core.repositoryformatversion ' test_expect_success 'config is shared as before' ' diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 2a3fedc6b0..b6aa04bbec 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/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index 093de9005b..7bab6000dc 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -424,4 +424,20 @@ test_expect_success 'abort last squash' ' ! grep first actual ' +test_expect_success 'fixup a fixup' ' + echo 0to-fixup >file0 && + test_tick && + git commit -m "to-fixup" file0 && + test_tick && + git commit --squash HEAD -m X --allow-empty && + test_tick && + git commit --squash HEAD^ -m Y --allow-empty && + test_tick && + git commit -m "squash! $(git rev-parse HEAD^)" -m Z --allow-empty && + test_tick && + git commit -m "squash! $(git rev-parse HEAD^^)" -m W --allow-empty && + git rebase -ki --autosquash HEAD~5 && + test XZWY = $(git show | tr -cd W-Z) +' + test_done 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..958c2da56e 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -81,16 +81,16 @@ test_expect_success 'format-patch --ignore-if-in-upstream handles tags' ' ' test_expect_success "format-patch doesn't consider merge commits" ' - git checkout -b slave master && + git checkout -b feature master && echo "Another line" >>file && test_tick && - git commit -am "Slave change #1" && + git commit -am "Feature branch change #1" && echo "Yet another line" >>file && test_tick && - git commit -am "Slave change #2" && + git commit -am "Feature branch change #2" && git checkout -b merger master && test_tick && - git merge --no-ff slave && + git merge --no-ff feature && git format-patch -3 --stdout >patch && grep "^From " patch >from && test_line_count = 3 from @@ -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 c7011f33e2..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 } @@ -152,4 +152,4 @@ test_expect_success 'Use Bloom filters if they exist in the latest but not all c test_bloom_filters_used_when_some_filters_are_missing "-- A/B" ' -test_done
\ No newline at end of file +test_done 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/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index 030a7222b2..7214cab36c 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -538,6 +538,33 @@ test_expect_success 'repack with minimum size does not alter existing packs' ' ) ' +test_expect_success 'repack respects repack.packKeptObjects=false' ' + test_when_finished rm -f dup/.git/objects/pack/*keep && + ( + cd dup && + ls .git/objects/pack/*idx >idx-list && + test_line_count = 5 idx-list && + ls .git/objects/pack/*.pack | sed "s/\.pack/.keep/" >keep-list && + test_line_count = 5 keep-list && + for keep in $(cat keep-list) + do + touch $keep || return 1 + done && + git multi-pack-index repack --batch-size=0 && + ls .git/objects/pack/*idx >idx-list && + test_line_count = 5 idx-list && + test-tool read-midx .git/objects | grep idx >midx-list && + test_line_count = 5 midx-list && + THIRD_SMALLEST_SIZE=$(test-tool path-utils file-size .git/objects/pack/*pack | sort -n | sed -n 3p) && + BATCH_SIZE=$((THIRD_SMALLEST_SIZE + 1)) && + git multi-pack-index repack --batch-size=$BATCH_SIZE && + ls .git/objects/pack/*idx >idx-list && + test_line_count = 5 idx-list && + test-tool read-midx .git/objects | grep idx >midx-list && + test_line_count = 5 midx-list + ) +' + test_expect_success 'repack creates a new pack' ' ( cd dup && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 8fee99ecfb..3557374312 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -386,7 +386,7 @@ test_expect_success 'clone shallow with packed refs' ' ' test_expect_success 'in_vain not triggered before first ACK' ' - rm -rf myserver myclient trace && + rm -rf myserver myclient && git init myserver && test_commit -C myserver foo && git clone "file://$(pwd)/myserver" myclient && @@ -399,12 +399,12 @@ test_expect_success 'in_vain not triggered before first ACK' ' # The new commit that the client wants to fetch. test_commit -C myserver bar && - GIT_TRACE_PACKET="$(pwd)/trace" git -C myclient fetch --progress origin && - test_i18ngrep "Total 3 " trace + git -C myclient fetch --progress origin 2>log && + test_i18ngrep "remote: Total 3 " log ' test_expect_success 'in_vain resetted upon ACK' ' - rm -rf myserver myclient trace && + rm -rf myserver myclient && git init myserver && # Linked list of commits on master. The first is common; the rest are @@ -429,8 +429,8 @@ test_expect_success 'in_vain resetted upon ACK' ' # first. The 256th commit is common between the client and the server, # and should reset in_vain. This allows negotiation to continue until # the client reports that first_anotherbranch_commit is common. - GIT_TRACE_PACKET="$(pwd)/trace" git -C myclient fetch --progress origin master && - test_i18ngrep "Total 3 " trace + git -C myclient fetch --progress origin master 2>log && + test_i18ngrep "Total 3 " log ' test_expect_success 'fetch in shallow repo unreachable shallow objects' ' @@ -1000,7 +1000,6 @@ fetch_filter_blob_limit_zero () { test_config -C "$SERVER" uploadpack.allowfilter 1 && git clone "$URL" client && - test_config -C client extensions.partialclone origin && test_commit -C "$SERVER" two && 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/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index e57716bacd..483578b2d7 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -217,6 +217,28 @@ test_expect_success 'fetch packed objects' ' git clone $HTTPD_URL/dumb/repo_pack.git ' +test_expect_success 'http-fetch --packfile' ' + # Arbitrary hash. Use rev-parse so that we get one of the correct + # length. + ARBITRARY=$(git -C "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git rev-parse HEAD) && + + git init packfileclient && + p=$(cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git && ls objects/pack/pack-*.pack) && + git -C packfileclient http-fetch --packfile=$ARBITRARY "$HTTPD_URL"/dumb/repo_pack.git/$p >out && + + grep "^keep.[0-9a-f]\{16,\}$" out && + cut -c6- out >packhash && + + # Ensure that the expected files are generated + test -e "packfileclient/.git/objects/pack/pack-$(cat packhash).pack" && + test -e "packfileclient/.git/objects/pack/pack-$(cat packhash).idx" && + test -e "packfileclient/.git/objects/pack/pack-$(cat packhash).keep" && + + # Ensure that it has the HEAD of repo_pack, at least + HASH=$(git -C "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git rev-parse HEAD) && + git -C packfileclient cat-file -e "$HASH" +' + test_expect_success 'fetch notices corrupt pack' ' cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad1.git && (cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad1.git && @@ -232,6 +254,14 @@ test_expect_success 'fetch notices corrupt pack' ' ) ' +test_expect_success 'http-fetch --packfile with corrupt pack' ' + rm -rf packfileclient && + git init packfileclient && + p=$(cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad1.git && ls objects/pack/pack-*.pack) && + test_must_fail git -C packfileclient http-fetch --packfile \ + "$HTTPD_URL"/dumb/repo_bad1.git/$p +' + test_expect_success 'fetch notices corrupt idx' ' cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad2.git && (cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad2.git && 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/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 88002b24af..8a27452a51 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -384,12 +384,11 @@ test_expect_success 'fetch lazy-fetches only to resolve deltas, protocol v2' ' grep "want $(cat hash)" trace ' -# The following two tests must be in this order, or else -# the first will not fail. It is important that the srv.bare -# repository did not have tags during clone, but has tags +# The following two tests must be in this order. It is important that +# the srv.bare repository did not have tags during clone, but has tags # in the fetch. -test_expect_failure 'verify fetch succeeds when asking for new tags' ' +test_expect_success 'verify fetch succeeds when asking for new tags' ' git clone --filter=blob:none "file://$(pwd)/srv.bare" tag-test && for i in I J K do diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 116358b9ac..1b54c35b01 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -349,7 +349,6 @@ test_expect_success 'partial fetch' ' rm -rf client "$(pwd)/trace" && git init client && SERVER="file://$(pwd)/server" && - test_config -C client extensions.partialClone "$SERVER" && GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \ fetch --filter=blob:none "$SERVER" master:refs/heads/other && @@ -588,6 +587,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" && @@ -750,6 +796,94 @@ test_expect_success 'when server does not send "ready", expect FLUSH' ' test_i18ngrep "expected no other sections to be sent after no .ready." err ' +configure_exclusion () { + git -C "$1" hash-object "$2" >objh && + git -C "$1" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && + git -C "$1" config --add \ + "uploadpack.blobpackfileuri" \ + "$(cat objh) $(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && + cat objh +} + +test_expect_success 'part of packfile response provided as URI' ' + P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && + rm -rf "$P" http_child log && + + git init "$P" && + git -C "$P" config "uploadpack.allowsidebandall" "true" && + + echo my-blob >"$P/my-blob" && + git -C "$P" add my-blob && + echo other-blob >"$P/other-blob" && + git -C "$P" add other-blob && + git -C "$P" commit -m x && + + configure_exclusion "$P" my-blob >h && + configure_exclusion "$P" other-blob >h2 && + + GIT_TRACE=1 GIT_TRACE_PACKET="$(pwd)/log" GIT_TEST_SIDEBAND_ALL=1 \ + git -c protocol.version=2 \ + -c fetch.uriprotocols=http,https \ + clone "$HTTPD_URL/smart/http_parent" http_child && + + # Ensure that my-blob and other-blob are in separate packfiles. + for idx in http_child/.git/objects/pack/*.idx + do + git verify-pack --verbose $idx >out && + { + grep "^[0-9a-f]\{16,\} " out || : + } >out.objectlist && + if test_line_count = 1 out.objectlist + then + if grep $(cat h) out + then + >hfound + fi && + if grep $(cat h2) out + then + >h2found + fi + fi + done && + test -f hfound && + test -f h2found && + + # Ensure that there are exactly 6 files (3 .pack and 3 .idx). + ls http_child/.git/objects/pack/* >filelist && + test_line_count = 6 filelist +' + +test_expect_success 'fetching with valid packfile URI but invalid hash fails' ' + P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && + rm -rf "$P" http_child log && + + git init "$P" && + git -C "$P" config "uploadpack.allowsidebandall" "true" && + + echo my-blob >"$P/my-blob" && + git -C "$P" add my-blob && + echo other-blob >"$P/other-blob" && + git -C "$P" add other-blob && + git -C "$P" commit -m x && + + configure_exclusion "$P" my-blob >h && + # Configure a URL for other-blob. Just reuse the hash of the object as + # the hash of the packfile, since the hash does not matter for this + # test as long as it is not the hash of the pack, and it is of the + # expected length. + git -C "$P" hash-object other-blob >objh && + git -C "$P" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && + git -C "$P" config --add \ + "uploadpack.blobpackfileuri" \ + "$(cat objh) $(cat objh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && + + test_must_fail env GIT_TEST_SIDEBAND_ALL=1 \ + git -c protocol.version=2 \ + -c fetch.uriprotocols=http,https \ + clone "$HTTPD_URL/smart/http_parent" http_child 2>err && + test_i18ngrep "pack downloaded from.*does not match expected hash" err +' + # DO NOT add non-httpd-specific tests here, because the last part of this # test script is only executed when httpd is available and enabled. diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index afe7f7f919..748282f058 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -58,15 +58,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 1313142564..36d9b2b2e4 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -792,6 +792,13 @@ test_expect_success 'bisect replay with old and new' ' git bisect reset ' +test_expect_success 'bisect replay with CRLF log' ' + append_cr <log_to_replay.txt >log_to_replay_crlf.txt && + git bisect replay log_to_replay_crlf.txt >bisect_result_crlf && + grep "$HASH2 is the first new commit" bisect_result_crlf && + git bisect reset +' + test_expect_success 'bisect cannot mix old/new and good/bad' ' git bisect start && git bisect bad $HASH4 && @@ -859,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/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh index 145603f124..2b551e6fd0 100755 --- a/t/t6113-rev-list-bitmap-filters.sh +++ b/t/t6113-rev-list-bitmap-filters.sh @@ -53,4 +53,25 @@ test_expect_success 'blob:limit filter with specified blob' ' test_bitmap_traversal expect actual ' +test_expect_success 'tree:0 filter' ' + git rev-list --objects --filter=tree:0 HEAD >expect && + git rev-list --use-bitmap-index \ + --objects --filter=tree:0 HEAD >actual && + test_bitmap_traversal expect actual +' + +test_expect_success 'tree:0 filter with specified blob, tree' ' + git rev-list --objects --filter=tree:0 HEAD HEAD:two.t >expect && + git rev-list --use-bitmap-index \ + --objects --filter=tree:0 HEAD HEAD:two.t >actual && + test_bitmap_traversal expect actual +' + +test_expect_success 'tree:1 filter' ' + git rev-list --objects --filter=tree:1 HEAD >expect && + git rev-list --use-bitmap-index \ + --objects --filter=tree:1 HEAD >actual && + test_cmp expect actual +' + test_done 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/t9834-git-p4-file-dir-bug.sh b/t/t9834-git-p4-file-dir-bug.sh new file mode 100755 index 0000000000..031e1f8668 --- /dev/null +++ b/t/t9834-git-p4-file-dir-bug.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +test_description='git p4 directory/file bug handling + +This test creates files and directories with the same name in perforce and +checks that git-p4 recovers from the error at the same time as the perforce +repository.' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d' ' + start_p4d && + test_might_fail p4 configure set submit.collision.check=0 +' + +test_expect_success 'init depot' ' + ( + cd "$cli" && + + touch add_file_add_dir_del_file add_file_add_dir_del_dir && + p4 add add_file_add_dir_del_file add_file_add_dir_del_dir && + mkdir add_dir_add_file_del_file add_dir_add_file_del_dir && + touch add_dir_add_file_del_file/file add_dir_add_file_del_dir/file && + p4 add add_dir_add_file_del_file/file add_dir_add_file_del_dir/file && + p4 submit -d "add initial" && + + rm -f add_file_add_dir_del_file add_file_add_dir_del_dir && + mkdir add_file_add_dir_del_file add_file_add_dir_del_dir && + touch add_file_add_dir_del_file/file add_file_add_dir_del_dir/file && + p4 add add_file_add_dir_del_file/file add_file_add_dir_del_dir/file && + rm -rf add_dir_add_file_del_file add_dir_add_file_del_dir && + touch add_dir_add_file_del_file add_dir_add_file_del_dir && + p4 add add_dir_add_file_del_file add_dir_add_file_del_dir && + p4 submit -d "add conflicting" && + + p4 delete -k add_file_add_dir_del_file && + p4 delete -k add_file_add_dir_del_dir/file && + p4 delete -k add_dir_add_file_del_file && + p4 delete -k add_dir_add_file_del_dir/file && + p4 submit -d "delete conflicting" && + + p4 delete -k "add_file_add_dir_del_file/file" && + p4 delete -k "add_file_add_dir_del_dir" && + p4 delete -k "add_dir_add_file_del_file/file" && + p4 delete -k "add_dir_add_file_del_dir" && + p4 submit -d "delete remaining" + ) +' + +test_expect_success 'clone with git-p4' ' + git p4 clone --dest="$git" //depot/@1,3 +' + +test_expect_success 'check contents' ' + test_path_is_dir "$git/add_file_add_dir_del_file" && + test_path_is_file "$git/add_file_add_dir_del_dir" && + test_path_is_dir "$git/add_dir_add_file_del_file" && + test_path_is_file "$git/add_dir_add_file_del_dir" +' + +test_expect_success 'rebase and check empty' ' + git -C "$git" p4 rebase && + + test_path_is_missing "$git/add_file_add_dir_del_file" && + test_path_is_missing "$git/add_file_add_dir_del_dir" && + test_path_is_missing "$git/add_dir_add_file_del_file" && + test_path_is_missing "$git/add_dir_add_file_del_dir" +' + +test_done 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 77e9a60fcb..618a7c8d5b 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; } @@ -1504,12 +1490,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 @@ -1517,6 +1497,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 @@ -1656,7 +1644,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 ' @@ -1665,7 +1653,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 ' |