summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README14
-rw-r--r--t/helper/test-bloom.c4
-rw-r--r--t/helper/test-pkt-line.c4
-rw-r--r--t/helper/test-reach.c2
-rw-r--r--t/helper/test-regex.c94
-rw-r--r--t/lib-httpd.sh2
-rw-r--r--t/lib-httpd/apache.conf8
-rw-r--r--t/lib-httpd/incomplete-body-upload-pack-v2-http.sh3
-rw-r--r--t/lib-httpd/incomplete-length-upload-pack-v2-http.sh3
-rwxr-xr-xt/perf/p1400-update-ref.sh32
-rwxr-xr-xt/perf/p5310-pack-bitmaps.sh10
-rwxr-xr-xt/t0002-gitfile.sh2
-rwxr-xr-xt/t0091-bugreport.sh15
-rwxr-xr-xt/t0095-bloom.sh8
-rwxr-xr-xt/t0410-partial-clone.sh23
-rwxr-xr-xt/t0500-progress-display.sh26
-rwxr-xr-xt/t1090-sparse-checkout-scope.sh1
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh22
-rwxr-xr-xt/t1400-update-ref.sh32
-rwxr-xr-xt/t1416-ref-transaction-hooks.sh109
-rwxr-xr-xt/t1450-fsck.sh29
-rwxr-xr-xt/t1506-rev-parse-diagnosis.sh2
-rwxr-xr-xt/t1509-root-work-tree.sh4
-rwxr-xr-xt/t2018-checkout-branch.sh10
-rwxr-xr-xt/t2027-checkout-track.sh24
-rwxr-xr-xt/t2060-switch.sh8
-rwxr-xr-xt/t2203-add-intent.sh53
-rwxr-xr-xt/t2401-worktree-prune.sh24
-rwxr-xr-xt/t2403-worktree-move.sh21
-rwxr-xr-xt/t2404-worktree-config.sh4
-rwxr-xr-xt/t3200-branch.sh67
-rwxr-xr-xt/t3415-rebase-autosquash.sh16
-rwxr-xr-xt/t3430-rebase-merges.sh2
-rwxr-xr-xt/t3701-add-interactive.sh19
-rwxr-xr-xt/t4014-format-patch.sh21
-rwxr-xr-xt/t4045-diff-relative.sh82
-rwxr-xr-xt/t4067-diff-partial-clone.sh4
-rwxr-xr-xt/t4068-diff-symmetric.sh91
-rwxr-xr-xt/t4202-log.sh2
-rwxr-xr-xt/t4210-log-i18n.sh77
-rwxr-xr-xt/t4211-line-log.sh68
-rwxr-xr-xt/t4216-log-bloom.sh4
-rwxr-xr-xt/t5318-commit-graph.sh54
-rwxr-xr-xt/t5319-multi-pack-index.sh27
-rwxr-xr-xt/t5500-fetch-pack.sh13
-rwxr-xr-xt/t5520-pull.sh2
-rwxr-xr-xt/t5541-http-push-smart.sh15
-rwxr-xr-xt/t5550-http-fetch-dumb.sh30
-rwxr-xr-xt/t5551-http-fetch-smart.sh56
-rwxr-xr-xt/t5581-http-curl-verbose.sh2
-rwxr-xr-xt/t5608-clone-2gb.sh11
-rwxr-xr-xt/t5616-partial-clone.sh7
-rwxr-xr-xt/t5702-protocol-v2.sh136
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh9
-rwxr-xr-xt/t6030-bisect-porcelain.sh9
-rwxr-xr-xt/t6042-merge-rename-corner-cases.sh55
-rwxr-xr-xt/t6050-replace.sh2
-rwxr-xr-xt/t6113-rev-list-bitmap-filters.sh21
-rwxr-xr-xt/t6132-pathspec-exclude.sh33
-rwxr-xr-xt/t6200-fmt-merge-msg.sh2
-rwxr-xr-xt/t9020-remote-svn.sh4
-rwxr-xr-xt/t9300-fast-import.sh28
-rwxr-xr-xt/t9834-git-p4-file-dir-bug.sh70
-rwxr-xr-xt/t9902-completion.sh455
-rw-r--r--t/test-lib.sh34
65 files changed, 1926 insertions, 195 deletions
diff --git a/t/README b/t/README
index cf863837ab..70ec61cf88 100644
--- a/t/README
+++ b/t/README
@@ -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
'