summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/helper/test-date.c5
-rw-r--r--t/helper/test-progress.c50
-rw-r--r--t/helper/test-run-command.c6
-rwxr-xr-xt/t0006-date.sh2
-rwxr-xr-xt/t0500-progress-display.sh109
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh125
-rwxr-xr-xt/t1512-rev-parse-disambiguation.sh81
-rwxr-xr-xt/t2400-worktree-add.sh58
-rwxr-xr-xt/t3903-stash.sh21
-rwxr-xr-xt/t4150-am.sh2
-rwxr-xr-xt/t4202-log.sh24
-rwxr-xr-xt/t5302-pack-index.sh8
-rwxr-xr-xt/t5316-pack-delta-depth.sh6
-rwxr-xr-xt/t5571-pre-push-hook.sh94
-rwxr-xr-xt/t5617-clone-submodules-remote.sh41
-rwxr-xr-xt/t6030-bisect-porcelain.sh45
-rwxr-xr-xt/t7500-commit-template-squash-signoff.sh2
-rwxr-xr-xt/t7810-grep.sh186
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh41
-rw-r--r--t/test-lib-functions.sh29
-rw-r--r--t/test-lib.sh50
21 files changed, 790 insertions, 195 deletions
diff --git a/t/helper/test-date.c b/t/helper/test-date.c
index 099eff4f0f..45951b1df8 100644
--- a/t/helper/test-date.c
+++ b/t/helper/test-date.c
@@ -1,5 +1,6 @@
#include "test-tool.h"
#include "cache.h"
+#include "date.h"
static const char *usage_msg = "\n"
" test-tool date relative [time_t]...\n"
@@ -34,7 +35,7 @@ static void show_human_dates(const char **argv)
static void show_dates(const char **argv, const char *format)
{
- struct date_mode mode;
+ struct date_mode mode = DATE_MODE_INIT;
parse_date_format(format, &mode);
for (; *argv; argv++) {
@@ -53,6 +54,8 @@ static void show_dates(const char **argv, const char *format)
printf("%s -> %s\n", *argv, show_date(t, tz, &mode));
}
+
+ date_mode_release(&mode);
}
static void parse_dates(const char **argv)
diff --git a/t/helper/test-progress.c b/t/helper/test-progress.c
index 5d05cbe789..6cc9735b60 100644
--- a/t/helper/test-progress.c
+++ b/t/helper/test-progress.c
@@ -3,6 +3,9 @@
*
* Reads instructions from standard input, one instruction per line:
*
+ * "start <total>[ <title>]" - Call start_progress(title, total),
+ * Uses the default title of "Working hard"
+ * if the " <title>" is omitted.
* "progress <items>" - Call display_progress() with the given item count
* as parameter.
* "throughput <bytes> <millis> - Call display_throughput() with the given
@@ -10,6 +13,7 @@
* specify the time elapsed since the
* start_progress() call.
* "update" - Set the 'progress_update' flag.
+ * "stop" - Call stop_progress().
*
* See 't0500-progress-display.sh' for examples.
*/
@@ -19,34 +23,50 @@
#include "parse-options.h"
#include "progress.h"
#include "strbuf.h"
+#include "string-list.h"
int cmd__progress(int argc, const char **argv)
{
- int total = 0;
- const char *title;
+ const char *const default_title = "Working hard";
+ struct string_list titles = STRING_LIST_INIT_DUP;
struct strbuf line = STRBUF_INIT;
- struct progress *progress;
+ struct progress *progress = NULL;
const char *usage[] = {
- "test-tool progress [--total=<n>] <progress-title>",
+ "test-tool progress <stdin",
NULL
};
struct option options[] = {
- OPT_INTEGER(0, "total", &total, "total number of items"),
OPT_END(),
};
argc = parse_options(argc, argv, NULL, options, usage, 0);
- if (argc != 1)
- die("need a title for the progress output");
- title = argv[0];
+ if (argc)
+ usage_with_options(usage, options);
progress_testing = 1;
- progress = start_progress(title, total);
while (strbuf_getline(&line, stdin) != EOF) {
char *end;
- if (skip_prefix(line.buf, "progress ", (const char **) &end)) {
+ if (skip_prefix(line.buf, "start ", (const char **) &end)) {
+ uint64_t total = strtoull(end, &end, 10);
+ const char *title;
+
+ /*
+ * We can't use "end + 1" as an argument to
+ * start_progress(), it doesn't xstrdup() its
+ * "title" argument. We need to hold onto a
+ * valid "char *" for it until the end.
+ */
+ if (!*end)
+ title = default_title;
+ else if (*end == ' ')
+ title = string_list_insert(&titles, end + 1)->string;
+ else
+ die("invalid input: '%s'\n", line.buf);
+
+ progress = start_progress(title, total);
+ } else if (skip_prefix(line.buf, "progress ", (const char **) &end)) {
uint64_t item_count = strtoull(end, &end, 10);
if (*end != '\0')
die("invalid input: '%s'\n", line.buf);
@@ -63,12 +83,16 @@ int cmd__progress(int argc, const char **argv)
die("invalid input: '%s'\n", line.buf);
progress_test_ns = test_ms * 1000 * 1000;
display_throughput(progress, byte_count);
- } else if (!strcmp(line.buf, "update"))
+ } else if (!strcmp(line.buf, "update")) {
progress_test_force_update();
- else
+ } else if (!strcmp(line.buf, "stop")) {
+ stop_progress(&progress);
+ } else {
die("invalid input: '%s'\n", line.buf);
+ }
}
- stop_progress(&progress);
+ strbuf_release(&line);
+ string_list_clear(&titles, 0);
return 0;
}
diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c
index 913775a14b..8f370cd89f 100644
--- a/t/helper/test-run-command.c
+++ b/t/helper/test-run-command.c
@@ -221,9 +221,9 @@ static int quote_stress_test(int argc, const char **argv)
struct strbuf out = STRBUF_INIT;
struct strvec args = STRVEC_INIT;
struct option options[] = {
- OPT_INTEGER('n', "trials", &trials, "Number of trials"),
- OPT_INTEGER('s', "skip", &skip, "Skip <n> trials"),
- OPT_BOOL('m', "msys2", &msys2, "Test quoting for MSYS2's sh"),
+ OPT_INTEGER('n', "trials", &trials, "number of trials"),
+ OPT_INTEGER('s', "skip", &skip, "skip <n> trials"),
+ OPT_BOOL('m', "msys2", &msys2, "test quoting for MSYS2's sh"),
OPT_END()
};
const char * const usage[] = {
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 794186961e..2490162071 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -1,6 +1,8 @@
#!/bin/sh
test_description='test date parsing and printing'
+
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
# arbitrary reference time: 2009-08-30 19:20:00
diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh
index 22058b503a..1eb3a8306b 100755
--- a/t/t0500-progress-display.sh
+++ b/t/t0500-progress-display.sh
@@ -2,6 +2,7 @@
test_description='progress display'
+TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
show_cr () {
@@ -17,6 +18,7 @@ test_expect_success 'simple progress display' '
EOF
cat >in <<-\EOF &&
+ start 0
update
progress 1
update
@@ -25,8 +27,9 @@ test_expect_success 'simple progress display' '
progress 4
update
progress 5
+ stop
EOF
- test-tool progress "Working hard" <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -41,11 +44,13 @@ test_expect_success 'progress display with total' '
EOF
cat >in <<-\EOF &&
+ start 3
progress 1
progress 2
progress 3
+ stop
EOF
- test-tool progress --total=3 "Working hard" <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -62,14 +67,14 @@ Working hard.......2.........3.........4.........5.........6:
EOF
cat >in <<-\EOF &&
+ start 100000 Working hard.......2.........3.........4.........5.........6
progress 100
progress 1000
progress 10000
progress 100000
+ stop
EOF
- test-tool progress --total=100000 \
- "Working hard.......2.........3.........4.........5.........6" \
- <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -88,16 +93,16 @@ Working hard.......2.........3.........4.........5.........6:
EOF
cat >in <<-\EOF &&
+ start 100000 Working hard.......2.........3.........4.........5.........6
update
progress 1
update
progress 2
progress 10000
progress 100000
+ stop
EOF
- test-tool progress --total=100000 \
- "Working hard.......2.........3.........4.........5.........6" \
- <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -116,14 +121,14 @@ Working hard.......2.........3.........4.........5.........6:
EOF
cat >in <<-\EOF &&
+ start 100000 Working hard.......2.........3.........4.........5.........6
progress 25000
progress 50000
progress 75000
progress 100000
+ stop
EOF
- test-tool progress --total=100000 \
- "Working hard.......2.........3.........4.........5.........6" \
- <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -140,14 +145,14 @@ Working hard.......2.........3.........4.........5.........6.........7.........:
EOF
cat >in <<-\EOF &&
+ start 100000 Working hard.......2.........3.........4.........5.........6.........7.........
progress 25000
progress 50000
progress 75000
progress 100000
+ stop
EOF
- test-tool progress --total=100000 \
- "Working hard.......2.........3.........4.........5.........6.........7........." \
- <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -164,12 +169,14 @@ test_expect_success 'progress shortens - crazy caller' '
EOF
cat >in <<-\EOF &&
+ start 1000
progress 100
progress 200
progress 1
progress 1000
+ stop
EOF
- test-tool progress --total=1000 "Working hard" <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -185,6 +192,7 @@ test_expect_success 'progress display with throughput' '
EOF
cat >in <<-\EOF &&
+ start 0
throughput 102400 1000
update
progress 10
@@ -197,8 +205,9 @@ test_expect_success 'progress display with throughput' '
throughput 409600 4000
update
progress 40
+ stop
EOF
- test-tool progress "Working hard" <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -214,6 +223,7 @@ test_expect_success 'progress display with throughput and total' '
EOF
cat >in <<-\EOF &&
+ start 40
throughput 102400 1000
progress 10
throughput 204800 2000
@@ -222,8 +232,9 @@ test_expect_success 'progress display with throughput and total' '
progress 30
throughput 409600 4000
progress 40
+ stop
EOF
- test-tool progress --total=40 "Working hard" <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -239,6 +250,7 @@ test_expect_success 'cover up after throughput shortens' '
EOF
cat >in <<-\EOF &&
+ start 0
throughput 409600 1000
update
progress 1
@@ -251,8 +263,9 @@ test_expect_success 'cover up after throughput shortens' '
throughput 1638400 4000
update
progress 4
+ stop
EOF
- test-tool progress "Working hard" <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -267,6 +280,7 @@ test_expect_success 'cover up after throughput shortens a lot' '
EOF
cat >in <<-\EOF &&
+ start 0
throughput 1 1000
update
progress 1
@@ -276,8 +290,9 @@ test_expect_success 'cover up after throughput shortens a lot' '
throughput 3145728 3000
update
progress 3
+ stop
EOF
- test-tool progress "Working hard" <in 2>stderr &&
+ test-tool progress <in 2>stderr &&
show_cr <stderr >out &&
test_cmp expect out
@@ -285,6 +300,7 @@ test_expect_success 'cover up after throughput shortens a lot' '
test_expect_success 'progress generates traces' '
cat >in <<-\EOF &&
+ start 40
throughput 102400 1000
update
progress 10
@@ -297,10 +313,11 @@ test_expect_success 'progress generates traces' '
throughput 409600 4000
update
progress 40
+ stop
EOF
- GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool progress --total=40 \
- "Working hard" <in 2>stderr &&
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool progress \
+ <in 2>stderr &&
# t0212/parse_events.perl intentionally omits regions and data.
test_region progress "Working hard" trace.event &&
@@ -308,4 +325,54 @@ test_expect_success 'progress generates traces' '
grep "\"key\":\"total_bytes\",\"value\":\"409600\"" trace.event
'
+test_expect_success 'progress generates traces: stop / start' '
+ cat >in <<-\EOF &&
+ start 0
+ stop
+ EOF
+
+ GIT_TRACE2_EVENT="$PWD/trace-startstop.event" test-tool progress \
+ <in 2>stderr &&
+ test_region progress "Working hard" trace-startstop.event
+'
+
+test_expect_success 'progress generates traces: start without stop' '
+ cat >in <<-\EOF &&
+ start 0
+ EOF
+
+ GIT_TRACE2_EVENT="$PWD/trace-start.event" \
+ LSAN_OPTIONS=detect_leaks=0 \
+ test-tool progress \
+ <in 2>stderr &&
+ grep region_enter.*progress trace-start.event &&
+ ! grep region_leave.*progress trace-start.event
+'
+
+test_expect_success 'progress generates traces: stop without start' '
+ cat >in <<-\EOF &&
+ stop
+ EOF
+
+ GIT_TRACE2_EVENT="$PWD/trace-stop.event" test-tool progress \
+ <in 2>stderr &&
+ ! grep region_enter.*progress trace-stop.event &&
+ ! grep region_leave.*progress trace-stop.event
+'
+
+test_expect_success 'progress generates traces: start with active progress bar (no stops)' '
+ cat >in <<-\EOF &&
+ start 0 One
+ start 0 Two
+ EOF
+
+ GIT_TRACE2_EVENT="$PWD/trace-2start.event" \
+ LSAN_OPTIONS=detect_leaks=0 \
+ test-tool progress \
+ <in 2>stderr &&
+ grep region_enter.*progress.*One trace-2start.event &&
+ grep region_enter.*progress.*Two trace-2start.event &&
+ ! grep region_leave trace-2start.event
+'
+
test_done
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index 3592d12442..9a90031018 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -126,7 +126,7 @@ test_expect_success 'switching to cone mode with non-cone mode patterns' '
cd bad-patterns &&
git sparse-checkout init &&
git sparse-checkout add dir &&
- git config core.sparseCheckoutCone true &&
+ git config --worktree core.sparseCheckoutCone true &&
test_must_fail git sparse-checkout add dir 2>err &&
grep "existing sparse-checkout patterns do not use cone mode" err
)
@@ -155,9 +155,9 @@ test_expect_success 'interaction with clone --no-checkout (unborn index)' '
'
test_expect_success 'set enables config' '
- git init empty-config &&
+ git init worktree-config &&
(
- cd empty-config &&
+ cd worktree-config &&
test_commit test file &&
test_path_is_missing .git/config.worktree &&
git sparse-checkout set nothing &&
@@ -210,6 +210,21 @@ test_expect_success 'add to sparse-checkout' '
check_files repo "a folder1 folder2"
'
+test_expect_success 'worktree: add copies sparse-checkout patterns' '
+ cat repo/.git/info/sparse-checkout >old &&
+ test_when_finished cp old repo/.git/info/sparse-checkout &&
+ test_when_finished git -C repo worktree remove ../worktree &&
+ git -C repo sparse-checkout set --no-cone "/*" &&
+ git -C repo worktree add --quiet ../worktree 2>err &&
+ test_must_be_empty err &&
+ new="$(git -C worktree rev-parse --git-path info/sparse-checkout)" &&
+ test_path_is_file "$new" &&
+ test_cmp repo/.git/info/sparse-checkout "$new" &&
+ git -C worktree sparse-checkout set --cone &&
+ test_cmp_config -C worktree true core.sparseCheckoutCone &&
+ test_must_fail git -C repo core.sparseCheckoutCone
+'
+
test_expect_success 'cone mode: match patterns' '
git -C repo config --worktree core.sparseCheckoutCone true &&
rm -rf repo/a repo/folder1 repo/folder2 &&
@@ -261,7 +276,7 @@ test_expect_success 'sparse-index enabled and disabled' '
test_cmp expect actual &&
git -C repo config --list >config &&
- ! grep index.sparse config
+ test_cmp_config -C repo false index.sparse
'
test_expect_success 'cone mode: init and set' '
@@ -495,6 +510,37 @@ test_expect_failure 'sparse-checkout reapply' '
git -C tweak sparse-checkout disable
'
+test_expect_success 'reapply can handle config options' '
+ git -C repo sparse-checkout init --cone --no-sparse-index &&
+ git -C repo config --worktree --list >actual &&
+ cat >expect <<-\EOF &&
+ core.sparsecheckout=true
+ core.sparsecheckoutcone=true
+ index.sparse=false
+ EOF
+ test_cmp expect actual &&
+
+ git -C repo sparse-checkout reapply --no-cone --no-sparse-index &&
+ git -C repo config --worktree --list >actual &&
+ cat >expect <<-\EOF &&
+ core.sparsecheckout=true
+ core.sparsecheckoutcone=false
+ index.sparse=false
+ EOF
+ test_cmp expect actual &&
+
+ git -C repo sparse-checkout reapply --cone --sparse-index &&
+ git -C repo config --worktree --list >actual &&
+ cat >expect <<-\EOF &&
+ core.sparsecheckout=true
+ core.sparsecheckoutcone=true
+ index.sparse=true
+ EOF
+ test_cmp expect actual &&
+
+ git -C repo sparse-checkout disable
+'
+
test_expect_success 'cone mode: set with core.ignoreCase=true' '
rm repo/.git/info/sparse-checkout &&
git -C repo sparse-checkout init --cone &&
@@ -524,17 +570,17 @@ test_expect_success 'interaction with submodules' '
'
test_expect_success 'different sparse-checkouts with worktrees' '
+ git -C repo sparse-checkout set --cone deep folder1 &&
git -C repo worktree add --detach ../worktree &&
- check_files worktree "a deep folder1 folder2" &&
- git -C worktree sparse-checkout init --cone &&
- git -C repo sparse-checkout set folder1 &&
- git -C worktree sparse-checkout set deep/deeper1 &&
- check_files repo a folder1 &&
- check_files worktree a deep
+ check_files worktree "a deep folder1" &&
+ git -C repo sparse-checkout set --cone folder1 &&
+ git -C worktree sparse-checkout set --cone deep/deeper1 &&
+ check_files repo "a folder1" &&
+ check_files worktree "a deep"
'
test_expect_success 'set using filename keeps file on-disk' '
- git -C repo sparse-checkout set a deep &&
+ git -C repo sparse-checkout set --skip-checks a deep &&
cat >expect <<-\EOF &&
/*
!/*/
@@ -645,7 +691,7 @@ test_expect_success BSLASHPSPEC 'pattern-checks: escaped characters' '
git -C escaped reset --hard $COMMIT &&
check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? &&
git -C escaped sparse-checkout init --cone &&
- git -C escaped sparse-checkout set zbad\\dir/bogus "zdoes*not*exist" "zdoes*exist" "zglob[!a]?" &&
+ git -C escaped sparse-checkout set --skip-checks zbad\\dir/bogus "zdoes*not*exist" "zdoes*exist" "zglob[!a]?" &&
cat >expect <<-\EOF &&
/*
!/*/
@@ -770,4 +816,59 @@ test_expect_success 'malformed cone-mode patterns' '
grep "warning: disabling cone pattern matching" err
'
+test_expect_success 'set from subdir pays attention to prefix' '
+ git -C repo sparse-checkout disable &&
+ git -C repo/deep sparse-checkout set --cone deeper2 ../folder1 &&
+
+ git -C repo sparse-checkout list >actual &&
+
+ cat >expect <<-\EOF &&
+ deep/deeper2
+ folder1
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'add from subdir pays attention to prefix' '
+ git -C repo sparse-checkout set --cone deep/deeper2 &&
+ git -C repo/deep sparse-checkout add deeper1/deepest ../folder1 &&
+
+ git -C repo sparse-checkout list >actual &&
+
+ cat >expect <<-\EOF &&
+ deep/deeper1/deepest
+ deep/deeper2
+ folder1
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'set from subdir in non-cone mode throws an error' '
+ git -C repo sparse-checkout disable &&
+ test_must_fail git -C repo/deep sparse-checkout set --no-cone deeper2 ../folder1 2>error &&
+
+ grep "run from the toplevel directory in non-cone mode" error
+'
+
+test_expect_success 'set from subdir in non-cone mode throws an error' '
+ git -C repo sparse-checkout set --no-cone deep/deeper2 &&
+ test_must_fail git -C repo/deep sparse-checkout add deeper1/deepest ../folder1 2>error &&
+
+ grep "run from the toplevel directory in non-cone mode" error
+'
+
+test_expect_success 'by default, cone mode will error out when passed files' '
+ git -C repo sparse-checkout reapply --cone &&
+ test_must_fail git -C repo sparse-checkout add .gitignore 2>error &&
+
+ grep ".gitignore.*is not a directory" error
+'
+
+test_expect_success 'by default, non-cone mode will warn on individual files' '
+ git -C repo sparse-checkout reapply --no-cone &&
+ git -C repo sparse-checkout add .gitignore 2>warning &&
+
+ grep "pass a leading slash before paths.*if you want a single file" warning
+'
+
test_done
diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh
index b0119bf8bc..98cefe3b70 100755
--- a/t/t1512-rev-parse-disambiguation.sh
+++ b/t/t1512-rev-parse-disambiguation.sh
@@ -25,6 +25,87 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
. ./test-lib.sh
+test_cmp_failed_rev_parse () {
+ dir=$1
+ rev=$2
+
+ cat >expect &&
+ test_must_fail git -C "$dir" rev-parse "$rev" 2>actual.raw &&
+ sed "s/\($rev\)[0-9a-f]*/\1.../" <actual.raw >actual &&
+ test_cmp expect actual
+}
+
+test_expect_success 'ambiguous blob output' '
+ git init --bare blob.prefix &&
+ (
+ cd blob.prefix &&
+
+ # Both start with "dead..", under both SHA-1 and SHA-256
+ echo brocdnra | git hash-object -w --stdin &&
+ echo brigddsv | git hash-object -w --stdin &&
+
+ # Both start with "beef.."
+ echo 1agllotbh | git hash-object -w --stdin &&
+ echo 1bbfctrkc | git hash-object -w --stdin
+ ) &&
+
+ test_must_fail git -C blob.prefix rev-parse dead &&
+ test_cmp_failed_rev_parse blob.prefix beef <<-\EOF
+ error: short object ID beef... is ambiguous
+ hint: The candidates are:
+ hint: beef... blob
+ hint: beef... blob
+ fatal: ambiguous argument '\''beef...'\'': unknown revision or path not in the working tree.
+ Use '\''--'\'' to separate paths from revisions, like this:
+ '\''git <command> [<revision>...] -- [<file>...]'\''
+ EOF
+'
+
+test_expect_success 'ambiguous loose bad object parsed as OBJ_BAD' '
+ git init --bare blob.bad &&
+ (
+ cd blob.bad &&
+
+ # Both have the prefix "bad0"
+ echo xyzfaowcoh | git hash-object -t bad -w --stdin --literally &&
+ echo xyzhjpyvwl | git hash-object -t bad -w --stdin --literally
+ ) &&
+
+ test_cmp_failed_rev_parse blob.bad bad0 <<-\EOF
+ error: short object ID bad0... is ambiguous
+ fatal: invalid object type
+ EOF
+'
+
+test_expect_success POSIXPERM 'ambigous zlib corrupt loose blob' '
+ git init --bare blob.corrupt &&
+ (
+ cd blob.corrupt &&
+
+ # Both have the prefix "cafe"
+ echo bnkxmdwz | git hash-object -w --stdin &&
+ oid=$(echo bmwsjxzi | git hash-object -w --stdin) &&
+
+ oidf=objects/$(test_oid_to_path "$oid") &&
+ chmod 755 $oidf &&
+ echo broken >$oidf
+ ) &&
+
+ test_cmp_failed_rev_parse blob.corrupt cafe <<-\EOF
+ error: short object ID cafe... is ambiguous
+ error: inflate: data stream error (incorrect header check)
+ error: unable to unpack cafe... header
+ error: inflate: data stream error (incorrect header check)
+ error: unable to unpack cafe... header
+ hint: The candidates are:
+ hint: cafe... [bad object]
+ hint: cafe... blob
+ fatal: ambiguous argument '\''cafe...'\'': unknown revision or path not in the working tree.
+ Use '\''--'\'' to separate paths from revisions, like this:
+ '\''git <command> [<revision>...] -- [<file>...]'\''
+ EOF
+'
+
if ! test_have_prereq SHA1
then
skip_all='not using SHA-1 for objects'
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index 37ad79470f..43139af08f 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -165,8 +165,62 @@ test_expect_success '"add" default branch of a bare repo' '
(
git clone --bare . bare2 &&
cd bare2 &&
- git worktree add ../there3 main
- )
+ git worktree add ../there3 main &&
+ cd ../there3 &&
+ # Simple check that a Git command does not
+ # immediately fail with the current setup
+ git status
+ ) &&
+ cat >expect <<-EOF &&
+ init.t
+ EOF
+ ls there3 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '"add" to bare repo with worktree config' '
+ (
+ git clone --bare . bare3 &&
+ cd bare3 &&
+ git config extensions.worktreeconfig true &&
+
+ # Add config values that are erroneous to have in
+ # a config.worktree file outside of the main
+ # working tree, to check that Git filters them out
+ # when copying config during "git worktree add".
+ git config --worktree core.bare true &&
+ git config --worktree core.worktree "$(pwd)" &&
+
+ # We want to check that bogus.key is copied
+ git config --worktree bogus.key value &&
+ git config --unset core.bare &&
+ git worktree add ../there4 main &&
+ cd ../there4 &&
+
+ # Simple check that a Git command does not
+ # immediately fail with the current setup
+ git status &&
+ git worktree add --detach ../there5 &&
+ cd ../there5 &&
+ git status
+ ) &&
+
+ # the worktree has the arbitrary value copied.
+ test_cmp_config -C there4 value bogus.key &&
+ test_cmp_config -C there5 value bogus.key &&
+
+ # however, core.bare and core.worktree were removed.
+ test_must_fail git -C there4 config core.bare &&
+ test_must_fail git -C there4 config core.worktree &&
+
+ cat >expect <<-EOF &&
+ init.t
+ EOF
+
+ ls there4 >actual &&
+ test_cmp expect actual &&
+ ls there5 >actual &&
+ test_cmp expect actual
'
test_expect_success 'checkout with grafts' '
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index b149e2af44..d5ecee4fcc 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -390,10 +390,11 @@ test_expect_success SYMLINKS 'stash file to symlink' '
rm file &&
ln -s file2 file &&
git stash save "file to symlink" &&
- test -f file &&
+ test_path_is_file_not_symlink file &&
test bar = "$(cat file)" &&
git stash apply &&
- case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
+ test_path_is_symlink file &&
+ test "$(test_readlink file)" = file2
'
test_expect_success SYMLINKS 'stash file to symlink (stage rm)' '
@@ -401,10 +402,11 @@ test_expect_success SYMLINKS 'stash file to symlink (stage rm)' '
git rm file &&
ln -s file2 file &&
git stash save "file to symlink (stage rm)" &&
- test -f file &&
+ test_path_is_file_not_symlink file &&
test bar = "$(cat file)" &&
git stash apply &&
- case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
+ test_path_is_symlink file &&
+ test "$(test_readlink file)" = file2
'
test_expect_success SYMLINKS 'stash file to symlink (full stage)' '
@@ -413,10 +415,11 @@ test_expect_success SYMLINKS 'stash file to symlink (full stage)' '
ln -s file2 file &&
git add file &&
git stash save "file to symlink (full stage)" &&
- test -f file &&
+ test_path_is_file_not_symlink file &&
test bar = "$(cat file)" &&
git stash apply &&
- case "$(ls -l file)" in *" file -> file2") :;; *) false;; esac
+ test_path_is_symlink file &&
+ test "$(test_readlink file)" = file2
'
# This test creates a commit with a symlink used for the following tests
@@ -487,7 +490,7 @@ test_expect_failure 'stash directory to file' '
rm -fr dir &&
echo bar >dir &&
git stash save "directory to file" &&
- test -d dir &&
+ test_path_is_dir dir &&
test foo = "$(cat dir/file)" &&
test_must_fail git stash apply &&
test bar = "$(cat dir)" &&
@@ -500,10 +503,10 @@ test_expect_failure 'stash file to directory' '
mkdir file &&
echo foo >file/file &&
git stash save "file to directory" &&
- test -f file &&
+ test_path_is_file file &&
test bar = "$(cat file)" &&
git stash apply &&
- test -f file/file &&
+ test_path_is_file file/file &&
test foo = "$(cat file/file)"
'
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index 6caff0ca39..159fae8d01 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -1169,7 +1169,7 @@ test_expect_success 'invalid when passing the --empty option alone' '
test_when_finished "git am --abort || :" &&
git checkout empty-commit^ &&
test_must_fail git am --empty empty-commit.patch 2>err &&
- echo "error: Invalid value for --empty: empty-commit.patch" >expected &&
+ echo "error: invalid value for '\''--empty'\'': '\''empty-commit.patch'\''" >expected &&
test_cmp expected err
'
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 544f0aa82e..55fac64446 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -462,6 +462,30 @@ test_expect_success !FAIL_PREREQS 'log with various grep.patternType configurati
)
'
+for cmd in show whatchanged reflog format-patch
+do
+ case "$cmd" in
+ format-patch) myarg="HEAD~.." ;;
+ *) myarg= ;;
+ esac
+
+ test_expect_success "$cmd: understands grep.patternType, like 'log'" '
+ git init "pattern-type-$cmd" &&
+ (
+ cd "pattern-type-$cmd" &&
+ test_commit 1 file A &&
+ test_commit "(1|2)" file B 2 &&
+
+ git -c grep.patternType=fixed $cmd --grep="..." $myarg >actual &&
+ test_must_be_empty actual &&
+
+ git -c grep.patternType=basic $cmd --grep="..." $myarg >actual &&
+ test_file_not_empty actual
+ )
+ '
+done
+test_done
+
test_expect_success 'log --author' '
cat >expect <<-\EOF &&
Author: <BOLD;RED>A U<RESET> Thor <author@example.com>
diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh
index 8ee67df38f..b0095ab41d 100755
--- a/t/t5302-pack-index.sh
+++ b/t/t5302-pack-index.sh
@@ -284,4 +284,12 @@ test_expect_success 'index-pack -v --stdin produces progress for both phases' '
test_i18ngrep "Resolving deltas" err
'
+test_expect_success 'too-large packs report the breach' '
+ pack=$(git pack-objects --all pack </dev/null) &&
+ sz="$(test_file_size pack-$pack.pack)" &&
+ test "$sz" -gt 20 &&
+ test_must_fail git index-pack --max-input-size=20 pack-$pack.pack 2>err &&
+ grep "maximum allowed size (20 bytes)" err
+'
+
test_done
diff --git a/t/t5316-pack-delta-depth.sh b/t/t5316-pack-delta-depth.sh
index df524f7b6d..e9045009a1 100755
--- a/t/t5316-pack-delta-depth.sh
+++ b/t/t5316-pack-delta-depth.sh
@@ -64,7 +64,11 @@ test_expect_success 'create series of packs' '
echo $cur &&
echo "$(git rev-parse :file) file"
} | git pack-objects --stdout >tmp &&
- git index-pack --stdin --fix-thin <tmp || return 1
+ GIT_TRACE2_EVENT=$PWD/trace \
+ git index-pack -v --stdin --fix-thin <tmp || return 1 &&
+ grep -c region_enter.*progress trace >enter &&
+ grep -c region_leave.*progress trace >leave &&
+ test_cmp enter leave &&
prev=$cur
done
'
diff --git a/t/t5571-pre-push-hook.sh b/t/t5571-pre-push-hook.sh
index 660f876eec..96d6ecc0af 100755
--- a/t/t5571-pre-push-hook.sh
+++ b/t/t5571-pre-push-hook.sh
@@ -11,7 +11,7 @@ HOOKDIR="$(git rev-parse --git-dir)/hooks"
HOOK="$HOOKDIR/pre-push"
mkdir -p "$HOOKDIR"
write_script "$HOOK" <<EOF
-cat >/dev/null
+cat >actual
exit 0
EOF
@@ -20,10 +20,16 @@ test_expect_success 'setup' '
git init --bare repo1 &&
git remote add parent1 repo1 &&
test_commit one &&
- git push parent1 HEAD:foreign
+ cat >expect <<-EOF &&
+ HEAD $(git rev-parse HEAD) refs/heads/foreign $(test_oid zero)
+ EOF
+
+ test_when_finished "rm actual" &&
+ git push parent1 HEAD:foreign &&
+ test_cmp expect actual
'
write_script "$HOOK" <<EOF
-cat >/dev/null
+cat >actual
exit 1
EOF
@@ -32,11 +38,18 @@ export COMMIT1
test_expect_success 'push with failing hook' '
test_commit two &&
- test_must_fail git push parent1 HEAD
+ cat >expect <<-EOF &&
+ HEAD $(git rev-parse HEAD) refs/heads/main $(test_oid zero)
+ EOF
+
+ test_when_finished "rm actual" &&
+ test_must_fail git push parent1 HEAD &&
+ test_cmp expect actual
'
test_expect_success '--no-verify bypasses hook' '
- git push --no-verify parent1 HEAD
+ git push --no-verify parent1 HEAD &&
+ test_path_is_missing actual
'
COMMIT2="$(git rev-parse HEAD)"
@@ -48,15 +61,15 @@ echo "$2" >>actual
cat >>actual
EOF
-cat >expected <<EOF
-parent1
-repo1
-refs/heads/main $COMMIT2 refs/heads/foreign $COMMIT1
-EOF
-
test_expect_success 'push with hook' '
+ cat >expect <<-EOF &&
+ parent1
+ repo1
+ refs/heads/main $COMMIT2 refs/heads/foreign $COMMIT1
+ EOF
+
git push parent1 main:foreign &&
- diff expected actual
+ test_cmp expect actual
'
test_expect_success 'add a branch' '
@@ -67,49 +80,48 @@ test_expect_success 'add a branch' '
COMMIT3="$(git rev-parse HEAD)"
export COMMIT3
-cat >expected <<EOF
-parent1
-repo1
-refs/heads/other $COMMIT3 refs/heads/foreign $COMMIT2
-EOF
-
test_expect_success 'push to default' '
+ cat >expect <<-EOF &&
+ parent1
+ repo1
+ refs/heads/other $COMMIT3 refs/heads/foreign $COMMIT2
+ EOF
git push &&
- diff expected actual
+ test_cmp expect actual
'
-cat >expected <<EOF
-parent1
-repo1
-refs/tags/one $COMMIT1 refs/tags/tag1 $ZERO_OID
-HEAD~ $COMMIT2 refs/heads/prev $ZERO_OID
-EOF
-
test_expect_success 'push non-branches' '
+ cat >expect <<-EOF &&
+ parent1
+ repo1
+ refs/tags/one $COMMIT1 refs/tags/tag1 $ZERO_OID
+ HEAD~ $COMMIT2 refs/heads/prev $ZERO_OID
+ EOF
+
git push parent1 one:tag1 HEAD~:refs/heads/prev &&
- diff expected actual
+ test_cmp expect actual
'
-cat >expected <<EOF
-parent1
-repo1
-(delete) $ZERO_OID refs/heads/prev $COMMIT2
-EOF
-
test_expect_success 'push delete' '
+ cat >expect <<-EOF &&
+ parent1
+ repo1
+ (delete) $ZERO_OID refs/heads/prev $COMMIT2
+ EOF
+
git push parent1 :prev &&
- diff expected actual
+ test_cmp expect actual
'
-cat >expected <<EOF
-repo1
-repo1
-HEAD $COMMIT3 refs/heads/other $ZERO_OID
-EOF
-
test_expect_success 'push to URL' '
+ cat >expect <<-EOF &&
+ repo1
+ repo1
+ HEAD $COMMIT3 refs/heads/other $ZERO_OID
+ EOF
+
git push repo1 HEAD &&
- diff expected actual
+ test_cmp expect actual
'
test_expect_success 'set up many-ref tests' '
diff --git a/t/t5617-clone-submodules-remote.sh b/t/t5617-clone-submodules-remote.sh
index e2dbb4eaba..ca8f80083a 100755
--- a/t/t5617-clone-submodules-remote.sh
+++ b/t/t5617-clone-submodules-remote.sh
@@ -28,6 +28,13 @@ test_expect_success 'setup' '
)
'
+# bare clone giving "srv.bare" for use as our server.
+test_expect_success 'setup bare clone for server' '
+ git clone --bare "file://$(pwd)/." srv.bare &&
+ git -C srv.bare config --local uploadpack.allowfilter 1 &&
+ git -C srv.bare config --local uploadpack.allowanysha1inwant 1
+'
+
test_expect_success 'clone with --no-remote-submodules' '
test_when_finished "rm -rf super_clone" &&
git clone --recurse-submodules --no-remote-submodules "file://$pwd/." super_clone &&
@@ -65,4 +72,38 @@ test_expect_success 'clone with --single-branch' '
)
'
+# do basic partial clone from "srv.bare"
+# confirm partial clone was registered in the local config for super and sub.
+test_expect_success 'clone with --filter' '
+ git clone --recurse-submodules \
+ --filter blob:none --also-filter-submodules \
+ "file://$pwd/srv.bare" super_clone &&
+ test_cmp_config -C super_clone true remote.origin.promisor &&
+ test_cmp_config -C super_clone blob:none remote.origin.partialclonefilter &&
+ test_cmp_config -C super_clone/sub true remote.origin.promisor &&
+ test_cmp_config -C super_clone/sub blob:none remote.origin.partialclonefilter
+'
+
+# check that clone.filterSubmodules works (--also-filter-submodules can be
+# omitted)
+test_expect_success 'filters applied with clone.filterSubmodules' '
+ test_config_global clone.filterSubmodules true &&
+ git clone --recurse-submodules --filter blob:none \
+ "file://$pwd/srv.bare" super_clone2 &&
+ test_cmp_config -C super_clone2 true remote.origin.promisor &&
+ test_cmp_config -C super_clone2 blob:none remote.origin.partialclonefilter &&
+ test_cmp_config -C super_clone2/sub true remote.origin.promisor &&
+ test_cmp_config -C super_clone2/sub blob:none remote.origin.partialclonefilter
+'
+
+test_expect_success '--no-also-filter-submodules overrides clone.filterSubmodules=true' '
+ test_config_global clone.filterSubmodules true &&
+ git clone --recurse-submodules --filter blob:none \
+ --no-also-filter-submodules \
+ "file://$pwd/srv.bare" super_clone3 &&
+ test_cmp_config -C super_clone3 true remote.origin.promisor &&
+ test_cmp_config -C super_clone3 blob:none remote.origin.partialclonefilter &&
+ test_cmp_config -C super_clone3/sub false --default false remote.origin.promisor
+'
+
test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 1be85d064e..5382e5d216 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -278,6 +278,51 @@ test_expect_success '"git bisect run" with more complex "git bisect start"' '
git bisect reset
'
+test_expect_success 'bisect run accepts exit code 126 as bad' '
+ test_when_finished "git bisect reset" &&
+ write_script test_script.sh <<-\EOF &&
+ ! grep Another hello || exit 126 >/dev/null
+ EOF
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ git bisect run ./test_script.sh >my_bisect_log.txt &&
+ grep "$HASH3 is the first bad commit" my_bisect_log.txt
+'
+
+test_expect_success POSIXPERM 'bisect run fails with non-executable test script' '
+ test_when_finished "git bisect reset" &&
+ >not-executable.sh &&
+ chmod -x not-executable.sh &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ test_must_fail git bisect run ./not-executable.sh >my_bisect_log.txt &&
+ ! grep "is the first bad commit" my_bisect_log.txt
+'
+
+test_expect_success 'bisect run accepts exit code 127 as bad' '
+ test_when_finished "git bisect reset" &&
+ write_script test_script.sh <<-\EOF &&
+ ! grep Another hello || exit 127 >/dev/null
+ EOF
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ git bisect run ./test_script.sh >my_bisect_log.txt &&
+ grep "$HASH3 is the first bad commit" my_bisect_log.txt
+'
+
+test_expect_success 'bisect run fails with missing test script' '
+ test_when_finished "git bisect reset" &&
+ rm -f does-not-exist.sh &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH4 &&
+ test_must_fail git bisect run ./does-not-exist.sh >my_bisect_log.txt &&
+ ! grep "is the first bad commit" my_bisect_log.txt
+'
+
# $HASH1 is good, $HASH5 is bad, we skip $HASH3
# but $HASH4 is good,
# so we should find $HASH5 as the first bad commit
diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh
index 91964653a0..5fcaa0b4f2 100755
--- a/t/t7500-commit-template-squash-signoff.sh
+++ b/t/t7500-commit-template-squash-signoff.sh
@@ -442,7 +442,7 @@ test_expect_success '--fixup=reword: give error with pathsec' '
'
test_expect_success '--fixup=reword: -F give error message' '
- echo "fatal: Only one of -c/-C/-F/--fixup can be used." >expect &&
+ echo "fatal: options '\''-F'\'' and '\''--fixup'\'' cannot be used together" >expect &&
test_must_fail git commit --fixup=reword:HEAD~ -F msg 2>actual &&
test_cmp expect actual
'
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 424c31c328..6935601171 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -98,6 +98,37 @@ test_expect_success 'grep should not segfault with a bad input' '
test_invalid_grep_expression --and -e A
+test_pattern_type () {
+ H=$1 &&
+ HC=$2 &&
+ L=$3 &&
+ type=$4 &&
+ shift 4 &&
+
+ expected_str= &&
+ case "$type" in
+ BRE)
+ expected_str="${HC}ab:a+bc"
+ ;;
+ ERE)
+ expected_str="${HC}ab:abc"
+ ;;
+ FIX)
+ expected_str="${HC}ab:a+b*c"
+ ;;
+ *)
+ BUG "unknown pattern type '$type'"
+ ;;
+ esac &&
+ config_str="$@" &&
+
+ test_expect_success "grep $L with '$config_str' interpreted as $type" '
+ echo $expected_str >expected &&
+ git $config_str grep "a+b*c" $H ab >actual &&
+ test_cmp expected actual
+ '
+}
+
for H in HEAD ''
do
case "$H" in
@@ -393,35 +424,13 @@ do
git grep --no-recursive -n -e vvv $H -- t . >actual &&
test_cmp expected actual
'
- test_expect_success "grep $L with grep.extendedRegexp=false" '
- echo "${HC}ab:a+bc" >expected &&
- git -c grep.extendedRegexp=false grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
- test_expect_success "grep $L with grep.extendedRegexp=true" '
- echo "${HC}ab:abc" >expected &&
- git -c grep.extendedRegexp=true grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
- test_expect_success "grep $L with grep.patterntype=basic" '
- echo "${HC}ab:a+bc" >expected &&
- git -c grep.patterntype=basic grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
-
- test_expect_success "grep $L with grep.patterntype=extended" '
- echo "${HC}ab:abc" >expected &&
- git -c grep.patterntype=extended grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
-
- test_expect_success "grep $L with grep.patterntype=fixed" '
- echo "${HC}ab:a+b*c" >expected &&
- git -c grep.patterntype=fixed grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
+ test_pattern_type "$H" "$HC" "$L" BRE -c grep.extendedRegexp=false
+ test_pattern_type "$H" "$HC" "$L" ERE -c grep.extendedRegexp=true
+ test_pattern_type "$H" "$HC" "$L" BRE -c grep.patternType=basic
+ test_pattern_type "$H" "$HC" "$L" ERE -c grep.patternType=extended
+ test_pattern_type "$H" "$HC" "$L" FIX -c grep.patternType=fixed
test_expect_success PCRE "grep $L with grep.patterntype=perl" '
echo "${HC}ab:a+b*c" >expected &&
@@ -433,59 +442,76 @@ do
test_must_fail git -c grep.patterntype=perl grep "foo.*bar"
'
- test_expect_success "grep $L with grep.patternType=default and grep.extendedRegexp=true" '
- echo "${HC}ab:abc" >expected &&
- git \
- -c grep.patternType=default \
- -c grep.extendedRegexp=true \
- grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
-
- test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=default" '
- echo "${HC}ab:abc" >expected &&
- git \
- -c grep.extendedRegexp=true \
- -c grep.patternType=default \
- grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
-
- test_expect_success "grep $L with grep.patternType=extended and grep.extendedRegexp=false" '
- echo "${HC}ab:abc" >expected &&
- git \
- -c grep.patternType=extended \
- -c grep.extendedRegexp=false \
- grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
-
- test_expect_success "grep $L with grep.patternType=basic and grep.extendedRegexp=true" '
- echo "${HC}ab:a+bc" >expected &&
- git \
- -c grep.patternType=basic \
- -c grep.extendedRegexp=true \
- grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
-
- test_expect_success "grep $L with grep.extendedRegexp=false and grep.patternType=extended" '
- echo "${HC}ab:abc" >expected &&
- git \
- -c grep.extendedRegexp=false \
- -c grep.patternType=extended \
- grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
-
- test_expect_success "grep $L with grep.extendedRegexp=true and grep.patternType=basic" '
- echo "${HC}ab:a+bc" >expected &&
- git \
- -c grep.extendedRegexp=true \
- -c grep.patternType=basic \
- grep "a+b*c" $H ab >actual &&
- test_cmp expected actual
- '
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.patternType=default \
+ -c grep.extendedRegexp=true
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=default
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.patternType=extended \
+ -c grep.extendedRegexp=false
+ test_pattern_type "$H" "$HC" "$L" BRE \
+ -c grep.patternType=basic \
+ -c grep.extendedRegexp=true
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.extendedRegexp=false \
+ -c grep.patternType=extended
+ test_pattern_type "$H" "$HC" "$L" BRE \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=basic
+
+ # grep.extendedRegexp is last-one-wins
+ test_pattern_type "$H" "$HC" "$L" BRE \
+ -c grep.extendedRegexp=true \
+ -c grep.extendedRegexp=false
+
+ # grep.patternType=basic pays no attention to grep.extendedRegexp
+ test_pattern_type "$H" "$HC" "$L" BRE \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=basic \
+ -c grep.extendedRegexp=false
+
+ # grep.patternType=extended pays no attention to grep.extendedRegexp
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=extended \
+ -c grep.extendedRegexp=false
+
+ # grep.extendedRegexp is used with a last-one-wins grep.patternType=default
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.patternType=fixed \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=default
+
+ # grep.extendedRegexp is used with earlier grep.patternType=default
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.extendedRegexp=false \
+ -c grep.patternType=default \
+ -c grep.extendedRegexp=true
+
+ # grep.extendedRegexp is used with a last-one-loses grep.patternType=default
+ test_pattern_type "$H" "$HC" "$L" ERE \
+ -c grep.extendedRegexp=false \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=default
+
+ # grep.extendedRegexp and grep.patternType are both last-one-wins independently
+ test_pattern_type "$H" "$HC" "$L" BRE \
+ -c grep.patternType=default \
+ -c grep.extendedRegexp=true \
+ -c grep.patternType=basic
+
+ # grep.patternType=extended and grep.patternType=default
+ test_pattern_type "$H" "$HC" "$L" BRE \
+ -c grep.patternType=extended \
+ -c grep.patternType=default
+
+ # grep.patternType=[extended -> default -> fixed] (BRE)" '
+ test_pattern_type "$H" "$HC" "$L" FIX \
+ -c grep.patternType=extended \
+ -c grep.patternType=default \
+ -c grep.patternType=fixed
test_expect_success "grep --count $L" '
echo ${HC}ab:3 >expected &&
diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index 058e5d0c96..a4476dc492 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -544,4 +544,45 @@ test_expect_failure 'grep saves textconv cache in the appropriate repository' '
test_path_is_file "$sub_textconv_cache"
'
+test_expect_success 'grep partially-cloned submodule' '
+ # Set up clean superproject and submodule for partial cloning.
+ git init super &&
+ git init super/sub &&
+ (
+ cd super &&
+ test_commit --no-tag "Add file in superproject" \
+ super-file "Some content for super-file" &&
+ test_commit -C sub --no-tag "Add file in submodule" \
+ sub-file "Some content for sub-file" &&
+ git submodule add ./sub &&
+ git commit -m "Add other as submodule sub" &&
+ test_tick &&
+ test_commit -C sub --no-tag --append "Update file in submodule" \
+ sub-file "Some more content for sub-file" &&
+ git add sub &&
+ git commit -m "Update submodule" &&
+ test_tick &&
+ git config --local uploadpack.allowfilter 1 &&
+ git config --local uploadpack.allowanysha1inwant 1 &&
+ git -C sub config --local uploadpack.allowfilter 1 &&
+ git -C sub config --local uploadpack.allowanysha1inwant 1
+ ) &&
+ # Clone the superproject & submodule, then make sure we can lazy-fetch submodule objects.
+ git clone --filter=blob:none --also-filter-submodules \
+ --recurse-submodules "file://$(pwd)/super" partial &&
+ (
+ cd partial &&
+ cat >expect <<-\EOF &&
+ HEAD^:sub/sub-file:Some content for sub-file
+ HEAD^:super-file:Some content for super-file
+ EOF
+
+ GIT_TRACE2_EVENT="$(pwd)/trace2.log" git grep -e content \
+ --recurse-submodules HEAD^ >actual &&
+ test_cmp expect actual &&
+ # Verify that we actually fetched data from the promisor remote:
+ grep \"category\":\"promisor\",\"key\":\"fetch_count\",\"value\":\"1\" trace2.log
+ )
+'
+
test_done
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 85385d2ede..0f439c99d6 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -856,6 +856,16 @@ test_path_is_file () {
fi
}
+test_path_is_file_not_symlink () {
+ test "$#" -ne 1 && BUG "1 param"
+ test_path_is_file "$1" &&
+ if test -h "$1"
+ then
+ echo "$1 shouldn't be a symbolic link"
+ false
+ fi
+}
+
test_path_is_dir () {
test "$#" -ne 1 && BUG "1 param"
if ! test -d "$1"
@@ -865,6 +875,16 @@ test_path_is_dir () {
fi
}
+test_path_is_dir_not_symlink () {
+ test "$#" -ne 1 && BUG "1 param"
+ test_path_is_dir "$1" &&
+ if test -h "$1"
+ then
+ echo "$1 shouldn't be a symbolic link"
+ false
+ fi
+}
+
test_path_exists () {
test "$#" -ne 1 && BUG "1 param"
if ! test -e "$1"
@@ -874,6 +894,15 @@ test_path_exists () {
fi
}
+test_path_is_symlink () {
+ test "$#" -ne 1 && BUG "1 param"
+ if ! test -h "$1"
+ then
+ echo "Symbolic link $1 doesn't exist"
+ false
+ fi
+}
+
# Check if the directory exists and is empty as expected, barf otherwise.
test_dir_is_empty () {
test "$#" -ne 1 && BUG "1 param"
diff --git a/t/test-lib.sh b/t/test-lib.sh
index e4716b0b86..9af5fb7674 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -19,13 +19,20 @@
# t/ subdirectory and are run in 'trash directory' subdirectory.
if test -z "$TEST_DIRECTORY"
then
- # We allow tests to override this, in case they want to run tests
- # outside of t/, e.g. for running tests on the test library
- # itself.
- TEST_DIRECTORY=$(pwd)
-else
# ensure that TEST_DIRECTORY is an absolute path so that it
# is valid even if the current working directory is changed
+ TEST_DIRECTORY=$(pwd)
+else
+ # The TEST_DIRECTORY will always be the path to the "t"
+ # directory in the git.git checkout. This is overridden by
+ # e.g. t/lib-subtest.sh, but only because its $(pwd) is
+ # different. Those tests still set "$TEST_DIRECTORY" to the
+ # same path.
+ #
+ # See use of "$GIT_BUILD_DIR" and "$TEST_DIRECTORY" below for
+ # hard assumptions about "$GIT_BUILD_DIR/t" existing and being
+ # the "$TEST_DIRECTORY", and e.g. "$TEST_DIRECTORY/helper"
+ # needing to exist.
TEST_DIRECTORY=$(cd "$TEST_DIRECTORY" && pwd) || exit 1
fi
if test -z "$TEST_OUTPUT_DIRECTORY"
@@ -34,19 +41,42 @@ then
# elsewhere
TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY
fi
-GIT_BUILD_DIR="$TEST_DIRECTORY"/..
+GIT_BUILD_DIR="${TEST_DIRECTORY%/t}"
+if test "$TEST_DIRECTORY" = "$GIT_BUILD_DIR"
+then
+ echo "PANIC: Running in a $TEST_DIRECTORY that doesn't end in '/t'?" >&2
+ exit 1
+fi
+
+# Prepend a string to a VAR using an arbitrary ":" delimiter, not
+# adding the delimiter if VAR or VALUE is empty. I.e. a generalized:
+#
+# VAR=$1${VAR:+${1:+$2}$VAR}
+#
+# Usage (using ":" as the $2 delimiter):
+#
+# prepend_var VAR : VALUE
+prepend_var () {
+ eval "$1=$3\${$1:+${3:+$2}\$$1}"
+}
+
+# If [AL]SAN is in effect we want to abort so that we notice
+# problems. The GIT_SAN_OPTIONS variable can be used to set common
+# defaults shared between [AL]SAN_OPTIONS.
+prepend_var GIT_SAN_OPTIONS : abort_on_error=1
+prepend_var GIT_SAN_OPTIONS : strip_path_prefix=\"$GIT_BUILD_DIR/\"
# If we were built with ASAN, it may complain about leaks
# of program-lifetime variables. Disable it by default to lower
# the noise level. This needs to happen at the start of the script,
# before we even do our "did we build git yet" check (since we don't
# want that one to complain to stderr).
-: ${ASAN_OPTIONS=detect_leaks=0:abort_on_error=1}
+prepend_var ASAN_OPTIONS : $GIT_SAN_OPTIONS
+prepend_var ASAN_OPTIONS : detect_leaks=0
export ASAN_OPTIONS
-# If LSAN is in effect we _do_ want leak checking, but we still
-# want to abort so that we notice the problems.
-: ${LSAN_OPTIONS=abort_on_error=1}
+prepend_var LSAN_OPTIONS : $GIT_SAN_OPTIONS
+prepend_var LSAN_OPTIONS : fast_unwind_on_malloc=0
export LSAN_OPTIONS
if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS