summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/helper/test-advise.c2
-rw-r--r--t/helper/test-oidtree.c49
-rw-r--r--t/helper/test-pkt-line.c12
-rw-r--r--t/helper/test-tool.c1
-rw-r--r--t/helper/test-tool.h1
-rwxr-xr-xt/t0069-oidtree.sh49
-rwxr-xr-xt/t1092-sparse-checkout-compatibility.sh168
-rwxr-xr-xt/t2400-worktree-add.sh16
-rwxr-xr-xt/t4202-log.sh14
-rwxr-xr-xt/t5319-multi-pack-index.sh5
-rw-r--r--t/t5411/once-0010-report-status-v1.sh4
-rwxr-xr-xt/t5562-http-backend-content-length.sh2
-rwxr-xr-xt/t5570-git-daemon.sh2
-rwxr-xr-xt/t6006-rev-list-format.sh80
-rwxr-xr-xt/t7500-commit-template-squash-signoff.sh2
-rwxr-xr-xt/t7519-status-fsmonitor.sh49
-rwxr-xr-xt/t9001-send-email.sh29
-rwxr-xr-xt/t9902-completion.sh13
-rw-r--r--t/test-lib-functions.sh38
19 files changed, 486 insertions, 50 deletions
diff --git a/t/helper/test-advise.c b/t/helper/test-advise.c
index a7043df1d3..cb881139f7 100644
--- a/t/helper/test-advise.c
+++ b/t/helper/test-advise.c
@@ -16,7 +16,7 @@ int cmd__advise_if_enabled(int argc, const char **argv)
* selected here and in t0018 where this command is being
* executed.
*/
- advise_if_enabled(ADVICE_NESTED_TAG, argv[1]);
+ advise_if_enabled(ADVICE_NESTED_TAG, "%s", argv[1]);
return 0;
}
diff --git a/t/helper/test-oidtree.c b/t/helper/test-oidtree.c
new file mode 100644
index 0000000000..180ee28dd9
--- /dev/null
+++ b/t/helper/test-oidtree.c
@@ -0,0 +1,49 @@
+#include "test-tool.h"
+#include "cache.h"
+#include "oidtree.h"
+
+static enum cb_next print_oid(const struct object_id *oid, void *data)
+{
+ puts(oid_to_hex(oid));
+ return CB_CONTINUE;
+}
+
+int cmd__oidtree(int argc, const char **argv)
+{
+ struct oidtree ot;
+ struct strbuf line = STRBUF_INIT;
+ int nongit_ok;
+ int algo = GIT_HASH_UNKNOWN;
+
+ oidtree_init(&ot);
+ setup_git_directory_gently(&nongit_ok);
+
+ while (strbuf_getline(&line, stdin) != EOF) {
+ const char *arg;
+ struct object_id oid;
+
+ if (skip_prefix(line.buf, "insert ", &arg)) {
+ if (get_oid_hex_any(arg, &oid) == GIT_HASH_UNKNOWN)
+ die("insert not a hexadecimal oid: %s", arg);
+ algo = oid.algo;
+ oidtree_insert(&ot, &oid);
+ } else if (skip_prefix(line.buf, "contains ", &arg)) {
+ if (get_oid_hex(arg, &oid))
+ die("contains not a hexadecimal oid: %s", arg);
+ printf("%d\n", oidtree_contains(&ot, &oid));
+ } else if (skip_prefix(line.buf, "each ", &arg)) {
+ char buf[GIT_MAX_HEXSZ + 1] = { '0' };
+ memset(&oid, 0, sizeof(oid));
+ memcpy(buf, arg, strlen(arg));
+ buf[hash_algos[algo].hexsz] = '\0';
+ get_oid_hex_any(buf, &oid);
+ oid.algo = algo;
+ oidtree_each(&ot, &oid, strlen(arg), print_oid, NULL);
+ } else if (!strcmp(line.buf, "clear")) {
+ oidtree_clear(&ot);
+ } else {
+ die("unknown command: %s", line.buf);
+ }
+ }
+ return 0;
+}
diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c
index 5e638f0b97..c5e052e537 100644
--- a/t/helper/test-pkt-line.c
+++ b/t/helper/test-pkt-line.c
@@ -26,6 +26,16 @@ static void pack(int argc, const char **argv)
}
}
+static void pack_raw_stdin(void)
+{
+ struct strbuf sb = STRBUF_INIT;
+
+ if (strbuf_read(&sb, 0, 0) < 0)
+ die_errno("failed to read from stdin");
+ packet_write(1, sb.buf, sb.len);
+ strbuf_release(&sb);
+}
+
static void unpack(void)
{
struct packet_reader reader;
@@ -110,6 +120,8 @@ int cmd__pkt_line(int argc, const char **argv)
if (!strcmp(argv[1], "pack"))
pack(argc - 2, argv + 2);
+ else if (!strcmp(argv[1], "pack-raw-stdin"))
+ pack_raw_stdin();
else if (!strcmp(argv[1], "unpack"))
unpack();
else if (!strcmp(argv[1], "unpack-sideband"))
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index b21e8f1519..490ac026c5 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -43,6 +43,7 @@ static struct test_cmd cmds[] = {
{ "mktemp", cmd__mktemp },
{ "oid-array", cmd__oid_array },
{ "oidmap", cmd__oidmap },
+ { "oidtree", cmd__oidtree },
{ "online-cpus", cmd__online_cpus },
{ "parse-options", cmd__parse_options },
{ "parse-pathspec-file", cmd__parse_pathspec_file },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index f845ced4b3..f8dc266721 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -32,6 +32,7 @@ int cmd__match_trees(int argc, const char **argv);
int cmd__mergesort(int argc, const char **argv);
int cmd__mktemp(int argc, const char **argv);
int cmd__oidmap(int argc, const char **argv);
+int cmd__oidtree(int argc, const char **argv);
int cmd__online_cpus(int argc, const char **argv);
int cmd__parse_options(int argc, const char **argv);
int cmd__parse_pathspec_file(int argc, const char** argv);
diff --git a/t/t0069-oidtree.sh b/t/t0069-oidtree.sh
new file mode 100755
index 0000000000..bfb1397d7b
--- /dev/null
+++ b/t/t0069-oidtree.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+test_description='basic tests for the oidtree implementation'
+. ./test-lib.sh
+
+maxhexsz=$(test_oid hexsz)
+echoid () {
+ prefix="${1:+$1 }"
+ shift
+ while test $# -gt 0
+ do
+ shortoid="$1"
+ shift
+ difference=$(($maxhexsz - ${#shortoid}))
+ printf "%s%s%0${difference}d\\n" "$prefix" "$shortoid" "0"
+ done
+}
+
+test_expect_success 'oidtree insert and contains' '
+ cat >expect <<-\EOF &&
+ 0
+ 0
+ 0
+ 1
+ 1
+ 0
+ EOF
+ {
+ echoid insert 444 1 2 3 4 5 a b c d e &&
+ echoid contains 44 441 440 444 4440 4444
+ echo clear
+ } | test-tool oidtree >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'oidtree each' '
+ echoid "" 123 321 321 >expect &&
+ {
+ echoid insert f 9 8 123 321 a b c d e
+ echo each 12300
+ echo each 3211
+ echo each 3210
+ echo each 32100
+ echo clear
+ } | test-tool oidtree >actual &&
+ test_cmp expect actual
+'
+
+test_done
diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
index d028b73eba..cabbd42e33 100755
--- a/t/t1092-sparse-checkout-compatibility.sh
+++ b/t/t1092-sparse-checkout-compatibility.sh
@@ -17,7 +17,7 @@ test_expect_success 'setup' '
echo "after folder1" >g &&
echo "after x" >z &&
mkdir folder1 folder2 deep x &&
- mkdir deep/deeper1 deep/deeper2 &&
+ mkdir deep/deeper1 deep/deeper2 deep/before deep/later &&
mkdir deep/deeper1/deepest &&
echo "after deeper1" >deep/e &&
echo "after deepest" >deep/deeper1/e &&
@@ -25,10 +25,23 @@ test_expect_success 'setup' '
cp a folder2 &&
cp a x &&
cp a deep &&
+ cp a deep/before &&
cp a deep/deeper1 &&
cp a deep/deeper2 &&
+ cp a deep/later &&
cp a deep/deeper1/deepest &&
cp -r deep/deeper1/deepest deep/deeper2 &&
+ mkdir deep/deeper1/0 &&
+ mkdir deep/deeper1/0/0 &&
+ touch deep/deeper1/0/1 &&
+ touch deep/deeper1/0/0/0 &&
+ >folder1- &&
+ >folder1.x &&
+ >folder10 &&
+ cp -r deep/deeper1/0 folder1 &&
+ cp -r deep/deeper1/0 folder2 &&
+ echo >>folder1/0/0/0 &&
+ echo >>folder2/0/1 &&
git add . &&
git commit -m "initial commit" &&
git checkout -b base &&
@@ -40,7 +53,7 @@ test_expect_success 'setup' '
done &&
git checkout -b rename-base base &&
- echo >folder1/larger-content <<-\EOF &&
+ cat >folder1/larger-content <<-\EOF &&
matching
lines
help
@@ -56,11 +69,17 @@ test_expect_success 'setup' '
mv folder1/a folder2/b &&
mv folder1/larger-content folder2/edited-content &&
echo >>folder2/edited-content &&
+ echo >>folder2/0/1 &&
+ echo stuff >>deep/deeper1/a &&
git add . &&
git commit -m "rename folder1/... to folder2/..." &&
git checkout -b rename-out-to-in rename-base &&
mv folder1/a deep/deeper1/b &&
+ echo more stuff >>deep/deeper1/a &&
+ rm folder2/0/1 &&
+ mkdir folder2/0/1 &&
+ echo >>folder2/0/1/1 &&
mv folder1/larger-content deep/deeper1/edited-content &&
echo >>deep/deeper1/edited-content &&
git add . &&
@@ -68,6 +87,9 @@ test_expect_success 'setup' '
git checkout -b rename-in-to-out rename-base &&
mv deep/deeper1/a folder1/b &&
+ echo >>folder2/0/1 &&
+ rm -rf folder1/0/0 &&
+ echo >>folder1/0/0 &&
mv deep/deeper1/larger-content folder1/edited-content &&
echo >>folder1/edited-content &&
git add . &&
@@ -196,6 +218,14 @@ test_expect_success 'status with options' '
test_all_match git status --porcelain=v2 -uno
'
+test_expect_success 'status reports sparse-checkout' '
+ init_repos &&
+ git -C sparse-checkout status >full &&
+ git -C sparse-index status >sparse &&
+ test_i18ngrep "You are in a sparse checkout with " full &&
+ test_i18ngrep "You are in a sparse checkout." sparse
+'
+
test_expect_success 'add, commit, checkout' '
init_repos &&
@@ -232,6 +262,44 @@ test_expect_success 'add, commit, checkout' '
test_all_match git checkout -
'
+test_expect_success 'status/add: outside sparse cone' '
+ init_repos &&
+
+ # adding a "missing" file outside the cone should fail
+ test_sparse_match test_must_fail git add folder1/a &&
+
+ # folder1 is at HEAD, but outside the sparse cone
+ run_on_sparse mkdir folder1 &&
+ cp initial-repo/folder1/a sparse-checkout/folder1/a &&
+ cp initial-repo/folder1/a sparse-index/folder1/a &&
+
+ test_sparse_match git status &&
+
+ write_script edit-contents <<-\EOF &&
+ echo text >>$1
+ EOF
+ run_on_sparse ../edit-contents folder1/a &&
+ run_on_all ../edit-contents folder1/new &&
+
+ test_sparse_match git status --porcelain=v2 &&
+
+ # This "git add folder1/a" fails with a warning
+ # in the sparse repos, differing from the full
+ # repo. This is intentional.
+ test_sparse_match test_must_fail git add folder1/a &&
+ test_sparse_match test_must_fail git add --refresh folder1/a &&
+ test_all_match git status --porcelain=v2 &&
+
+ test_all_match git add . &&
+ test_all_match git status --porcelain=v2 &&
+ test_all_match git commit -m folder1/new &&
+
+ run_on_all ../edit-contents folder1/newer &&
+ test_all_match git add folder1/ &&
+ test_all_match git status --porcelain=v2 &&
+ test_all_match git commit -m folder1/newer
+'
+
test_expect_success 'checkout and reset --hard' '
init_repos &&
@@ -262,13 +330,29 @@ test_expect_success 'diff --staged' '
test_all_match git diff --staged
'
-test_expect_success 'diff with renames' '
+test_expect_success 'diff with renames and conflicts' '
init_repos &&
for branch in rename-out-to-out rename-out-to-in rename-in-to-out
do
test_all_match git checkout rename-base &&
test_all_match git checkout $branch -- . &&
+ test_all_match git status --porcelain=v2 &&
+ test_all_match git diff --staged --no-renames &&
+ test_all_match git diff --staged --find-renames || return 1
+ done
+'
+
+test_expect_success 'diff with directory/file conflicts' '
+ init_repos &&
+
+ for branch in rename-out-to-out rename-out-to-in rename-in-to-out
+ do
+ git -C full-checkout reset --hard &&
+ test_sparse_match git reset --hard &&
+ test_all_match git checkout $branch &&
+ test_all_match git checkout rename-base -- . &&
+ test_all_match git status --porcelain=v2 &&
test_all_match git diff --staged --no-renames &&
test_all_match git diff --staged --find-renames || return 1
done
@@ -308,8 +392,8 @@ test_expect_failure 'blame with pathspec outside sparse definition' '
test_all_match git blame deep/deeper2/deepest/a
'
-# TODO: reset currently does not behave as expected when in a
-# sparse-checkout.
+# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
+# in this scenario, but it shouldn't.
test_expect_failure 'checkout and reset (mixed)' '
init_repos &&
@@ -319,8 +403,8 @@ test_expect_failure 'checkout and reset (mixed)' '
test_all_match git reset update-folder2
'
-# Ensure that sparse-index behaves identically to
-# sparse-checkout with a full index.
+# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
+# in this scenario, but it shouldn't.
test_expect_success 'checkout and reset (mixed) [sparse]' '
init_repos &&
@@ -352,6 +436,28 @@ test_expect_success 'merge with outside renames' '
done
'
+# Sparse-index fails to convert the index in the
+# final 'git cherry-pick' command.
+test_expect_success 'cherry-pick with conflicts' '
+ init_repos &&
+
+ write_script edit-conflict <<-\EOF &&
+ echo $1 >conflict
+ EOF
+
+ test_all_match git checkout -b to-cherry-pick &&
+ run_on_all ../edit-conflict ABC &&
+ test_all_match git add conflict &&
+ test_all_match git commit -m "conflict to pick" &&
+
+ test_all_match git checkout -B base HEAD~1 &&
+ run_on_all ../edit-conflict DEF &&
+ test_all_match git add conflict &&
+ test_all_match git commit -m "conflict in base" &&
+
+ test_all_match test_must_fail git cherry-pick to-cherry-pick
+'
+
test_expect_success 'clean' '
init_repos &&
@@ -405,12 +511,52 @@ test_expect_success 'sparse-index is expanded and converted back' '
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
git -C sparse-index -c core.fsmonitor="" reset --hard &&
test_region index convert_to_sparse trace2.txt &&
- test_region index ensure_full_index trace2.txt &&
+ test_region index ensure_full_index trace2.txt
+'
- rm trace2.txt &&
+test_expect_success 'sparse-index is not expanded' '
+ init_repos &&
+
+ rm -f trace2.txt &&
+ echo >>sparse-index/untracked.txt &&
GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
- git -C sparse-index -c core.fsmonitor="" status -uno &&
- test_region index ensure_full_index trace2.txt
+ git -C sparse-index status &&
+ test_region ! index ensure_full_index trace2.txt
+'
+
+# NEEDSWORK: a sparse-checkout behaves differently from a full checkout
+# in this scenario, but it shouldn't.
+test_expect_success 'reset mixed and checkout orphan' '
+ init_repos &&
+
+ test_all_match git checkout rename-out-to-in &&
+
+ # Sparse checkouts do not agree with full checkouts about
+ # how to report a directory/file conflict during a reset.
+ # This command would fail with test_all_match because the
+ # full checkout reports "T folder1/0/1" while a sparse
+ # checkout reports "D folder1/0/1". This matches because
+ # the sparse checkouts skip "adding" the other side of
+ # the conflict.
+ test_sparse_match git reset --mixed HEAD~1 &&
+ test_sparse_match test-tool read-cache --table --expand &&
+ test_sparse_match git status --porcelain=v2 &&
+
+ # At this point, sparse-checkouts behave differently
+ # from the full-checkout.
+ test_sparse_match git checkout --orphan new-branch &&
+ test_sparse_match test-tool read-cache --table --expand &&
+ test_sparse_match git status --porcelain=v2
+'
+
+test_expect_success 'add everything with deep new file' '
+ init_repos &&
+
+ run_on_sparse git sparse-checkout set deep/deeper1/deepest &&
+
+ run_on_all touch deep/deeper1/x &&
+ test_all_match git add . &&
+ test_all_match git status --porcelain=v2
'
test_done
diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh
index 96dfca1554..37ad79470f 100755
--- a/t/t2400-worktree-add.sh
+++ b/t/t2400-worktree-add.sh
@@ -67,11 +67,25 @@ test_expect_success '"add" worktree' '
'
test_expect_success '"add" worktree with lock' '
- git rev-parse HEAD >expect &&
git worktree add --detach --lock here-with-lock main &&
+ test_when_finished "git worktree unlock here-with-lock || :" &&
test -f .git/worktrees/here-with-lock/locked
'
+test_expect_success '"add" worktree with lock and reason' '
+ lock_reason="why not" &&
+ git worktree add --detach --lock --reason "$lock_reason" here-with-lock-reason main &&
+ test_when_finished "git worktree unlock here-with-lock-reason || :" &&
+ test -f .git/worktrees/here-with-lock-reason/locked &&
+ echo "$lock_reason" >expect &&
+ test_cmp expect .git/worktrees/here-with-lock-reason/locked
+'
+
+test_expect_success '"add" worktree with reason but no lock' '
+ test_must_fail git worktree add --detach --reason "why not" here-with-reason-only main &&
+ test_path_is_missing .git/worktrees/here-with-reason-only/locked
+'
+
test_expect_success '"add" worktree from a subdir' '
(
mkdir sub &&
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 39e746fbcb..9dfead936b 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -1915,6 +1915,20 @@ test_expect_success '--exclude-promisor-objects does not BUG-crash' '
test_must_fail git log --exclude-promisor-objects source-a
'
+test_expect_success 'log --decorate includes all levels of tag annotated tags' '
+ git checkout -b branch &&
+ git commit --allow-empty -m "new commit" &&
+ git tag lightweight HEAD &&
+ git tag -m annotated annotated HEAD &&
+ git tag -m double-0 double-0 HEAD &&
+ git tag -m double-1 double-1 double-0 &&
+ cat >expect <<-\EOF &&
+ HEAD -> branch, tag: lightweight, tag: double-1, tag: double-0, tag: annotated
+ EOF
+ git log -1 --format="%D" >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'log --end-of-options' '
git update-ref refs/heads/--source HEAD &&
git log --end-of-options --source >actual &&
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 7609f1ea64..3d4d9f10c3 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -837,4 +837,9 @@ test_expect_success 'load reverse index when missing .idx, .pack' '
)
'
+test_expect_success 'usage shown without sub-command' '
+ test_expect_code 129 git multi-pack-index 2>err &&
+ ! test_i18ngrep "unrecognized subcommand" err
+'
+
test_done
diff --git a/t/t5411/once-0010-report-status-v1.sh b/t/t5411/once-0010-report-status-v1.sh
index 1233a46eac..297b10925d 100644
--- a/t/t5411/once-0010-report-status-v1.sh
+++ b/t/t5411/once-0010-report-status-v1.sh
@@ -28,10 +28,10 @@ test_expect_success "proc-receive: report status v1" '
if test -z "$GIT_DEFAULT_HASH" || test "$GIT_DEFAULT_HASH" = "sha1"
then
printf "%s %s refs/heads/main\0report-status\n" \
- $A $B | packetize
+ $A $B | packetize_raw
else
printf "%s %s refs/heads/main\0report-status object-format=$GIT_DEFAULT_HASH\n" \
- $A $B | packetize
+ $A $B | packetize_raw
fi &&
printf "%s %s refs/for/main/topic1\n" \
$ZERO_OID $A | packetize &&
diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh
index e5d3d15ba8..05a58069b0 100755
--- a/t/t5562-http-backend-content-length.sh
+++ b/t/t5562-http-backend-content-length.sh
@@ -63,7 +63,7 @@ test_expect_success 'setup' '
hash_next=$(git commit-tree -p HEAD -m next HEAD^{tree}) &&
{
printf "%s %s refs/heads/newbranch\\0report-status object-format=%s\\n" \
- "$ZERO_OID" "$hash_next" "$(test_oid algo)" | packetize &&
+ "$ZERO_OID" "$hash_next" "$(test_oid algo)" | packetize_raw
printf 0000 &&
echo "$hash_next" | git pack-objects --stdout
} >push_body &&
diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
index 82c31ab6cd..b87ca06a58 100755
--- a/t/t5570-git-daemon.sh
+++ b/t/t5570-git-daemon.sh
@@ -194,7 +194,7 @@ test_expect_success 'hostname cannot break out of directory' '
test_expect_success FAKENC 'hostname interpolation works after LF-stripping' '
{
- printf "git-upload-pack /interp.git\n\0host=localhost" | packetize
+ printf "git-upload-pack /interp.git\n\0host=localhost" | packetize_raw
printf "0000"
} >input &&
fake_nc "$GIT_DAEMON_HOST_PORT" <input >output &&
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 35a2f62392..41d0ca00b1 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -41,22 +41,59 @@ test_expect_success 'setup' '
echo "$added_iso88591" | git commit -F - &&
head1=$(git rev-parse --verify HEAD) &&
head1_short=$(git rev-parse --verify --short $head1) &&
+ head1_short4=$(git rev-parse --verify --short=4 $head1) &&
tree1=$(git rev-parse --verify HEAD:) &&
tree1_short=$(git rev-parse --verify --short $tree1) &&
echo "$changed" > foo &&
echo "$changed_iso88591" | git commit -a -F - &&
head2=$(git rev-parse --verify HEAD) &&
head2_short=$(git rev-parse --verify --short $head2) &&
+ head2_short4=$(git rev-parse --verify --short=4 $head2) &&
tree2=$(git rev-parse --verify HEAD:) &&
tree2_short=$(git rev-parse --verify --short $tree2) &&
git config --unset i18n.commitEncoding
'
-# usage: test_format name format_string [failure] <expected_output
+# usage: test_format [argument...] name format_string [failure] <expected_output
test_format () {
+ local args=
+ while true
+ do
+ case "$1" in
+ --*)
+ args="$args $1"
+ shift;;
+ *)
+ break;;
+ esac
+ done
cat >expect.$1
test_expect_${3:-success} "format $1" "
- git rev-list --pretty=format:'$2' main >output.$1 &&
+ git rev-list $args --pretty=format:'$2' main >output.$1 &&
+ test_cmp expect.$1 output.$1
+ "
+}
+
+# usage: test_pretty [argument...] name format_name [failure] <expected_output
+test_pretty () {
+ local args=
+ while true
+ do
+ case "$1" in
+ --*)
+ args="$args $1"
+ shift;;
+ *)
+ break;;
+ esac
+ done
+ cat >expect.$1
+ test_expect_${3:-success} "pretty $1 (without --no-commit-header)" "
+ git rev-list $args --pretty='$2' main >output.$1 &&
+ test_cmp expect.$1 output.$1
+ "
+ test_expect_${3:-success} "pretty $1 (with --no-commit-header)" "
+ git rev-list $args --no-commit-header --pretty='$2' main >output.$1 &&
test_cmp expect.$1 output.$1
"
}
@@ -93,6 +130,20 @@ $head1
$head1_short
EOF
+test_format --no-commit-header hash-no-header %H%n%h <<EOF
+$head2
+$head2_short
+$head1
+$head1_short
+EOF
+
+test_format --abbrev-commit --abbrev=0 --no-commit-header hash-no-header-abbrev %H%n%h <<EOF
+$head2
+$head2_short4
+$head1
+$head1_short4
+EOF
+
test_format tree %T%n%t <<EOF
commit $head2
$tree2
@@ -181,6 +232,31 @@ $added
EOF
+test_format --no-commit-header raw-body-no-header %B <<EOF
+$changed
+
+$added
+
+EOF
+
+test_pretty oneline oneline <<EOF
+$head2 $changed
+$head1 $added
+EOF
+
+test_pretty short short <<EOF
+commit $head2
+Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+
+ $changed
+
+commit $head1
+Author: $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>
+
+ $added
+
+EOF
+
test_expect_success 'basic colors' '
cat >expect <<-EOF &&
commit $head2
diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh
index 7d02f79c0d..54c2082acb 100755
--- a/t/t7500-commit-template-squash-signoff.sh
+++ b/t/t7500-commit-template-squash-signoff.sh
@@ -498,7 +498,7 @@ test_expect_success 'invalid message options when using --fixup' '
cat >expected-template <<EOF
# Please enter the commit message for your changes. Lines starting
-# with '#' will be ignored, and an empty message aborts the commit.
+# with '#' will be ignored.
#
# Author: A U Thor <author@example.com>
#
diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh
index 637391c6ce..deea88d443 100755
--- a/t/t7519-status-fsmonitor.sh
+++ b/t/t7519-status-fsmonitor.sh
@@ -73,6 +73,7 @@ test_expect_success 'setup' '
expect*
actual*
marker*
+ trace2*
EOF
'
@@ -383,4 +384,52 @@ test_expect_success 'status succeeds after staging/unstaging' '
)
'
+# Usage:
+# check_sparse_index_behavior [!]
+# 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_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
+ git 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
+}
+
+test_expect_success 'status succeeds with sparse index' '
+ git reset --hard &&
+
+ test_config core.fsmonitor "$TEST_DIRECTORY/t7519/fsmonitor-all" &&
+ check_sparse_index_behavior ! &&
+
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
+ EOF
+ git config core.fsmonitor .git/hooks/fsmonitor-test &&
+ check_sparse_index_behavior ! &&
+
+ 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" &&
+
+ # This one modifies outside the sparse-checkout definition
+ # and hence we expect to expand the sparse-index.
+ write_script .git/hooks/fsmonitor-test<<-\EOF &&
+ printf "last_update_token\0"
+ printf "dir1a/modified\0"
+ EOF
+ check_sparse_index_behavior
+'
+
test_done
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index e9dc58f508..57fc10e7f8 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -1368,6 +1368,16 @@ test_expect_success $PREREQ 'sendemail.identity: bool variable fallback' '
! grep "X-Mailer" stdout
'
+test_expect_success $PREREQ 'sendemail.identity: bool variable without a value' '
+ git -c sendemail.xmailer \
+ send-email \
+ --dry-run \
+ --from="nobody@example.com" \
+ $patches >stdout &&
+ grep "To: default@example.com" stdout &&
+ grep "X-Mailer" stdout
+'
+
test_expect_success $PREREQ '--no-to overrides sendemail.to' '
git send-email \
--dry-run \
@@ -2092,6 +2102,18 @@ test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=true' '
do_xmailer_test 1 "--xmailer"
'
+test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer' '
+ test_when_finished "test_unconfig sendemail.xmailer" &&
+ cat >>.git/config <<-\EOF &&
+ [sendemail]
+ xmailer
+ EOF
+ test_config sendemail.xmailer true &&
+ do_xmailer_test 1 "" &&
+ do_xmailer_test 0 "--no-xmailer" &&
+ do_xmailer_test 1 "--xmailer"
+'
+
test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' '
test_config sendemail.xmailer false &&
do_xmailer_test 0 "" &&
@@ -2099,6 +2121,13 @@ test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=false' '
do_xmailer_test 1 "--xmailer"
'
+test_expect_success $PREREQ '--[no-]xmailer with sendemail.xmailer=' '
+ test_config sendemail.xmailer "" &&
+ do_xmailer_test 0 "" &&
+ do_xmailer_test 0 "--no-xmailer" &&
+ do_xmailer_test 1 "--xmailer"
+'
+
test_expect_success $PREREQ 'setup expected-list' '
git send-email \
--dry-run \
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index cb057ef161..11573936d5 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2404,6 +2404,19 @@ test_expect_success 'sourcing the completion script clears cached --options' '
verbose test -z "$__gitcomp_builtin_notes_edit"
'
+test_expect_success 'option aliases are not shown by default' '
+ test_completion "git clone --recurs" "--recurse-submodules "
+'
+
+test_expect_success 'option aliases are shown with GIT_COMPLETION_SHOW_ALL' '
+ . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
+ GIT_COMPLETION_SHOW_ALL=1 && export GIT_COMPLETION_SHOW_ALL &&
+ test_completion "git clone --recurs" <<-\EOF
+ --recurse-submodules Z
+ --recursive Z
+ EOF
+'
+
test_expect_success '__git_complete' '
unset -f __git_wrap__git_main &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index ce41596514..e28411bb75 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -1479,46 +1479,24 @@ nongit () {
)
} 7>&2 2>&4
-# convert function arguments or stdin (if not arguments given) to pktline
-# representation. If multiple arguments are given, they are separated by
-# whitespace and put in a single packet. Note that data containing NULs must be
-# given on stdin, and that empty input becomes an empty packet, not a flush
-# packet (for that you can just print 0000 yourself).
+# These functions are historical wrappers around "test-tool pkt-line"
+# for older tests. Use "test-tool pkt-line" itself in new tests.
packetize () {
if test $# -gt 0
then
packet="$*"
printf '%04x%s' "$((4 + ${#packet}))" "$packet"
else
- perl -e '
- my $packet = do { local $/; <STDIN> };
- printf "%04x%s", 4 + length($packet), $packet;
- '
+ test-tool pkt-line pack
fi
}
-# Parse the input as a series of pktlines, writing the result to stdout.
-# Sideband markers are removed automatically, and the output is routed to
-# stderr if appropriate.
-#
-# NUL bytes are converted to "\\0" for ease of parsing with text tools.
+packetize_raw () {
+ test-tool pkt-line pack-raw-stdin
+}
+
depacketize () {
- perl -e '
- while (read(STDIN, $len, 4) == 4) {
- if ($len eq "0000") {
- print "FLUSH\n";
- } else {
- read(STDIN, $buf, hex($len) - 4);
- $buf =~ s/\0/\\0/g;
- if ($buf =~ s/^[\x2\x3]//) {
- print STDERR $buf;
- } else {
- $buf =~ s/^\x1//;
- print $buf;
- }
- }
- }
- '
+ test-tool pkt-line unpack
}
# Converts base-16 data into base-8. The output is given as a sequence of