summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README3
-rw-r--r--t/helper/test-example-decorate.c6
-rw-r--r--t/helper/test-read-cache.c66
-rwxr-xr-xt/perf/p2000-sparse-operations.sh101
-rwxr-xr-xt/perf/p5600-partial-clone.sh12
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh13
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh143
-rwxr-xr-xt/t1300-config.sh15
-rwxr-xr-xt/t4013-diff-various.sh31
-rwxr-xr-xt/t5523-push-upstream.sh7
-rwxr-xr-xt/t5582-fetch-negative-refspec.sh43
-rwxr-xr-xt/t7900-maintenance.sh22
-rwxr-xr-xt/t9902-completion.sh3
13 files changed, 429 insertions, 36 deletions
diff --git a/t/README b/t/README
index fd9375b146..8eb9e46b1d 100644
--- a/t/README
+++ b/t/README
@@ -436,6 +436,9 @@ and "sha256".
GIT_TEST_WRITE_REV_INDEX=<boolean>, when true enables the
'pack.writeReverseIndex' setting.
+GIT_TEST_SPARSE_INDEX=<boolean>, when true enables index writes to use the
+sparse-index format by default.
+
Naming Tests
------------
diff --git a/t/helper/test-example-decorate.c b/t/helper/test-example-decorate.c
index c8a1cde7d2..b9d1200eb9 100644
--- a/t/helper/test-example-decorate.c
+++ b/t/helper/test-example-decorate.c
@@ -26,8 +26,8 @@ int cmd__example_decorate(int argc, const char **argv)
* Add 2 objects, one with a non-NULL decoration and one with a NULL
* decoration.
*/
- one = lookup_unknown_object(&one_oid);
- two = lookup_unknown_object(&two_oid);
+ one = lookup_unknown_object(the_repository, &one_oid);
+ two = lookup_unknown_object(the_repository, &two_oid);
ret = add_decoration(&n, one, &decoration_a);
if (ret)
BUG("when adding a brand-new object, NULL should be returned");
@@ -56,7 +56,7 @@ int cmd__example_decorate(int argc, const char **argv)
ret = lookup_decoration(&n, two);
if (ret != &decoration_b)
BUG("lookup should return added declaration");
- three = lookup_unknown_object(&three_oid);
+ three = lookup_unknown_object(the_repository, &three_oid);
ret = lookup_decoration(&n, three);
if (ret)
BUG("lookup for unknown object should return NULL");
diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c
index 244977a29b..b52c174acc 100644
--- a/t/helper/test-read-cache.c
+++ b/t/helper/test-read-cache.c
@@ -1,36 +1,82 @@
#include "test-tool.h"
#include "cache.h"
#include "config.h"
+#include "blob.h"
+#include "commit.h"
+#include "tree.h"
+#include "sparse-index.h"
+
+static void print_cache_entry(struct cache_entry *ce)
+{
+ const char *type;
+ printf("%06o ", ce->ce_mode & 0177777);
+
+ if (S_ISSPARSEDIR(ce->ce_mode))
+ type = tree_type;
+ else if (S_ISGITLINK(ce->ce_mode))
+ type = commit_type;
+ else
+ type = blob_type;
+
+ printf("%s %s\t%s\n",
+ type,
+ oid_to_hex(&ce->oid),
+ ce->name);
+}
+
+static void print_cache(struct index_state *istate)
+{
+ int i;
+ for (i = 0; i < istate->cache_nr; i++)
+ print_cache_entry(istate->cache[i]);
+}
int cmd__read_cache(int argc, const char **argv)
{
+ struct repository *r = the_repository;
int i, cnt = 1;
const char *name = NULL;
+ int table = 0, expand = 0;
+
+ initialize_the_repository();
+ prepare_repo_settings(r);
+ r->settings.command_requires_full_index = 0;
- if (argc > 1 && skip_prefix(argv[1], "--print-and-refresh=", &name)) {
- argc--;
- argv++;
+ for (++argv, --argc; *argv && starts_with(*argv, "--"); ++argv, --argc) {
+ if (skip_prefix(*argv, "--print-and-refresh=", &name))
+ continue;
+ if (!strcmp(*argv, "--table"))
+ table = 1;
+ else if (!strcmp(*argv, "--expand"))
+ expand = 1;
}
- if (argc == 2)
- cnt = strtol(argv[1], NULL, 0);
+ if (argc == 1)
+ cnt = strtol(argv[0], NULL, 0);
setup_git_directory();
git_config(git_default_config, NULL);
+
for (i = 0; i < cnt; i++) {
- read_cache();
+ repo_read_index(r);
+
+ if (expand)
+ ensure_full_index(r->index);
+
if (name) {
int pos;
- refresh_index(&the_index, REFRESH_QUIET,
+ refresh_index(r->index, REFRESH_QUIET,
NULL, NULL, NULL);
- pos = index_name_pos(&the_index, name, strlen(name));
+ pos = index_name_pos(r->index, name, strlen(name));
if (pos < 0)
die("%s not in index", name);
printf("%s is%s up to date\n", name,
- ce_uptodate(the_index.cache[pos]) ? "" : " not");
+ ce_uptodate(r->index->cache[pos]) ? "" : " not");
write_file(name, "%d\n", i);
}
- discard_cache();
+ if (table)
+ print_cache(r->index);
+ discard_index(r->index);
}
return 0;
}
diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh
new file mode 100755
index 0000000000..94513c9774
--- /dev/null
+++ b/t/perf/p2000-sparse-operations.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+test_description="test performance of Git operations using the index"
+
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+SPARSE_CONE=f2/f4/f1
+
+test_expect_success 'setup repo and indexes' '
+ git reset --hard HEAD &&
+
+ # Remove submodules from the example repo, because our
+ # duplication of the entire repo creates an unlikely data shape.
+ if git config --file .gitmodules --get-regexp "submodule.*.path" >modules
+ then
+ git rm $(awk "{print \$2}" modules) &&
+ git commit -m "remove submodules" || return 1
+ fi &&
+
+ echo bogus >a &&
+ cp a b &&
+ git add a b &&
+ git commit -m "level 0" &&
+ BLOB=$(git rev-parse HEAD:a) &&
+ OLD_COMMIT=$(git rev-parse HEAD) &&
+ OLD_TREE=$(git rev-parse HEAD^{tree}) &&
+
+ for i in $(test_seq 1 4)
+ do
+ cat >in <<-EOF &&
+ 100755 blob $BLOB a
+ 040000 tree $OLD_TREE f1
+ 040000 tree $OLD_TREE f2
+ 040000 tree $OLD_TREE f3
+ 040000 tree $OLD_TREE f4
+ EOF
+ NEW_TREE=$(git mktree <in) &&
+ NEW_COMMIT=$(git commit-tree $NEW_TREE -p $OLD_COMMIT -m "level $i") &&
+ OLD_TREE=$NEW_TREE &&
+ OLD_COMMIT=$NEW_COMMIT || return 1
+ done &&
+
+ git sparse-checkout init --cone &&
+ git branch -f wide $OLD_COMMIT &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-index-v3 &&
+ (
+ cd full-index-v3 &&
+ git sparse-checkout init --cone &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 3 &&
+ git update-index --index-version=3
+ ) &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . full-index-v4 &&
+ (
+ cd full-index-v4 &&
+ git sparse-checkout init --cone &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 4 &&
+ git update-index --index-version=4
+ ) &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-index-v3 &&
+ (
+ cd sparse-index-v3 &&
+ git sparse-checkout init --cone --sparse-index &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 3 &&
+ git update-index --index-version=3
+ ) &&
+ git -c core.sparseCheckoutCone=true clone --branch=wide --sparse . sparse-index-v4 &&
+ (
+ cd sparse-index-v4 &&
+ git sparse-checkout init --cone --sparse-index &&
+ git sparse-checkout set $SPARSE_CONE &&
+ git config index.version 4 &&
+ git update-index --index-version=4
+ )
+'
+
+test_perf_on_all () {
+ command="$@"
+ for repo in full-index-v3 full-index-v4 \
+ sparse-index-v3 sparse-index-v4
+ do
+ test_perf "$command ($repo)" "
+ (
+ cd $repo &&
+ echo >>$SPARSE_CONE/a &&
+ $command
+ )
+ "
+ done
+}
+
+test_perf_on_all git status
+test_perf_on_all git add -A
+test_perf_on_all git add .
+test_perf_on_all git commit -a -m A
+
+test_done
diff --git a/t/perf/p5600-partial-clone.sh b/t/perf/p5600-partial-clone.sh
index 3e04bd2ae1..ca785a3341 100755
--- a/t/perf/p5600-partial-clone.sh
+++ b/t/perf/p5600-partial-clone.sh
@@ -23,4 +23,16 @@ test_perf 'checkout of result' '
git -C worktree checkout -f
'
+test_perf 'fsck' '
+ git -C bare.git fsck
+'
+
+test_perf 'count commits' '
+ git -C bare.git rev-list --all --count
+'
+
+test_perf 'count non-promisor commits' '
+ git -C bare.git rev-list --all --count --exclude-promisor-objects
+'
+
test_done
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index fc64e9ed99..38fc8340f5 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -205,6 +205,19 @@ test_expect_success 'sparse-checkout disable' '
check_files repo a deep folder1 folder2
'
+test_expect_success 'sparse-index enabled and disabled' '
+ git -C repo sparse-checkout init --cone --sparse-index &&
+ test_cmp_config -C repo true index.sparse &&
+ test-tool -C repo read-cache --table >cache &&
+ grep " tree " cache &&
+
+ git -C repo sparse-checkout disable &&
+ test-tool -C repo read-cache --table >cache &&
+ ! grep " tree " cache &&
+ git -C repo config --list >config &&
+ ! grep index.sparse config
+'
+
test_expect_success 'cone mode: init and set' '
git -C repo sparse-checkout init --cone &&
git -C repo config --list >config &&
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index 8cd3e5a8d2..12e6c45302 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -2,11 +2,15 @@
test_description='compare full workdir to sparse workdir'
+GIT_TEST_SPLIT_INDEX=0
+GIT_TEST_SPARSE_INDEX=
+
. ./test-lib.sh
test_expect_success 'setup' '
git init initial-repo &&
(
+ GIT_TEST_SPARSE_INDEX=0 &&
cd initial-repo &&
echo a >a &&
echo "after deep" >e &&
@@ -87,39 +91,102 @@ init_repos () {
cp -r initial-repo sparse-checkout &&
git -C sparse-checkout reset --hard &&
- git -C sparse-checkout sparse-checkout init --cone &&
+
+ cp -r initial-repo sparse-index &&
+ git -C sparse-index reset --hard &&
# initialize sparse-checkout definitions
- git -C sparse-checkout sparse-checkout set deep
+ git -C sparse-checkout sparse-checkout init --cone &&
+ git -C sparse-checkout sparse-checkout set deep &&
+ git -C sparse-index sparse-checkout init --cone --sparse-index &&
+ test_cmp_config -C sparse-index true index.sparse &&
+ git -C sparse-index sparse-checkout set deep
}
run_on_sparse () {
(
cd sparse-checkout &&
- $* >../sparse-checkout-out 2>../sparse-checkout-err
+ "$@" >../sparse-checkout-out 2>../sparse-checkout-err
+ ) &&
+ (
+ cd sparse-index &&
+ "$@" >../sparse-index-out 2>../sparse-index-err
)
}
run_on_all () {
(
cd full-checkout &&
- $* >../full-checkout-out 2>../full-checkout-err
+ "$@" >../full-checkout-out 2>../full-checkout-err
) &&
- run_on_sparse $*
+ run_on_sparse "$@"
}
test_all_match () {
- run_on_all $* &&
+ run_on_all "$@" &&
test_cmp full-checkout-out sparse-checkout-out &&
- test_cmp full-checkout-err sparse-checkout-err
+ test_cmp full-checkout-out sparse-index-out &&
+ test_cmp full-checkout-err sparse-checkout-err &&
+ test_cmp full-checkout-err sparse-index-err
+}
+
+test_sparse_match () {
+ run_on_sparse "$@" &&
+ test_cmp sparse-checkout-out sparse-index-out &&
+ test_cmp sparse-checkout-err sparse-index-err
}
+test_expect_success 'sparse-index contents' '
+ init_repos &&
+
+ test-tool -C sparse-index read-cache --table >cache &&
+ for dir in folder1 folder2 x
+ do
+ TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
+ grep "040000 tree $TREE $dir/" cache \
+ || return 1
+ done &&
+
+ git -C sparse-index sparse-checkout set folder1 &&
+
+ test-tool -C sparse-index read-cache --table >cache &&
+ for dir in deep folder2 x
+ do
+ TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
+ grep "040000 tree $TREE $dir/" cache \
+ || return 1
+ done &&
+
+ git -C sparse-index sparse-checkout set deep/deeper1 &&
+
+ test-tool -C sparse-index read-cache --table >cache &&
+ for dir in deep/deeper2 folder1 folder2 x
+ do
+ TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
+ grep "040000 tree $TREE $dir/" cache \
+ || return 1
+ done &&
+
+ # Disabling the sparse-index removes tree entries with full ones
+ git -C sparse-index sparse-checkout init --no-sparse-index &&
+
+ test-tool -C sparse-index read-cache --table >cache &&
+ ! grep "040000 tree" cache &&
+ test_sparse_match test-tool read-cache --table
+'
+
+test_expect_success 'expanded in-memory index matches full index' '
+ init_repos &&
+ test_sparse_match test-tool read-cache --expand --table
+'
+
test_expect_success 'status with options' '
init_repos &&
+ test_sparse_match ls &&
test_all_match git status --porcelain=v2 &&
test_all_match git status --porcelain=v2 -z -u &&
test_all_match git status --porcelain=v2 -uno &&
- run_on_all "touch README.md" &&
+ run_on_all touch README.md &&
test_all_match git status --porcelain=v2 &&
test_all_match git status --porcelain=v2 -z -u &&
test_all_match git status --porcelain=v2 -uno &&
@@ -135,7 +202,7 @@ test_expect_success 'add, commit, checkout' '
write_script edit-contents <<-\EOF &&
echo text >>$1
EOF
- run_on_all "../edit-contents README.md" &&
+ run_on_all ../edit-contents README.md &&
test_all_match git add README.md &&
test_all_match git status --porcelain=v2 &&
@@ -144,7 +211,7 @@ test_expect_success 'add, commit, checkout' '
test_all_match git checkout HEAD~1 &&
test_all_match git checkout - &&
- run_on_all "../edit-contents README.md" &&
+ run_on_all ../edit-contents README.md &&
test_all_match git add -A &&
test_all_match git status --porcelain=v2 &&
@@ -153,7 +220,7 @@ test_expect_success 'add, commit, checkout' '
test_all_match git checkout HEAD~1 &&
test_all_match git checkout - &&
- run_on_all "../edit-contents deep/newfile" &&
+ run_on_all ../edit-contents deep/newfile &&
test_all_match git status --porcelain=v2 -uno &&
test_all_match git status --porcelain=v2 &&
@@ -186,7 +253,7 @@ test_expect_success 'diff --staged' '
write_script edit-contents <<-\EOF &&
echo text >>README.md
EOF
- run_on_all "../edit-contents" &&
+ run_on_all ../edit-contents &&
test_all_match git diff &&
test_all_match git diff --staged &&
@@ -252,6 +319,17 @@ test_expect_failure 'checkout and reset (mixed)' '
test_all_match git reset update-folder2
'
+# Ensure that sparse-index behaves identically to
+# sparse-checkout with a full index.
+test_expect_success 'checkout and reset (mixed) [sparse]' '
+ init_repos &&
+
+ test_sparse_match git checkout -b reset-test update-deep &&
+ test_sparse_match git reset deepest &&
+ test_sparse_match git reset update-folder1 &&
+ test_sparse_match git reset update-folder2
+'
+
test_expect_success 'merge' '
init_repos &&
@@ -280,7 +358,7 @@ test_expect_success 'clean' '
echo bogus >>.gitignore &&
run_on_all cp ../.gitignore . &&
test_all_match git add .gitignore &&
- test_all_match git commit -m ignore-bogus-files &&
+ test_all_match git commit -m "ignore bogus files" &&
run_on_sparse mkdir folder1 &&
run_on_all touch folder1/bogus &&
@@ -288,14 +366,51 @@ test_expect_success 'clean' '
test_all_match git status --porcelain=v2 &&
test_all_match git clean -f &&
test_all_match git status --porcelain=v2 &&
+ test_sparse_match ls &&
+ test_sparse_match ls folder1 &&
test_all_match git clean -xf &&
test_all_match git status --porcelain=v2 &&
+ test_sparse_match ls &&
+ test_sparse_match ls folder1 &&
test_all_match git clean -xdf &&
test_all_match git status --porcelain=v2 &&
+ test_sparse_match ls &&
+ test_sparse_match ls folder1 &&
+
+ test_sparse_match test_path_is_dir folder1
+'
+
+test_expect_success 'submodule handling' '
+ init_repos &&
+
+ test_all_match mkdir modules &&
+ test_all_match touch modules/a &&
+ test_all_match git add modules &&
+ test_all_match git commit -m "add modules directory" &&
+
+ run_on_all git submodule add "$(pwd)/initial-repo" modules/sub &&
+ test_all_match git commit -m "add submodule" &&
+
+ # having a submodule prevents "modules" from collapse
+ test-tool -C sparse-index read-cache --table >cache &&
+ grep "100644 blob .* modules/a" cache &&
+ grep "160000 commit $(git -C initial-repo rev-parse HEAD) modules/sub" cache
+'
+
+test_expect_success 'sparse-index is expanded and converted back' '
+ init_repos &&
+
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
+ git -C sparse-index -c core.fsmonitor="" reset --hard &&
+ test_region index convert_to_sparse trace2.txt &&
+ test_region index ensure_full_index trace2.txt &&
- test_path_is_dir sparse-checkout/folder1
+ rm trace2.txt &&
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
+ git -C sparse-index -c core.fsmonitor="" status -uno &&
+ test_region index ensure_full_index trace2.txt
'
test_done
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index e0dd5d65ce..ad4e6d0cfc 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -1374,16 +1374,29 @@ test_expect_success 'git --config-env=key=envvar support' '
cat >expect <<-\EOF &&
value
value
+ value
+ value
+ false
false
EOF
{
ENVVAR=value git --config-env=core.name=ENVVAR config core.name &&
+ ENVVAR=value git --config-env core.name=ENVVAR config core.name &&
ENVVAR=value git --config-env=foo.CamelCase=ENVVAR config foo.camelcase &&
- ENVVAR= git --config-env=foo.flag=ENVVAR config --bool foo.flag
+ ENVVAR=value git --config-env foo.CamelCase=ENVVAR config foo.camelcase &&
+ ENVVAR= git --config-env=foo.flag=ENVVAR config --bool foo.flag &&
+ ENVVAR= git --config-env foo.flag=ENVVAR config --bool foo.flag
} >actual &&
test_cmp expect actual
'
+test_expect_success 'git --config-env with missing value' '
+ test_must_fail env ENVVAR=value git --config-env 2>error &&
+ grep "no config key given for --config-env" error &&
+ test_must_fail env ENVVAR=value git --config-env config core.name 2>error &&
+ grep "invalid config format: config" error
+'
+
test_expect_success 'git --config-env fails with invalid parameters' '
test_must_fail git --config-env=foo.flag config --bool foo.flag 2>error &&
test_i18ngrep "invalid config format: foo.flag" error &&
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 6cca8b84a6..87def81699 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -452,6 +452,37 @@ diff-tree --stat --compact-summary initial mode
diff-tree -R --stat --compact-summary initial mode
EOF
+test_expect_success 'log --diff-merges=on matches --diff-merges=separate' '
+ git log -p --diff-merges=separate master >result &&
+ process_diffs result >expected &&
+ git log -p --diff-merges=on master >result &&
+ process_diffs result >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'deny wrong log.diffMerges config' '
+ test_config log.diffMerges wrong-value &&
+ test_expect_code 128 git log
+'
+
+test_expect_success 'git config log.diffMerges first-parent' '
+ git log -p --diff-merges=first-parent master >result &&
+ process_diffs result >expected &&
+ test_config log.diffMerges first-parent &&
+ git log -p --diff-merges=on master >result &&
+ process_diffs result >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'git config log.diffMerges first-parent vs -m' '
+ git log -p --diff-merges=first-parent master >result &&
+ process_diffs result >expected &&
+ test_config log.diffMerges first-parent &&
+ git log -p -m master >result &&
+ process_diffs result >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'log -S requires an argument' '
test_must_fail git log -S
'
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
index 9fbe7f784d..fdb4292056 100755
--- a/t/t5523-push-upstream.sh
+++ b/t/t5523-push-upstream.sh
@@ -119,4 +119,11 @@ test_expect_success TTY 'quiet push' '
test_must_be_empty output
'
+test_expect_success TTY 'quiet push -u' '
+ ensure_fresh_upstream &&
+
+ test_terminal git push --quiet -u --no-progress upstream main 2>&1 | tee output &&
+ test_must_be_empty output
+'
+
test_done
diff --git a/t/t5582-fetch-negative-refspec.sh b/t/t5582-fetch-negative-refspec.sh
index f345097277..e5d2e79ad3 100755
--- a/t/t5582-fetch-negative-refspec.sh
+++ b/t/t5582-fetch-negative-refspec.sh
@@ -240,4 +240,47 @@ test_expect_success "push with matching +: and negative refspec" '
git -C two push -v one
'
+test_expect_success '--prefetch correctly modifies refspecs' '
+ git -C one config --unset-all remote.origin.fetch &&
+ git -C one config --add remote.origin.fetch ^refs/heads/bogus/ignore &&
+ git -C one config --add remote.origin.fetch "refs/tags/*:refs/tags/*" &&
+ git -C one config --add remote.origin.fetch "refs/heads/bogus/*:bogus/*" &&
+
+ git tag -a -m never never-fetch-tag HEAD &&
+
+ git branch bogus/fetched HEAD~1 &&
+ git branch bogus/ignore HEAD &&
+
+ git -C one fetch --prefetch --no-tags &&
+ test_must_fail git -C one rev-parse never-fetch-tag &&
+ git -C one rev-parse refs/prefetch/bogus/fetched &&
+ test_must_fail git -C one rev-parse refs/prefetch/bogus/ignore &&
+
+ # correctly handle when refspec set becomes empty
+ # after removing the refs/tags/* refspec.
+ git -C one config --unset-all remote.origin.fetch &&
+ git -C one config --add remote.origin.fetch "refs/tags/*:refs/tags/*" &&
+
+ git -C one fetch --prefetch --no-tags &&
+ test_must_fail git -C one rev-parse never-fetch-tag &&
+
+ # The refspec for refs that are not fully qualified
+ # are filtered multiple times.
+ git -C one rev-parse refs/prefetch/bogus/fetched &&
+ test_must_fail git -C one rev-parse refs/prefetch/bogus/ignore
+'
+
+test_expect_success '--prefetch succeeds when refspec becomes empty' '
+ git checkout bogus/fetched &&
+ test_commit extra &&
+
+ git -C one config --unset-all remote.origin.fetch &&
+ git -C one config --unset branch.main.remote &&
+ git -C one config remote.origin.fetch "+refs/tags/extra" &&
+ git -C one config remote.origin.skipfetchall true &&
+ git -C one config remote.origin.tagopt "--no-tags" &&
+
+ git -C one fetch --prefetch
+'
+
test_done
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index 2412d8c5c0..b93ae014ee 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -141,19 +141,25 @@ test_expect_success 'prefetch multiple remotes' '
test_commit -C clone1 one &&
test_commit -C clone2 two &&
GIT_TRACE2_EVENT="$(pwd)/run-prefetch.txt" git maintenance run --task=prefetch 2>/dev/null &&
- fetchargs="--prune --no-tags --no-write-fetch-head --recurse-submodules=no --refmap= --quiet" &&
- test_subcommand git fetch remote1 $fetchargs +refs/heads/\\*:refs/prefetch/remote1/\\* <run-prefetch.txt &&
- test_subcommand git fetch remote2 $fetchargs +refs/heads/\\*:refs/prefetch/remote2/\\* <run-prefetch.txt &&
+ fetchargs="--prefetch --prune --no-tags --no-write-fetch-head --recurse-submodules=no --quiet" &&
+ test_subcommand git fetch remote1 $fetchargs <run-prefetch.txt &&
+ test_subcommand git fetch remote2 $fetchargs <run-prefetch.txt &&
test_path_is_missing .git/refs/remotes &&
- git log prefetch/remote1/one &&
- git log prefetch/remote2/two &&
+ git log prefetch/remotes/remote1/one &&
+ git log prefetch/remotes/remote2/two &&
git fetch --all &&
- test_cmp_rev refs/remotes/remote1/one refs/prefetch/remote1/one &&
- test_cmp_rev refs/remotes/remote2/two refs/prefetch/remote2/two &&
+ test_cmp_rev refs/remotes/remote1/one refs/prefetch/remotes/remote1/one &&
+ test_cmp_rev refs/remotes/remote2/two refs/prefetch/remotes/remote2/two &&
test_cmp_config refs/prefetch/ log.excludedecoration &&
git log --oneline --decorate --all >log &&
- ! grep "prefetch" log
+ ! grep "prefetch" log &&
+
+ test_when_finished git config --unset remote.remote1.skipFetchAll &&
+ git config remote.remote1.skipFetchAll true &&
+ GIT_TRACE2_EVENT="$(pwd)/skip-remote1.txt" git maintenance run --task=prefetch 2>/dev/null &&
+ test_subcommand ! git fetch remote1 $fetchargs <skip-remote1.txt &&
+ test_subcommand git fetch remote2 $fetchargs <skip-remote1.txt
'
test_expect_success 'prefetch and existing log.excludeDecoration values' '
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 04ce884ef5..4d732d6d4f 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2306,6 +2306,7 @@ test_expect_success 'git config - variable name' '
test_completion "git config log.d" <<-\EOF
log.date Z
log.decorate Z
+ log.diffMerges Z
EOF
'
@@ -2327,6 +2328,7 @@ test_expect_success 'git -c - variable name' '
test_completion "git -c log.d" <<-\EOF
log.date=Z
log.decorate=Z
+ log.diffMerges=Z
EOF
'
@@ -2348,6 +2350,7 @@ test_expect_success 'git clone --config= - variable name' '
test_completion "git clone --config=log.d" <<-\EOF
log.date=Z
log.decorate=Z
+ log.diffMerges=Z
EOF
'