summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README25
-rw-r--r--t/helper/test-dump-untracked-cache.c6
-rw-r--r--t/helper/test-parse-options.c1
-rw-r--r--t/helper/test-read-midx.c16
-rw-r--r--t/helper/test-run-command.c5
-rw-r--r--t/helper/test-serve-v2.c14
-rw-r--r--t/helper/test-submodule-nested-repo-config.c4
-rw-r--r--t/lib-bitmap.sh240
-rw-r--r--t/lib-httpd/apache.conf7
-rw-r--r--t/perf/lib-bitmap.sh69
-rwxr-xr-xt/perf/p5310-pack-bitmaps.sh65
-rwxr-xr-xt/perf/p5326-multi-pack-bitmaps.sh43
-rwxr-xr-xt/perf/run2
-rwxr-xr-xt/t0000-basic.sh23
-rwxr-xr-xt/t0012-help.sh16
-rwxr-xr-xt/t0021-conversion.sh71
-rwxr-xr-xt/t0040-parse-options.sh5
-rwxr-xr-xt/t0090-cache-tree.sh1
-rwxr-xr-xt/t0301-credential-cache.sh32
-rwxr-xr-xt/t0410-partial-clone.sh12
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh59
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh92
-rwxr-xr-xt/t1400-update-ref.sh34
-rwxr-xr-xt/t2021-checkout-overwrite.sh1
-rwxr-xr-xt/t3200-branch.sh13
-rwxr-xr-xt/t3404-rebase-interactive.sh1
-rwxr-xr-xt/t3407-rebase-abort.sh105
-rwxr-xr-xt/t3435-rebase-gpg-sign.sh1
-rwxr-xr-xt/t3501-revert-cherry-pick.sh16
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh17
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh1
-rwxr-xr-xt/t3903-stash.sh58
-rw-r--r--t/t4018/php-enum4
-rwxr-xr-xt/t4045-diff-relative.sh53
-rwxr-xr-xt/t4060-diff-submodule-option-diff-format.sh159
-rwxr-xr-xt/t4108-apply-threeway.sh45
-rwxr-xr-xt/t4151-am-abort.sh39
-rwxr-xr-xt/t4210-log-i18n.sh7
-rwxr-xr-xt/t5304-prune.sh1
-rwxr-xr-xt/t5310-pack-bitmaps.sh233
-rwxr-xr-xt/t5318-commit-graph.sh19
-rwxr-xr-xt/t5319-multi-pack-index.sh75
-rwxr-xr-xt/t5323-pack-redundant.sh4
-rwxr-xr-xt/t5326-multi-pack-bitmaps.sh286
-rwxr-xr-xt/t5551-http-fetch-smart.sh33
-rwxr-xr-xt/t5555-http-smart-common.sh161
-rw-r--r--t/t5562/invoke-with-content-length.pl16
-rwxr-xr-xt/t5582-fetch-negative-refspec.sh1
-rwxr-xr-xt/t5606-clone-options.sh12
-rwxr-xr-xt/t5701-git-serve.sh75
-rwxr-xr-xt/t5702-protocol-v2.sh19
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh208
-rwxr-xr-xt/t5704-protocol-violations.sh15
-rwxr-xr-xt/t6030-bisect-porcelain.sh18
-rwxr-xr-xt/t6300-for-each-ref.sh29
-rwxr-xr-xt/t6415-merge-dir-to-symlink.sh6
-rwxr-xr-xt/t6424-merge-unrelated-index-changes.sh1
-rwxr-xr-xt/t6430-merge-recursive.sh4
-rwxr-xr-xt/t6436-merge-overwrite.sh3
-rwxr-xr-xt/t7201-co.sh1
-rwxr-xr-xt/t7519-status-fsmonitor.sh38
-rwxr-xr-xt/t7600-merge.sh1
-rwxr-xr-xt/t7700-repack.sh18
-rwxr-xr-xt/t7800-difftool.sh67
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh3
-rwxr-xr-xt/t7900-maintenance.sh126
-rwxr-xr-xt/t9001-send-email.sh62
-rwxr-xr-xt/t9002-column.sh18
-rwxr-xr-xt/t9351-fast-export-anonymize.sh10
-rwxr-xr-xt/t9400-git-cvsserver-server.sh9
-rw-r--r--t/test-lib-functions.sh107
-rw-r--r--t/test-lib.sh15
72 files changed, 2496 insertions, 560 deletions
diff --git a/t/README b/t/README
index 8b5f86a46f..b92155a822 100644
--- a/t/README
+++ b/t/README
@@ -432,6 +432,10 @@ GIT_TEST_MULTI_PACK_INDEX=<boolean>, when true, forces the multi-pack-
index to be written after every 'git repack' command, and overrides the
'core.multiPackIndex' setting to true.
+GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=<boolean>, when true, sets the
+'--bitmap' option on all invocations of 'git multi-pack-index write',
+and ignores pack-objects' '--write-bitmap-index'.
+
GIT_TEST_SIDEBAND_ALL=<boolean>, when true, overrides the
'uploadpack.allowSidebandAll' setting to true, and when false, forces
fetch-pack to not request sideband-all (even if the server advertises
@@ -455,6 +459,16 @@ GIT_TEST_CHECKOUT_WORKERS=<n> overrides the 'checkout.workers' setting
to <n> and 'checkout.thresholdForParallelism' to 0, forcing the
execution of the parallel-checkout code.
+GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=<boolean>, when true, makes
+registering submodule ODBs as alternates a fatal action. Support for
+this environment variable can be removed once the migration to
+explicitly providing repositories when accessing submodule objects is
+complete (in which case we might want to replace this with a trace2
+call so that users can make it visible if accessing submodule objects
+without an explicit repository still happens) or needs to be abandoned
+for whatever reason (in which case the migrated codepaths still retain
+their performance benefits).
+
Naming Tests
------------
@@ -760,7 +774,8 @@ Test harness library
--------------------
There are a handful helper functions defined in the test harness
-library for your script to use.
+library for your script to use. Some of them are listed below;
+see test-lib-functions.sh for the full list and their options.
- test_expect_success [<prereq>] <message> <script>
@@ -806,10 +821,12 @@ library for your script to use.
argument. This is primarily meant for use during the
development of a new test script.
- - debug <git-command>
+ - debug [options] <git-command>
Run a git command inside a debugger. This is primarily meant for
- use when debugging a failing test script.
+ use when debugging a failing test script. With '-t', use your
+ original TERM instead of test-lib.sh's "dumb", so that your
+ debugger interface has colors.
- test_done
@@ -996,7 +1013,7 @@ library for your script to use.
EOF
- - test_pause
+ - test_pause [options]
This command is useful for writing and debugging tests and must be
removed before submitting. It halts the execution of the test and
diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c
index cf0f2c7228..99010614f6 100644
--- a/t/helper/test-dump-untracked-cache.c
+++ b/t/helper/test-dump-untracked-cache.c
@@ -45,8 +45,10 @@ int cmd__dump_untracked_cache(int ac, const char **av)
struct untracked_cache *uc;
struct strbuf base = STRBUF_INIT;
- /* Hack to avoid modifying the untracked cache when we read it */
- ignore_untracked_cache_config = 1;
+ /* Set core.untrackedCache=keep before setup_git_directory() */
+ xsetenv("GIT_CONFIG_COUNT", "1", 1);
+ xsetenv("GIT_CONFIG_KEY_0", "core.untrackedCache", 1);
+ xsetenv("GIT_CONFIG_VALUE_0", "keep", 1);
setup_git_directory();
if (read_cache() < 0)
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index 2051ce57db..a282b6ff13 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -134,7 +134,6 @@ int cmd__parse_options(int argc, const char **argv)
OPT_NOOP_NOARG(0, "obsolete"),
OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
OPT_GROUP("Magic arguments"),
- OPT_ARGUMENT("quux", NULL, "means --quux"),
OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
number_callback),
{ OPTION_COUNTUP, '+', NULL, &boolean, NULL, "same as -b",
diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c
index 7c2eb11a8e..cb0d27049a 100644
--- a/t/helper/test-read-midx.c
+++ b/t/helper/test-read-midx.c
@@ -60,12 +60,26 @@ static int read_midx_file(const char *object_dir, int show_objects)
return 0;
}
+static int read_midx_checksum(const char *object_dir)
+{
+ struct multi_pack_index *m;
+
+ setup_git_directory();
+ m = load_multi_pack_index(object_dir, 1);
+ if (!m)
+ return 1;
+ printf("%s\n", hash_to_hex(get_midx_checksum(m)));
+ return 0;
+}
+
int cmd__read_midx(int argc, const char **argv)
{
if (!(argc == 2 || argc == 3))
- usage("read-midx [--show-objects] <object-dir>");
+ usage("read-midx [--show-objects|--checksum] <object-dir>");
if (!strcmp(argv[1], "--show-objects"))
return read_midx_file(argv[2], 1);
+ else if (!strcmp(argv[1], "--checksum"))
+ return read_midx_checksum(argv[2]);
return read_midx_file(argv[1], 0);
}
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index 7ae03dc712..14c57365e7 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -61,7 +61,7 @@ struct testsuite {
int quiet, immediate, verbose, verbose_log, trace, write_junit_xml;
};
#define TESTSUITE_INIT \
- { STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, -1, 0, 0, 0, 0, 0, 0 }
+ { STRING_LIST_INIT_DUP, STRING_LIST_INIT_DUP, 0, 0, 0, 0, 0, 0, 0 }
static int next_test(struct child_process *cp, struct strbuf *err, void *cb,
void **task_cb)
@@ -142,9 +142,6 @@ static int testsuite(int argc, const char **argv)
OPT_END()
};
- memset(&suite, 0, sizeof(suite));
- suite.tests.strdup_strings = suite.failed.strdup_strings = 1;
-
argc = parse_options(argc, argv, NULL, options,
testsuite_usage, PARSE_OPT_STOP_AT_NON_OPTION);
diff --git a/t/helper/test-serve-v2.c b/t/helper/test-serve-v2.c
index aee35e5aef..28e905afc3 100644
--- a/t/helper/test-serve-v2.c
+++ b/t/helper/test-serve-v2.c
@@ -10,12 +10,12 @@ static char const * const serve_usage[] = {
int cmd__serve_v2(int argc, const char **argv)
{
- struct serve_options opts = SERVE_OPTIONS_INIT;
-
+ int stateless_rpc = 0;
+ int advertise_capabilities = 0;
struct option options[] = {
- OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc,
+ OPT_BOOL(0, "stateless-rpc", &stateless_rpc,
N_("quit after a single request/response exchange")),
- OPT_BOOL(0, "advertise-capabilities", &opts.advertise_capabilities,
+ OPT_BOOL(0, "advertise-capabilities", &advertise_capabilities,
N_("exit immediately after advertising capabilities")),
OPT_END()
};
@@ -25,7 +25,11 @@ int cmd__serve_v2(int argc, const char **argv)
argc = parse_options(argc, argv, prefix, options, serve_usage,
PARSE_OPT_KEEP_DASHDASH |
PARSE_OPT_KEEP_UNKNOWN);
- serve(&opts);
+
+ if (advertise_capabilities)
+ protocol_v2_advertise_capabilities();
+ else
+ protocol_v2_serve_loop(stateless_rpc);
return 0;
}
diff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c
index e3f11ff5a7..dc1c14bde3 100644
--- a/t/helper/test-submodule-nested-repo-config.c
+++ b/t/helper/test-submodule-nested-repo-config.c
@@ -11,15 +11,13 @@ static void die_usage(const char **argv, const char *msg)
int cmd__submodule_nested_repo_config(int argc, const char **argv)
{
struct repository subrepo;
- const struct submodule *sub;
if (argc < 3)
die_usage(argv, "Wrong number of arguments.");
setup_git_directory();
- sub = submodule_from_path(the_repository, null_oid(), argv[1]);
- if (repo_submodule_init(&subrepo, the_repository, sub)) {
+ if (repo_submodule_init(&subrepo, the_repository, argv[1], null_oid())) {
die_usage(argv, "Submodule not found.");
}
diff --git a/t/lib-bitmap.sh b/t/lib-bitmap.sh
index fe3f98be24..21d0392dda 100644
--- a/t/lib-bitmap.sh
+++ b/t/lib-bitmap.sh
@@ -1,3 +1,6 @@
+# Helpers for scripts testing bitmap functionality; see t5310 for
+# example usage.
+
# Compare a file containing rev-list bitmap traversal output to its non-bitmap
# counterpart. You can't just use test_cmp for this, because the two produce
# subtly different output:
@@ -24,3 +27,240 @@ test_bitmap_traversal () {
test_cmp "$1.normalized" "$2.normalized" &&
rm -f "$1.normalized" "$2.normalized"
}
+
+# To ensure the logic for "maximal commits" is exercised, make
+# the repository a bit more complicated.
+#
+# other second
+# * *
+# (99 commits) (99 commits)
+# * *
+# |\ /|
+# | * octo-other octo-second * |
+# |/|\_________ ____________/|\|
+# | \ \/ __________/ |
+# | | ________/\ / |
+# * |/ * merge-right *
+# | _|__________/ \____________ |
+# |/ | \|
+# (l1) * * merge-left * (r1)
+# | / \________________________ |
+# |/ \|
+# (l2) * * (r2)
+# \___________________________ |
+# \|
+# * (base)
+#
+# We only push bits down the first-parent history, which
+# makes some of these commits unimportant!
+#
+# The important part for the maximal commit algorithm is how
+# the bitmasks are extended. Assuming starting bit positions
+# for second (bit 0) and other (bit 1), the bitmasks at the
+# end should be:
+#
+# second: 1 (maximal, selected)
+# other: 01 (maximal, selected)
+# (base): 11 (maximal)
+#
+# This complicated history was important for a previous
+# version of the walk that guarantees never walking a
+# commit multiple times. That goal might be important
+# again, so preserve this complicated case. For now, this
+# test will guarantee that the bitmaps are computed
+# correctly, even with the repeat calculations.
+setup_bitmap_history() {
+ test_expect_success 'setup repo with moderate-sized history' '
+ test_commit_bulk --id=file 10 &&
+ git branch -M second &&
+ git checkout -b other HEAD~5 &&
+ test_commit_bulk --id=side 10 &&
+
+ # add complicated history setup, including merges and
+ # ambiguous merge-bases
+
+ git checkout -b merge-left other~2 &&
+ git merge second~2 -m "merge-left" &&
+
+ git checkout -b merge-right second~1 &&
+ git merge other~1 -m "merge-right" &&
+
+ git checkout -b octo-second second &&
+ git merge merge-left merge-right -m "octopus-second" &&
+
+ git checkout -b octo-other other &&
+ git merge merge-left merge-right -m "octopus-other" &&
+
+ git checkout other &&
+ git merge octo-other -m "pull octopus" &&
+
+ git checkout second &&
+ git merge octo-second -m "pull octopus" &&
+
+ # Remove these branches so they are not selected
+ # as bitmap tips
+ git branch -D merge-left &&
+ git branch -D merge-right &&
+ git branch -D octo-other &&
+ git branch -D octo-second &&
+
+ # add padding to make these merges less interesting
+ # and avoid having them selected for bitmaps
+ test_commit_bulk --id=file 100 &&
+ git checkout other &&
+ test_commit_bulk --id=side 100 &&
+ git checkout second &&
+
+ bitmaptip=$(git rev-parse second) &&
+ blob=$(echo tagged-blob | git hash-object -w --stdin) &&
+ git tag tagged-blob $blob
+ '
+}
+
+rev_list_tests_head () {
+ test_expect_success "counting commits via bitmap ($state, $branch)" '
+ git rev-list --count $branch >expect &&
+ git rev-list --use-bitmap-index --count $branch >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "counting partial commits via bitmap ($state, $branch)" '
+ git rev-list --count $branch~5..$branch >expect &&
+ git rev-list --use-bitmap-index --count $branch~5..$branch >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "counting commits with limit ($state, $branch)" '
+ git rev-list --count -n 1 $branch >expect &&
+ git rev-list --use-bitmap-index --count -n 1 $branch >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "counting non-linear history ($state, $branch)" '
+ git rev-list --count other...second >expect &&
+ git rev-list --use-bitmap-index --count other...second >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "counting commits with limiting ($state, $branch)" '
+ git rev-list --count $branch -- 1.t >expect &&
+ git rev-list --use-bitmap-index --count $branch -- 1.t >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "counting objects via bitmap ($state, $branch)" '
+ git rev-list --count --objects $branch >expect &&
+ git rev-list --use-bitmap-index --count --objects $branch >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success "enumerate commits ($state, $branch)" '
+ git rev-list --use-bitmap-index $branch >actual &&
+ git rev-list $branch >expect &&
+ test_bitmap_traversal --no-confirm-bitmaps expect actual
+ '
+
+ test_expect_success "enumerate --objects ($state, $branch)" '
+ git rev-list --objects --use-bitmap-index $branch >actual &&
+ git rev-list --objects $branch >expect &&
+ test_bitmap_traversal expect actual
+ '
+
+ test_expect_success "bitmap --objects handles non-commit objects ($state, $branch)" '
+ git rev-list --objects --use-bitmap-index $branch tagged-blob >actual &&
+ grep $blob actual
+ '
+}
+
+rev_list_tests () {
+ state=$1
+
+ for branch in "second" "other"
+ do
+ rev_list_tests_head
+ done
+}
+
+basic_bitmap_tests () {
+ tip="$1"
+ test_expect_success 'rev-list --test-bitmap verifies bitmaps' "
+ git rev-list --test-bitmap "${tip:-HEAD}"
+ "
+
+ rev_list_tests 'full bitmap'
+
+ test_expect_success 'clone from bitmapped repository' '
+ rm -fr clone.git &&
+ git clone --no-local --bare . clone.git &&
+ git rev-parse HEAD >expect &&
+ git --git-dir=clone.git rev-parse HEAD >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success 'partial clone from bitmapped repository' '
+ test_config uploadpack.allowfilter true &&
+ rm -fr partial-clone.git &&
+ git clone --no-local --bare --filter=blob:none . partial-clone.git &&
+ (
+ cd partial-clone.git &&
+ pack=$(echo objects/pack/*.pack) &&
+ git verify-pack -v "$pack" >have &&
+ awk "/blob/ { print \$1 }" <have >blobs &&
+ # we expect this single blob because of the direct ref
+ git rev-parse refs/tags/tagged-blob >expect &&
+ test_cmp expect blobs
+ )
+ '
+
+ test_expect_success 'setup further non-bitmapped commits' '
+ test_commit_bulk --id=further 10
+ '
+
+ rev_list_tests 'partial bitmap'
+
+ test_expect_success 'fetch (partial bitmap)' '
+ git --git-dir=clone.git fetch origin second:second &&
+ git rev-parse HEAD >expect &&
+ git --git-dir=clone.git rev-parse HEAD >actual &&
+ test_cmp expect actual
+ '
+
+ test_expect_success 'enumerating progress counts pack-reused objects' '
+ count=$(git rev-list --objects --all --count) &&
+ git repack -adb &&
+
+ # check first with only reused objects; confirm that our
+ # progress showed the right number, and also that we did
+ # pack-reuse as expected. Check only the final "done"
+ # line of the meter (there may be an arbitrary number of
+ # intermediate lines ending with CR).
+ GIT_PROGRESS_DELAY=0 \
+ git pack-objects --all --stdout --progress \
+ </dev/null >/dev/null 2>stderr &&
+ grep "Enumerating objects: $count, done" stderr &&
+ grep "pack-reused $count" stderr &&
+
+ # now the same but with one non-reused object
+ git commit --allow-empty -m "an extra commit object" &&
+ GIT_PROGRESS_DELAY=0 \
+ git pack-objects --all --stdout --progress \
+ </dev/null >/dev/null 2>stderr &&
+ grep "Enumerating objects: $((count+1)), done" stderr &&
+ grep "pack-reused $count" stderr
+ '
+}
+
+# have_delta <obj> <expected_base>
+#
+# Note that because this relies on cat-file, it might find _any_ copy of an
+# object in the repository. The caller is responsible for making sure
+# there's only one (e.g., via "repack -ad", or having just fetched a copy).
+have_delta () {
+ echo $2 >expect &&
+ echo $1 | git cat-file --batch-check="%(deltabase)" >actual &&
+ test_cmp expect actual
+}
+
+midx_checksum () {
+ test-tool read-midx --checksum "$1"
+}
diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf
index afa91e38b0..180a41fe96 100644
--- a/t/lib-httpd/apache.conf
+++ b/t/lib-httpd/apache.conf
@@ -81,8 +81,6 @@ PassEnv GIT_TRACE
PassEnv GIT_CONFIG_NOSYSTEM
PassEnv GIT_TEST_SIDEBAND_ALL
-SetEnvIf Git-Protocol ".*" GIT_PROTOCOL=$0
-
Alias /dumb/ www/
Alias /auth/dumb/ www/auth/dumb/
@@ -117,6 +115,11 @@ Alias /auth/dumb/ www/auth/dumb/
SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
SetEnv GIT_HTTP_EXPORT_ALL
</LocationMatch>
+<LocationMatch /smart_v0/>
+ SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
+ SetEnv GIT_HTTP_EXPORT_ALL
+ SetEnv GIT_PROTOCOL
+</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/
diff --git a/t/perf/lib-bitmap.sh b/t/perf/lib-bitmap.sh
new file mode 100644
index 0000000000..63d3bc7cec
--- /dev/null
+++ b/t/perf/lib-bitmap.sh
@@ -0,0 +1,69 @@
+# Helper functions for testing bitmap performance; see p5310.
+
+test_full_bitmap () {
+ test_perf 'simulated clone' '
+ git pack-objects --stdout --all </dev/null >/dev/null
+ '
+
+ test_perf 'simulated fetch' '
+ have=$(git rev-list HEAD~100 -1) &&
+ {
+ echo HEAD &&
+ echo ^$have
+ } | git pack-objects --revs --stdout >/dev/null
+ '
+
+ test_perf 'pack to file (bitmap)' '
+ git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null
+ '
+
+ test_perf 'rev-list (commits)' '
+ git rev-list --all --use-bitmap-index >/dev/null
+ '
+
+ test_perf 'rev-list (objects)' '
+ git rev-list --all --use-bitmap-index --objects >/dev/null
+ '
+
+ test_perf 'rev-list with tag negated via --not --all (objects)' '
+ git rev-list perf-tag --not --all --use-bitmap-index --objects >/dev/null
+ '
+
+ test_perf 'rev-list with negative tag (objects)' '
+ git rev-list HEAD --not perf-tag --use-bitmap-index --objects >/dev/null
+ '
+
+ test_perf 'rev-list count with blob:none' '
+ git rev-list --use-bitmap-index --count --objects --all \
+ --filter=blob:none >/dev/null
+ '
+
+ test_perf 'rev-list count with blob:limit=1k' '
+ git rev-list --use-bitmap-index --count --objects --all \
+ --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
+ '
+}
+
+test_partial_bitmap () {
+ test_perf 'clone (partial bitmap)' '
+ git pack-objects --stdout --all </dev/null >/dev/null
+ '
+
+ 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
+ '
+}
diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh
index 452be01056..7ad4f237bc 100755
--- a/t/perf/p5310-pack-bitmaps.sh
+++ b/t/perf/p5310-pack-bitmaps.sh
@@ -2,6 +2,7 @@
test_description='Tests pack performance using bitmaps'
. ./perf-lib.sh
+. "${TEST_DIRECTORY}/perf/lib-bitmap.sh"
test_perf_large_repo
@@ -25,56 +26,7 @@ test_perf 'repack to disk' '
git repack -ad
'
-test_perf 'simulated clone' '
- git pack-objects --stdout --all </dev/null >/dev/null
-'
-
-test_perf 'simulated fetch' '
- have=$(git rev-list HEAD~100 -1) &&
- {
- echo HEAD &&
- echo ^$have
- } | git pack-objects --revs --stdout >/dev/null
-'
-
-test_perf 'pack to file (bitmap)' '
- git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null
-'
-
-test_perf 'rev-list (commits)' '
- git rev-list --all --use-bitmap-index >/dev/null
-'
-
-test_perf 'rev-list (objects)' '
- git rev-list --all --use-bitmap-index --objects >/dev/null
-'
-
-test_perf 'rev-list with tag negated via --not --all (objects)' '
- git rev-list perf-tag --not --all --use-bitmap-index --objects >/dev/null
-'
-
-test_perf 'rev-list with negative tag (objects)' '
- git rev-list HEAD --not perf-tag --use-bitmap-index --objects >/dev/null
-'
-
-test_perf 'rev-list count with blob:none' '
- git rev-list --use-bitmap-index --count --objects --all \
- --filter=blob:none >/dev/null
-'
-
-test_perf 'rev-list count with blob:limit=1k' '
- git rev-list --use-bitmap-index --count --objects --all \
- --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
-'
+test_full_bitmap
test_expect_success 'create partial bitmap state' '
# pick a commit to represent the repo tip in the past
@@ -97,17 +49,6 @@ test_expect_success 'create partial bitmap state' '
git update-ref HEAD $orig_tip
'
-test_perf 'clone (partial bitmap)' '
- git pack-objects --stdout --all </dev/null >/dev/null
-'
-
-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_partial_bitmap
test_done
diff --git a/t/perf/p5326-multi-pack-bitmaps.sh b/t/perf/p5326-multi-pack-bitmaps.sh
new file mode 100755
index 0000000000..5845109ac7
--- /dev/null
+++ b/t/perf/p5326-multi-pack-bitmaps.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+test_description='Tests performance using midx bitmaps'
+. ./perf-lib.sh
+. "${TEST_DIRECTORY}/perf/lib-bitmap.sh"
+
+test_perf_large_repo
+
+test_expect_success 'enable multi-pack index' '
+ git config core.multiPackIndex true
+'
+
+test_perf 'setup multi-pack index' '
+ git repack -ad &&
+ git multi-pack-index write --bitmap
+'
+
+test_full_bitmap
+
+test_expect_success 'create partial bitmap state' '
+ # pick a commit to represent the repo tip in the past
+ cutoff=$(git rev-list HEAD~100 -1) &&
+ orig_tip=$(git rev-parse HEAD) &&
+
+ # now pretend we have just one tip
+ rm -rf .git/logs .git/refs/* .git/packed-refs &&
+ git update-ref HEAD $cutoff &&
+
+ # and then repack, which will leave us with a nice
+ # big bitmap pack of the "old" history, and all of
+ # the new history will be loose, as if it had been pushed
+ # up incrementally and exploded via unpack-objects
+ git repack -Ad &&
+ git multi-pack-index write --bitmap &&
+
+ # and now restore our original tip, as if the pushes
+ # had happened
+ git update-ref HEAD $orig_tip
+'
+
+test_partial_bitmap
+
+test_done
diff --git a/t/perf/run b/t/perf/run
index d19dec258a..55219aa405 100755
--- a/t/perf/run
+++ b/t/perf/run
@@ -74,7 +74,7 @@ set_git_test_installed () {
mydir=$1
mydir_abs=$(cd $mydir && pwd)
- mydir_abs_wrappers="$mydir_abs_wrappers/bin-wrappers"
+ mydir_abs_wrappers="$mydir_abs/bin-wrappers"
if test -d "$mydir_abs_wrappers"
then
GIT_TEST_INSTALLED=$mydir_abs_wrappers
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index cb87768513..5c342de713 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -1271,28 +1271,29 @@ P=$(test_oid root)
test_expect_success 'git commit-tree records the correct tree in a commit' '
commit0=$(echo NO | git commit-tree $P) &&
- tree=$(git show --pretty=raw $commit0 |
- sed -n -e "s/^tree //p" -e "/^author /q") &&
+ git show --pretty=raw $commit0 >out &&
+ tree=$(sed -n -e "s/^tree //p" -e "/^author /q" out) &&
test "z$tree" = "z$P"
'
test_expect_success 'git commit-tree records the correct parent in a commit' '
commit1=$(echo NO | git commit-tree $P -p $commit0) &&
- parent=$(git show --pretty=raw $commit1 |
- sed -n -e "s/^parent //p" -e "/^author /q") &&
+ git show --pretty=raw $commit1 >out &&
+ parent=$(sed -n -e "s/^parent //p" -e "/^author /q" out) &&
test "z$commit0" = "z$parent"
'
test_expect_success 'git commit-tree omits duplicated parent in a commit' '
commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) &&
- parent=$(git show --pretty=raw $commit2 |
- sed -n -e "s/^parent //p" -e "/^author /q" |
- sort -u) &&
+ git show --pretty=raw $commit2 >out &&
+ cat >match.sed <<-\EOF &&
+ s/^parent //p
+ /^author /q
+ EOF
+ parent=$(sed -n -f match.sed out | sort -u) &&
test "z$commit0" = "z$parent" &&
- numparent=$(git show --pretty=raw $commit2 |
- sed -n -e "s/^parent //p" -e "/^author /q" |
- wc -l) &&
- test $numparent = 1
+ git show --pretty=raw $commit2 >out &&
+ test_stdout_line_count = 1 sed -n -f match.sed out
'
test_expect_success 'update-index D/F conflict' '
diff --git a/t/t0012-help.sh b/t/t0012-help.sh
index 5679e29c62..913f34c8e9 100755
--- a/t/t0012-help.sh
+++ b/t/t0012-help.sh
@@ -73,6 +73,22 @@ test_expect_success 'git help -g' '
test_i18ngrep "^ tutorial " help.output
'
+test_expect_success 'git help fails for non-existing html pages' '
+ configure_help &&
+ mkdir html-empty &&
+ test_must_fail git -c help.htmlpath=html-empty help status &&
+ test_must_be_empty test-browser.log
+'
+
+test_expect_success 'git help succeeds without git.html' '
+ configure_help &&
+ mkdir html-with-docs &&
+ touch html-with-docs/git-status.html &&
+ git -c help.htmlpath=html-with-docs help status &&
+ echo "html-with-docs/git-status.html" >expect &&
+ test_cmp expect test-browser.log
+'
+
test_expect_success 'generate builtin list' '
git --list-cmds=builtins >builtins
'
diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh
index b5749f327d..33dfc9cd56 100755
--- a/t/t0021-conversion.sh
+++ b/t/t0021-conversion.sh
@@ -6,6 +6,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-terminal.sh
TEST_ROOT="$PWD"
PATH=$TEST_ROOT:$PATH
@@ -1061,4 +1062,74 @@ test_expect_success PERL,SYMLINKS,CASE_INSENSITIVE_FS \
)
'
+test_expect_success PERL 'setup for progress tests' '
+ git init progress &&
+ (
+ cd progress &&
+ git config filter.delay.process "rot13-filter.pl delay-progress.log clean smudge delay" &&
+ git config filter.delay.required true &&
+
+ echo "*.a filter=delay" >.gitattributes &&
+ touch test-delay10.a &&
+ git add . &&
+ git commit -m files
+ )
+'
+
+test_delayed_checkout_progress () {
+ if test "$1" = "!"
+ then
+ local expect_progress=N &&
+ shift
+ else
+ local expect_progress=
+ fi &&
+
+ if test $# -lt 1
+ then
+ BUG "no command given to test_delayed_checkout_progress"
+ fi &&
+
+ (
+ cd progress &&
+ GIT_PROGRESS_DELAY=0 &&
+ export GIT_PROGRESS_DELAY &&
+ rm -f *.a delay-progress.log &&
+
+ "$@" 2>err &&
+ grep "IN: smudge test-delay10.a .* \\[DELAYED\\]" delay-progress.log &&
+ if test "$expect_progress" = N
+ then
+ ! grep "Filtering content" err
+ else
+ grep "Filtering content" err
+ fi
+ )
+}
+
+for mode in pathspec branch
+do
+ case "$mode" in
+ pathspec) opt='.' ;;
+ branch) opt='-f HEAD' ;;
+ esac
+
+ test_expect_success PERL,TTY "delayed checkout shows progress by default on tty ($mode checkout)" '
+ test_delayed_checkout_progress test_terminal git checkout $opt
+ '
+
+ test_expect_success PERL "delayed checkout ommits progress on non-tty ($mode checkout)" '
+ test_delayed_checkout_progress ! git checkout $opt
+ '
+
+ test_expect_success PERL,TTY "delayed checkout ommits progress with --quiet ($mode checkout)" '
+ test_delayed_checkout_progress ! test_terminal git checkout --quiet $opt
+ '
+
+ test_expect_success PERL,TTY "delayed checkout honors --[no]-progress ($mode checkout)" '
+ test_delayed_checkout_progress ! test_terminal git checkout --no-progress $opt &&
+ test_delayed_checkout_progress test_terminal git checkout --quiet --progress $opt
+ '
+done
+
test_done
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index ad4746d899..da310ed29b 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -37,7 +37,6 @@ String options
--list <str> add str to list
Magic arguments
- --quux means --quux
-NUM set integer to NUM
+ same as -b
--ambiguous positive ambiguity
@@ -263,10 +262,6 @@ test_expect_success 'detect possible typos' '
test_cmp typo.err output.err
'
-test_expect_success 'keep some options as arguments' '
- test-tool parse-options --expect="arg 00: --quux" --quux
-'
-
cat >expect <<\EOF
Callback: "four", 0
boolean: 5
diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh
index 9bf66c9e68..9067572648 100755
--- a/t/t0090-cache-tree.sh
+++ b/t/t0090-cache-tree.sh
@@ -195,6 +195,7 @@ test_expect_success 'reset --hard gives cache-tree' '
test_expect_success 'reset --hard without index gives cache-tree' '
rm -f .git/index &&
+ git clean -fd &&
git reset --hard &&
test_cache_tree
'
diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh
index ebd5fa5249..698b7159f0 100755
--- a/t/t0301-credential-cache.sh
+++ b/t/t0301-credential-cache.sh
@@ -9,6 +9,21 @@ test -z "$NO_UNIX_SOCKETS" || {
test_done
}
+uname_s=$(uname -s)
+case $uname_s in
+*MINGW*)
+ test_path_is_socket () {
+ # `test -S` cannot detect Win10's Unix sockets
+ test_path_exists "$1"
+ }
+ ;;
+*)
+ test_path_is_socket () {
+ test -S "$1"
+ }
+ ;;
+esac
+
# don't leave a stale daemon running
test_atexit 'git credential-cache exit'
@@ -21,7 +36,7 @@ test_expect_success 'socket defaults to ~/.cache/git/credential/socket' '
rmdir -p .cache/git/credential/
" &&
test_path_is_missing "$HOME/.git-credential-cache" &&
- test -S "$HOME/.cache/git/credential/socket"
+ test_path_is_socket "$HOME/.cache/git/credential/socket"
'
XDG_CACHE_HOME="$HOME/xdg"
@@ -31,7 +46,7 @@ helper_test cache
test_expect_success "use custom XDG_CACHE_HOME if set and default sockets are not created" '
test_when_finished "git credential-cache exit" &&
- test -S "$XDG_CACHE_HOME/git/credential/socket" &&
+ test_path_is_socket "$XDG_CACHE_HOME/git/credential/socket" &&
test_path_is_missing "$HOME/.git-credential-cache/socket" &&
test_path_is_missing "$HOME/.cache/git/credential/socket"
'
@@ -48,7 +63,7 @@ test_expect_success 'credential-cache --socket option overrides default location
username=store-user
password=store-pass
EOF
- test -S "$HOME/dir/socket"
+ test_path_is_socket "$HOME/dir/socket"
'
test_expect_success "use custom XDG_CACHE_HOME even if xdg socket exists" '
@@ -62,7 +77,7 @@ test_expect_success "use custom XDG_CACHE_HOME even if xdg socket exists" '
username=store-user
password=store-pass
EOF
- test -S "$HOME/.cache/git/credential/socket" &&
+ test_path_is_socket "$HOME/.cache/git/credential/socket" &&
XDG_CACHE_HOME="$HOME/xdg" &&
export XDG_CACHE_HOME &&
check approve cache <<-\EOF &&
@@ -71,7 +86,7 @@ test_expect_success "use custom XDG_CACHE_HOME even if xdg socket exists" '
username=store-user
password=store-pass
EOF
- test -S "$XDG_CACHE_HOME/git/credential/socket"
+ test_path_is_socket "$XDG_CACHE_HOME/git/credential/socket"
'
test_expect_success 'use user socket if user directory exists' '
@@ -79,14 +94,15 @@ test_expect_success 'use user socket if user directory exists' '
git credential-cache exit &&
rmdir \"\$HOME/.git-credential-cache/\"
" &&
- mkdir -p -m 700 "$HOME/.git-credential-cache/" &&
+ mkdir -p "$HOME/.git-credential-cache/" &&
+ chmod 700 "$HOME/.git-credential-cache/" &&
check approve cache <<-\EOF &&
protocol=https
host=example.com
username=store-user
password=store-pass
EOF
- test -S "$HOME/.git-credential-cache/socket"
+ test_path_is_socket "$HOME/.git-credential-cache/socket"
'
test_expect_success SYMLINKS 'use user socket if user directory is a symlink to a directory' '
@@ -103,7 +119,7 @@ test_expect_success SYMLINKS 'use user socket if user directory is a symlink to
username=store-user
password=store-pass
EOF
- test -S "$HOME/.git-credential-cache/socket"
+ test_path_is_socket "$HOME/.git-credential-cache/socket"
'
helper_test_timeout cache --timeout=1
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh
index a211a66c67..bba679685f 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -4,6 +4,9 @@ test_description='partial clone'
. ./test-lib.sh
+# missing promisor objects cause repacks which write bitmaps to fail
+GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0
+
delete_object () {
rm $1/.git/objects/$(echo $2 | sed -e 's|^..|&/|')
}
@@ -536,7 +539,13 @@ test_expect_success 'gc does not repack promisor objects if there are none' '
repack_and_check () {
rm -rf repo2 &&
cp -r repo repo2 &&
- git -C repo2 repack $1 -d &&
+ if test x"$1" = "x--must-fail"
+ then
+ shift
+ test_must_fail git -C repo2 repack $1 -d
+ else
+ git -C repo2 repack $1 -d
+ fi &&
git -C repo2 fsck &&
git -C repo2 cat-file -e $2 &&
@@ -561,6 +570,7 @@ test_expect_success 'repack -d does not irreversibly delete promisor objects' '
printf "$THREE\n" | pack_as_from_promisor &&
delete_object repo "$ONE" &&
+ repack_and_check --must-fail -ab "$TWO" "$THREE" &&
repack_and_check -a "$TWO" "$THREE" &&
repack_and_check -A "$TWO" "$THREE" &&
repack_and_check -l "$TWO" "$THREE"
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index 38fc8340f5..71236981e6 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -642,4 +642,63 @@ test_expect_success MINGW 'cone mode replaces backslashes with slashes' '
check_files repo/deep a deeper1
'
+test_expect_success 'cone mode clears ignored subdirectories' '
+ rm repo/.git/info/sparse-checkout &&
+
+ git -C repo sparse-checkout init --cone &&
+ git -C repo sparse-checkout set deep/deeper1 &&
+
+ cat >repo/.gitignore <<-\EOF &&
+ obj/
+ *.o
+ EOF
+
+ git -C repo add .gitignore &&
+ git -C repo commit -m ".gitignore" &&
+
+ mkdir -p repo/obj repo/folder1/obj repo/deep/deeper2/obj &&
+ for file in folder1/obj/a obj/a folder1/file.o folder1.o \
+ deep/deeper2/obj/a deep/deeper2/file.o file.o
+ do
+ echo ignored >repo/$file || return 1
+ done &&
+
+ git -C repo status --porcelain=v2 >out &&
+ test_must_be_empty out &&
+
+ git -C repo sparse-checkout reapply &&
+ test_path_is_missing repo/folder1 &&
+ test_path_is_missing repo/deep/deeper2 &&
+ test_path_is_dir repo/obj &&
+ test_path_is_file repo/file.o &&
+
+ git -C repo status --porcelain=v2 >out &&
+ test_must_be_empty out &&
+
+ git -C repo sparse-checkout set deep/deeper2 &&
+ test_path_is_missing repo/deep/deeper1 &&
+ test_path_is_dir repo/deep/deeper2 &&
+ test_path_is_dir repo/obj &&
+ test_path_is_file repo/file.o &&
+
+ >repo/deep/deeper2/ignored.o &&
+ >repo/deep/deeper2/untracked &&
+
+ # When an untracked file is in the way, all untracked files
+ # (even ignored files) are preserved.
+ git -C repo sparse-checkout set folder1 2>err &&
+ grep "contains untracked files" err &&
+ test_path_is_file repo/deep/deeper2/ignored.o &&
+ test_path_is_file repo/deep/deeper2/untracked &&
+
+ # The rest of the cone matches expectation
+ test_path_is_missing repo/deep/deeper1 &&
+ test_path_is_dir repo/obj &&
+ test_path_is_file repo/file.o &&
+
+ git -C repo status --porcelain=v2 >out &&
+ echo "? deep/deeper2/untracked" >expect &&
+ test_cmp expect out
+'
+
test_done
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index ddc86bb415..886e78715f 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -47,7 +47,7 @@ test_expect_success 'setup' '
git checkout -b base &&
for dir in folder1 folder2 deep
do
- git checkout -b update-$dir &&
+ git checkout -b update-$dir base &&
echo "updated $dir" >$dir/a &&
git commit -a -m "update $dir" || return 1
done &&
@@ -481,14 +481,17 @@ test_expect_success 'checkout and reset (mixed) [sparse]' '
test_sparse_match git reset update-folder2
'
-test_expect_success 'merge' '
+test_expect_success 'merge, cherry-pick, and rebase' '
init_repos &&
- test_all_match git checkout -b merge update-deep &&
- test_all_match git merge -m "folder1" update-folder1 &&
- test_all_match git rev-parse HEAD^{tree} &&
- test_all_match git merge -m "folder2" update-folder2 &&
- test_all_match git rev-parse HEAD^{tree}
+ for OPERATION in "merge -m merge" cherry-pick rebase
+ do
+ test_all_match git checkout -B temp update-deep &&
+ test_all_match git $OPERATION update-folder1 &&
+ test_all_match git rev-parse HEAD^{tree} &&
+ test_all_match git $OPERATION update-folder2 &&
+ test_all_match git rev-parse HEAD^{tree} || return 1
+ done
'
# NEEDSWORK: This test is documenting current behavior, but that
@@ -524,6 +527,38 @@ test_expect_success 'merge with conflict outside cone' '
test_all_match git rev-parse HEAD^{tree}
'
+test_expect_success 'cherry-pick/rebase with conflict outside cone' '
+ init_repos &&
+
+ for OPERATION in cherry-pick rebase
+ do
+ test_all_match git checkout -B tip &&
+ test_all_match git reset --hard merge-left &&
+ test_all_match git status --porcelain=v2 &&
+ test_all_match test_must_fail git $OPERATION merge-right &&
+ test_all_match git status --porcelain=v2 &&
+
+ # Resolve the conflict in different ways:
+ # 1. Revert to the base
+ test_all_match git checkout base -- deep/deeper2/a &&
+ test_all_match git status --porcelain=v2 &&
+
+ # 2. Add the file with conflict markers
+ test_all_match git add folder1/a &&
+ test_all_match git status --porcelain=v2 &&
+
+ # 3. Rename the file to another sparse filename and
+ # accept conflict markers as resolved content.
+ run_on_all mv folder2/a folder2/z &&
+ test_all_match git add folder2 &&
+ test_all_match git status --porcelain=v2 &&
+
+ test_all_match git $OPERATION --continue &&
+ test_all_match git status --porcelain=v2 &&
+ test_all_match git rev-parse HEAD^{tree} || return 1
+ done
+'
+
test_expect_success 'merge with outside renames' '
init_repos &&
@@ -617,8 +652,17 @@ test_expect_success 'sparse-index is expanded and converted back' '
ensure_not_expanded () {
rm -f trace2.txt &&
echo >>sparse-index/untracked.txt &&
- GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
- git -C sparse-index "$@" &&
+
+ if test "$1" = "!"
+ then
+ shift &&
+ test_must_fail env \
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
+ git -C sparse-index "$@" || return 1
+ else
+ GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
+ git -C sparse-index "$@" || return 1
+ fi &&
test_region ! index ensure_full_index trace2.txt
}
@@ -647,7 +691,35 @@ test_expect_success 'sparse-index is not expanded' '
echo >>sparse-index/extra.txt &&
ensure_not_expanded add extra.txt &&
echo >>sparse-index/untracked.txt &&
- ensure_not_expanded add .
+ ensure_not_expanded add . &&
+
+ ensure_not_expanded checkout -f update-deep &&
+ test_config -C sparse-index pull.twohead ort &&
+ (
+ sane_unset GIT_TEST_MERGE_ALGORITHM &&
+ for OPERATION in "merge -m merge" cherry-pick rebase
+ do
+ ensure_not_expanded merge -m merge update-folder1 &&
+ ensure_not_expanded merge -m merge update-folder2 || return 1
+ done
+ )
+'
+
+test_expect_success 'sparse-index is not expanded: merge conflict in cone' '
+ init_repos &&
+
+ for side in right left
+ do
+ git -C sparse-index checkout -b expand-$side base &&
+ echo $side >sparse-index/deep/a &&
+ git -C sparse-index commit -a -m "$side" || return 1
+ done &&
+
+ (
+ sane_unset GIT_TEST_MERGE_ALGORITHM &&
+ git -C sparse-index config pull.twohead ort &&
+ ensure_not_expanded ! merge -m merged expand-right
+ )
'
# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh
index 4506cd435b..0d4f73acaa 100755
--- a/t/t1400-update-ref.sh
+++ b/t/t1400-update-ref.sh
@@ -1598,6 +1598,40 @@ test_expect_success 'transaction cannot restart ongoing transaction' '
test_must_fail git show-ref --verify refs/heads/restart
'
+test_expect_success PIPE 'transaction flushes status updates' '
+ mkfifo in out &&
+ (git update-ref --stdin <in >out &) &&
+
+ exec 9>in &&
+ exec 8<out &&
+ test_when_finished "exec 9>&-" &&
+ test_when_finished "exec 8<&-" &&
+
+ echo "start" >&9 &&
+ echo "start: ok" >expected &&
+ read line <&8 &&
+ echo "$line" >actual &&
+ test_cmp expected actual &&
+
+ echo "create refs/heads/flush $A" >&9 &&
+
+ echo prepare >&9 &&
+ echo "prepare: ok" >expected &&
+ read line <&8 &&
+ echo "$line" >actual &&
+ test_cmp expected actual &&
+
+ # This must now fail given that we have locked the ref.
+ test_must_fail git update-ref refs/heads/flush $B 2>stderr &&
+ grep "fatal: update_ref failed for ref ${SQ}refs/heads/flush${SQ}: cannot lock ref" stderr &&
+
+ echo commit >&9 &&
+ echo "commit: ok" >expected &&
+ read line <&8 &&
+ echo "$line" >actual &&
+ test_cmp expected actual
+'
+
test_expect_success 'directory not created deleting packed ref' '
git branch d1/d2/r1 HEAD &&
git pack-refs --all &&
diff --git a/t/t2021-checkout-overwrite.sh b/t/t2021-checkout-overwrite.sh
index 70d69263e6..660132ff8d 100755
--- a/t/t2021-checkout-overwrite.sh
+++ b/t/t2021-checkout-overwrite.sh
@@ -48,6 +48,7 @@ test_expect_success 'checkout commit with dir must not remove untracked a/b' '
test_expect_success SYMLINKS 'the symlink remained' '
+ test_when_finished "rm a/b" &&
test -h a/b
'
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index cc4b10236e..e575ffb4ff 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -1272,6 +1272,19 @@ test_expect_success 'attempt to delete a branch merged to its base' '
test_must_fail git branch -d my10
'
+test_expect_success 'branch --delete --force removes dangling branch' '
+ git checkout main &&
+ test_commit unstable &&
+ hash=$(git rev-parse HEAD) &&
+ objpath=$(echo $hash | sed -e "s|^..|.git/objects/&/|") &&
+ git branch --no-track dangling &&
+ mv $objpath $objpath.x &&
+ test_when_finished "mv $objpath.x $objpath" &&
+ git branch --delete --force dangling &&
+ git for-each-ref refs/heads/dangling >actual &&
+ test_must_be_empty actual
+'
+
test_expect_success 'use --edit-description' '
write_script editor <<-\EOF &&
echo "New contents" >"$1"
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index d877872e8f..972ce026bb 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -297,6 +297,7 @@ test_expect_success 'abort with error when new base cannot be checked out' '
output &&
test_i18ngrep "file1" output &&
test_path_is_missing .git/rebase-merge &&
+ rm file1 &&
git reset --hard HEAD^
'
diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh
index 7c381fbc89..ebbaed147a 100755
--- a/t/t3407-rebase-abort.sh
+++ b/t/t3407-rebase-abort.sh
@@ -7,77 +7,77 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
-### Test that we handle space characters properly
-work_dir="$(pwd)/test dir"
-
test_expect_success setup '
- mkdir -p "$work_dir" &&
- cd "$work_dir" &&
- git init &&
- echo a > a &&
- git add a &&
- git commit -m a &&
+ test_commit a a a &&
git branch to-rebase &&
- echo b > a &&
- git commit -a -m b &&
- echo c > a &&
- git commit -a -m c &&
+ test_commit --annotate b a b &&
+ test_commit --annotate c a c &&
git checkout to-rebase &&
- echo d > a &&
- git commit -a -m "merge should fail on this" &&
- echo e > a &&
- git commit -a -m "merge should fail on this, too" &&
- git branch pre-rebase
+ test_commit "merge should fail on this" a d d &&
+ test_commit --annotate "merge should fail on this, too" a e pre-rebase
'
+# Check that HEAD is equal to "pre-rebase" and the current branch is
+# "to-rebase"
+check_head() {
+ test_cmp_rev HEAD pre-rebase^{commit} &&
+ test "$(git symbolic-ref HEAD)" = refs/heads/to-rebase
+}
+
testrebase() {
type=$1
- dotest=$2
+ state_dir=$2
test_expect_success "rebase$type --abort" '
- cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
test_must_fail git rebase$type main &&
- test_path_is_dir "$dotest" &&
+ test_path_is_dir "$state_dir" &&
git rebase --abort &&
- test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) &&
- test ! -d "$dotest"
+ check_head &&
+ test_path_is_missing "$state_dir"
'
test_expect_success "rebase$type --abort after --skip" '
- cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
test_must_fail git rebase$type main &&
- test_path_is_dir "$dotest" &&
+ test_path_is_dir "$state_dir" &&
test_must_fail git rebase --skip &&
- test $(git rev-parse HEAD) = $(git rev-parse main) &&
+ test_cmp_rev HEAD main &&
git rebase --abort &&
- test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) &&
- test ! -d "$dotest"
+ check_head &&
+ test_path_is_missing "$state_dir"
'
test_expect_success "rebase$type --abort after --continue" '
- cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
test_must_fail git rebase$type main &&
- test_path_is_dir "$dotest" &&
+ test_path_is_dir "$state_dir" &&
echo c > a &&
echo d >> a &&
git add a &&
test_must_fail git rebase --continue &&
- test $(git rev-parse HEAD) != $(git rev-parse main) &&
+ test_cmp_rev ! HEAD main &&
+ git rebase --abort &&
+ check_head &&
+ test_path_is_missing "$state_dir"
+ '
+
+ test_expect_success "rebase$type --abort when checking out a tag" '
+ test_when_finished "git symbolic-ref HEAD refs/heads/to-rebase" &&
+ git reset --hard a -- &&
+ test_must_fail git rebase$type --onto b c pre-rebase &&
+ test_cmp_rev HEAD b^{commit} &&
git rebase --abort &&
- test $(git rev-parse to-rebase) = $(git rev-parse pre-rebase) &&
- test ! -d "$dotest"
+ test_cmp_rev HEAD pre-rebase^{commit} &&
+ ! git symbolic-ref HEAD
'
test_expect_success "rebase$type --abort does not update reflog" '
- cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
git reflog show to-rebase > reflog_before &&
@@ -89,7 +89,6 @@ testrebase() {
'
test_expect_success 'rebase --abort can not be used with other options' '
- cd "$work_dir" &&
# Clean up the state from the previous one
git reset --hard pre-rebase &&
test_must_fail git rebase$type main &&
@@ -97,33 +96,21 @@ testrebase() {
test_must_fail git rebase --abort -v &&
git rebase --abort
'
+
+ test_expect_success "rebase$type --quit" '
+ test_when_finished "git symbolic-ref HEAD refs/heads/to-rebase" &&
+ # Clean up the state from the previous one
+ git reset --hard pre-rebase &&
+ test_must_fail git rebase$type main &&
+ test_path_is_dir $state_dir &&
+ head_before=$(git rev-parse HEAD) &&
+ git rebase --quit &&
+ test_cmp_rev HEAD $head_before &&
+ test_path_is_missing .git/rebase-apply
+ '
}
testrebase " --apply" .git/rebase-apply
testrebase " --merge" .git/rebase-merge
-test_expect_success 'rebase --apply --quit' '
- cd "$work_dir" &&
- # Clean up the state from the previous one
- git reset --hard pre-rebase &&
- test_must_fail git rebase --apply main &&
- test_path_is_dir .git/rebase-apply &&
- head_before=$(git rev-parse HEAD) &&
- git rebase --quit &&
- test $(git rev-parse HEAD) = $head_before &&
- test ! -d .git/rebase-apply
-'
-
-test_expect_success 'rebase --merge --quit' '
- cd "$work_dir" &&
- # Clean up the state from the previous one
- git reset --hard pre-rebase &&
- test_must_fail git rebase --merge main &&
- test_path_is_dir .git/rebase-merge &&
- head_before=$(git rev-parse HEAD) &&
- git rebase --quit &&
- test $(git rev-parse HEAD) = $head_before &&
- test ! -d .git/rebase-merge
-'
-
test_done
diff --git a/t/t3435-rebase-gpg-sign.sh b/t/t3435-rebase-gpg-sign.sh
index ec10766858..5f8ba2c739 100755
--- a/t/t3435-rebase-gpg-sign.sh
+++ b/t/t3435-rebase-gpg-sign.sh
@@ -65,6 +65,7 @@ test_rebase_gpg_sign ! true -i --gpg-sign --no-gpg-sign
test_rebase_gpg_sign false -i --no-gpg-sign --gpg-sign
test_expect_failure 'rebase -p --no-gpg-sign override commit.gpgsign' '
+ test_when_finished "git clean -f" &&
git reset --hard merged &&
git config commit.gpgsign true &&
git rebase -p --no-gpg-sign --onto=one fork-point main &&
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 9d100cd188..4b5b607673 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -158,4 +158,20 @@ test_expect_success 'cherry-pick works with dirty renamed file' '
grep -q "^modified$" renamed
'
+test_expect_success 'advice from failed revert' '
+ test_commit --no-tag "add dream" dream dream &&
+ dream_oid=$(git rev-parse --short HEAD) &&
+ cat <<-EOF >expected &&
+ error: could not revert $dream_oid... add dream
+ hint: After resolving the conflicts, mark them with
+ hint: "git add/rm <pathspec>", then run
+ hint: "git revert --continue".
+ hint: You can instead skip this commit with "git revert --skip".
+ hint: To abort and get back to the state before "git revert",
+ hint: run "git revert --abort".
+ EOF
+ test_commit --append --no-tag "double-add dream" dream dream &&
+ test_must_fail git revert HEAD^ 2>actual &&
+ test_cmp expected actual
+'
test_done
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 014001b8f3..979e843c65 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -47,20 +47,23 @@ test_expect_success 'failed cherry-pick does not advance HEAD' '
test "$head" = "$newhead"
'
-test_expect_success 'advice from failed cherry-pick' "
+test_expect_success 'advice from failed cherry-pick' '
pristine_detach initial &&
- picked=\$(git rev-parse --short picked) &&
+ picked=$(git rev-parse --short picked) &&
cat <<-EOF >expected &&
- error: could not apply \$picked... picked
- hint: after resolving the conflicts, mark the corrected paths
- hint: with 'git add <paths>' or 'git rm <paths>'
- hint: and commit the result with 'git commit'
+ error: could not apply $picked... picked
+ hint: After resolving the conflicts, mark them with
+ hint: "git add/rm <pathspec>", then run
+ hint: "git cherry-pick --continue".
+ hint: You can instead skip this commit with "git cherry-pick --skip".
+ hint: To abort and get back to the state before "git cherry-pick",
+ hint: run "git cherry-pick --abort".
EOF
test_must_fail git cherry-pick picked 2>actual &&
test_cmp expected actual
-"
+'
test_expect_success 'advice from failed cherry-pick --no-commit' "
pristine_detach initial &&
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index 49010aa946..3b0fa66c33 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -238,6 +238,7 @@ test_expect_success 'allow skipping commit but not abort for a new history' '
'
test_expect_success 'allow skipping stopped cherry-pick because of untracked file modifications' '
+ test_when_finished "rm unrelated" &&
pristine_detach initial &&
git rm --cached unrelated &&
git commit -m "untrack unrelated" &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 873aa56e35..f0a82be9de 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -1307,4 +1307,62 @@ test_expect_success 'stash -c stash.useBuiltin=false warning ' '
test_must_be_empty err
'
+test_expect_success 'git stash succeeds despite directory/file change' '
+ test_create_repo directory_file_switch_v1 &&
+ (
+ cd directory_file_switch_v1 &&
+ test_commit init &&
+
+ test_write_lines this file has some words >filler &&
+ git add filler &&
+ git commit -m filler &&
+
+ git rm filler &&
+ mkdir filler &&
+ echo contents >filler/file &&
+ git stash push
+ )
+'
+
+test_expect_success 'git stash can pop file -> directory saved changes' '
+ test_create_repo directory_file_switch_v2 &&
+ (
+ cd directory_file_switch_v2 &&
+ test_commit init &&
+
+ test_write_lines this file has some words >filler &&
+ git add filler &&
+ git commit -m filler &&
+
+ git rm filler &&
+ mkdir filler &&
+ echo contents >filler/file &&
+ cp filler/file expect &&
+ git stash push --include-untracked &&
+ git stash apply --index &&
+ test_cmp expect filler/file
+ )
+'
+
+test_expect_success 'git stash can pop directory -> file saved changes' '
+ test_create_repo directory_file_switch_v3 &&
+ (
+ cd directory_file_switch_v3 &&
+ test_commit init &&
+
+ mkdir filler &&
+ test_write_lines some words >filler/file1 &&
+ test_write_lines and stuff >filler/file2 &&
+ git add filler &&
+ git commit -m filler &&
+
+ git rm -rf filler &&
+ echo contents >filler &&
+ cp filler expect &&
+ git stash push --include-untracked &&
+ git stash apply --index &&
+ test_cmp expect filler
+ )
+'
+
test_done
diff --git a/t/t4018/php-enum b/t/t4018/php-enum
new file mode 100644
index 0000000000..91a69c1a2b
--- /dev/null
+++ b/t/t4018/php-enum
@@ -0,0 +1,4 @@
+enum RIGHT: string
+{
+ case Foo = 'ChangeMe';
+}
diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh
index 61ba5f707f..fab351b48a 100755
--- a/t/t4045-diff-relative.sh
+++ b/t/t4045-diff-relative.sh
@@ -162,4 +162,57 @@ 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_expect_success 'setup diff --relative unmerged' '
+ test_commit zero file0 &&
+ test_commit base subdir/file0 &&
+ git switch -c br1 &&
+ test_commit one file0 &&
+ test_commit sub1 subdir/file0 &&
+ git switch -c br2 base &&
+ test_commit two file0 &&
+ git switch -c br3 &&
+ test_commit sub3 subdir/file0
+'
+
+test_expect_success 'diff --relative without change in subdir' '
+ git switch br2 &&
+ test_when_finished "git merge --abort" &&
+ test_must_fail git merge one &&
+ git -C subdir diff --relative >out &&
+ test_must_be_empty out &&
+ git -C subdir diff --relative --name-only >out &&
+ test_must_be_empty out
+'
+
+test_expect_success 'diff --relative --name-only with change in subdir' '
+ git switch br3 &&
+ test_when_finished "git merge --abort" &&
+ test_must_fail git merge sub1 &&
+ test_write_lines file0 file0 >expected &&
+ git -C subdir diff --relative --name-only >out &&
+ test_cmp expected out
+'
+
+test_expect_failure 'diff --relative with change in subdir' '
+ git switch br3 &&
+ br1_blob=$(git rev-parse --short --verify br1:subdir/file0) &&
+ br3_blob=$(git rev-parse --short --verify br3:subdir/file0) &&
+ test_when_finished "git merge --abort" &&
+ test_must_fail git merge br1 &&
+ cat >expected <<-EOF &&
+ diff --cc file0
+ index $br3_blob,$br1_blob..0000000
+ --- a/file0
+ +++ b/file0
+ @@@ -1,1 -1,1 +1,5 @@@
+ ++<<<<<<< HEAD
+ +sub3
+ ++=======
+ + sub1
+ ++>>>>>>> br1
+ EOF
+ git -C subdir diff --relative >out &&
+ test_cmp expected out
+'
+
test_done
diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh
index dc7b242697..d86e38abd8 100755
--- a/t/t4060-diff-submodule-option-diff-format.sh
+++ b/t/t4060-diff-submodule-option-diff-format.sh
@@ -361,7 +361,6 @@ test_expect_success 'typechanged submodule(submodule->blob)' '
rm -f sm1 &&
test_create_repo sm1 &&
head6=$(add_file sm1 foo6 foo7)
-fullhead6=$(cd sm1; git rev-parse --verify HEAD)
test_expect_success 'nonexistent commit' '
git diff-index -p --submodule=diff HEAD >actual &&
cat >expected <<-EOF &&
@@ -704,10 +703,26 @@ test_expect_success 'path filter' '
diff_cmp expected actual
'
-commit_file sm2
+cat >.gitmodules <<-EOF
+[submodule "sm2"]
+ path = sm2
+ url = bogus_url
+EOF
+git add .gitmodules
+commit_file sm2 .gitmodules
+
test_expect_success 'given commit' '
git diff-index -p --submodule=diff HEAD^ >actual &&
cat >expected <<-EOF &&
+ diff --git a/.gitmodules b/.gitmodules
+ new file mode 100644
+ index 1234567..89abcde
+ --- /dev/null
+ +++ b/.gitmodules
+ @@ -0,0 +1,3 @@
+ +[submodule "sm2"]
+ +path = sm2
+ +url = bogus_url
Submodule sm1 $head7...0000000 (submodule deleted)
Submodule sm2 0000000...$head9 (new submodule)
diff --git a/sm2/foo8 b/sm2/foo8
@@ -729,15 +744,21 @@ test_expect_success 'given commit' '
'
test_expect_success 'setup .git file for sm2' '
- (cd sm2 &&
- REAL="$(pwd)/../.real" &&
- mv .git "$REAL" &&
- echo "gitdir: $REAL" >.git)
+ git submodule absorbgitdirs sm2
'
test_expect_success 'diff --submodule=diff with .git file' '
git diff --submodule=diff HEAD^ >actual &&
cat >expected <<-EOF &&
+ diff --git a/.gitmodules b/.gitmodules
+ new file mode 100644
+ index 1234567..89abcde
+ --- /dev/null
+ +++ b/.gitmodules
+ @@ -0,0 +1,3 @@
+ +[submodule "sm2"]
+ +path = sm2
+ +url = bogus_url
Submodule sm1 $head7...0000000 (submodule deleted)
Submodule sm2 0000000...$head9 (new submodule)
diff --git a/sm2/foo8 b/sm2/foo8
@@ -758,9 +779,67 @@ test_expect_success 'diff --submodule=diff with .git file' '
diff_cmp expected actual
'
+mv sm2 sm2-bak
+
+test_expect_success 'deleted submodule with .git file' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head7...0000000 (submodule deleted)
+ Submodule sm2 $head9...0000000 (submodule deleted)
+ diff --git a/sm2/foo8 b/sm2/foo8
+ deleted file mode 100644
+ index 1234567..89abcde
+ --- a/sm2/foo8
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo8
+ diff --git a/sm2/foo9 b/sm2/foo9
+ deleted file mode 100644
+ index 1234567..89abcde
+ --- a/sm2/foo9
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo9
+ EOF
+ diff_cmp expected actual
+'
+
+echo submodule-to-blob>sm2
+
+test_expect_success 'typechanged(submodule->blob) submodule with .git file' '
+ git diff-index -p --submodule=diff HEAD >actual &&
+ cat >expected <<-EOF &&
+ Submodule sm1 $head7...0000000 (submodule deleted)
+ Submodule sm2 $head9...0000000 (submodule deleted)
+ diff --git a/sm2/foo8 b/sm2/foo8
+ deleted file mode 100644
+ index 1234567..89abcde
+ --- a/sm2/foo8
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo8
+ diff --git a/sm2/foo9 b/sm2/foo9
+ deleted file mode 100644
+ index 1234567..89abcde
+ --- a/sm2/foo9
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo9
+ diff --git a/sm2 b/sm2
+ new file mode 100644
+ index 1234567..89abcde
+ --- /dev/null
+ +++ b/sm2
+ @@ -0,0 +1 @@
+ +submodule-to-blob
+ EOF
+ diff_cmp expected actual
+'
+
+rm sm2
+mv sm2-bak sm2
+
test_expect_success 'setup nested submodule' '
- git submodule add -f ./sm2 &&
- git commit -a -m "add sm2" &&
git -C sm2 submodule add ../sm2 nested &&
git -C sm2 commit -a -m "nested sub" &&
head10=$(git -C sm2 rev-parse --short --verify HEAD)
@@ -791,6 +870,7 @@ test_expect_success 'diff --submodule=diff with moved nested submodule HEAD' '
test_expect_success 'diff --submodule=diff recurses into nested submodules' '
cat >expected <<-EOF &&
+ Submodule sm1 $head7...0000000 (submodule deleted)
Submodule sm2 contains modified content
Submodule sm2 $head9..$head10:
diff --git a/sm2/.gitmodules b/sm2/.gitmodules
@@ -830,4 +910,67 @@ test_expect_success 'diff --submodule=diff recurses into nested submodules' '
diff_cmp expected actual
'
+(cd sm2; commit_file nested)
+commit_file sm2
+head12=$(cd sm2; git rev-parse --short --verify HEAD)
+
+mv sm2 sm2-bak
+
+test_expect_success 'diff --submodule=diff recurses into deleted nested submodules' '
+ cat >expected <<-EOF &&
+ Submodule sm1 $head7...0000000 (submodule deleted)
+ Submodule sm2 $head12...0000000 (submodule deleted)
+ diff --git a/sm2/.gitmodules b/sm2/.gitmodules
+ deleted file mode 100644
+ index 3a816b8..0000000
+ --- a/sm2/.gitmodules
+ +++ /dev/null
+ @@ -1,3 +0,0 @@
+ -[submodule "nested"]
+ - path = nested
+ - url = ../sm2
+ diff --git a/sm2/foo8 b/sm2/foo8
+ deleted file mode 100644
+ index db9916b..0000000
+ --- a/sm2/foo8
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo8
+ diff --git a/sm2/foo9 b/sm2/foo9
+ deleted file mode 100644
+ index 9c3b4f6..0000000
+ --- a/sm2/foo9
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo9
+ Submodule nested $head11...0000000 (submodule deleted)
+ diff --git a/sm2/nested/file b/sm2/nested/file
+ deleted file mode 100644
+ index ca281f5..0000000
+ --- a/sm2/nested/file
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -nested content
+ diff --git a/sm2/nested/foo8 b/sm2/nested/foo8
+ deleted file mode 100644
+ index db9916b..0000000
+ --- a/sm2/nested/foo8
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo8
+ diff --git a/sm2/nested/foo9 b/sm2/nested/foo9
+ deleted file mode 100644
+ index 9c3b4f6..0000000
+ --- a/sm2/nested/foo9
+ +++ /dev/null
+ @@ -1 +0,0 @@
+ -foo9
+ EOF
+ git diff --submodule=diff >actual 2>err &&
+ test_must_be_empty err &&
+ diff_cmp expected actual
+'
+
+mv sm2-bak sm2
+
test_done
diff --git a/t/t4108-apply-threeway.sh b/t/t4108-apply-threeway.sh
index 65147efdea..cc3aa3314a 100755
--- a/t/t4108-apply-threeway.sh
+++ b/t/t4108-apply-threeway.sh
@@ -230,4 +230,49 @@ test_expect_success 'apply with --3way --cached and conflicts' '
test_cmp expect.diff actual.diff
'
+test_expect_success 'apply binary file patch' '
+ git reset --hard main &&
+ cp "$TEST_DIRECTORY/test-binary-1.png" bin.png &&
+ git add bin.png &&
+ git commit -m "add binary file" &&
+
+ cp "$TEST_DIRECTORY/test-binary-2.png" bin.png &&
+
+ git diff --binary >bin.diff &&
+ git reset --hard &&
+
+ # Apply must succeed.
+ git apply bin.diff
+'
+
+test_expect_success 'apply binary file patch with 3way' '
+ git reset --hard main &&
+ cp "$TEST_DIRECTORY/test-binary-1.png" bin.png &&
+ git add bin.png &&
+ git commit -m "add binary file" &&
+
+ cp "$TEST_DIRECTORY/test-binary-2.png" bin.png &&
+
+ git diff --binary >bin.diff &&
+ git reset --hard &&
+
+ # Apply must succeed.
+ git apply --3way --index bin.diff
+'
+
+test_expect_success 'apply full-index patch with 3way' '
+ git reset --hard main &&
+ cp "$TEST_DIRECTORY/test-binary-1.png" bin.png &&
+ git add bin.png &&
+ git commit -m "add binary file" &&
+
+ cp "$TEST_DIRECTORY/test-binary-2.png" bin.png &&
+
+ git diff --full-index >bin.diff &&
+ git reset --hard &&
+
+ # Apply must succeed.
+ git apply --3way --index bin.diff
+'
+
test_done
diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh
index 9d8d3c72e7..2374151662 100755
--- a/t/t4151-am-abort.sh
+++ b/t/t4151-am-abort.sh
@@ -23,7 +23,13 @@ test_expect_success setup '
test_tick &&
git commit -a -m $i || return 1
done &&
+ git branch changes &&
git format-patch --no-numbered initial &&
+ git checkout -b conflicting initial &&
+ echo different >>file-1 &&
+ echo whatever >new-file &&
+ git add file-1 new-file &&
+ git commit -m different &&
git checkout -b side initial &&
echo local change >file-2-expect
'
@@ -191,4 +197,37 @@ test_expect_success 'am --abort leaves index stat info alone' '
git diff-files --exit-code --quiet
'
+test_expect_success 'git am --abort return failed exit status when it fails' '
+ test_when_finished "rm -rf file-2/ && git reset --hard && git am --abort" &&
+ git checkout changes &&
+ git format-patch -1 --stdout conflicting >changes.mbox &&
+ test_must_fail git am --3way changes.mbox &&
+
+ git rm file-2 &&
+ mkdir file-2 &&
+ echo precious >file-2/somefile &&
+ test_must_fail git am --abort &&
+ test_path_is_dir file-2/
+'
+
+test_expect_success 'git am --abort cleans relevant files' '
+ git checkout changes &&
+ git format-patch -1 --stdout conflicting >changes.mbox &&
+ test_must_fail git am --3way changes.mbox &&
+
+ test_path_is_file new-file &&
+ echo further changes >>file-1 &&
+ echo change other file >>file-2 &&
+
+ # Abort, and expect the files touched by am to be reverted
+ git am --abort &&
+
+ test_path_is_missing new-file &&
+
+ # Files not involved in am operation are left modified
+ git diff --name-only changes >actual &&
+ test_write_lines file-2 >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh
index d2dfcf164e..0141f36e33 100755
--- a/t/t4210-log-i18n.sh
+++ b/t/t4210-log-i18n.sh
@@ -131,4 +131,11 @@ do
fi
done
+test_expect_success 'log shows warning when conversion fails' '
+ enc=this-encoding-does-not-exist &&
+ git log -1 --encoding=$enc 2>err &&
+ echo "warning: unable to reencode commit to ${SQ}${enc}${SQ}" >expect &&
+ test_cmp expect err
+'
+
test_done
diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh
index 7cabb85ca6..8ae314af58 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -291,6 +291,7 @@ test_expect_success 'prune: handle HEAD reflog in multiple worktrees' '
cat ../expected >blob &&
git add blob &&
git commit -m "second commit in third" &&
+ git clean -f && # Remove untracked left behind by deleting index
git reset --hard HEAD^
) &&
git prune --expire=now &&
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index b02838750e..673baa5c3c 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -8,6 +8,10 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. "$TEST_DIRECTORY"/lib-bundle.sh
. "$TEST_DIRECTORY"/lib-bitmap.sh
+# t5310 deals only with single-pack bitmaps, so don't write MIDX bitmaps in
+# their place.
+GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0
+
objpath () {
echo ".git/objects/$(echo "$1" | sed -e 's|\(..\)|\1/|')"
}
@@ -25,93 +29,10 @@ has_any () {
grep -Ff "$1" "$2"
}
-# To ensure the logic for "maximal commits" is exercised, make
-# the repository a bit more complicated.
-#
-# other second
-# * *
-# (99 commits) (99 commits)
-# * *
-# |\ /|
-# | * octo-other octo-second * |
-# |/|\_________ ____________/|\|
-# | \ \/ __________/ |
-# | | ________/\ / |
-# * |/ * merge-right *
-# | _|__________/ \____________ |
-# |/ | \|
-# (l1) * * merge-left * (r1)
-# | / \________________________ |
-# |/ \|
-# (l2) * * (r2)
-# \___________________________ |
-# \|
-# * (base)
-#
-# We only push bits down the first-parent history, which
-# makes some of these commits unimportant!
-#
-# The important part for the maximal commit algorithm is how
-# the bitmasks are extended. Assuming starting bit positions
-# for second (bit 0) and other (bit 1), the bitmasks at the
-# end should be:
-#
-# second: 1 (maximal, selected)
-# other: 01 (maximal, selected)
-# (base): 11 (maximal)
-#
-# This complicated history was important for a previous
-# version of the walk that guarantees never walking a
-# commit multiple times. That goal might be important
-# again, so preserve this complicated case. For now, this
-# test will guarantee that the bitmaps are computed
-# correctly, even with the repeat calculations.
-
-test_expect_success 'setup repo with moderate-sized history' '
- test_commit_bulk --id=file 10 &&
- git branch -M second &&
- git checkout -b other HEAD~5 &&
- test_commit_bulk --id=side 10 &&
-
- # add complicated history setup, including merges and
- # ambiguous merge-bases
-
- git checkout -b merge-left other~2 &&
- git merge second~2 -m "merge-left" &&
-
- git checkout -b merge-right second~1 &&
- git merge other~1 -m "merge-right" &&
-
- git checkout -b octo-second second &&
- git merge merge-left merge-right -m "octopus-second" &&
-
- git checkout -b octo-other other &&
- git merge merge-left merge-right -m "octopus-other" &&
-
- git checkout other &&
- git merge octo-other -m "pull octopus" &&
-
- git checkout second &&
- git merge octo-second -m "pull octopus" &&
-
- # Remove these branches so they are not selected
- # as bitmap tips
- git branch -D merge-left &&
- git branch -D merge-right &&
- git branch -D octo-other &&
- git branch -D octo-second &&
-
- # add padding to make these merges less interesting
- # and avoid having them selected for bitmaps
- test_commit_bulk --id=file 100 &&
- git checkout other &&
- test_commit_bulk --id=side 100 &&
- git checkout second &&
-
- bitmaptip=$(git rev-parse second) &&
- blob=$(echo tagged-blob | git hash-object -w --stdin) &&
- git tag tagged-blob $blob &&
- git config repack.writebitmaps true
+setup_bitmap_history
+
+test_expect_success 'setup writing bitmaps during repack' '
+ git config repack.writeBitmaps true
'
test_expect_success 'full repack creates bitmaps' '
@@ -123,109 +44,7 @@ test_expect_success 'full repack creates bitmaps' '
grep "\"key\":\"num_maximal_commits\",\"value\":\"107\"" trace
'
-test_expect_success 'rev-list --test-bitmap verifies bitmaps' '
- git rev-list --test-bitmap HEAD
-'
-
-rev_list_tests_head () {
- test_expect_success "counting commits via bitmap ($state, $branch)" '
- git rev-list --count $branch >expect &&
- git rev-list --use-bitmap-index --count $branch >actual &&
- test_cmp expect actual
- '
-
- test_expect_success "counting partial commits via bitmap ($state, $branch)" '
- git rev-list --count $branch~5..$branch >expect &&
- git rev-list --use-bitmap-index --count $branch~5..$branch >actual &&
- test_cmp expect actual
- '
-
- test_expect_success "counting commits with limit ($state, $branch)" '
- git rev-list --count -n 1 $branch >expect &&
- git rev-list --use-bitmap-index --count -n 1 $branch >actual &&
- test_cmp expect actual
- '
-
- test_expect_success "counting non-linear history ($state, $branch)" '
- git rev-list --count other...second >expect &&
- git rev-list --use-bitmap-index --count other...second >actual &&
- test_cmp expect actual
- '
-
- test_expect_success "counting commits with limiting ($state, $branch)" '
- git rev-list --count $branch -- 1.t >expect &&
- git rev-list --use-bitmap-index --count $branch -- 1.t >actual &&
- test_cmp expect actual
- '
-
- test_expect_success "counting objects via bitmap ($state, $branch)" '
- git rev-list --count --objects $branch >expect &&
- git rev-list --use-bitmap-index --count --objects $branch >actual &&
- test_cmp expect actual
- '
-
- test_expect_success "enumerate commits ($state, $branch)" '
- git rev-list --use-bitmap-index $branch >actual &&
- git rev-list $branch >expect &&
- test_bitmap_traversal --no-confirm-bitmaps expect actual
- '
-
- test_expect_success "enumerate --objects ($state, $branch)" '
- git rev-list --objects --use-bitmap-index $branch >actual &&
- git rev-list --objects $branch >expect &&
- test_bitmap_traversal expect actual
- '
-
- test_expect_success "bitmap --objects handles non-commit objects ($state, $branch)" '
- git rev-list --objects --use-bitmap-index $branch tagged-blob >actual &&
- grep $blob actual
- '
-}
-
-rev_list_tests () {
- state=$1
-
- for branch in "second" "other"
- do
- rev_list_tests_head
- done
-}
-
-rev_list_tests 'full bitmap'
-
-test_expect_success 'clone from bitmapped repository' '
- git clone --no-local --bare . clone.git &&
- git rev-parse HEAD >expect &&
- git --git-dir=clone.git rev-parse HEAD >actual &&
- test_cmp expect actual
-'
-
-test_expect_success 'partial clone from bitmapped repository' '
- test_config uploadpack.allowfilter true &&
- git clone --no-local --bare --filter=blob:none . partial-clone.git &&
- (
- cd partial-clone.git &&
- pack=$(echo objects/pack/*.pack) &&
- git verify-pack -v "$pack" >have &&
- awk "/blob/ { print \$1 }" <have >blobs &&
- # we expect this single blob because of the direct ref
- git rev-parse refs/tags/tagged-blob >expect &&
- test_cmp expect blobs
- )
-'
-
-test_expect_success 'setup further non-bitmapped commits' '
- test_commit_bulk --id=further 10
-'
-
-rev_list_tests 'partial bitmap'
-
-test_expect_success 'fetch (partial bitmap)' '
- git --git-dir=clone.git fetch origin second:second &&
- git rev-parse HEAD >expect &&
- git --git-dir=clone.git rev-parse HEAD >actual &&
- test_cmp expect actual
-'
+basic_bitmap_tests
test_expect_success 'incremental repack fails when bitmaps are requested' '
test_commit more-1 &&
@@ -461,40 +280,6 @@ test_expect_success 'truncated bitmap fails gracefully (cache)' '
test_i18ngrep corrupted.bitmap.index stderr
'
-test_expect_success 'enumerating progress counts pack-reused objects' '
- count=$(git rev-list --objects --all --count) &&
- git repack -adb &&
-
- # check first with only reused objects; confirm that our progress
- # showed the right number, and also that we did pack-reuse as expected.
- # Check only the final "done" line of the meter (there may be an
- # arbitrary number of intermediate lines ending with CR).
- GIT_PROGRESS_DELAY=0 \
- git pack-objects --all --stdout --progress \
- </dev/null >/dev/null 2>stderr &&
- grep "Enumerating objects: $count, done" stderr &&
- grep "pack-reused $count" stderr &&
-
- # now the same but with one non-reused object
- git commit --allow-empty -m "an extra commit object" &&
- GIT_PROGRESS_DELAY=0 \
- git pack-objects --all --stdout --progress \
- </dev/null >/dev/null 2>stderr &&
- grep "Enumerating objects: $((count+1)), done" stderr &&
- grep "pack-reused $count" stderr
-'
-
-# have_delta <obj> <expected_base>
-#
-# Note that because this relies on cat-file, it might find _any_ copy of an
-# object in the repository. The caller is responsible for making sure
-# there's only one (e.g., via "repack -ad", or having just fetched a copy).
-have_delta () {
- echo $2 >expect &&
- echo $1 | git cat-file --batch-check="%(deltabase)" >actual &&
- test_cmp expect actual
-}
-
# Create a state of history with these properties:
#
# - refs that allow a client to fetch some new history, while sharing some old
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index af88f805aa..295c5bd94d 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -5,6 +5,25 @@ test_description='commit graph'
GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS=0
+test_expect_success 'usage' '
+ test_expect_code 129 git commit-graph write blah 2>err &&
+ test_expect_code 129 git commit-graph write verify
+'
+
+test_expect_success 'usage shown without sub-command' '
+ test_expect_code 129 git commit-graph 2>err &&
+ ! grep error: err
+'
+
+test_expect_success 'usage shown with an error on unknown sub-command' '
+ cat >expect <<-\EOF &&
+ error: unrecognized subcommand: unknown
+ EOF
+ test_expect_code 129 git commit-graph unknown 2>stderr &&
+ grep error stderr >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup full repo' '
mkdir full &&
cd "$TRASH_DIRECTORY/full" &&
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 3d4d9f10c3..bd17f308b3 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -174,12 +174,12 @@ test_expect_success 'write progress off for redirected stderr' '
'
test_expect_success 'write force progress on for stderr' '
- GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir --progress write 2>err &&
+ GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir write --progress 2>err &&
test_file_not_empty err
'
test_expect_success 'write with the --no-progress option' '
- GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir --no-progress write 2>err &&
+ GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir write --no-progress 2>err &&
test_line_count = 0 err
'
@@ -201,6 +201,34 @@ test_expect_success 'write midx with twelve packs' '
compare_results_with_midx "twelve packs"
+test_expect_success 'multi-pack-index *.rev cleanup with --object-dir' '
+ git init repo &&
+ git clone -s repo alternate &&
+
+ test_when_finished "rm -rf repo alternate" &&
+
+ (
+ cd repo &&
+ test_commit base &&
+ git repack -d
+ ) &&
+
+ ours="alternate/.git/objects/pack/multi-pack-index-123.rev" &&
+ theirs="repo/.git/objects/pack/multi-pack-index-abc.rev" &&
+ touch "$ours" "$theirs" &&
+
+ (
+ cd alternate &&
+ git multi-pack-index --object-dir ../repo/.git/objects write
+ ) &&
+
+ # writing a midx in "repo" should not remove the .rev file in the
+ # alternate
+ test_path_is_file repo/.git/objects/pack/multi-pack-index &&
+ test_path_is_file $ours &&
+ test_path_is_missing $theirs
+'
+
test_expect_success 'warn on improper hash version' '
git init --object-format=sha1 sha1 &&
(
@@ -277,6 +305,23 @@ test_expect_success 'midx picks objects from preferred pack' '
)
'
+test_expect_success 'preferred packs must be non-empty' '
+ test_when_finished rm -rf preferred.git &&
+ git init preferred.git &&
+ (
+ cd preferred.git &&
+
+ test_commit base &&
+ git repack -ad &&
+
+ empty="$(git pack-objects $objdir/pack/pack </dev/null)" &&
+
+ test_must_fail git multi-pack-index write \
+ --preferred-pack=pack-$empty.pack 2>err &&
+ grep "with no objects" err
+ )
+'
+
test_expect_success 'verify multi-pack-index success' '
git multi-pack-index verify --object-dir=$objdir
'
@@ -429,12 +474,12 @@ test_expect_success 'repack progress off for redirected stderr' '
'
test_expect_success 'repack force progress on for stderr' '
- GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir --progress repack 2>err &&
+ GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir repack --progress 2>err &&
test_file_not_empty err
'
test_expect_success 'repack with the --no-progress option' '
- GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir --no-progress repack 2>err &&
+ GIT_PROGRESS_DELAY=0 git multi-pack-index --object-dir=$objdir repack --no-progress 2>err &&
test_line_count = 0 err
'
@@ -487,7 +532,8 @@ test_expect_success 'repack preserves multi-pack-index when creating packs' '
compare_results_with_midx "after repack"
test_expect_success 'multi-pack-index and pack-bitmap' '
- git -c repack.writeBitmaps=true repack -ad &&
+ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 \
+ git -c repack.writeBitmaps=true repack -ad &&
git multi-pack-index write &&
git rev-list --test-bitmap HEAD
'
@@ -537,7 +583,15 @@ test_expect_success 'force some 64-bit offsets with pack-objects' '
idx64=objects64/pack/test-64-$pack64.idx &&
chmod u+w $idx64 &&
corrupt_data $idx64 $(test_oid idxoff) "\02" &&
- midx64=$(git multi-pack-index --object-dir=objects64 write) &&
+ # objects64 is not a real repository, but can serve as an alternate
+ # anyway so we can write a MIDX into it
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ ( cd ../objects64 && pwd ) >.git/objects/info/alternates &&
+ midx64=$(git multi-pack-index --object-dir=../objects64 write)
+ ) &&
midx_read_expect 1 63 5 objects64 " large-offsets"
'
@@ -618,7 +672,7 @@ test_expect_success 'expire progress off for redirected stderr' '
test_expect_success 'expire force progress on for stderr' '
(
cd dup &&
- GIT_PROGRESS_DELAY=0 git multi-pack-index --progress expire 2>err &&
+ GIT_PROGRESS_DELAY=0 git multi-pack-index expire --progress 2>err &&
test_file_not_empty err
)
'
@@ -626,7 +680,7 @@ test_expect_success 'expire force progress on for stderr' '
test_expect_success 'expire with the --no-progress option' '
(
cd dup &&
- GIT_PROGRESS_DELAY=0 git multi-pack-index --no-progress expire 2>err &&
+ GIT_PROGRESS_DELAY=0 git multi-pack-index expire --no-progress 2>err &&
test_line_count = 0 err
)
'
@@ -842,4 +896,9 @@ test_expect_success 'usage shown without sub-command' '
! test_i18ngrep "unrecognized subcommand" err
'
+test_expect_success 'complains when run outside of a repository' '
+ nongit test_must_fail git multi-pack-index write 2>err &&
+ grep "not a git repository" err
+'
+
test_done
diff --git a/t/t5323-pack-redundant.sh b/t/t5323-pack-redundant.sh
index 8b01793845..8dbbcc5e51 100755
--- a/t/t5323-pack-redundant.sh
+++ b/t/t5323-pack-redundant.sh
@@ -114,9 +114,9 @@ test_expect_success 'setup main repo' '
create_commits_in "$main_repo" A B C D E F G H I J K L M N O P Q R
'
-test_expect_success 'master: pack-redundant works with no packfile' '
+test_expect_success 'main: pack-redundant works with no packfile' '
(
- cd "$master_repo" &&
+ cd "$main_repo" &&
cat >expect <<-EOF &&
fatal: Zero packs found!
EOF
diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh
new file mode 100755
index 0000000000..4ad7c2c969
--- /dev/null
+++ b/t/t5326-multi-pack-bitmaps.sh
@@ -0,0 +1,286 @@
+#!/bin/sh
+
+test_description='exercise basic multi-pack bitmap functionality'
+. ./test-lib.sh
+. "${TEST_DIRECTORY}/lib-bitmap.sh"
+
+# We'll be writing our own midx and bitmaps, so avoid getting confused by the
+# automatic ones.
+GIT_TEST_MULTI_PACK_INDEX=0
+GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0
+
+objdir=.git/objects
+midx=$objdir/pack/multi-pack-index
+
+# midx_pack_source <obj>
+midx_pack_source () {
+ test-tool read-midx --show-objects .git/objects | grep "^$1 " | cut -f2
+}
+
+setup_bitmap_history
+
+test_expect_success 'enable core.multiPackIndex' '
+ git config core.multiPackIndex true
+'
+
+test_expect_success 'create single-pack midx with bitmaps' '
+ git repack -ad &&
+ git multi-pack-index write --bitmap &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_file $midx-$(midx_checksum $objdir).rev
+'
+
+basic_bitmap_tests
+
+test_expect_success 'create new additional packs' '
+ for i in $(test_seq 1 16)
+ do
+ test_commit "$i" &&
+ git repack -d || return 1
+ done &&
+
+ git checkout -b other2 HEAD~8 &&
+ for i in $(test_seq 1 8)
+ do
+ test_commit "side-$i" &&
+ git repack -d || return 1
+ done &&
+ git checkout second
+'
+
+test_expect_success 'create multi-pack midx with bitmaps' '
+ git multi-pack-index write --bitmap &&
+
+ ls $objdir/pack/pack-*.pack >packs &&
+ test_line_count = 25 packs &&
+
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_file $midx-$(midx_checksum $objdir).rev
+'
+
+basic_bitmap_tests
+
+test_expect_success '--no-bitmap is respected when bitmaps exist' '
+ git multi-pack-index write --bitmap &&
+
+ test_commit respect--no-bitmap &&
+ git repack -d &&
+
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_file $midx-$(midx_checksum $objdir).rev &&
+
+ git multi-pack-index write --no-bitmap &&
+
+ test_path_is_file $midx &&
+ test_path_is_missing $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_missing $midx-$(midx_checksum $objdir).rev
+'
+
+test_expect_success 'setup midx with base from later pack' '
+ # Write a and b so that "a" is a delta on top of base "b", since Git
+ # prefers to delete contents out of a base rather than add to a shorter
+ # object.
+ test_seq 1 128 >a &&
+ test_seq 1 130 >b &&
+
+ git add a b &&
+ git commit -m "initial commit" &&
+
+ a=$(git rev-parse HEAD:a) &&
+ b=$(git rev-parse HEAD:b) &&
+
+ # In the first pack, "a" is stored as a delta to "b".
+ p1=$(git pack-objects .git/objects/pack/pack <<-EOF
+ $a
+ $b
+ EOF
+ ) &&
+
+ # In the second pack, "a" is missing, and "b" is not a delta nor base to
+ # any other object.
+ p2=$(git pack-objects .git/objects/pack/pack <<-EOF
+ $b
+ $(git rev-parse HEAD)
+ $(git rev-parse HEAD^{tree})
+ EOF
+ ) &&
+
+ git prune-packed &&
+ # Use the second pack as the preferred source, so that "b" occurs
+ # earlier in the MIDX object order, rendering "a" unusable for pack
+ # reuse.
+ git multi-pack-index write --bitmap --preferred-pack=pack-$p2.idx &&
+
+ have_delta $a $b &&
+ test $(midx_pack_source $a) != $(midx_pack_source $b)
+'
+
+rev_list_tests 'full bitmap with backwards delta'
+
+test_expect_success 'clone with bitmaps enabled' '
+ git clone --no-local --bare . clone-reverse-delta.git &&
+ test_when_finished "rm -fr clone-reverse-delta.git" &&
+
+ git rev-parse HEAD >expect &&
+ git --git-dir=clone-reverse-delta.git rev-parse HEAD >actual &&
+ test_cmp expect actual
+'
+
+bitmap_reuse_tests() {
+ from=$1
+ to=$2
+
+ test_expect_success "setup pack reuse tests ($from -> $to)" '
+ rm -fr repo &&
+ git init repo &&
+ (
+ cd repo &&
+ test_commit_bulk 16 &&
+ git tag old-tip &&
+
+ git config core.multiPackIndex true &&
+ if test "MIDX" = "$from"
+ then
+ git repack -Ad &&
+ git multi-pack-index write --bitmap
+ else
+ git repack -Adb
+ fi
+ )
+ '
+
+ test_expect_success "build bitmap from existing ($from -> $to)" '
+ (
+ cd repo &&
+ test_commit_bulk --id=further 16 &&
+ git tag new-tip &&
+
+ if test "MIDX" = "$to"
+ then
+ git repack -d &&
+ git multi-pack-index write --bitmap
+ else
+ git repack -Adb
+ fi
+ )
+ '
+
+ test_expect_success "verify resulting bitmaps ($from -> $to)" '
+ (
+ cd repo &&
+ git for-each-ref &&
+ git rev-list --test-bitmap refs/tags/old-tip &&
+ git rev-list --test-bitmap refs/tags/new-tip
+ )
+ '
+}
+
+bitmap_reuse_tests 'pack' 'MIDX'
+bitmap_reuse_tests 'MIDX' 'pack'
+bitmap_reuse_tests 'MIDX' 'MIDX'
+
+test_expect_success 'missing object closure fails gracefully' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ test_commit loose &&
+ test_commit packed &&
+
+ # Do not pass "--revs"; we want a pack without the "loose"
+ # commit.
+ git pack-objects $objdir/pack/pack <<-EOF &&
+ $(git rev-parse packed)
+ EOF
+
+ test_must_fail git multi-pack-index write --bitmap 2>err &&
+ grep "doesn.t have full closure" err &&
+ test_path_is_missing $midx
+ )
+'
+
+test_expect_success 'setup partial bitmaps' '
+ test_commit packed &&
+ git repack &&
+ test_commit loose &&
+ git multi-pack-index write --bitmap 2>err &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_file $midx-$(midx_checksum $objdir).rev
+'
+
+basic_bitmap_tests HEAD~
+
+test_expect_success 'removing a MIDX clears stale bitmaps' '
+ rm -fr repo &&
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+ test_commit base &&
+ git repack &&
+ git multi-pack-index write --bitmap &&
+
+ # Write a MIDX and bitmap; remove the MIDX but leave the bitmap.
+ stale_bitmap=$midx-$(midx_checksum $objdir).bitmap &&
+ stale_rev=$midx-$(midx_checksum $objdir).rev &&
+ rm $midx &&
+
+ # Then write a new MIDX.
+ test_commit new &&
+ git repack &&
+ git multi-pack-index write --bitmap &&
+
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_file $midx-$(midx_checksum $objdir).rev &&
+ test_path_is_missing $stale_bitmap &&
+ test_path_is_missing $stale_rev
+ )
+'
+
+test_expect_success 'pack.preferBitmapTips' '
+ git init repo &&
+ test_when_finished "rm -fr repo" &&
+ (
+ cd repo &&
+
+ test_commit_bulk --message="%s" 103 &&
+
+ git log --format="%H" >commits.raw &&
+ sort <commits.raw >commits &&
+
+ git log --format="create refs/tags/%s %H" HEAD >refs &&
+ git update-ref --stdin <refs &&
+
+ git multi-pack-index write --bitmap &&
+ test_path_is_file $midx &&
+ test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
+ test_path_is_file $midx-$(midx_checksum $objdir).rev &&
+
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >before &&
+ test_line_count = 1 before &&
+
+ perl -ne "printf(\"create refs/tags/include/%d \", $.); print" \
+ <before | git update-ref --stdin &&
+
+ rm -fr $midx-$(midx_checksum $objdir).bitmap &&
+ rm -fr $midx-$(midx_checksum $objdir).rev &&
+ rm -fr $midx &&
+
+ git -c pack.preferBitmapTips=refs/tags/include \
+ multi-pack-index write --bitmap &&
+ test-tool bitmap list-commits | sort >bitmaps &&
+ comm -13 bitmaps commits >after &&
+
+ ! test_cmp before after
+ )
+'
+
+test_done
diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
index 4f87d90c5b..f92c79c132 100755
--- a/t/t5551-http-fetch-smart.sh
+++ b/t/t5551-http-fetch-smart.sh
@@ -196,8 +196,8 @@ test_expect_success 'GIT_TRACE_CURL redacts auth details' '
# 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
+ ! grep -i "Authorization: Basic [0-9a-zA-Z+/]" trace &&
+ grep -i "Authorization: Basic <redacted>" trace
'
test_expect_success 'GIT_CURL_VERBOSE redacts auth details' '
@@ -208,8 +208,8 @@ test_expect_success 'GIT_CURL_VERBOSE redacts auth details' '
# 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
+ ! grep -i "Authorization: Basic [0-9a-zA-Z+/]" trace &&
+ grep -i "Authorization: Basic <redacted>" trace
'
test_expect_success 'GIT_TRACE_CURL does not redact auth details if GIT_TRACE_REDACT=0' '
@@ -219,7 +219,7 @@ test_expect_success 'GIT_TRACE_CURL does not redact auth details if GIT_TRACE_RE
git clone --bare "$HTTPD_URL/auth/smart/repo.git" redact-auth &&
expect_askpass both user@host &&
- grep "Authorization: Basic [0-9a-zA-Z+/]" trace
+ grep -i "Authorization: Basic [0-9a-zA-Z+/]" trace
'
test_expect_success 'disable dumb http on server' '
@@ -474,10 +474,10 @@ test_expect_success 'cookies are redacted by default' '
GIT_TRACE_CURL=true \
git -c "http.cookieFile=$(pwd)/cookies" clone \
$HTTPD_URL/smart/repo.git clone 2>err &&
- grep "Cookie:.*Foo=<redacted>" err &&
- grep "Cookie:.*Bar=<redacted>" err &&
- ! grep "Cookie:.*Foo=1" err &&
- ! grep "Cookie:.*Bar=2" err
+ grep -i "Cookie:.*Foo=<redacted>" err &&
+ grep -i "Cookie:.*Bar=<redacted>" err &&
+ ! grep -i "Cookie:.*Foo=1" err &&
+ ! grep -i "Cookie:.*Bar=2" err
'
test_expect_success 'empty values of cookies are also redacted' '
@@ -486,7 +486,7 @@ test_expect_success 'empty values of cookies are also redacted' '
GIT_TRACE_CURL=true \
git -c "http.cookieFile=$(pwd)/cookies" clone \
$HTTPD_URL/smart/repo.git clone 2>err &&
- grep "Cookie:.*Foo=<redacted>" err
+ grep -i "Cookie:.*Foo=<redacted>" err
'
test_expect_success 'GIT_TRACE_REDACT=0 disables cookie redaction' '
@@ -496,8 +496,8 @@ test_expect_success 'GIT_TRACE_REDACT=0 disables cookie redaction' '
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
+ grep -i "Cookie:.*Foo=1" err &&
+ grep -i "Cookie:.*Bar=2" err
'
test_expect_success 'GIT_TRACE_CURL_NO_DATA prevents data from being traced' '
@@ -558,4 +558,13 @@ test_expect_success 'http auth forgets bogus credentials' '
expect_askpass both user@host
'
+test_expect_success 'client falls back from v2 to v0 to match server' '
+ GIT_TRACE_PACKET=$PWD/trace \
+ GIT_TEST_PROTOCOL_VERSION=2 \
+ git clone $HTTPD_URL/smart_v0/repo.git repo-v0 &&
+ # check for v0; there the HEAD symref is communicated in the capability
+ # line; v2 uses a different syntax on each ref advertisement line
+ grep symref=HEAD:refs/heads/ trace
+'
+
test_done
diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh
new file mode 100755
index 0000000000..49faf5e283
--- /dev/null
+++ b/t/t5555-http-smart-common.sh
@@ -0,0 +1,161 @@
+#!/bin/sh
+
+test_description='test functionality common to smart fetch & push'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit --no-tag initial
+'
+
+test_expect_success 'git upload-pack --http-backend-info-refs and --advertise-refs are aliased' '
+ git upload-pack --http-backend-info-refs . >expected 2>err.expected &&
+ git upload-pack --advertise-refs . >actual 2>err.actual &&
+ test_cmp err.expected err.actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'git receive-pack --http-backend-info-refs and --advertise-refs are aliased' '
+ git receive-pack --http-backend-info-refs . >expected 2>err.expected &&
+ git receive-pack --advertise-refs . >actual 2>err.actual &&
+ test_cmp err.expected err.actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'git upload-pack --advertise-refs' '
+ cat >expect <<-EOF &&
+ $(git rev-parse HEAD) HEAD
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ # We only care about GIT_PROTOCOL, not GIT_TEST_PROTOCOL_VERSION
+ sane_unset GIT_PROTOCOL &&
+ GIT_TEST_PROTOCOL_VERSION=2 \
+ git upload-pack --advertise-refs . >out 2>err &&
+
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect &&
+
+ # The --advertise-refs alias works
+ git upload-pack --advertise-refs . >out 2>err &&
+
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_expect_success 'git upload-pack --advertise-refs: v0' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ $(git rev-parse HEAD) HEAD
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ git upload-pack --advertise-refs . >out 2>err &&
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect &&
+
+ # With explicit v0
+ GIT_PROTOCOL=version=0 \
+ git upload-pack --advertise-refs . >out 2>err &&
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+
+'
+
+test_expect_success 'git receive-pack --advertise-refs: v0' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ git receive-pack --advertise-refs . >out 2>err &&
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect &&
+
+ # With explicit v0
+ GIT_PROTOCOL=version=0 \
+ git receive-pack --advertise-refs . >out 2>err &&
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+
+'
+
+test_expect_success 'git upload-pack --advertise-refs: v1' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ version 1
+ $(git rev-parse HEAD) HEAD
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=1 \
+ git upload-pack --advertise-refs . >out &&
+
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_expect_success 'git receive-pack --advertise-refs: v1' '
+ # With no specified protocol
+ cat >expect <<-EOF &&
+ version 1
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=1 \
+ git receive-pack --advertise-refs . >out &&
+
+ test-tool pkt-line unpack <out >actual 2>err &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_expect_success 'git upload-pack --advertise-refs: v2' '
+ cat >expect <<-EOF &&
+ version 2
+ agent=FAKE
+ ls-refs=unborn
+ fetch=shallow wait-for-done
+ server-option
+ object-format=$(test_oid algo)
+ object-info
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=2 \
+ GIT_USER_AGENT=FAKE \
+ git upload-pack --advertise-refs . >out 2>err &&
+
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_expect_success 'git receive-pack --advertise-refs: v2' '
+ # There is no v2 yet for receive-pack, implicit v0
+ cat >expect <<-EOF &&
+ $(git rev-parse HEAD) $(git symbolic-ref HEAD)
+ 0000
+ EOF
+
+ GIT_PROTOCOL=version=2 \
+ git receive-pack --advertise-refs . >out 2>err &&
+
+ test-tool pkt-line unpack <out >actual &&
+ test_must_be_empty err &&
+ test_cmp actual expect
+'
+
+test_done
diff --git a/t/t5562/invoke-with-content-length.pl b/t/t5562/invoke-with-content-length.pl
index 0943474af2..718dd9b49d 100644
--- a/t/t5562/invoke-with-content-length.pl
+++ b/t/t5562/invoke-with-content-length.pl
@@ -13,11 +13,6 @@ my $body_data;
defined read($body_fh, $body_data, $body_size) or die "Cannot read $body_filename: $!";
close($body_fh);
-my $exited = 0;
-$SIG{"CHLD"} = sub {
- $exited = 1;
-};
-
# write data
my $pid = open(my $out, "|-", @command);
{
@@ -29,8 +24,13 @@ my $pid = open(my $out, "|-", @command);
}
print $out $body_data or die "Cannot write data: $!";
-sleep 60; # is interrupted by SIGCHLD
-if (!$exited) {
- close($out);
+$SIG{ALRM} = sub {
+ kill 'KILL', $pid;
die "Command did not exit after reading whole body";
+};
+alarm 60;
+
+my $ret = waitpid($pid, 0);
+if ($ret != $pid) {
+ die "confusing return from waitpid: $ret";
}
diff --git a/t/t5582-fetch-negative-refspec.sh b/t/t5582-fetch-negative-refspec.sh
index e5d2e79ad3..7a80e47c2b 100755
--- a/t/t5582-fetch-negative-refspec.sh
+++ b/t/t5582-fetch-negative-refspec.sh
@@ -105,7 +105,6 @@ test_expect_success "fetch with negative pattern refspec does not expand prefix"
'
test_expect_success "fetch with negative refspec avoids duplicate conflict" '
- cd "$D" &&
(
cd one &&
git branch dups/a &&
diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh
index 3a595c0f82..d822153e4d 100755
--- a/t/t5606-clone-options.sh
+++ b/t/t5606-clone-options.sh
@@ -16,6 +16,18 @@ test_expect_success 'setup' '
'
+test_expect_success 'submodule.stickyRecursiveClone flag manipulates submodule.recurse value' '
+
+ test_config_global submodule.stickyRecursiveClone true &&
+ git clone --recurse-submodules parent clone_recurse_true &&
+ test_cmp_config -C clone_recurse_true true submodule.recurse &&
+
+ test_config_global submodule.stickyRecursiveClone false &&
+ git clone --recurse-submodules parent clone_recurse_false &&
+ test_expect_code 1 git -C clone_recurse_false config --get submodule.recurse
+
+'
+
test_expect_success 'clone -o' '
git clone -o foo parent clone-o &&
diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
index 930721f053..aa1827d841 100755
--- a/t/t5701-git-serve.sh
+++ b/t/t5701-git-serve.sh
@@ -72,6 +72,37 @@ test_expect_success 'request invalid command' '
test_i18ngrep "invalid command" err
'
+test_expect_success 'request capability as command' '
+ test-tool pkt-line pack >in <<-EOF &&
+ command=agent
+ object-format=$(test_oid algo)
+ 0000
+ EOF
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
+ grep invalid.command.*agent err
+'
+
+test_expect_success 'request command as capability' '
+ test-tool pkt-line pack >in <<-EOF &&
+ command=ls-refs
+ object-format=$(test_oid algo)
+ fetch
+ 0000
+ EOF
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
+ grep unknown.capability err
+'
+
+test_expect_success 'requested command is command=value' '
+ test-tool pkt-line pack >in <<-EOF &&
+ command=ls-refs=whatever
+ object-format=$(test_oid algo)
+ 0000
+ EOF
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
+ grep invalid.command.*ls-refs=whatever err
+'
+
test_expect_success 'wrong object-format' '
test-tool pkt-line pack >in <<-EOF &&
command=fetch
@@ -116,6 +147,19 @@ test_expect_success 'basics of ls-refs' '
test_cmp expect actual
'
+test_expect_success 'ls-refs complains about unknown options' '
+ test-tool pkt-line pack >in <<-EOF &&
+ command=ls-refs
+ object-format=$(test_oid algo)
+ 0001
+ no-such-arg
+ 0000
+ EOF
+
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
+ grep unexpected.line.*no-such-arg err
+'
+
test_expect_success 'basic ref-prefixes' '
test-tool pkt-line pack >in <<-EOF &&
command=ls-refs
@@ -158,6 +202,37 @@ test_expect_success 'refs/heads prefix' '
test_cmp expect actual
'
+test_expect_success 'ignore very large set of prefixes' '
+ # generate a large number of ref-prefixes that we expect
+ # to match nothing; the value here exceeds TOO_MANY_PREFIXES
+ # from ls-refs.c.
+ {
+ echo command=ls-refs &&
+ echo object-format=$(test_oid algo) &&
+ echo 0001 &&
+ perl -le "print \"ref-prefix refs/heads/\$_\" for (1..65536)" &&
+ echo 0000
+ } |
+ test-tool pkt-line pack >in &&
+
+ # and then confirm that we see unmatched prefixes anyway (i.e.,
+ # that the prefix was not applied).
+ cat >expect <<-EOF &&
+ $(git rev-parse HEAD) HEAD
+ $(git rev-parse refs/heads/dev) refs/heads/dev
+ $(git rev-parse refs/heads/main) refs/heads/main
+ $(git rev-parse refs/heads/release) refs/heads/release
+ $(git rev-parse refs/tags/annotated-tag) refs/tags/annotated-tag
+ $(git rev-parse refs/tags/one) refs/tags/one
+ $(git rev-parse refs/tags/two) refs/tags/two
+ 0000
+ EOF
+
+ test-tool serve-v2 --stateless-rpc <in >out &&
+ test-tool pkt-line unpack <out >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'peel parameter' '
test-tool pkt-line pack >in <<-EOF &&
command=ls-refs
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 78de1ff2ad..d527cf6c49 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -27,9 +27,9 @@ test_expect_success 'list refs with git:// using protocol v2' '
ls-remote --symref "$GIT_DAEMON_URL/parent" >actual &&
# Client requested to use protocol v2
- grep "git> .*\\\0\\\0version=2\\\0$" log &&
+ grep "ls-remote> .*\\\0\\\0version=2\\\0$" log &&
# Server responded using protocol v2
- grep "git< version 2" log &&
+ grep "ls-remote< version 2" log &&
git ls-remote --symref "$GIT_DAEMON_URL/parent" >expect &&
test_cmp expect actual
@@ -151,7 +151,7 @@ test_expect_success 'list refs with file:// using protocol v2' '
ls-remote --symref "file://$(pwd)/file_parent" >actual &&
# Server responded using protocol v2
- grep "git< version 2" log &&
+ grep "ls-remote< version 2" log &&
git ls-remote --symref "file://$(pwd)/file_parent" >expect &&
test_cmp expect actual
@@ -237,6 +237,19 @@ test_expect_success '...but not if explicitly forbidden by config' '
! grep "refs/heads/mydefaultbranch" file_empty_child/.git/HEAD
'
+test_expect_success 'bare clone propagates empty default branch' '
+ test_when_finished "rm -rf file_empty_parent file_empty_child.git" &&
+
+ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \
+ git -c init.defaultBranch=mydefaultbranch init file_empty_parent &&
+
+ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME= \
+ git -c init.defaultBranch=main -c protocol.version=2 \
+ clone --bare \
+ "file://$(pwd)/file_empty_parent" file_empty_child.git &&
+ grep "refs/heads/mydefaultbranch" file_empty_child.git/HEAD
+'
+
test_expect_success 'fetch with file:// using protocol v2' '
test_when_finished "rm -f log" &&
diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index e9e471621d..220098523a 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -40,6 +40,30 @@ write_command () {
fi
}
+# Write a complete fetch command to stdout, suitable for use with `test-tool
+# pkt-line`. "want-ref", "want", and "have" lines are read from stdin.
+#
+# Examples:
+#
+# write_fetch_command <<-EOF
+# want-ref refs/heads/main
+# have $(git rev-parse a)
+# EOF
+#
+# write_fetch_command <<-EOF
+# want $(git rev-parse b)
+# have $(git rev-parse a)
+# EOF
+#
+write_fetch_command () {
+ write_command fetch &&
+ echo "0001" &&
+ echo "no-progress" &&
+ cat &&
+ echo "done" &&
+ echo "0000"
+}
+
# c(o/foo) d(o/bar)
# \ /
# b e(baz) f(main)
@@ -77,15 +101,11 @@ test_expect_success 'config controls ref-in-want advertisement' '
'
test_expect_success 'invalid want-ref line' '
- test-tool pkt-line pack >in <<-EOF &&
- $(write_command fetch)
- 0001
- no-progress
+ write_fetch_command >pkt <<-EOF &&
want-ref refs/heads/non-existent
- done
- 0000
EOF
+ test-tool pkt-line pack <pkt >in &&
test_must_fail test-tool serve-v2 --stateless-rpc 2>out <in &&
grep "unknown ref" out
'
@@ -97,16 +117,11 @@ test_expect_success 'basic want-ref' '
EOF
git rev-parse f >expected_commits &&
- oid=$(git rev-parse a) &&
- test-tool pkt-line pack >in <<-EOF &&
- $(write_command fetch)
- 0001
- no-progress
+ write_fetch_command >pkt <<-EOF &&
want-ref refs/heads/main
- have $oid
- done
- 0000
+ have $(git rev-parse a)
EOF
+ test-tool pkt-line pack <pkt >in &&
test-tool serve-v2 --stateless-rpc >out <in &&
check_output
@@ -121,17 +136,12 @@ test_expect_success 'multiple want-ref lines' '
EOF
git rev-parse c d >expected_commits &&
- oid=$(git rev-parse b) &&
- test-tool pkt-line pack >in <<-EOF &&
- $(write_command fetch)
- 0001
- no-progress
+ write_fetch_command >pkt <<-EOF &&
want-ref refs/heads/o/foo
want-ref refs/heads/o/bar
- have $oid
- done
- 0000
+ have $(git rev-parse b)
EOF
+ test-tool pkt-line pack <pkt >in &&
test-tool serve-v2 --stateless-rpc >out <in &&
check_output
@@ -144,16 +154,12 @@ test_expect_success 'mix want and want-ref' '
EOF
git rev-parse e f >expected_commits &&
- test-tool pkt-line pack >in <<-EOF &&
- $(write_command fetch)
- 0001
- no-progress
+ write_fetch_command >pkt <<-EOF &&
want-ref refs/heads/main
want $(git rev-parse e)
have $(git rev-parse a)
- done
- 0000
EOF
+ test-tool pkt-line pack <pkt >in &&
test-tool serve-v2 --stateless-rpc >out <in &&
check_output
@@ -166,16 +172,11 @@ test_expect_success 'want-ref with ref we already have commit for' '
EOF
>expected_commits &&
- oid=$(git rev-parse c) &&
- test-tool pkt-line pack >in <<-EOF &&
- $(write_command fetch)
- 0001
- no-progress
+ write_fetch_command >pkt <<-EOF &&
want-ref refs/heads/o/foo
- have $oid
- done
- 0000
+ have $(git rev-parse c)
EOF
+ test-tool pkt-line pack <pkt >in &&
test-tool serve-v2 --stateless-rpc >out <in &&
check_output
@@ -298,6 +299,141 @@ test_expect_success 'fetching with wildcard that matches multiple refs' '
grep "want-ref refs/heads/o/bar" log
'
+REPO="$(pwd)/repo-ns"
+
+test_expect_success 'setup namespaced repo' '
+ (
+ git init -b main "$REPO" &&
+ cd "$REPO" &&
+ test_commit a &&
+ test_commit b &&
+ git checkout a &&
+ test_commit c &&
+ git checkout a &&
+ test_commit d &&
+ git update-ref refs/heads/ns-no b &&
+ git update-ref refs/namespaces/ns/refs/heads/ns-yes c &&
+ git update-ref refs/namespaces/ns/refs/heads/hidden d
+ ) &&
+ git -C "$REPO" config uploadpack.allowRefInWant true
+'
+
+test_expect_success 'with namespace: want-ref is considered relative to namespace' '
+ wanted_ref=refs/heads/ns-yes &&
+
+ oid=$(git -C "$REPO" rev-parse "refs/namespaces/ns/$wanted_ref") &&
+ cat >expected_refs <<-EOF &&
+ $oid $wanted_ref
+ EOF
+ cat >expected_commits <<-EOF &&
+ $oid
+ $(git -C "$REPO" rev-parse a)
+ EOF
+
+ write_fetch_command >pkt <<-EOF &&
+ want-ref $wanted_ref
+ EOF
+ test-tool pkt-line pack <pkt >in &&
+
+ GIT_NAMESPACE=ns test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+ check_output
+'
+
+test_expect_success 'with namespace: want-ref outside namespace is unknown' '
+ wanted_ref=refs/heads/ns-no &&
+
+ write_fetch_command >pkt <<-EOF &&
+ want-ref $wanted_ref
+ EOF
+ test-tool pkt-line pack <pkt >in &&
+
+ test_must_fail env GIT_NAMESPACE=ns \
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+ grep "unknown ref" out
+'
+
+# Cross-check refs/heads/ns-no indeed exists
+test_expect_success 'without namespace: want-ref outside namespace succeeds' '
+ wanted_ref=refs/heads/ns-no &&
+
+ oid=$(git -C "$REPO" rev-parse $wanted_ref) &&
+ cat >expected_refs <<-EOF &&
+ $oid $wanted_ref
+ EOF
+ cat >expected_commits <<-EOF &&
+ $oid
+ $(git -C "$REPO" rev-parse a)
+ EOF
+
+ write_fetch_command >pkt <<-EOF &&
+ want-ref $wanted_ref
+ EOF
+ test-tool pkt-line pack <pkt >in &&
+
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+ check_output
+'
+
+test_expect_success 'with namespace: hideRefs is matched, relative to namespace' '
+ wanted_ref=refs/heads/hidden &&
+ git -C "$REPO" config transfer.hideRefs $wanted_ref &&
+
+ write_fetch_command >pkt <<-EOF &&
+ want-ref $wanted_ref
+ EOF
+ test-tool pkt-line pack <pkt >in &&
+
+ test_must_fail env GIT_NAMESPACE=ns \
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+ grep "unknown ref" out
+'
+
+# Cross-check refs/heads/hidden indeed exists
+test_expect_success 'with namespace: want-ref succeeds if hideRefs is removed' '
+ wanted_ref=refs/heads/hidden &&
+ git -C "$REPO" config --unset transfer.hideRefs $wanted_ref &&
+
+ oid=$(git -C "$REPO" rev-parse "refs/namespaces/ns/$wanted_ref") &&
+ cat >expected_refs <<-EOF &&
+ $oid $wanted_ref
+ EOF
+ cat >expected_commits <<-EOF &&
+ $oid
+ $(git -C "$REPO" rev-parse a)
+ EOF
+
+ write_fetch_command >pkt <<-EOF &&
+ want-ref $wanted_ref
+ EOF
+ test-tool pkt-line pack <pkt >in &&
+
+ GIT_NAMESPACE=ns test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+ check_output
+'
+
+test_expect_success 'without namespace: relative hideRefs does not match' '
+ wanted_ref=refs/namespaces/ns/refs/heads/hidden &&
+ git -C "$REPO" config transfer.hideRefs refs/heads/hidden &&
+
+ oid=$(git -C "$REPO" rev-parse $wanted_ref) &&
+ cat >expected_refs <<-EOF &&
+ $oid $wanted_ref
+ EOF
+ cat >expected_commits <<-EOF &&
+ $oid
+ $(git -C "$REPO" rev-parse a)
+ EOF
+
+ write_fetch_command >pkt <<-EOF &&
+ want-ref $wanted_ref
+ EOF
+ test-tool pkt-line pack <pkt >in &&
+
+ test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+ check_output
+'
+
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
diff --git a/t/t5704-protocol-violations.sh b/t/t5704-protocol-violations.sh
index 5c941949b9..bc393d7c31 100755
--- a/t/t5704-protocol-violations.sh
+++ b/t/t5704-protocol-violations.sh
@@ -32,4 +32,19 @@ test_expect_success 'extra delim packet in v2 fetch args' '
test_i18ngrep "expected flush after fetch arguments" err
'
+test_expect_success 'bogus symref in v0 capabilities' '
+ test_commit foo &&
+ oid=$(git rev-parse HEAD) &&
+ dst=refs/heads/foo &&
+ {
+ printf "%s HEAD\0symref object-format=%s symref=HEAD:%s\n" \
+ "$oid" "$GIT_DEFAULT_HASH" "$dst" |
+ test-tool pkt-line pack-raw-stdin &&
+ printf "0000"
+ } >input &&
+ git ls-remote --symref --upload-pack="cat input; read junk;:" . >actual &&
+ printf "ref: %s\tHEAD\n%s\tHEAD\n" "$dst" "$oid" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index a1baf4e451..1be85d064e 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -962,4 +962,22 @@ test_expect_success 'bisect handles annotated tags' '
grep "$bad is the first bad commit" output
'
+test_expect_success 'bisect run fails with exit code equals or greater than 128' '
+ write_script test_script.sh <<-\EOF &&
+ exit 128
+ EOF
+ test_must_fail git bisect run ./test_script.sh &&
+ write_script test_script.sh <<-\EOF &&
+ exit 255
+ EOF
+ test_must_fail git bisect run ./test_script.sh
+'
+
+test_expect_success 'bisect visualize with a filename with dash and space' '
+ echo "My test line" >>"./-hello 2" &&
+ git add -- "./-hello 2" &&
+ git commit --quiet -m "Add test line" -- "./-hello 2" &&
+ git bisect visualize -p -- "-hello 2"
+'
+
test_done
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 0d2e062f79..80679d5e12 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -59,18 +59,25 @@ test_atom() {
# Automatically test "contents:size" atom after testing "contents"
if test "$2" = "contents"
then
- case $(git cat-file -t "$ref") in
- tag)
- # We cannot use $3 as it expects sanitize_pgp to run
- expect=$(git cat-file tag $ref | tail -n +6 | wc -c) ;;
- tree | blob)
- expect='' ;;
- commit)
- expect=$(printf '%s' "$3" | wc -c) ;;
- esac
- # Leave $expect unquoted to lose possible leading whitespaces
- echo $expect >expected
+ # for commit leg, $3 is changed there
+ expect=$(printf '%s' "$3" | wc -c)
test_expect_${4:-success} $PREREQ "basic atom: $1 contents:size" '
+ type=$(git cat-file -t "$ref") &&
+ case $type in
+ tag)
+ # We cannot use $3 as it expects sanitize_pgp to run
+ git cat-file tag $ref >out &&
+ expect=$(tail -n +6 out | wc -c) &&
+ rm -f out ;;
+ tree | blob)
+ expect="" ;;
+ commit)
+ : "use the calculated expect" ;;
+ *)
+ BUG "unknown object type" ;;
+ esac &&
+ # Leave $expect unquoted to lose possible leading whitespaces
+ echo $expect >expected &&
git for-each-ref --format="%(contents:size)" "$ref" >actual &&
test_cmp expected actual
'
diff --git a/t/t6415-merge-dir-to-symlink.sh b/t/t6415-merge-dir-to-symlink.sh
index 2ce104aca7..2655e295f5 100755
--- a/t/t6415-merge-dir-to-symlink.sh
+++ b/t/t6415-merge-dir-to-symlink.sh
@@ -25,7 +25,8 @@ test_expect_success 'checkout does not clobber untracked symlink' '
git reset --hard main &&
git rm --cached a/b &&
git commit -m "untracked symlink remains" &&
- test_must_fail git checkout start^0
+ test_must_fail git checkout start^0 &&
+ git clean -fd # Do not leave the untracked symlink in the way
'
test_expect_success 'a/b-2/c/d is kept when clobbering symlink b' '
@@ -34,7 +35,8 @@ test_expect_success 'a/b-2/c/d is kept when clobbering symlink b' '
git rm --cached a/b &&
git commit -m "untracked symlink remains" &&
git checkout -f start^0 &&
- test_path_is_file a/b-2/c/d
+ test_path_is_file a/b-2/c/d &&
+ git clean -fd # Do not leave the untracked symlink in the way
'
test_expect_success 'checkout should not have deleted a/b-2/c/d' '
diff --git a/t/t6424-merge-unrelated-index-changes.sh b/t/t6424-merge-unrelated-index-changes.sh
index 5e3779ebc9..89dd544f38 100755
--- a/t/t6424-merge-unrelated-index-changes.sh
+++ b/t/t6424-merge-unrelated-index-changes.sh
@@ -132,6 +132,7 @@ test_expect_success 'merge-recursive, when index==head but head!=HEAD' '
# Make index match B
git diff C B -- | git apply --cached &&
+ test_when_finished "git clean -fd" && # Do not leave untracked around
# Merge B & F, with B as "head"
git merge-recursive A -- B F > out &&
test_i18ngrep "Already up to date" out
diff --git a/t/t6430-merge-recursive.sh b/t/t6430-merge-recursive.sh
index ffcc01fe65..a0efe7cb6d 100755
--- a/t/t6430-merge-recursive.sh
+++ b/t/t6430-merge-recursive.sh
@@ -718,7 +718,9 @@ test_expect_success 'merge-recursive remembers the names of all base trees' '
# merge-recursive prints in reverse order, but we do not care
sort <trees >expect &&
sed -n "s/^virtual //p" out | sort >actual &&
- test_cmp expect actual
+ test_cmp expect actual &&
+
+ git clean -fd
'
test_expect_success 'merge-recursive internal merge resolves to the sameness' '
diff --git a/t/t6436-merge-overwrite.sh b/t/t6436-merge-overwrite.sh
index 84b4aacf49..c0b7bd7c3f 100755
--- a/t/t6436-merge-overwrite.sh
+++ b/t/t6436-merge-overwrite.sh
@@ -68,7 +68,8 @@ test_expect_success 'will not overwrite removed file' '
git commit -m "rm c1.c" &&
cp important c1.c &&
test_must_fail git merge c1a &&
- test_cmp important c1.c
+ test_cmp important c1.c &&
+ rm c1.c # Do not leave untracked file in way of future tests
'
test_expect_success 'will not overwrite re-added file' '
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 7f6e23a4bb..b7ba1c3268 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -585,6 +585,7 @@ test_expect_success 'checkout --conflict=diff3' '
'
test_expect_success 'failing checkout -b should not break working tree' '
+ git clean -fd && # Remove untracked files in the way
git reset --hard main &&
git symbolic-ref HEAD refs/heads/main &&
test_must_fail git checkout -b renamer side^ &&
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index deea88d443..f1463197b9 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -389,43 +389,47 @@ test_expect_success 'status succeeds after staging/unstaging' '
# If "!" is supplied, then we verify that we do not call ensure_full_index
# during a call to 'git status'. Otherwise, we verify that we _do_ call it.
check_sparse_index_behavior () {
- git status --porcelain=v2 >expect &&
- git sparse-checkout init --cone --sparse-index &&
- git sparse-checkout set dir1 dir2 &&
+ git -C full status --porcelain=v2 >expect &&
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
- git status --porcelain=v2 >actual &&
+ git -C sparse status --porcelain=v2 >actual &&
test_region $1 index ensure_full_index trace2.txt &&
test_region fsm_hook query trace2.txt &&
test_cmp expect actual &&
- rm trace2.txt &&
- git sparse-checkout disable
+ rm trace2.txt
}
test_expect_success 'status succeeds with sparse index' '
- git reset --hard &&
+ git clone . full &&
+ git clone --sparse . sparse &&
+ git -C sparse sparse-checkout init --cone --sparse-index &&
+ git -C sparse sparse-checkout set dir1 dir2 &&
- test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" &&
- check_sparse_index_behavior ! &&
-
- write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ write_script .git/hooks/fsmonitor-test <<-\EOF &&
printf "last_update_token\0"
EOF
- git config core.fsmonitor .git/hooks/fsmonitor-test &&
+ git -C full config core.fsmonitor ../.git/hooks/fsmonitor-test &&
+ git -C sparse config core.fsmonitor ../.git/hooks/fsmonitor-test &&
check_sparse_index_behavior ! &&
- write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ write_script .git/hooks/fsmonitor-test <<-\EOF &&
printf "last_update_token\0"
printf "dir1/modified\0"
EOF
check_sparse_index_behavior ! &&
- cp -r dir1 dir1a &&
- git add dir1a &&
- git commit -m "add dir1a" &&
+ git -C sparse sparse-checkout add dir1a &&
+
+ for repo in full sparse
+ do
+ cp -r $repo/dir1 $repo/dir1a &&
+ git -C $repo add dir1a &&
+ git -C $repo commit -m "add dir1a" || return 1
+ done &&
+ git -C sparse sparse-checkout set dir1 dir2 &&
# This one modifies outside the sparse-checkout definition
# and hence we expect to expand the sparse-index.
- write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ write_script .git/hooks/fsmonitor-test <<-\EOF &&
printf "last_update_token\0"
printf "dir1a/modified\0"
EOF
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 2ef39d3088..c773e30b3f 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -717,6 +717,7 @@ test_expect_success 'failed fast-forward merge with --autostash' '
git reset --hard c0 &&
git merge-file file file.orig file.5 &&
cp file.5 other &&
+ test_when_finished "rm other" &&
test_must_fail git merge --autostash c1 2>err &&
test_i18ngrep "Applied autostash." err &&
test_cmp file.5 file
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 25b235c063..98eda3bfeb 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -63,13 +63,14 @@ test_expect_success 'objects in packs marked .keep are not repacked' '
test_expect_success 'writing bitmaps via command-line can duplicate .keep objects' '
# build on $oid, $packid, and .keep state from previous
- git repack -Adbl &&
+ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 git repack -Adbl &&
test_has_duplicate_object true
'
test_expect_success 'writing bitmaps via config can duplicate .keep objects' '
# build on $oid, $packid, and .keep state from previous
- git -c repack.writebitmaps=true repack -Adl &&
+ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 \
+ git -c repack.writebitmaps=true repack -Adl &&
test_has_duplicate_object true
'
@@ -189,7 +190,9 @@ test_expect_success 'repack --keep-pack' '
test_expect_success 'bitmaps are created by default in bare repos' '
git clone --bare .git bare.git &&
- git -C bare.git repack -ad &&
+ rm -f bare.git/objects/pack/*.bitmap &&
+ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 \
+ git -C bare.git repack -ad &&
bitmap=$(ls bare.git/objects/pack/*.bitmap) &&
test_path_is_file "$bitmap"
'
@@ -200,7 +203,8 @@ test_expect_success 'incremental repack does not complain' '
'
test_expect_success 'bitmaps can be disabled on bare repos' '
- git -c repack.writeBitmaps=false -C bare.git repack -ad &&
+ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 \
+ git -c repack.writeBitmaps=false -C bare.git repack -ad &&
bitmap=$(ls bare.git/objects/pack/*.bitmap || :) &&
test -z "$bitmap"
'
@@ -211,7 +215,8 @@ test_expect_success 'no bitmaps created if .keep files present' '
keep=${pack%.pack}.keep &&
test_when_finished "rm -f \"\$keep\"" &&
>"$keep" &&
- git -C bare.git repack -ad 2>stderr &&
+ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 \
+ git -C bare.git repack -ad 2>stderr &&
test_must_be_empty stderr &&
find bare.git/objects/pack/ -type f -name "*.bitmap" >actual &&
test_must_be_empty actual
@@ -222,7 +227,8 @@ test_expect_success 'auto-bitmaps do not complain if unavailable' '
blob=$(test-tool genrandom big $((1024*1024)) |
git -C bare.git hash-object -w --stdin) &&
git -C bare.git update-ref refs/tags/big $blob &&
- git -C bare.git repack -ad 2>stderr &&
+ GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 \
+ git -C bare.git repack -ad 2>stderr &&
test_must_be_empty stderr &&
find bare.git/objects/pack -type f -name "*.bitmap" >actual &&
test_must_be_empty actual
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index a173f564bc..528e0dabf0 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -674,7 +674,6 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
rm c &&
ln -s d c &&
cat >expect <<-EOF &&
- b
c
c
@@ -710,7 +709,6 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
# Deleted symlinks
rm -f c &&
cat >expect <<-EOF &&
- b
c
EOF
@@ -723,6 +721,71 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
test_cmp expect actual
'
+test_expect_success SYMLINKS 'difftool --dir-diff writes symlinks as raw text' '
+ # Start out on a branch called "branch-init".
+ git init -b branch-init symlink-files &&
+ (
+ cd symlink-files &&
+ # This test ensures that symlinks are written as raw text.
+ # The "cat" tools output link and file contents.
+ git config difftool.cat-left-link.cmd "cat \"\$LOCAL/link\"" &&
+ git config difftool.cat-left-a.cmd "cat \"\$LOCAL/file-a\"" &&
+ git config difftool.cat-right-link.cmd "cat \"\$REMOTE/link\"" &&
+ git config difftool.cat-right-b.cmd "cat \"\$REMOTE/file-b\"" &&
+
+ # Record the empty initial state so that we can come back here
+ # later and not have to consider the any cases where difftool
+ # will create symlinks back into the worktree.
+ test_tick &&
+ git commit --allow-empty -m init &&
+
+ # Create a file called "file-a" with a symlink pointing to it.
+ git switch -c branch-a &&
+ echo a >file-a &&
+ ln -s file-a link &&
+ git add file-a link &&
+ test_tick &&
+ git commit -m link-to-file-a &&
+
+ # Create a file called "file-b" and point the symlink to it.
+ git switch -c branch-b &&
+ echo b >file-b &&
+ rm link &&
+ ln -s file-b link &&
+ git add file-b link &&
+ git rm file-a &&
+ test_tick &&
+ git commit -m link-to-file-b &&
+
+ # Checkout the initial branch so that the --symlinks behavior is
+ # not activated. The two directories should be completely
+ # independent with no symlinks pointing back here.
+ git switch branch-init &&
+
+ # The left link must be "file-a" and "file-a" must contain "a".
+ echo file-a >expect &&
+ git difftool --symlinks --dir-diff --tool cat-left-link \
+ branch-a branch-b >actual &&
+ test_cmp expect actual &&
+
+ echo a >expect &&
+ git difftool --symlinks --dir-diff --tool cat-left-a \
+ branch-a branch-b >actual &&
+ test_cmp expect actual &&
+
+ # The right link must be "file-b" and "file-b" must contain "b".
+ echo file-b >expect &&
+ git difftool --symlinks --dir-diff --tool cat-right-link \
+ branch-a branch-b >actual &&
+ test_cmp expect actual &&
+
+ echo b >expect &&
+ git difftool --symlinks --dir-diff --tool cat-right-b \
+ branch-a branch-b >actual &&
+ test_cmp expect actual
+ )
+'
+
test_expect_success 'add -N and difftool -d' '
test_when_finished git reset --hard &&
diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index 828cb3ba58..3172f5b936 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -8,6 +8,9 @@ submodules.
. ./test-lib.sh
+GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1
+export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB
+
test_expect_success 'setup directory structure and submodule' '
echo "(1|2)d(3|4)" >a &&
mkdir b &&
diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh
index 58f46c77e6..6b4941980c 100755
--- a/t/t7900-maintenance.sh
+++ b/t/t7900-maintenance.sh
@@ -20,6 +20,17 @@ test_xmllint () {
fi
}
+test_lazy_prereq SYSTEMD_ANALYZE '
+ systemd-analyze verify /lib/systemd/system/basic.target
+'
+
+test_systemd_analyze_verify () {
+ if test_have_prereq SYSTEMD_ANALYZE
+ then
+ systemd-analyze verify "$@"
+ fi
+}
+
test_expect_success 'help text' '
test_expect_code 129 git maintenance -h 2>err &&
test_i18ngrep "usage: git maintenance <subcommand>" err &&
@@ -492,8 +503,21 @@ test_expect_success !MINGW 'register and unregister with regex metacharacters' '
maintenance.repo "$(pwd)/$META"
'
+test_expect_success 'start --scheduler=<scheduler>' '
+ test_expect_code 129 git maintenance start --scheduler=foo 2>err &&
+ test_i18ngrep "unrecognized --scheduler argument" err &&
+
+ test_expect_code 129 git maintenance start --no-scheduler 2>err &&
+ test_i18ngrep "unknown option" err &&
+
+ test_expect_code 128 \
+ env GIT_TEST_MAINT_SCHEDULER="launchctl:true,schtasks:true" \
+ git maintenance start --scheduler=crontab 2>err &&
+ test_i18ngrep "fatal: crontab scheduler is not available" err
+'
+
test_expect_success 'start from empty cron table' '
- GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt" git maintenance start &&
+ GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt" git maintenance start --scheduler=crontab &&
# start registers the repo
git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
@@ -516,7 +540,7 @@ test_expect_success 'stop from existing schedule' '
test_expect_success 'start preserves existing schedule' '
echo "Important information!" >cron.txt &&
- GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt" git maintenance start &&
+ GIT_TEST_MAINT_SCHEDULER="crontab:test-tool crontab cron.txt" git maintenance start --scheduler=crontab &&
grep "Important information!" cron.txt
'
@@ -545,7 +569,7 @@ test_expect_success 'start and stop macOS maintenance' '
EOF
rm -f args &&
- GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start &&
+ GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start --scheduler=launchctl &&
# start registers the repo
git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
@@ -582,6 +606,23 @@ test_expect_success 'start and stop macOS maintenance' '
test_line_count = 0 actual
'
+test_expect_success 'use launchctl list to prevent extra work' '
+ # ensure we are registered
+ GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start --scheduler=launchctl &&
+
+ # do it again on a fresh args file
+ rm -f args &&
+ GIT_TEST_MAINT_SCHEDULER=launchctl:./print-args git maintenance start --scheduler=launchctl &&
+
+ ls "$HOME/Library/LaunchAgents" >actual &&
+ cat >expect <<-\EOF &&
+ list org.git-scm.git.hourly
+ list org.git-scm.git.daily
+ list org.git-scm.git.weekly
+ EOF
+ test_cmp expect args
+'
+
test_expect_success 'start and stop Windows maintenance' '
write_script print-args <<-\EOF &&
echo $* >>args
@@ -596,7 +637,7 @@ test_expect_success 'start and stop Windows maintenance' '
EOF
rm -f args &&
- GIT_TEST_MAINT_SCHEDULER="schtasks:./print-args" git maintenance start &&
+ GIT_TEST_MAINT_SCHEDULER="schtasks:./print-args" git maintenance start --scheduler=schtasks &&
# start registers the repo
git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
@@ -619,6 +660,83 @@ test_expect_success 'start and stop Windows maintenance' '
test_cmp expect args
'
+test_expect_success 'start and stop Linux/systemd maintenance' '
+ write_script print-args <<-\EOF &&
+ printf "%s\n" "$*" >>args
+ EOF
+
+ XDG_CONFIG_HOME="$PWD" &&
+ export XDG_CONFIG_HOME &&
+ rm -f args &&
+ GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args" git maintenance start --scheduler=systemd-timer &&
+
+ # start registers the repo
+ git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
+
+ test_systemd_analyze_verify "systemd/user/git-maintenance@.service" &&
+
+ printf -- "--user enable --now git-maintenance@%s.timer\n" hourly daily weekly >expect &&
+ test_cmp expect args &&
+
+ rm -f args &&
+ GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args" git maintenance stop &&
+
+ # stop does not unregister the repo
+ git config --get --global --fixed-value maintenance.repo "$(pwd)" &&
+
+ test_path_is_missing "systemd/user/git-maintenance@.timer" &&
+ test_path_is_missing "systemd/user/git-maintenance@.service" &&
+
+ printf -- "--user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect &&
+ test_cmp expect args
+'
+
+test_expect_success 'start and stop when several schedulers are available' '
+ write_script print-args <<-\EOF &&
+ printf "%s\n" "$*" | sed "s:gui/[0-9][0-9]*:gui/[UID]:; s:\(schtasks /create .* /xml\).*:\1:;" >>args
+ EOF
+
+ rm -f args &&
+ GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args systemctl,launchctl:./print-args launchctl,schtasks:./print-args schtasks" git maintenance start --scheduler=systemd-timer &&
+ printf "launchctl bootout gui/[UID] $pfx/Library/LaunchAgents/org.git-scm.git.%s.plist\n" \
+ hourly daily weekly >expect &&
+ printf "schtasks /delete /tn Git Maintenance (%s) /f\n" \
+ hourly daily weekly >>expect &&
+ printf -- "systemctl --user enable --now git-maintenance@%s.timer\n" hourly daily weekly >>expect &&
+ test_cmp expect args &&
+
+ rm -f args &&
+ GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args systemctl,launchctl:./print-args launchctl,schtasks:./print-args schtasks" git maintenance start --scheduler=launchctl &&
+ printf -- "systemctl --user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect &&
+ printf "schtasks /delete /tn Git Maintenance (%s) /f\n" \
+ hourly daily weekly >>expect &&
+ for frequency in hourly daily weekly
+ do
+ PLIST="$pfx/Library/LaunchAgents/org.git-scm.git.$frequency.plist" &&
+ echo "launchctl bootout gui/[UID] $PLIST" >>expect &&
+ echo "launchctl bootstrap gui/[UID] $PLIST" >>expect || return 1
+ done &&
+ test_cmp expect args &&
+
+ rm -f args &&
+ GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args systemctl,launchctl:./print-args launchctl,schtasks:./print-args schtasks" git maintenance start --scheduler=schtasks &&
+ printf -- "systemctl --user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect &&
+ printf "launchctl bootout gui/[UID] $pfx/Library/LaunchAgents/org.git-scm.git.%s.plist\n" \
+ hourly daily weekly >>expect &&
+ printf "schtasks /create /tn Git Maintenance (%s) /f /xml\n" \
+ hourly daily weekly >>expect &&
+ test_cmp expect args &&
+
+ rm -f args &&
+ GIT_TEST_MAINT_SCHEDULER="systemctl:./print-args systemctl,launchctl:./print-args launchctl,schtasks:./print-args schtasks" git maintenance stop &&
+ printf -- "systemctl --user disable --now git-maintenance@%s.timer\n" hourly daily weekly >expect &&
+ printf "launchctl bootout gui/[UID] $pfx/Library/LaunchAgents/org.git-scm.git.%s.plist\n" \
+ hourly daily weekly >>expect &&
+ printf "schtasks /delete /tn Git Maintenance (%s) /f\n" \
+ hourly daily weekly >>expect &&
+ test_cmp expect args
+'
+
test_expect_success 'register preserves existing strategy' '
git config maintenance.strategy none &&
git maintenance register &&
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 57fc10e7f8..aa0c20499b 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -1533,6 +1533,21 @@ test_expect_success $PREREQ 'sendemail.8bitEncoding works' '
test_cmp content-type-decl actual
'
+test_expect_success $PREREQ 'sendemail.8bitEncoding in .git/config overrides --global .gitconfig' '
+ clean_fake_sendmail &&
+ git config sendemail.assume8bitEncoding UTF-8 &&
+ test_when_finished "rm -rf home" &&
+ mkdir home &&
+ git config -f home/.gitconfig sendemail.assume8bitEncoding "bogus too" &&
+ echo bogus |
+ env HOME="$(pwd)/home" DEBUG=1 \
+ git send-email --from=author@example.com --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ email-using-8bit >stdout &&
+ egrep "Content|MIME" msgtxt1 >actual &&
+ test_cmp content-type-decl actual
+'
+
test_expect_success $PREREQ '--8bit-encoding overrides sendemail.8bitEncoding' '
clean_fake_sendmail &&
git config sendemail.assume8bitEncoding "bogus too" &&
@@ -2198,7 +2213,7 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' '
test_expect_success $PREREQ 'test using command name with --sendmail-cmd' '
clean_fake_sendmail &&
- PATH="$(pwd):$PATH" \
+ PATH="$PWD:$PATH" \
git send-email \
--from="Example <nobody@example.com>" \
--to=nobody@example.com \
@@ -2227,6 +2242,51 @@ test_expect_success $PREREQ 'test shell expression with --sendmail-cmd' '
test_path_is_file commandline1
'
+test_expect_success $PREREQ 'set up in-reply-to/references patches' '
+ cat >has-reply.patch <<-\EOF &&
+ From: A U Thor <author@example.com>
+ Subject: patch with in-reply-to
+ Message-ID: <patch.with.in.reply.to@example.com>
+ In-Reply-To: <replied.to@example.com>
+ References: <replied.to@example.com>
+
+ This is the body.
+ EOF
+ cat >no-reply.patch <<-\EOF
+ From: A U Thor <author@example.com>
+ Subject: patch without in-reply-to
+ Message-ID: <patch.without.in.reply.to@example.com>
+
+ This is the body.
+ EOF
+'
+
+test_expect_success $PREREQ 'patch reply headers correct with --no-thread' '
+ clean_fake_sendmail &&
+ git send-email \
+ --no-thread \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ has-reply.patch no-reply.patch &&
+ grep "In-Reply-To: <replied.to@example.com>" msgtxt1 &&
+ grep "References: <replied.to@example.com>" msgtxt1 &&
+ ! grep replied.to@example.com msgtxt2
+'
+
+test_expect_success $PREREQ 'cmdline in-reply-to used with --no-thread' '
+ clean_fake_sendmail &&
+ git send-email \
+ --no-thread \
+ --in-reply-to="<cmdline.reply@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ has-reply.patch no-reply.patch &&
+ grep "In-Reply-To: <cmdline.reply@example.com>" msgtxt1 &&
+ grep "References: <cmdline.reply@example.com>" msgtxt1 &&
+ grep "In-Reply-To: <cmdline.reply@example.com>" msgtxt2 &&
+ grep "References: <cmdline.reply@example.com>" msgtxt2
+'
+
test_expect_success $PREREQ 'invoke hook' '
mkdir -p .git/hooks &&
diff --git a/t/t9002-column.sh b/t/t9002-column.sh
index 89983527b6..6d3dbde3fe 100755
--- a/t/t9002-column.sh
+++ b/t/t9002-column.sh
@@ -42,6 +42,24 @@ EOF
test_cmp expected actual
'
+test_expect_success '--nl' '
+ cat >expected <<\EOF &&
+oneZ
+twoZ
+threeZ
+fourZ
+fiveZ
+sixZ
+sevenZ
+eightZ
+nineZ
+tenZ
+elevenZ
+EOF
+ git column --nl="Z$LF" --mode=plain <lista >actual &&
+ test_cmp expected actual
+'
+
test_expect_success '80 columns' '
cat >expected <<\EOF &&
one two three four five six seven eight nine ten eleven
diff --git a/t/t9351-fast-export-anonymize.sh b/t/t9351-fast-export-anonymize.sh
index 1c6e6fcdaf..77047e250d 100755
--- a/t/t9351-fast-export-anonymize.sh
+++ b/t/t9351-fast-export-anonymize.sh
@@ -18,7 +18,8 @@ test_expect_success 'setup simple repo' '
git update-index --add --cacheinfo 160000,$fake_commit,link1 &&
git update-index --add --cacheinfo 160000,$fake_commit,link2 &&
git commit -m "add gitlink" &&
- git tag -m "annotated tag" mytag
+ git tag -m "annotated tag" mytag &&
+ git tag -m "annotated tag with long message" longtag
'
test_expect_success 'export anonymized stream' '
@@ -55,7 +56,8 @@ test_expect_success 'stream retains other as refname' '
test_expect_success 'stream omits other refnames' '
! grep main stream &&
- ! grep mytag stream
+ ! grep mytag stream &&
+ ! grep longtag stream
'
test_expect_success 'stream omits identities' '
@@ -118,9 +120,9 @@ test_expect_success 'identical gitlinks got identical oid' '
test_line_count = 1 commits
'
-test_expect_success 'tag points to branch tip' '
+test_expect_success 'all tags point to branch tip' '
git rev-parse $other_branch >expect &&
- git for-each-ref --format="%(*objectname)" | grep . >actual &&
+ git for-each-ref --format="%(*objectname)" | grep . | uniq >actual &&
test_cmp expect actual
'
diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh
index 2d29d486ee..17f988edd2 100755
--- a/t/t9400-git-cvsserver-server.sh
+++ b/t/t9400-git-cvsserver-server.sh
@@ -36,6 +36,13 @@ CVSWORK="$PWD/cvswork"
CVS_SERVER=git-cvsserver
export CVSROOT CVS_SERVER
+if perl -e 'exit(1) if not defined crypt("", "cv")'
+then
+ PWDHASH='lac2ItudM3.KM'
+else
+ PWDHASH='$2b$10$t8fGvE/a9eLmfOLzsZme2uOa2QtoMYwIxq9wZA6aBKtF1Yb7FJIzi'
+fi
+
rm -rf "$CVSWORK" "$SERVERDIR"
test_expect_success 'setup' '
git config push.default matching &&
@@ -54,7 +61,7 @@ test_expect_success 'setup' '
GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true &&
GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" &&
GIT_DIR="$SERVERDIR" git config gitcvs.authdb "$SERVERDIR/auth.db" &&
- echo cvsuser:cvGVEarMLnhlA > "$SERVERDIR/auth.db"
+ echo "cvsuser:$PWDHASH" >"$SERVERDIR/auth.db"
'
# note that cvs doesn't accept absolute pathnames
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index e28411bb75..eef2262a36 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -137,33 +137,110 @@ test_tick () {
# Stop execution and start a shell. This is useful for debugging tests.
#
# Be sure to remove all invocations of this command before submitting.
+# WARNING: the shell invoked by this helper does not have the same environment
+# as the one running the tests (shell variables and functions are not
+# available, and the options below further modify the environment). As such,
+# commands copied from a test script might behave differently than when
+# running the test.
+#
+# Usage: test_pause [options]
+# -t
+# Use your original TERM instead of test-lib.sh's "dumb".
+# This usually restores color output in the invoked shell.
+# -s
+# Invoke $SHELL instead of $TEST_SHELL_PATH.
+# -h
+# Use your original HOME instead of test-lib.sh's "$TRASH_DIRECTORY".
+# This allows you to use your regular shell environment and Git aliases.
+# CAUTION: running commands copied from a test script into the paused shell
+# might result in files in your HOME being overwritten.
+# -a
+# Shortcut for -t -s -h
test_pause () {
- "$SHELL_PATH" <&6 >&5 2>&7
+ PAUSE_TERM=$TERM &&
+ PAUSE_SHELL=$TEST_SHELL_PATH &&
+ PAUSE_HOME=$HOME &&
+ while test $# != 0
+ do
+ case "$1" in
+ -t)
+ PAUSE_TERM="$USER_TERM"
+ ;;
+ -s)
+ PAUSE_SHELL="$SHELL"
+ ;;
+ -h)
+ PAUSE_HOME="$USER_HOME"
+ ;;
+ -a)
+ PAUSE_TERM="$USER_TERM"
+ PAUSE_SHELL="$SHELL"
+ PAUSE_HOME="$USER_HOME"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done &&
+ TERM="$PAUSE_TERM" HOME="$PAUSE_HOME" "$PAUSE_SHELL" <&6 >&5 2>&7
}
# Wrap git with a debugger. Adding this to a command can make it easier
# to understand what is going on in a failing test.
#
+# Usage: debug [options] <git command>
+# -d <debugger>
+# --debugger=<debugger>
+# Use <debugger> instead of GDB
+# -t
+# Use your original TERM instead of test-lib.sh's "dumb".
+# This usually restores color output in the debugger.
+# WARNING: the command being debugged might behave differently than when
+# running the test.
+#
# Examples:
# debug git checkout master
# debug --debugger=nemiver git $ARGS
# debug -d "valgrind --tool=memcheck --track-origins=yes" git $ARGS
debug () {
- case "$1" in
- -d)
- GIT_DEBUGGER="$2" &&
- shift 2
- ;;
- --debugger=*)
- GIT_DEBUGGER="${1#*=}" &&
- shift 1
- ;;
- *)
- GIT_DEBUGGER=1
- ;;
- esac &&
- GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7
+ GIT_DEBUGGER=1 &&
+ DEBUG_TERM=$TERM &&
+ while test $# != 0
+ do
+ case "$1" in
+ -t)
+ DEBUG_TERM="$USER_TERM"
+ ;;
+ -d)
+ GIT_DEBUGGER="$2" &&
+ shift
+ ;;
+ --debugger=*)
+ GIT_DEBUGGER="${1#*=}"
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+ done &&
+
+ dotfiles=".gdbinit .lldbinit"
+
+ for dotfile in $dotfiles
+ do
+ dotfile="$USER_HOME/$dotfile" &&
+ test -f "$dotfile" && cp "$dotfile" "$HOME" || :
+ done &&
+
+ TERM="$DEBUG_TERM" GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7 &&
+
+ for dotfile in $dotfiles
+ do
+ rm -f "$HOME/$dotfile"
+ done
}
# Usage: test_commit [options] <message> [<file> [<contents> [<tag>]]]
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 3b7acfec23..8361b5c1c5 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -534,7 +534,7 @@ SQ=\'
# when case-folding filenames
u200c=$(printf '\342\200\214')
-export _x05 _x35 _x40 _z40 LF u200c EMPTY_TREE EMPTY_BLOB ZERO_OID OID_REGEX
+export _x05 _x35 LF u200c EMPTY_TREE EMPTY_BLOB ZERO_OID OID_REGEX
# Each test should start with something like this, after copyright notices:
#
@@ -585,8 +585,9 @@ else
}
fi
+USER_TERM="$TERM"
TERM=dumb
-export TERM
+export TERM USER_TERM
error () {
say_color error "error: $*"
@@ -1343,7 +1344,8 @@ fi
GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt
GIT_CONFIG_NOSYSTEM=1
GIT_ATTR_NOSYSTEM=1
-export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM
+GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.."
+export PATH GIT_EXEC_PATH GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_ATTR_NOSYSTEM GIT_CEILING_DIRECTORIES
if test -z "$GIT_TEST_CMP"
then
@@ -1400,9 +1402,10 @@ then
fi
# Last-minute variable setup
+USER_HOME="$HOME"
HOME="$TRASH_DIRECTORY"
GNUPGHOME="$HOME/gnupg-home-not-used"
-export HOME GNUPGHOME
+export HOME GNUPGHOME USER_HOME
# Test repository
rm -fr "$TRASH_DIRECTORY" || {
@@ -1442,10 +1445,9 @@ then
fi
# Convenience
-# A regexp to match 5, 35 and 40 hexdigits
+# A regexp to match 5 and 35 hexdigits
_x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x35="$_x05$_x05$_x05$_x05$_x05$_x05$_x05"
-_x40="$_x35$_x05"
test_oid_init
@@ -1454,7 +1456,6 @@ OID_REGEX=$(echo $ZERO_OID | sed -e 's/0/[0-9a-f]/g')
OIDPATH_REGEX=$(test_oid_to_path $ZERO_OID | sed -e 's/0/[0-9a-f]/g')
EMPTY_TREE=$(test_oid empty_tree)
EMPTY_BLOB=$(test_oid empty_blob)
-_z40=$ZERO_OID
# Provide an implementation of the 'yes' utility; the upper bound
# limit is there to help Windows that cannot stop this loop from