summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README44
-rw-r--r--t/helper/test-oid-array.c (renamed from t/helper/test-sha1-array.c)8
-rw-r--r--t/helper/test-pkt-line.c2
-rw-r--r--t/helper/test-tool.c3
-rw-r--r--t/helper/test-tool.h2
-rw-r--r--[-rwxr-xr-x]t/lib-credential.sh5
-rw-r--r--[-rwxr-xr-x]t/lib-gpg.sh110
-rw-r--r--[-rwxr-xr-x]t/lib-log-graph.sh0
-rw-r--r--[-rwxr-xr-x]t/lib-submodule-update.sh0
-rwxr-xr-xt/perf/p5310-pack-bitmaps.sh4
-rwxr-xr-xt/perf/p9300-fast-import-export.sh23
-rwxr-xr-xt/t0000-basic.sh13
-rwxr-xr-xt/t0001-init.sh9
-rwxr-xr-xt/t0007-git-var.sh2
-rwxr-xr-xt/t0040-parse-options.sh2
-rwxr-xr-xt/t0060-path-utils.sh2
-rwxr-xr-xt/t0064-sha1-array.sh16
-rwxr-xr-xt/t0212-trace2-event.sh37
-rwxr-xr-xt/t0300-credentials.sh185
-rwxr-xr-xt/t1011-read-tree-sparse-checkout.sh11
-rwxr-xr-xt/t1091-sparse-checkout-builtin.sh105
-rwxr-xr-xt/t2018-checkout-branch.sh22
-rwxr-xr-xt/t2402-worktree-list.sh2
-rwxr-xr-xt/t3000-ls-files-others.sh121
-rwxr-xr-xt/t3033-merge-toplevel.sh22
-rwxr-xr-xt/t3206-range-diff.sh10
-rwxr-xr-xt/t3402-rebase-merge.sh77
-rwxr-xr-xt/t3406-rebase-message.sh16
-rwxr-xr-xt/t3417-rebase-whitespace-fix.sh4
-rwxr-xr-xt/t3419-rebase-patch-id.sh114
-rwxr-xr-xt/t3420-rebase-autostash.sh20
-rwxr-xr-xt/t3421-rebase-topology-linear.sh10
-rwxr-xr-xt/t3424-rebase-empty.sh36
-rwxr-xr-xt/t3432-rebase-fast-forward.sh24
-rwxr-xr-xt/t3435-rebase-gpg-sign.sh71
-rwxr-xr-xt/t3514-cherry-pick-revert-gpg.sh86
-rwxr-xr-xt/t3700-add.sh2
-rwxr-xr-xt/t3701-add-interactive.sh2
-rwxr-xr-xt/t3904-stash-patch.sh6
-rwxr-xr-xt/t4013-diff-various.sh12
-rw-r--r--t/t4013/diff.diff-tree_--format=%N_note6
-rw-r--r--t/t4013/diff.diff-tree_--pretty_--notes_note12
-rw-r--r--t/t4013/diff.diff-tree_--pretty_note9
-rw-r--r--t/t4013/diff.log_--decorate=full_--all15
-rw-r--r--t/t4013/diff.log_--decorate_--all15
-rwxr-xr-xt/t4014-format-patch.sh53
-rwxr-xr-xt/t4057-diff-combined-paths.sh2
-rwxr-xr-xt/t4061-diff-indent.sh2
-rwxr-xr-xt/t4067-diff-partial-clone.sh48
-rwxr-xr-xt/t4124-apply-ws-rule.sh7
-rwxr-xr-xt/t4150-am.sh2
-rwxr-xr-xt/t4202-log.sh51
-rwxr-xr-xt/t4208-log-magic-pathspec.sh4
-rwxr-xr-xt/t5003-archive-zip.sh24
-rwxr-xr-xt/t5319-multi-pack-index.sh21
-rw-r--r--t/t5319/no-objects.midxbin0 -> 1116 bytes
-rwxr-xr-xt/t5322-pack-objects-sparse.sh4
-rwxr-xr-xt/t5324-split-commit-graph.sh8
-rwxr-xr-xt/t5504-fetch-receive-strict.sh1
-rwxr-xr-xt/t5512-ls-remote.sh80
-rwxr-xr-xt/t5516-fetch-push.sh1
-rwxr-xr-xt/t5520-pull.sh57
-rwxr-xr-xt/t5537-fetch-shallow.sh2
-rwxr-xr-xt/t5541-http-push-smart.sh12
-rwxr-xr-xt/t5543-atomic-push.sh89
-rwxr-xr-xt/t5548-push-porcelain.sh279
-rwxr-xr-xt/t5550-http-fetch-dumb.sh20
-rwxr-xr-xt/t5562-http-backend-content-length.sh19
-rwxr-xr-xt/t5604-clone-reference.sh2
-rwxr-xr-xt/t5607-clone-bundle.sh2
-rwxr-xr-xt/t5611-clone-config.sh13
-rwxr-xr-xt/t5612-clone-refspec.sh26
-rwxr-xr-xt/t5616-partial-clone.sh10
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh5
-rwxr-xr-xt/t5704-protocol-violations.sh33
-rwxr-xr-xt/t5801-remote-helpers.sh10
-rwxr-xr-xt/t6012-rev-list-simplify.sh120
-rwxr-xr-xt/t7063-status-untracked-cache.sh54
-rwxr-xr-xt/t7400-submodule-basic.sh4
-rwxr-xr-xt/t7416-submodule-dash-url.sh143
-rwxr-xr-xt/t7600-merge.sh154
-rwxr-xr-xt/t7609-merge-co-error-msgs.sh2
-rwxr-xr-xt/t7810-grep.sh47
-rwxr-xr-xt/t9010-svn-fe.sh2
-rwxr-xr-xt/t9500-gitweb-standalone-no-errors.sh70
-rwxr-xr-xt/t9831-git-p4-triggers.sh2
-rwxr-xr-xt/t9902-completion.sh5
-rw-r--r--t/test-lib-functions.sh34
-rw-r--r--t/test-lib.sh82
89 files changed, 2493 insertions, 410 deletions
diff --git a/t/README b/t/README
index 369e3a9..13747f1 100644
--- a/t/README
+++ b/t/README
@@ -69,7 +69,8 @@ You can also run each test individually from command line, like this:
You can pass --verbose (or -v), --debug (or -d), and --immediate
(or -i) command line argument to the test, or by setting GIT_TEST_OPTS
-appropriately before running "make".
+appropriately before running "make". Short options can be bundled, i.e.
+'-d -v' is the same as '-dv'.
-v::
--verbose::
@@ -386,9 +387,9 @@ GIT_TEST_INDEX_VERSION=<n> exercises the index read/write code path
for the index version specified. Can be set to any valid version
(currently 2, 3, or 4).
-GIT_TEST_PACK_SPARSE=<boolean> if enabled will default the pack-objects
-builtin to use the sparse object walk. This can still be overridden by
-the --no-sparse command-line argument.
+GIT_TEST_PACK_SPARSE=<boolean> if disabled will default the pack-objects
+builtin to use the non-sparse object walk. This can still be overridden by
+the --sparse command-line argument.
GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
by overriding the minimum number of cache entries required per thread.
@@ -546,6 +547,41 @@ Here are the "do's:"
reports "ok" or "not ok" to the end user running the tests. Under
--verbose, they are shown to help debug the tests.
+ - Be careful when you loop
+
+ You may need to verify multiple things in a loop, but the
+ following does not work correctly:
+
+ test_expect_success 'test three things' '
+ for i in one two three
+ do
+ test_something "$i"
+ done &&
+ test_something_else
+ '
+
+ Because the status of the loop itself is the exit status of the
+ test_something in the last round, the loop does not fail when
+ "test_something" for "one" or "two" fails. This is not what you
+ want.
+
+ Instead, you can break out of the loop immediately when you see a
+ failure. Because all test_expect_* snippets are executed inside
+ a function, "return 1" can be used to fail the test immediately
+ upon a failure:
+
+ test_expect_success 'test three things' '
+ for i in one two three
+ do
+ test_something "$i" || return 1
+ done &&
+ test_something_else
+ '
+
+ Note that we still &&-chain the loop to propagate failures from
+ earlier commands.
+
+
And here are the "don'ts:"
- Don't exit() within a <script> part.
diff --git a/t/helper/test-sha1-array.c b/t/helper/test-oid-array.c
index ad5e69f..ce9fd5f 100644
--- a/t/helper/test-sha1-array.c
+++ b/t/helper/test-oid-array.c
@@ -1,6 +1,6 @@
#include "test-tool.h"
#include "cache.h"
-#include "sha1-array.h"
+#include "oid-array.h"
static int print_oid(const struct object_id *oid, void *data)
{
@@ -8,7 +8,7 @@ static int print_oid(const struct object_id *oid, void *data)
return 0;
}
-int cmd__sha1_array(int argc, const char **argv)
+int cmd__oid_array(int argc, const char **argv)
{
struct oid_array array = OID_ARRAY_INIT;
struct strbuf line = STRBUF_INIT;
@@ -19,11 +19,11 @@ int cmd__sha1_array(int argc, const char **argv)
if (skip_prefix(line.buf, "append ", &arg)) {
if (get_oid_hex(arg, &oid))
- die("not a hexadecimal SHA1: %s", arg);
+ die("not a hexadecimal oid: %s", arg);
oid_array_append(&array, &oid);
} else if (skip_prefix(line.buf, "lookup ", &arg)) {
if (get_oid_hex(arg, &oid))
- die("not a hexadecimal SHA1: %s", arg);
+ die("not a hexadecimal oid: %s", arg);
printf("%d\n", oid_array_lookup(&array, &oid));
} else if (!strcmp(line.buf, "clear"))
oid_array_clear(&array);
diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c
index 282d536..12ca698 100644
--- a/t/helper/test-pkt-line.c
+++ b/t/helper/test-pkt-line.c
@@ -67,7 +67,7 @@ static void unpack_sideband(void)
case PACKET_READ_NORMAL:
band = reader.line[0] & 0xff;
if (band < 1 || band > 2)
- die("unexpected side band %d", band);
+ continue; /* skip non-sideband packets */
fd = band;
write_or_die(fd, reader.line + 1, reader.pktlen - 1);
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 31eedcd..2ece4d1 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -37,6 +37,7 @@ static struct test_cmd cmds[] = {
{ "match-trees", cmd__match_trees },
{ "mergesort", cmd__mergesort },
{ "mktemp", cmd__mktemp },
+ { "oid-array", cmd__oid_array },
{ "oidmap", cmd__oidmap },
{ "online-cpus", cmd__online_cpus },
{ "parse-options", cmd__parse_options },
@@ -57,7 +58,6 @@ static struct test_cmd cmds[] = {
{ "scrap-cache-tree", cmd__scrap_cache_tree },
{ "serve-v2", cmd__serve_v2 },
{ "sha1", cmd__sha1 },
- { "sha1-array", cmd__sha1_array },
{ "sha256", cmd__sha256 },
{ "sigchain", cmd__sigchain },
{ "strcmp-offset", cmd__strcmp_offset },
@@ -112,6 +112,7 @@ int cmd_main(int argc, const char **argv)
argc--;
trace2_cmd_name(cmds[i].name);
trace2_cmd_list_config();
+ trace2_cmd_list_env_vars();
return cmds[i].fn(argc, argv);
}
}
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 4eb5e66..1cbaec0 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -47,7 +47,7 @@ int cmd__run_command(int argc, const char **argv);
int cmd__scrap_cache_tree(int argc, const char **argv);
int cmd__serve_v2(int argc, const char **argv);
int cmd__sha1(int argc, const char **argv);
-int cmd__sha1_array(int argc, const char **argv);
+int cmd__oid_array(int argc, const char **argv);
int cmd__sha256(int argc, const char **argv);
int cmd__sigchain(int argc, const char **argv);
int cmd__strcmp_offset(int argc, const char **argv);
diff --git a/t/lib-credential.sh b/t/lib-credential.sh
index 937b831..dea2cbe 100755..100644
--- a/t/lib-credential.sh
+++ b/t/lib-credential.sh
@@ -1,4 +1,5 @@
-#!/bin/sh
+# Shell library for testing credential handling including helpers. See t0302
+# for an example of testing a specific helper.
# Try a set of credential helpers; the expected stdin,
# stdout and stderr should be provided on stdin,
@@ -19,7 +20,7 @@ check() {
false
fi &&
test_cmp expect-stdout stdout &&
- test_cmp expect-stderr stderr
+ test_i18ncmp expect-stderr stderr
}
read_chunk() {
diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh
index 8d28652..9fc5241 100755..100644
--- a/t/lib-gpg.sh
+++ b/t/lib-gpg.sh
@@ -1,14 +1,25 @@
-#!/bin/sh
+# We always set GNUPGHOME, even if no usable GPG was found, as
+#
+# - It does not hurt, and
+#
+# - we cannot set global environment variables in lazy prereqs because they are
+# executed in an eval'ed subshell that changes the working directory to a
+# temporary one.
+
+GNUPGHOME="$PWD/gpghome"
+export GNUPGHOME
+
+test_lazy_prereq GPG '
+ gpg_version=$(gpg --version 2>&1)
+ test $? != 127 || exit 1
-gpg_version=$(gpg --version 2>&1)
-if test $? != 127
-then
# As said here: http://www.gnupg.org/documentation/faqs.html#q6.19
- # the gpg version 1.0.6 didn't parse trust packets correctly, so for
+ # the gpg version 1.0.6 did not parse trust packets correctly, so for
# that version, creation of signed tags using the generated key fails.
case "$gpg_version" in
- 'gpg (GnuPG) 1.0.6'*)
+ "gpg (GnuPG) 1.0.6"*)
say "Your version of gpg (1.0.6) is too buggy for testing"
+ exit 1
;;
*)
# Available key info:
@@ -27,55 +38,54 @@ then
# To export ownertrust:
# gpg --homedir /tmp/gpghome --export-ownertrust \
# > lib-gpg/ownertrust
- mkdir ./gpghome &&
- chmod 0700 ./gpghome &&
- GNUPGHOME="$(pwd)/gpghome" &&
- export GNUPGHOME &&
- (gpgconf --kill gpg-agent >/dev/null 2>&1 || : ) &&
- gpg --homedir "${GNUPGHOME}" 2>/dev/null --import \
+ mkdir "$GNUPGHOME" &&
+ chmod 0700 "$GNUPGHOME" &&
+ (gpgconf --kill gpg-agent || : ) &&
+ gpg --homedir "${GNUPGHOME}" --import \
"$TEST_DIRECTORY"/lib-gpg/keyring.gpg &&
- gpg --homedir "${GNUPGHOME}" 2>/dev/null --import-ownertrust \
+ gpg --homedir "${GNUPGHOME}" --import-ownertrust \
"$TEST_DIRECTORY"/lib-gpg/ownertrust &&
- gpg --homedir "${GNUPGHOME}" </dev/null >/dev/null 2>&1 \
- --sign -u committer@example.com &&
- test_set_prereq GPG &&
- # Available key info:
- # * see t/lib-gpg/gpgsm-gen-key.in
- # To generate new certificate:
- # * no passphrase
- # gpgsm --homedir /tmp/gpghome/ \
- # -o /tmp/gpgsm.crt.user \
- # --generate-key \
- # --batch t/lib-gpg/gpgsm-gen-key.in
- # To import certificate:
- # gpgsm --homedir /tmp/gpghome/ \
- # --import /tmp/gpgsm.crt.user
- # To export into a .p12 we can later import:
- # gpgsm --homedir /tmp/gpghome/ \
- # -o t/lib-gpg/gpgsm_cert.p12 \
- # --export-secret-key-p12 "committer@example.com"
- echo | gpgsm --homedir "${GNUPGHOME}" 2>/dev/null \
- --passphrase-fd 0 --pinentry-mode loopback \
- --import "$TEST_DIRECTORY"/lib-gpg/gpgsm_cert.p12 &&
-
- gpgsm --homedir "${GNUPGHOME}" 2>/dev/null -K |
- grep fingerprint: |
- cut -d" " -f4 |
- tr -d '\n' >"${GNUPGHOME}/trustlist.txt" &&
-
- echo " S relax" >>"${GNUPGHOME}/trustlist.txt" &&
- echo hello | gpgsm --homedir "${GNUPGHOME}" >/dev/null \
- -u committer@example.com -o /dev/null --sign - 2>&1 &&
- test_set_prereq GPGSM
+ gpg --homedir "${GNUPGHOME}" </dev/null >/dev/null \
+ --sign -u committer@example.com
;;
esac
-fi
+'
+
+test_lazy_prereq GPGSM '
+ test_have_prereq GPG &&
+ # Available key info:
+ # * see t/lib-gpg/gpgsm-gen-key.in
+ # To generate new certificate:
+ # * no passphrase
+ # gpgsm --homedir /tmp/gpghome/ \
+ # -o /tmp/gpgsm.crt.user \
+ # --generate-key \
+ # --batch t/lib-gpg/gpgsm-gen-key.in
+ # To import certificate:
+ # gpgsm --homedir /tmp/gpghome/ \
+ # --import /tmp/gpgsm.crt.user
+ # To export into a .p12 we can later import:
+ # gpgsm --homedir /tmp/gpghome/ \
+ # -o t/lib-gpg/gpgsm_cert.p12 \
+ # --export-secret-key-p12 "committer@example.com"
+ echo | gpgsm --homedir "${GNUPGHOME}" \
+ --passphrase-fd 0 --pinentry-mode loopback \
+ --import "$TEST_DIRECTORY"/lib-gpg/gpgsm_cert.p12 &&
+
+ gpgsm --homedir "${GNUPGHOME}" -K |
+ grep fingerprint: |
+ cut -d" " -f4 |
+ tr -d "\\n" >"${GNUPGHOME}/trustlist.txt" &&
+
+ echo " S relax" >>"${GNUPGHOME}/trustlist.txt" &&
+ echo hello | gpgsm --homedir "${GNUPGHOME}" >/dev/null \
+ -u committer@example.com -o /dev/null --sign -
+'
-if test_have_prereq GPG &&
- echo | gpg --homedir "${GNUPGHOME}" -b --rfc1991 >/dev/null 2>&1
-then
- test_set_prereq RFC1991
-fi
+test_lazy_prereq RFC1991 '
+ test_have_prereq GPG &&
+ echo | gpg --homedir "${GNUPGHOME}" -b --rfc1991 >/dev/null
+'
sanitize_pgp() {
perl -ne '
diff --git a/t/lib-log-graph.sh b/t/lib-log-graph.sh
index 1184cce..1184cce 100755..100644
--- a/t/lib-log-graph.sh
+++ b/t/lib-log-graph.sh
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 64fc648..64fc648 100755..100644
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh
index 7743f4f..80c53ed 100755
--- a/t/perf/p5310-pack-bitmaps.sh
+++ b/t/perf/p5310-pack-bitmaps.sh
@@ -31,10 +31,6 @@ test_perf 'simulated fetch' '
} | git pack-objects --revs --stdout >/dev/null
'
-test_perf 'pack to file' '
- git pack-objects --all pack1 </dev/null >/dev/null
-'
-
test_perf 'pack to file (bitmap)' '
git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null
'
diff --git a/t/perf/p9300-fast-import-export.sh b/t/perf/p9300-fast-import-export.sh
new file mode 100755
index 0000000..586161e
--- /dev/null
+++ b/t/perf/p9300-fast-import-export.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+test_description='test fast-import and fast-export performance'
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+# Use --no-data here to produce a vastly smaller export file.
+# This is much cheaper to work with but should still exercise
+# fast-import pretty well (we'll still process all commits and
+# trees, which account for 60% or more of objects in most repos).
+#
+# Use --reencode to avoid the default of aborting on non-utf8 commits,
+# which lets this test run against a wider variety of sample repos.
+test_perf 'export (no-blobs)' '
+ git fast-export --reencode=yes --no-data HEAD >export
+'
+
+test_perf 'import (no-blobs)' '
+ git fast-import --force <export
+'
+
+test_done
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 3e440c0..b859721 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -833,6 +833,19 @@ then
exit 1
fi
+test_expect_success 'lazy prereqs do not turn off tracing' "
+ run_sub_test_lib_test lazy-prereq-and-tracing \
+ 'lazy prereqs and -x' -v -x <<-\\EOF &&
+ test_lazy_prereq LAZY true
+
+ test_expect_success lazy 'test_have_prereq LAZY && echo trace'
+
+ test_done
+ EOF
+
+ grep 'echo trace' lazy-prereq-and-tracing/err
+"
+
test_expect_success 'tests clean up even on failures' "
run_sub_test_lib_test_err \
failing-cleanup 'Failing tests with cleanup commands' <<-\\EOF &&
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 26f8206..1edd5ae 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -392,13 +392,6 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' '
test_path_is_dir realgitdir/refs
'
-# Tests for the hidden file attribute on windows
-is_hidden () {
- # Use the output of `attrib`, ignore the absolute path
- case "$(attrib "$1")" in *H*?:*) return 0;; esac
- return 1
-}
-
test_expect_success MINGW '.git hidden' '
rm -rf newdir &&
(
@@ -406,7 +399,7 @@ test_expect_success MINGW '.git hidden' '
mkdir newdir &&
cd newdir &&
git init &&
- is_hidden .git
+ test_path_is_hidden .git
) &&
check_config newdir/.git false unset
'
diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh
index 1f600e2..88b9ae8 100755
--- a/t/t0007-git-var.sh
+++ b/t/t0007-git-var.sh
@@ -17,7 +17,7 @@ test_expect_success 'get GIT_COMMITTER_IDENT' '
test_cmp expect actual
'
-test_expect_success !FAIL_PREREQS,!AUTOIDENT 'requested identites are strict' '
+test_expect_success !FAIL_PREREQS,!AUTOIDENT 'requested identities are strict' '
(
sane_unset GIT_COMMITTER_NAME &&
sane_unset GIT_COMMITTER_EMAIL &&
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 3483b72..f8178ee 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -54,7 +54,7 @@ Alias
-A, --alias-source <string>
get a string
-Z, --alias-target <string>
- get a string
+ alias of --alias-source
EOF
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index 2ea2d00..56db5c8 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -476,6 +476,7 @@ test_expect_success MINGW 'is_valid_path() on Windows' '
C:\\git \
comm \
conout.c \
+ com0.c \
lptN \
\
--not \
@@ -488,6 +489,7 @@ test_expect_success MINGW 'is_valid_path() on Windows' '
"AUX.c" \
"abc/conOut\$ .xyz/test" \
lpt8 \
+ com9.c \
"lpt*" \
Nul \
"PRN./abc"
diff --git a/t/t0064-sha1-array.sh b/t/t0064-sha1-array.sh
index 5dda570..45685af 100755
--- a/t/t0064-sha1-array.sh
+++ b/t/t0064-sha1-array.sh
@@ -18,7 +18,7 @@ test_expect_success 'ordered enumeration' '
{
echoid append 88 44 aa 55 &&
echo for_each_unique
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
test_cmp expect actual
'
@@ -28,7 +28,7 @@ test_expect_success 'ordered enumeration with duplicate suppression' '
echoid append 88 44 aa 55 &&
echoid append 88 44 aa 55 &&
echo for_each_unique
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
test_cmp expect actual
'
@@ -36,7 +36,7 @@ test_expect_success 'lookup' '
{
echoid append 88 44 aa 55 &&
echoid lookup 55
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -eq 1
'
@@ -45,7 +45,7 @@ test_expect_success 'lookup non-existing entry' '
{
echoid append 88 44 aa 55 &&
echoid lookup 33
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -lt 0
'
@@ -55,7 +55,7 @@ test_expect_success 'lookup with duplicates' '
echoid append 88 44 aa 55 &&
echoid append 88 44 aa 55 &&
echoid lookup 55
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -ge 2 &&
test "$n" -le 3
@@ -66,7 +66,7 @@ test_expect_success 'lookup non-existing entry with duplicates' '
echoid append 88 44 aa 55 &&
echoid append 88 44 aa 55 &&
echoid lookup 66
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -lt 0
'
@@ -81,7 +81,7 @@ test_expect_success 'lookup with almost duplicate values' '
echo "append $id1" &&
echo "append $id2" &&
echoid lookup 55
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -eq 0
'
@@ -90,7 +90,7 @@ test_expect_success 'lookup with single duplicate value' '
{
echoid append 55 55 &&
echoid lookup 55
- } | test-tool sha1-array >actual &&
+ } | test-tool oid-array >actual &&
n=$(cat actual) &&
test "$n" -ge 0 &&
test "$n" -le 1
diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh
index 7065a1b..1529155 100755
--- a/t/t0212-trace2-event.sh
+++ b/t/t0212-trace2-event.sh
@@ -199,6 +199,43 @@ test_expect_success JSON_PP 'event stream, list config' '
test_cmp expect actual
'
+# Test listing of all "interesting" environment variables.
+
+test_expect_success JSON_PP 'event stream, list env vars' '
+ test_when_finished "rm trace.event actual expect" &&
+ GIT_TRACE2_EVENT="$(pwd)/trace.event" \
+ GIT_TRACE2_ENV_VARS="A_VAR,OTHER_VAR,MISSING" \
+ A_VAR=1 OTHER_VAR="hello world" test-tool trace2 001return 0 &&
+ perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual &&
+ sed -e "s/^|//" >expect <<-EOF &&
+ |VAR1 = {
+ | "_SID0_":{
+ | "argv":[
+ | "_EXE_",
+ | "trace2",
+ | "001return",
+ | "0"
+ | ],
+ | "exit_code":0,
+ | "hierarchy":"trace2",
+ | "name":"trace2",
+ | "params":[
+ | {
+ | "param":"A_VAR",
+ | "value":"1"
+ | },
+ | {
+ | "param":"OTHER_VAR",
+ | "value":"hello world"
+ | }
+ | ],
+ | "version":"$V"
+ | }
+ |};
+ EOF
+ test_cmp expect actual
+'
+
test_expect_success JSON_PP 'basic trace2_data' '
test_when_finished "rm trace.event actual expect" &&
GIT_TRACE2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 &&
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
index 39f097e..48484cb 100755
--- a/t/t0300-credentials.sh
+++ b/t/t0300-credentials.sh
@@ -22,6 +22,11 @@ test_expect_success 'setup helper scripts' '
exit 0
EOF
+ write_script git-credential-quit <<-\EOF &&
+ . ./dump
+ echo quit=1
+ EOF
+
write_script git-credential-verbatim <<-\EOF &&
user=$1; shift
pass=$1; shift
@@ -35,43 +40,71 @@ test_expect_success 'setup helper scripts' '
test_expect_success 'credential_fill invokes helper' '
check fill "verbatim foo bar" <<-\EOF
+ protocol=http
+ host=example.com
--
+ protocol=http
+ host=example.com
username=foo
password=bar
--
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
EOF
'
test_expect_success 'credential_fill invokes multiple helpers' '
check fill useless "verbatim foo bar" <<-\EOF
+ protocol=http
+ host=example.com
--
+ protocol=http
+ host=example.com
username=foo
password=bar
--
useless: get
+ useless: protocol=http
+ useless: host=example.com
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
EOF
'
test_expect_success 'credential_fill stops when we get a full response' '
check fill "verbatim one two" "verbatim three four" <<-\EOF
+ protocol=http
+ host=example.com
--
+ protocol=http
+ host=example.com
username=one
password=two
--
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
EOF
'
test_expect_success 'credential_fill continues through partial response' '
check fill "verbatim one \"\"" "verbatim two three" <<-\EOF
+ protocol=http
+ host=example.com
--
+ protocol=http
+ host=example.com
username=two
password=three
--
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
verbatim: username=one
EOF
'
@@ -97,14 +130,20 @@ test_expect_success 'credential_fill passes along metadata' '
test_expect_success 'credential_approve calls all helpers' '
check approve useless "verbatim one two" <<-\EOF
+ protocol=http
+ host=example.com
username=foo
password=bar
--
--
useless: store
+ useless: protocol=http
+ useless: host=example.com
useless: username=foo
useless: password=bar
verbatim: store
+ verbatim: protocol=http
+ verbatim: host=example.com
verbatim: username=foo
verbatim: password=bar
EOF
@@ -112,6 +151,8 @@ test_expect_success 'credential_approve calls all helpers' '
test_expect_success 'do not bother storing password-less credential' '
check approve useless <<-\EOF
+ protocol=http
+ host=example.com
username=foo
--
--
@@ -121,14 +162,20 @@ test_expect_success 'do not bother storing password-less credential' '
test_expect_success 'credential_reject calls all helpers' '
check reject useless "verbatim one two" <<-\EOF
+ protocol=http
+ host=example.com
username=foo
password=bar
--
--
useless: erase
+ useless: protocol=http
+ useless: host=example.com
useless: username=foo
useless: password=bar
verbatim: erase
+ verbatim: protocol=http
+ verbatim: host=example.com
verbatim: username=foo
verbatim: password=bar
EOF
@@ -136,33 +183,49 @@ test_expect_success 'credential_reject calls all helpers' '
test_expect_success 'usernames can be preserved' '
check fill "verbatim \"\" three" <<-\EOF
+ protocol=http
+ host=example.com
username=one
--
+ protocol=http
+ host=example.com
username=one
password=three
--
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
verbatim: username=one
EOF
'
test_expect_success 'usernames can be overridden' '
check fill "verbatim two three" <<-\EOF
+ protocol=http
+ host=example.com
username=one
--
+ protocol=http
+ host=example.com
username=two
password=three
--
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
verbatim: username=one
EOF
'
test_expect_success 'do not bother completing already-full credential' '
check fill "verbatim three four" <<-\EOF
+ protocol=http
+ host=example.com
username=one
password=two
--
+ protocol=http
+ host=example.com
username=one
password=two
--
@@ -174,23 +237,31 @@ test_expect_success 'do not bother completing already-full credential' '
# askpass helper is run, we know the internal getpass is working.
test_expect_success 'empty helper list falls back to internal getpass' '
check fill <<-\EOF
+ protocol=http
+ host=example.com
--
+ protocol=http
+ host=example.com
username=askpass-username
password=askpass-password
--
- askpass: Username:
- askpass: Password:
+ askpass: Username for '\''http://example.com'\'':
+ askpass: Password for '\''http://askpass-username@example.com'\'':
EOF
'
test_expect_success 'internal getpass does not ask for known username' '
check fill <<-\EOF
+ protocol=http
+ host=example.com
username=foo
--
+ protocol=http
+ host=example.com
username=foo
password=askpass-password
--
- askpass: Password:
+ askpass: Password for '\''http://foo@example.com'\'':
EOF
'
@@ -202,7 +273,11 @@ HELPER="!f() {
test_expect_success 'respect configured credentials' '
test_config credential.helper "$HELPER" &&
check fill <<-\EOF
+ protocol=http
+ host=example.com
--
+ protocol=http
+ host=example.com
username=foo
password=bar
--
@@ -419,21 +494,119 @@ test_expect_success 'context uses urlmatch' '
test_expect_success 'helpers can abort the process' '
test_must_fail git \
- -c credential.helper="!f() { echo quit=1; }; f" \
+ -c credential.helper=quit \
-c credential.helper="verbatim foo bar" \
- credential fill >stdout &&
- test_must_be_empty stdout
+ credential fill >stdout 2>stderr <<-\EOF &&
+ protocol=http
+ host=example.com
+ EOF
+ test_must_be_empty stdout &&
+ cat >expect <<-\EOF &&
+ quit: get
+ quit: protocol=http
+ quit: host=example.com
+ fatal: credential helper '\''quit'\'' told us to quit
+ EOF
+ test_i18ncmp expect stderr
'
test_expect_success 'empty helper spec resets helper list' '
test_config credential.helper "verbatim file file" &&
check fill "" "verbatim cmdline cmdline" <<-\EOF
+ protocol=http
+ host=example.com
--
+ protocol=http
+ host=example.com
username=cmdline
password=cmdline
--
verbatim: get
+ verbatim: protocol=http
+ verbatim: host=example.com
+ EOF
+'
+
+test_expect_success 'url parser rejects embedded newlines' '
+ test_must_fail git credential fill 2>stderr <<-\EOF &&
+ url=https://one.example.com?%0ahost=two.example.com/
+ EOF
+ cat >expect <<-\EOF &&
+ warning: url contains a newline in its path component: https://one.example.com?%0ahost=two.example.com/
+ fatal: credential url cannot be parsed: https://one.example.com?%0ahost=two.example.com/
+ EOF
+ test_i18ncmp expect stderr
+'
+
+test_expect_success 'host-less URLs are parsed as empty host' '
+ check fill "verbatim foo bar" <<-\EOF
+ url=cert:///path/to/cert.pem
+ --
+ protocol=cert
+ host=
+ path=path/to/cert.pem
+ username=foo
+ password=bar
+ --
+ verbatim: get
+ verbatim: protocol=cert
+ verbatim: host=
+ verbatim: path=path/to/cert.pem
+ EOF
+'
+
+test_expect_success 'credential system refuses to work with missing host' '
+ test_must_fail git credential fill 2>stderr <<-\EOF &&
+ protocol=http
+ EOF
+ cat >expect <<-\EOF &&
+ fatal: refusing to work with credential missing host field
+ EOF
+ test_i18ncmp expect stderr
+'
+
+test_expect_success 'credential system refuses to work with missing protocol' '
+ test_must_fail git credential fill 2>stderr <<-\EOF &&
+ host=example.com
+ EOF
+ cat >expect <<-\EOF &&
+ fatal: refusing to work with credential missing protocol field
+ EOF
+ test_i18ncmp expect stderr
+'
+
+# usage: check_host_and_path <url> <expected-host> <expected-path>
+check_host_and_path () {
+ # we always parse the path component, but we need this to make sure it
+ # is passed to the helper
+ test_config credential.useHTTPPath true &&
+ check fill "verbatim user pass" <<-EOF
+ url=$1
+ --
+ protocol=https
+ host=$2
+ path=$3
+ username=user
+ password=pass
+ --
+ verbatim: get
+ verbatim: protocol=https
+ verbatim: host=$2
+ verbatim: path=$3
EOF
+}
+
+test_expect_success 'url parser handles bare query marker' '
+ check_host_and_path https://example.com?foo.git example.com ?foo.git
+'
+
+test_expect_success 'url parser handles bare fragment marker' '
+ check_host_and_path https://example.com#foo.git example.com "#foo.git"
+'
+
+test_expect_success 'url parser not confused by encoded markers' '
+ check_host_and_path https://example.com%23%3f%2f/foo.git \
+ "example.com#?/" foo.git
'
test_done
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index eb44baf..63223e1 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -233,18 +233,19 @@ test_expect_success 'read-tree --reset removes outside worktree' '
test_must_be_empty result
'
-test_expect_success 'print errors when failed to update worktree' '
+test_expect_success 'print warnings when some worktree updates disabled' '
echo sub >.git/info/sparse-checkout &&
git checkout -f init &&
mkdir sub &&
touch sub/added sub/addedtoo &&
- test_must_fail git checkout top 2>actual &&
+ # Use -q to suppress "Previous HEAD position" and "Head is now at" msgs
+ git checkout -q top 2>actual &&
cat >expected <<\EOF &&
-error: The following untracked working tree files would be overwritten by checkout:
+warning: The following paths were already present and thus not updated despite sparse patterns:
sub/added
sub/addedtoo
-Please move or remove them before you switch branches.
-Aborting
+
+After fixing the above paths, you may want to run `git sparse-checkout reapply`.
EOF
test_i18ncmp expected actual
'
diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh
index 44a9120..dee99ee 100755
--- a/t/t1091-sparse-checkout-builtin.sh
+++ b/t/t1091-sparse-checkout-builtin.sh
@@ -277,15 +277,23 @@ test_expect_success 'cone mode: add parent path' '
check_files repo a deep folder1
'
-test_expect_success 'revert to old sparse-checkout on bad update' '
+test_expect_success 'not-up-to-date does not block rest of sparsification' '
+ test_when_finished git -C repo sparse-checkout disable &&
test_when_finished git -C repo reset --hard &&
git -C repo sparse-checkout set deep &&
+
echo update >repo/deep/deeper2/a &&
cp repo/.git/info/sparse-checkout expect &&
- test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err &&
- test_i18ngrep "cannot set sparse-checkout patterns" err &&
- test_cmp repo/.git/info/sparse-checkout expect &&
- check_files repo/deep a deeper1 deeper2
+ test_write_lines "!/deep/*/" "/deep/deeper1/" >>expect &&
+
+ git -C repo sparse-checkout set deep/deeper1 2>err &&
+
+ test_i18ngrep "The following paths are not up to date" err &&
+ test_cmp expect repo/.git/info/sparse-checkout &&
+ check_files repo/deep a deeper1 deeper2 &&
+ check_files repo/deep/deeper1 a deepest &&
+ check_files repo/deep/deeper1/deepest a &&
+ check_files repo/deep/deeper2 a
'
test_expect_success 'revert to old sparse-checkout on empty update' '
@@ -315,19 +323,96 @@ test_expect_success '.gitignore should not warn about cone mode' '
test_i18ngrep ! "disabling cone patterns" err
'
-test_expect_success 'sparse-checkout (init|set|disable) fails with dirty status' '
+test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' '
git clone repo dirty &&
echo dirty >dirty/folder1/a &&
- test_must_fail git -C dirty sparse-checkout init &&
- test_must_fail git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
- test_must_fail git -C dirty sparse-checkout disable &&
+
+ git -C dirty sparse-checkout init 2>err &&
+ test_i18ngrep "warning.*The following paths are not up to date" err &&
+
+ git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&
+ test_i18ngrep "warning.*The following paths are not up to date" err &&
+ test_path_is_file dirty/folder1/a &&
+
+ git -C dirty sparse-checkout disable 2>err &&
+ test_must_be_empty err &&
+
git -C dirty reset --hard &&
git -C dirty sparse-checkout init &&
git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* &&
- git -C dirty sparse-checkout disable
+ test_path_is_missing dirty/folder1/a &&
+ git -C dirty sparse-checkout disable &&
+ test_path_is_file dirty/folder1/a
+'
+
+test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged status' '
+ git clone repo unmerged &&
+
+ cat >input <<-EOF &&
+ 0 0000000000000000000000000000000000000000 folder1/a
+ 100644 $(git -C unmerged rev-parse HEAD:folder1/a) 1 folder1/a
+ EOF
+ git -C unmerged update-index --index-info <input &&
+
+ git -C unmerged sparse-checkout init 2>err &&
+ test_i18ngrep "warning.*The following paths are unmerged" err &&
+
+ git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* 2>err &&
+ test_i18ngrep "warning.*The following paths are unmerged" err &&
+ test_path_is_file dirty/folder1/a &&
+
+ git -C unmerged sparse-checkout disable 2>err &&
+ test_i18ngrep "warning.*The following paths are unmerged" err &&
+
+ git -C unmerged reset --hard &&
+ git -C unmerged sparse-checkout init &&
+ git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* &&
+ git -C unmerged sparse-checkout disable
+'
+
+test_expect_success 'sparse-checkout reapply' '
+ git clone repo tweak &&
+
+ echo dirty >tweak/deep/deeper2/a &&
+
+ cat >input <<-EOF &&
+ 0 0000000000000000000000000000000000000000 folder1/a
+ 100644 $(git -C tweak rev-parse HEAD:folder1/a) 1 folder1/a
+ EOF
+ git -C tweak update-index --index-info <input &&
+
+ git -C tweak sparse-checkout init --cone 2>err &&
+ test_i18ngrep "warning.*The following paths are not up to date" err &&
+ test_i18ngrep "warning.*The following paths are unmerged" err &&
+
+ git -C tweak sparse-checkout set folder2 deep/deeper1 2>err &&
+ test_i18ngrep "warning.*The following paths are not up to date" err &&
+ test_i18ngrep "warning.*The following paths are unmerged" err &&
+
+ git -C tweak sparse-checkout reapply 2>err &&
+ test_i18ngrep "warning.*The following paths are not up to date" err &&
+ test_path_is_file tweak/deep/deeper2/a &&
+ test_i18ngrep "warning.*The following paths are unmerged" err &&
+ test_path_is_file tweak/folder1/a &&
+
+ git -C tweak checkout HEAD deep/deeper2/a &&
+ git -C tweak sparse-checkout reapply 2>err &&
+ test_i18ngrep ! "warning.*The following paths are not up to date" err &&
+ test_path_is_missing tweak/deep/deeper2/a &&
+ test_i18ngrep "warning.*The following paths are unmerged" err &&
+ test_path_is_file tweak/folder1/a &&
+
+ git -C tweak add folder1/a &&
+ git -C tweak sparse-checkout reapply 2>err &&
+ test_must_be_empty err &&
+ test_path_is_missing tweak/deep/deeper2/a &&
+ test_path_is_missing tweak/folder1/a &&
+
+ git -C tweak 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 &&
git -C repo -c core.ignoreCase=true sparse-checkout set folder1 &&
cat >expect <<-\EOF &&
diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh
index bbca7ef..2158315 100755
--- a/t/t2018-checkout-branch.sh
+++ b/t/t2018-checkout-branch.sh
@@ -238,4 +238,26 @@ test_expect_success 'checkout -b after clone --no-checkout does a checkout of HE
test_path_is_file dest/a.t
'
+test_expect_success 'checkout -b to a new branch preserves mergeable changes despite sparse-checkout' '
+ test_when_finished "
+ git reset --hard &&
+ git checkout branch1-scratch &&
+ test_might_fail git branch -D branch3 &&
+ git config core.sparseCheckout false &&
+ rm .git/info/sparse-checkout" &&
+
+ test_commit file2 &&
+
+ echo stuff >>file1 &&
+ echo file2 >.git/info/sparse-checkout &&
+ git config core.sparseCheckout true &&
+
+ CURHEAD=$(git rev-parse HEAD) &&
+ do_checkout branch3 $CURHEAD &&
+
+ echo file1 >expect &&
+ git diff --name-only >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh
index 69ffe86..52585ec 100755
--- a/t/t2402-worktree-list.sh
+++ b/t/t2402-worktree-list.sh
@@ -152,7 +152,7 @@ test_expect_success 'linked worktrees are sorted' '
'
test_expect_success 'worktree path when called in .git directory' '
- git worktree list >list1&&
+ git worktree list >list1 &&
git -C .git worktree list >list2 &&
test_cmp list1 list2
'
diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh
index 0aefada..ffdfb16 100755
--- a/t/t3000-ls-files-others.sh
+++ b/t/t3000-ls-files-others.sh
@@ -91,4 +91,125 @@ test_expect_success SYMLINKS 'ls-files --others with symlinked submodule' '
test_cmp expect actual
'
+test_expect_success 'setup nested pathspec search' '
+ test_create_repo nested &&
+ (
+ cd nested &&
+
+ mkdir -p partially_tracked/untracked_dir &&
+ > partially_tracked/content &&
+ > partially_tracked/untracked_dir/file &&
+
+ mkdir -p untracked/deep &&
+ > untracked/deep/path &&
+ > untracked/deep/foo.c &&
+
+ git add partially_tracked/content
+ )
+'
+
+test_expect_success 'ls-files -o --directory with single deep dir pathspec' '
+ (
+ cd nested &&
+
+ git ls-files -o --directory untracked/deep/ >actual &&
+
+ cat <<-EOF >expect &&
+ untracked/deep/
+ EOF
+
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'ls-files -o --directory with multiple dir pathspecs' '
+ (
+ cd nested &&
+
+ git ls-files -o --directory partially_tracked/ untracked/ >actual &&
+
+ cat <<-EOF >expect &&
+ partially_tracked/untracked_dir/
+ untracked/
+ EOF
+
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'ls-files -o --directory with mix dir/file pathspecs' '
+ (
+ cd nested &&
+
+ git ls-files -o --directory partially_tracked/ untracked/deep/path >actual &&
+
+ cat <<-EOF >expect &&
+ partially_tracked/untracked_dir/
+ untracked/deep/path
+ EOF
+
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'ls-files --o --directory with glob filetype match' '
+ (
+ cd nested &&
+
+ # globs kinda defeat --directory, but only for that pathspec
+ git ls-files --others --directory partially_tracked "untracked/*.c" >actual &&
+
+ cat <<-EOF >expect &&
+ partially_tracked/untracked_dir/
+ untracked/deep/foo.c
+ EOF
+
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'ls-files --o --directory with mix of tracked states' '
+ (
+ cd nested &&
+
+ # globs kinda defeat --directory, but only for that pathspec
+ git ls-files --others --directory partially_tracked/ "untracked/?*" >actual &&
+
+ cat <<-EOF >expect &&
+ partially_tracked/untracked_dir/
+ untracked/deep/
+ EOF
+
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'ls-files --o --directory with glob filetype match only' '
+ (
+ cd nested &&
+
+ git ls-files --others --directory "untracked/*.c" >actual &&
+
+ cat <<-EOF >expect &&
+ untracked/deep/foo.c
+ EOF
+
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'ls-files --o --directory to get immediate paths under one dir only' '
+ (
+ cd nested &&
+
+ git ls-files --others --directory "untracked/?*" >actual &&
+
+ cat <<-EOF >expect &&
+ untracked/deep/
+ EOF
+
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t3033-merge-toplevel.sh b/t/t3033-merge-toplevel.sh
index d314599..e29c284 100755
--- a/t/t3033-merge-toplevel.sh
+++ b/t/t3033-merge-toplevel.sh
@@ -142,6 +142,17 @@ test_expect_success 'refuse two-project merge by default' '
test_must_fail git merge five
'
+test_expect_success 'refuse two-project merge by default, quit before --autostash happens' '
+ t3033_reset &&
+ git reset --hard four &&
+ echo change >>one.t &&
+ git diff >expect &&
+ test_must_fail git merge --autostash five 2>err &&
+ test_i18ngrep ! "stash" err &&
+ git diff >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'two-project merge with --allow-unrelated-histories' '
t3033_reset &&
git reset --hard four &&
@@ -149,4 +160,15 @@ test_expect_success 'two-project merge with --allow-unrelated-histories' '
git diff --exit-code five
'
+test_expect_success 'two-project merge with --allow-unrelated-histories with --autostash' '
+ t3033_reset &&
+ git reset --hard four &&
+ echo change >>one.t &&
+ git diff one.t >expect &&
+ git merge --allow-unrelated-histories --autostash five 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ git diff one.t >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index bd808f8..e024cff 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -513,6 +513,16 @@ test_expect_success 'range-diff overrides diff.noprefix internally' '
git -c diff.noprefix=true range-diff HEAD^...
'
+test_expect_success 'basic with modified format.pretty with suffix' '
+ git -c format.pretty="format:commit %H%d%n" range-diff \
+ master..topic master..unmodified
+'
+
+test_expect_success 'basic with modified format.pretty without "commit "' '
+ git -c format.pretty="format:%H%n" range-diff \
+ master..topic master..unmodified
+'
+
test_expect_success 'range-diff compares notes by default' '
git notes add -m "topic note" topic &&
git notes add -m "unmodified note" unmodified &&
diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh
index a1ec501..6e03271 100755
--- a/t/t3402-rebase-merge.sh
+++ b/t/t3402-rebase-merge.sh
@@ -162,4 +162,81 @@ test_expect_success 'rebase --skip works with two conflicts in a row' '
git rebase --skip
'
+test_expect_success '--reapply-cherry-picks' '
+ git init repo &&
+
+ # O(1-10) -- O(1-11) -- O(0-10) master
+ # \
+ # -- O(1-11) -- O(1-12) otherbranch
+
+ printf "Line %d\n" $(test_seq 1 10) >repo/file.txt &&
+ git -C repo add file.txt &&
+ git -C repo commit -m "base commit" &&
+
+ printf "Line %d\n" $(test_seq 1 11) >repo/file.txt &&
+ git -C repo commit -a -m "add 11" &&
+
+ printf "Line %d\n" $(test_seq 0 10) >repo/file.txt &&
+ git -C repo commit -a -m "add 0 delete 11" &&
+
+ git -C repo checkout -b otherbranch HEAD^^ &&
+ printf "Line %d\n" $(test_seq 1 11) >repo/file.txt &&
+ git -C repo commit -a -m "add 11 in another branch" &&
+
+ printf "Line %d\n" $(test_seq 1 12) >repo/file.txt &&
+ git -C repo commit -a -m "add 12 in another branch" &&
+
+ # Regular rebase fails, because the 1-11 commit is deduplicated
+ test_must_fail git -C repo rebase --merge master 2> err &&
+ test_i18ngrep "error: could not apply.*add 12 in another branch" err &&
+ git -C repo rebase --abort &&
+
+ # With --reapply-cherry-picks, it works
+ git -C repo rebase --merge --reapply-cherry-picks master
+'
+
+test_expect_success '--reapply-cherry-picks refrains from reading unneeded blobs' '
+ git init server &&
+
+ # O(1-10) -- O(1-11) -- O(1-12) master
+ # \
+ # -- O(0-10) otherbranch
+
+ printf "Line %d\n" $(test_seq 1 10) >server/file.txt &&
+ git -C server add file.txt &&
+ git -C server commit -m "merge base" &&
+
+ printf "Line %d\n" $(test_seq 1 11) >server/file.txt &&
+ git -C server commit -a -m "add 11" &&
+
+ printf "Line %d\n" $(test_seq 1 12) >server/file.txt &&
+ git -C server commit -a -m "add 12" &&
+
+ git -C server checkout -b otherbranch HEAD^^ &&
+ printf "Line %d\n" $(test_seq 0 10) >server/file.txt &&
+ git -C server commit -a -m "add 0" &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+
+ git clone --filter=blob:none "file://$(pwd)/server" client &&
+ git -C client checkout origin/master &&
+ git -C client checkout origin/otherbranch &&
+
+ # Sanity check to ensure that the blobs from the merge base and "add
+ # 11" are missing
+ git -C client rev-list --objects --all --missing=print >missing_list &&
+ MERGE_BASE_BLOB=$(git -C server rev-parse master^^:file.txt) &&
+ ADD_11_BLOB=$(git -C server rev-parse master^:file.txt) &&
+ grep "[?]$MERGE_BASE_BLOB" missing_list &&
+ grep "[?]$ADD_11_BLOB" missing_list &&
+
+ git -C client rebase --merge --reapply-cherry-picks origin/master &&
+
+ # The blob from the merge base had to be fetched, but not "add 11"
+ git -C client rev-list --objects --all --missing=print >missing_list &&
+ ! grep "[?]$MERGE_BASE_BLOB" missing_list &&
+ grep "[?]$ADD_11_BLOB" missing_list
+'
+
test_done
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 61b76f3..927a4f4 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -89,22 +89,22 @@ test_expect_success 'GIT_REFLOG_ACTION' '
git checkout -b reflog-topic start &&
test_commit reflog-to-rebase &&
- git rebase --apply reflog-onto &&
+ git rebase reflog-onto &&
git log -g --format=%gs -3 >actual &&
cat >expect <<-\EOF &&
- rebase finished: returning to refs/heads/reflog-topic
- rebase: reflog-to-rebase
- rebase: checkout reflog-onto
+ rebase (finish): returning to refs/heads/reflog-topic
+ rebase (pick): reflog-to-rebase
+ rebase (start): checkout reflog-onto
EOF
test_cmp expect actual &&
git checkout -b reflog-prefix reflog-to-rebase &&
- GIT_REFLOG_ACTION=change-the-reflog git rebase --apply reflog-onto &&
+ GIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto &&
git log -g --format=%gs -3 >actual &&
cat >expect <<-\EOF &&
- rebase finished: returning to refs/heads/reflog-prefix
- change-the-reflog: reflog-to-rebase
- change-the-reflog: checkout reflog-onto
+ change-the-reflog (finish): returning to refs/heads/reflog-prefix
+ change-the-reflog (pick): reflog-to-rebase
+ change-the-reflog (start): checkout reflog-onto
EOF
test_cmp expect actual
'
diff --git a/t/t3417-rebase-whitespace-fix.sh b/t/t3417-rebase-whitespace-fix.sh
index e85cdc7..946e92f 100755
--- a/t/t3417-rebase-whitespace-fix.sh
+++ b/t/t3417-rebase-whitespace-fix.sh
@@ -52,7 +52,7 @@ test_expect_success 'blank line at end of file; extend at end of file' '
git commit --allow-empty -m "Initial empty commit" &&
git add file && git commit -m first &&
mv second file &&
- git add file && git commit -m second &&
+ git add file && git commit -m second &&
git rebase --whitespace=fix HEAD^^ &&
git diff --exit-code HEAD^:file expect-first &&
test_cmp expect-second file
@@ -118,7 +118,7 @@ test_expect_success 'at beginning of file' '
for i in 1 2 3 4 5; do
echo $i
done >> file &&
- git commit -m more file &&
+ git commit -m more file &&
git rebase --whitespace=fix HEAD^^ &&
test_cmp expect-beginning file
'
diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh
index d934583..1f32faa 100755
--- a/t/t3419-rebase-patch-id.sh
+++ b/t/t3419-rebase-patch-id.sh
@@ -4,15 +4,6 @@ test_description='git rebase - test patch id computation'
. ./test-lib.sh
-count () {
- i=0
- while test $i -lt $1
- do
- echo "$i"
- i=$(($i+1))
- done
-}
-
scramble () {
i=0
while read x
@@ -26,76 +17,55 @@ scramble () {
mv -f "$1.new" "$1"
}
-run () {
- echo \$ "$@"
- /usr/bin/time "$@" >/dev/null
-}
-
test_expect_success 'setup' '
git commit --allow-empty -m initial &&
git tag root
'
-do_tests () {
- nlines=$1 pr=${2-}
-
- test_expect_success $pr "setup: $nlines lines" "
- rm -f .gitattributes &&
- git checkout -q -f master &&
- git reset --hard root &&
- count $nlines >file &&
- git add file &&
- git commit -q -m initial &&
- git branch -f other &&
-
- scramble file &&
- git add file &&
- git commit -q -m 'change big file' &&
-
- git checkout -q other &&
- : >newfile &&
- git add newfile &&
- git commit -q -m 'add small file' &&
-
- git cherry-pick master >/dev/null 2>&1
- "
-
- test_debug "
- run git diff master^\!
- "
-
- test_expect_success $pr 'setup attributes' "
- echo 'file binary' >.gitattributes
- "
-
- test_debug "
- run git format-patch --stdout master &&
- run git format-patch --stdout --ignore-if-in-upstream master
- "
+test_expect_success 'setup: 500 lines' '
+ rm -f .gitattributes &&
+ git checkout -q -f master &&
+ git reset --hard root &&
+ test_seq 500 >file &&
+ git add file &&
+ git commit -q -m initial &&
+ git branch -f other &&
+
+ scramble file &&
+ git add file &&
+ git commit -q -m "change big file" &&
+
+ git checkout -q other &&
+ : >newfile &&
+ git add newfile &&
+ git commit -q -m "add small file" &&
+
+ git cherry-pick master >/dev/null 2>&1
+'
- test_expect_success $pr 'detect upstream patch' '
- git checkout -q master &&
- scramble file &&
- git add file &&
- git commit -q -m "change big file again" &&
- git checkout -q other^{} &&
- git rebase master &&
- git rev-list master...HEAD~ >revs &&
- test_must_be_empty revs
- '
+test_expect_success 'setup attributes' '
+ echo "file binary" >.gitattributes
+'
- test_expect_success $pr 'do not drop patch' '
- git branch -f squashed master &&
- git checkout -q -f squashed &&
- git reset -q --soft HEAD~2 &&
- git commit -q -m squashed &&
- git checkout -q other^{} &&
- test_must_fail git rebase squashed &&
- git rebase --quit
- '
-}
+test_expect_success 'detect upstream patch' '
+ git checkout -q master &&
+ scramble file &&
+ git add file &&
+ git commit -q -m "change big file again" &&
+ git checkout -q other^{} &&
+ git rebase master &&
+ git rev-list master...HEAD~ >revs &&
+ test_must_be_empty revs
+'
-do_tests 500
-do_tests 50000 EXPENSIVE
+test_expect_success 'do not drop patch' '
+ git branch -f squashed master &&
+ git checkout -q -f squashed &&
+ git reset -q --soft HEAD~2 &&
+ git commit -q -m squashed &&
+ git checkout -q other^{} &&
+ test_must_fail git rebase squashed &&
+ git rebase --quit
+'
test_done
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index b97ea62..ca33173 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -184,6 +184,26 @@ testrebase () {
git checkout feature-branch
'
+ test_expect_success "rebase$type: --quit" '
+ test_config rebase.autostash true &&
+ git reset --hard &&
+ git checkout -b rebased-feature-branch feature-branch &&
+ test_when_finished git branch -D rebased-feature-branch &&
+ echo dirty >>file3 &&
+ git diff >expect &&
+ test_must_fail git rebase$type related-onto-branch &&
+ test_path_is_file $dotest/autostash &&
+ test_path_is_missing file3 &&
+ git rebase --quit &&
+ test_when_finished git stash drop &&
+ test_path_is_missing $dotest/autostash &&
+ ! grep dirty file3 &&
+ git stash show -p >actual &&
+ test_cmp expect actual &&
+ git reset --hard &&
+ git checkout feature-branch
+ '
+
test_expect_success "rebase$type: non-conflicting rebase, conflicting stash" '
test_config rebase.autostash true &&
git reset --hard &&
diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh
index cf8dfd6..4a9204b 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -220,14 +220,13 @@ test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
shift
- test_expect_$result "rebase $* --keep-empty" "
+ test_expect_$result "rebase $* --no-keep-empty drops begin-empty commits" "
reset_rebase &&
- git rebase $* --keep-empty c l &&
- test_cmp_rev c HEAD~3 &&
- test_linear_range 'd k l' c..
+ git rebase $* --no-keep-empty c l &&
+ test_cmp_rev c HEAD~2 &&
+ test_linear_range 'd l' c..
"
}
-test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
@@ -242,7 +241,6 @@ test_run_rebase () {
test_linear_range 'd k l' j..
"
}
-test_run_rebase success --apply
test_run_rebase success -m
test_run_rebase success -i
test_have_prereq !REBASE_P || test_run_rebase success -p
diff --git a/t/t3424-rebase-empty.sh b/t/t3424-rebase-empty.sh
index e1e3051..5e1045a 100755
--- a/t/t3424-rebase-empty.sh
+++ b/t/t3424-rebase-empty.sh
@@ -123,6 +123,42 @@ test_expect_success 'rebase --interactive uses default of --empty=ask' '
test_cmp expect actual
'
+test_expect_success 'rebase --merge --empty=drop --keep-empty' '
+ git checkout -B testing localmods &&
+ git rebase --merge --empty=drop --keep-empty upstream &&
+
+ test_write_lines D C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge --empty=drop --no-keep-empty' '
+ git checkout -B testing localmods &&
+ git rebase --merge --empty=drop --no-keep-empty upstream &&
+
+ test_write_lines C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge --empty=keep --keep-empty' '
+ git checkout -B testing localmods &&
+ git rebase --merge --empty=keep --keep-empty upstream &&
+
+ test_write_lines D C2 C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase --merge --empty=keep --no-keep-empty' '
+ git checkout -B testing localmods &&
+ git rebase --merge --empty=keep --no-keep-empty upstream &&
+
+ test_write_lines C2 C B A >expect &&
+ git log --format=%s >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'rebase --merge does not leave state laying around' '
git checkout -B testing localmods~2 &&
git rebase --merge upstream &&
diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh
index 6c9d4a1..6f0452c 100755
--- a/t/t3432-rebase-fast-forward.sh
+++ b/t/t3432-rebase-fast-forward.sh
@@ -28,10 +28,12 @@ test_rebase_same_head () {
shift &&
cmp_f="$1" &&
shift &&
- test_rebase_same_head_ $status_n $what_n $cmp_n " --apply" "$*" &&
- test_rebase_same_head_ $status_f $what_f $cmp_f " --apply --no-ff" "$*"
- test_rebase_same_head_ $status_n $what_n $cmp_n " --merge" "$*" &&
- test_rebase_same_head_ $status_f $what_f $cmp_f " --merge --no-ff" "$*"
+ test_rebase_same_head_ $status_n $what_n $cmp_n 0 " --apply" "$*" &&
+ test_rebase_same_head_ $status_f $what_f $cmp_f 0 " --apply --no-ff" "$*"
+ test_rebase_same_head_ $status_n $what_n $cmp_n 0 " --merge" "$*" &&
+ test_rebase_same_head_ $status_f $what_f $cmp_f 0 " --merge --no-ff" "$*"
+ test_rebase_same_head_ $status_n $what_n $cmp_n 1 " --merge" "$*" &&
+ test_rebase_same_head_ $status_f $what_f $cmp_f 1 " --merge --no-ff" "$*"
}
test_rebase_same_head_ () {
@@ -41,9 +43,21 @@ test_rebase_same_head_ () {
shift &&
cmp="$1" &&
shift &&
+ abbreviate="$1" &&
+ shift &&
flag="$1"
shift &&
- test_expect_$status "git rebase$flag $* with $changes is $what with $cmp HEAD" "
+ if test $abbreviate -eq 1
+ then
+ msg="git rebase$flag $* (rebase.abbreviateCommands = true) with $changes is $what with $cmp HEAD"
+ else
+ msg="git rebase$flag $* with $changes is $what with $cmp HEAD"
+ fi &&
+ test_expect_$status "$msg" "
+ if test $abbreviate -eq 1
+ then
+ test_config rebase.abbreviateCommands true
+ fi &&
oldhead=\$(git rev-parse HEAD) &&
test_when_finished 'git reset --hard \$oldhead' &&
cp .git/logs/HEAD expect &&
diff --git a/t/t3435-rebase-gpg-sign.sh b/t/t3435-rebase-gpg-sign.sh
new file mode 100755
index 0000000..b47c59c
--- /dev/null
+++ b/t/t3435-rebase-gpg-sign.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+#
+# Copyright (c) 2020 Doan Tran Cong Danh
+#
+
+test_description='test rebase --[no-]gpg-sign'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY/lib-rebase.sh"
+. "$TEST_DIRECTORY/lib-gpg.sh"
+
+if ! test_have_prereq GPG
+then
+ skip_all='skip all test rebase --[no-]gpg-sign, gpg not available'
+ test_done
+fi
+
+test_rebase_gpg_sign () {
+ local must_fail= will=will fake_editor=
+ if test "x$1" = "x!"
+ then
+ must_fail=test_must_fail
+ will="won't"
+ shift
+ fi
+ conf=$1
+ shift
+ test_expect_success "rebase $* with commit.gpgsign=$conf $will sign commit" "
+ git reset two &&
+ git config commit.gpgsign $conf &&
+ set_fake_editor &&
+ FAKE_LINES='r 1 p 2' git rebase --force-rebase --root $* &&
+ $must_fail git verify-commit HEAD^ &&
+ $must_fail git verify-commit HEAD
+ "
+}
+
+test_expect_success 'setup' '
+ test_commit one &&
+ test_commit two &&
+ test_must_fail git verify-commit HEAD &&
+ test_must_fail git verify-commit HEAD^
+'
+
+test_expect_success 'setup: merge commit' '
+ test_commit fork-point &&
+ git switch -c side &&
+ test_commit three &&
+ git switch master &&
+ git merge --no-ff side &&
+ git tag merged
+'
+
+test_rebase_gpg_sign ! false
+test_rebase_gpg_sign true
+test_rebase_gpg_sign ! true --no-gpg-sign
+test_rebase_gpg_sign ! true --gpg-sign --no-gpg-sign
+test_rebase_gpg_sign false --no-gpg-sign --gpg-sign
+test_rebase_gpg_sign true -i
+test_rebase_gpg_sign ! true -i --no-gpg-sign
+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' '
+ git reset --hard merged &&
+ git config commit.gpgsign true &&
+ git rebase -p --no-gpg-sign --onto=one fork-point master &&
+ test_must_fail git verify-commit HEAD
+'
+
+test_done
diff --git a/t/t3514-cherry-pick-revert-gpg.sh b/t/t3514-cherry-pick-revert-gpg.sh
new file mode 100755
index 0000000..5b2e250
--- /dev/null
+++ b/t/t3514-cherry-pick-revert-gpg.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+#
+# Copyright (c) 2020 Doan Tran Cong Danh
+#
+
+test_description='test {cherry-pick,revert} --[no-]gpg-sign'
+
+. ./test-lib.sh
+. "$TEST_DIRECTORY/lib-gpg.sh"
+
+if ! test_have_prereq GPG
+then
+ skip_all='skip all test {cherry-pick,revert} --[no-]gpg-sign, gpg not available'
+ test_done
+fi
+
+test_gpg_sign () {
+ local must_fail= will=will fake_editor=
+ if test "x$1" = "x!"
+ then
+ must_fail=test_must_fail
+ will="won't"
+ shift
+ fi
+ conf=$1
+ cmd=$2
+ cmit=$3
+ shift 3
+ test_expect_success "$cmd $* $cmit with commit.gpgsign=$conf $will sign commit" "
+ git reset --hard tip &&
+ git config commit.gpgsign $conf &&
+ git $cmd $* $cmit &&
+ git rev-list tip.. >rev-list &&
+ $must_fail git verify-commit \$(cat rev-list)
+ "
+}
+
+test_expect_success 'setup' '
+ test_commit one &&
+ git switch -c side &&
+ test_commit side1 &&
+ test_commit side2 &&
+ git switch - &&
+ test_commit two &&
+ test_commit three &&
+ test_commit tip
+'
+
+test_gpg_sign ! false cherry-pick side
+test_gpg_sign ! false cherry-pick ..side
+test_gpg_sign true cherry-pick side
+test_gpg_sign true cherry-pick ..side
+test_gpg_sign ! true cherry-pick side --no-gpg-sign
+test_gpg_sign ! true cherry-pick ..side --no-gpg-sign
+test_gpg_sign ! true cherry-pick side --gpg-sign --no-gpg-sign
+test_gpg_sign ! true cherry-pick ..side --gpg-sign --no-gpg-sign
+test_gpg_sign false cherry-pick side --no-gpg-sign --gpg-sign
+test_gpg_sign false cherry-pick ..side --no-gpg-sign --gpg-sign
+test_gpg_sign true cherry-pick side --edit
+test_gpg_sign true cherry-pick ..side --edit
+test_gpg_sign ! true cherry-pick side --edit --no-gpg-sign
+test_gpg_sign ! true cherry-pick ..side --edit --no-gpg-sign
+test_gpg_sign ! true cherry-pick side --edit --gpg-sign --no-gpg-sign
+test_gpg_sign ! true cherry-pick ..side --edit --gpg-sign --no-gpg-sign
+test_gpg_sign false cherry-pick side --edit --no-gpg-sign --gpg-sign
+test_gpg_sign false cherry-pick ..side --edit --no-gpg-sign --gpg-sign
+
+test_gpg_sign ! false revert HEAD --edit
+test_gpg_sign ! false revert two.. --edit
+test_gpg_sign true revert HEAD --edit
+test_gpg_sign true revert two.. --edit
+test_gpg_sign ! true revert HEAD --edit --no-gpg-sign
+test_gpg_sign ! true revert two.. --edit --no-gpg-sign
+test_gpg_sign ! true revert HEAD --edit --gpg-sign --no-gpg-sign
+test_gpg_sign ! true revert two.. --edit --gpg-sign --no-gpg-sign
+test_gpg_sign false revert HEAD --edit --no-gpg-sign --gpg-sign
+test_gpg_sign false revert two.. --edit --no-gpg-sign --gpg-sign
+test_gpg_sign true revert HEAD --no-edit
+test_gpg_sign true revert two.. --no-edit
+test_gpg_sign ! true revert HEAD --no-edit --no-gpg-sign
+test_gpg_sign ! true revert two.. --no-edit --no-gpg-sign
+test_gpg_sign ! true revert HEAD --no-edit --gpg-sign --no-gpg-sign
+test_gpg_sign ! true revert two.. --no-edit --gpg-sign --no-gpg-sign
+test_gpg_sign false revert HEAD --no-edit --no-gpg-sign --gpg-sign
+
+test_done
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index 88bc7998..b7d4ba6 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -192,7 +192,7 @@ test_expect_success 'git add --refresh with pathspec' '
test_must_be_empty actual &&
git diff-files --name-only >actual &&
- ! grep bar actual&&
+ ! grep bar actual &&
grep baz actual
'
diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh
index 5bae6e5..b3d8bb7 100755
--- a/t/t3701-add-interactive.sh
+++ b/t/t3701-add-interactive.sh
@@ -780,7 +780,7 @@ test_expect_success 'add -p patch editing works with pathological context lines'
test_expect_success 'checkout -p works with pathological context lines' '
test_write_lines a a a a a a >a &&
git add a &&
- test_write_lines a b a b a b a b a b a > a&&
+ test_write_lines a b a b a b a b a b a >a &&
test_write_lines s n n y q | git checkout -p &&
test_write_lines a b a b a a b a b a >expect &&
test_cmp expect a
diff --git a/t/t3904-stash-patch.sh b/t/t3904-stash-patch.sh
index 9546b6f..accfe38 100755
--- a/t/t3904-stash-patch.sh
+++ b/t/t3904-stash-patch.sh
@@ -89,7 +89,7 @@ test_expect_success 'none of this moved HEAD' '
verify_saved_head
'
-test_expect_failure 'stash -p with split hunk' '
+test_expect_success 'stash -p with split hunk' '
git reset --hard &&
cat >test <<-\EOF &&
aaa
@@ -106,8 +106,8 @@ test_expect_failure 'stash -p with split hunk' '
ccc
EOF
printf "%s\n" s n y q |
- test_might_fail git stash -p 2>error &&
- ! test_must_be_empty error &&
+ git stash -p 2>error &&
+ test_must_be_empty error &&
grep "added line 1" test &&
! grep "added line 2" test
'
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index dde3f11..3f60f7d 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -95,6 +95,15 @@ test_expect_success setup '
git commit -m "update mode" &&
git checkout -f master &&
+ GIT_AUTHOR_DATE="2006-06-26 00:06:00 +0000" &&
+ GIT_COMMITTER_DATE="2006-06-26 00:06:00 +0000" &&
+ export GIT_AUTHOR_DATE GIT_COMMITTER_DATE &&
+ git checkout -b note initial &&
+ git update-index --chmod=+x file2 &&
+ git commit -m "update mode (file2)" &&
+ git notes add -m "note" &&
+ git checkout -f master &&
+
# Same merge as master, but with parents reversed. Hide it in a
# pseudo-ref to avoid impacting tests with --all.
commit=$(echo reverse |
@@ -398,6 +407,9 @@ diff --no-index --raw --no-abbrev dir2 dir
diff-tree --pretty --root --stat --compact-summary initial
diff-tree --pretty -R --root --stat --compact-summary initial
+diff-tree --pretty note
+diff-tree --pretty --notes note
+diff-tree --format=%N note
diff-tree --stat --compact-summary initial mode
diff-tree -R --stat --compact-summary initial mode
EOF
diff --git a/t/t4013/diff.diff-tree_--format=%N_note b/t/t4013/diff.diff-tree_--format=%N_note
new file mode 100644
index 0000000..93042ed
--- /dev/null
+++ b/t/t4013/diff.diff-tree_--format=%N_note
@@ -0,0 +1,6 @@
+$ git diff-tree --format=%N note
+note
+
+
+:100644 100755 01e79c32a8c99c557f0757da7cb6d65b3414466d 01e79c32a8c99c557f0757da7cb6d65b3414466d M file2
+$
diff --git a/t/t4013/diff.diff-tree_--pretty_--notes_note b/t/t4013/diff.diff-tree_--pretty_--notes_note
new file mode 100644
index 0000000..4d0bde6
--- /dev/null
+++ b/t/t4013/diff.diff-tree_--pretty_--notes_note
@@ -0,0 +1,12 @@
+$ git diff-tree --pretty --notes note
+commit a6f364368ca320bc5a92e18912e16fa6b3dff598
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ update mode (file2)
+
+Notes:
+ note
+
+:100644 100755 01e79c32a8c99c557f0757da7cb6d65b3414466d 01e79c32a8c99c557f0757da7cb6d65b3414466d M file2
+$
diff --git a/t/t4013/diff.diff-tree_--pretty_note b/t/t4013/diff.diff-tree_--pretty_note
new file mode 100644
index 0000000..1fa5967
--- /dev/null
+++ b/t/t4013/diff.diff-tree_--pretty_note
@@ -0,0 +1,9 @@
+$ git diff-tree --pretty note
+commit a6f364368ca320bc5a92e18912e16fa6b3dff598
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ update mode (file2)
+
+:100644 100755 01e79c32a8c99c557f0757da7cb6d65b3414466d 01e79c32a8c99c557f0757da7cb6d65b3414466d M file2
+$
diff --git a/t/t4013/diff.log_--decorate=full_--all b/t/t4013/diff.log_--decorate=full_--all
index 2afe91f..3f9b872 100644
--- a/t/t4013/diff.log_--decorate=full_--all
+++ b/t/t4013/diff.log_--decorate=full_--all
@@ -5,12 +5,27 @@ Date: Mon Jun 26 00:06:00 2006 +0000
update mode
+commit a6f364368ca320bc5a92e18912e16fa6b3dff598 (refs/heads/note)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ update mode (file2)
+
+Notes:
+ note
+
commit cd4e72fd96faed3f0ba949dc42967430374e2290 (refs/heads/rearrange)
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:06:00 2006 +0000
Rearranged lines in dir/sub
+commit cbacedd14cb8b89255a2c02b59e77a2e9a8021a0 (refs/notes/commits)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ Notes added by 'git notes add'
+
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD -> refs/heads/master)
Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
diff --git a/t/t4013/diff.log_--decorate_--all b/t/t4013/diff.log_--decorate_--all
index d0f308a..f5e20e1 100644
--- a/t/t4013/diff.log_--decorate_--all
+++ b/t/t4013/diff.log_--decorate_--all
@@ -5,12 +5,27 @@ Date: Mon Jun 26 00:06:00 2006 +0000
update mode
+commit a6f364368ca320bc5a92e18912e16fa6b3dff598 (note)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ update mode (file2)
+
+Notes:
+ note
+
commit cd4e72fd96faed3f0ba949dc42967430374e2290 (rearrange)
Author: A U Thor <author@example.com>
Date: Mon Jun 26 00:06:00 2006 +0000
Rearranged lines in dir/sub
+commit cbacedd14cb8b89255a2c02b59e77a2e9a8021a0 (refs/notes/commits)
+Author: A U Thor <author@example.com>
+Date: Mon Jun 26 00:06:00 2006 +0000
+
+ Notes added by 'git notes add'
+
commit 59d314ad6f356dd08601a4cd5e530381da3e3c64 (HEAD -> master)
Merge: 9a6d494 c7a2ab9
Author: A U Thor <author@example.com>
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index b653dd7..db7e733 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -1161,6 +1161,59 @@ test_expect_success 'format-patch wraps extremely long from-header (rfc2047)' '
'
cat >expect <<'EOF'
+From: Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar
+ Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo
+ Bar Foo Bar Foo Bar Foo Bar <author@example.com>
+EOF
+test_expect_success 'format-patch wraps extremely long from-header (non-ASCII without Q-encoding)' '
+ echo content >>file &&
+ git add file &&
+ GIT_AUTHOR_NAME="Foö Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar Foo Bar" \
+ git commit -m author-check &&
+ git format-patch --no-encode-email-headers --stdout -1 >patch &&
+ sed -n "/^From: /p; /^ /p; /^$/q" patch >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Subject: [PATCH] Foö
+EOF
+test_expect_success 'subject lines are unencoded with --no-encode-email-headers' '
+ echo content >>file &&
+ git add file &&
+ git commit -m "Foö" &&
+ git format-patch --no-encode-email-headers -1 --stdout >patch &&
+ grep ^Subject: patch >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Subject: [PATCH] Foö
+EOF
+test_expect_success 'subject lines are unencoded with format.encodeEmailHeaders=false' '
+ echo content >>file &&
+ git add file &&
+ git commit -m "Foö" &&
+ git config format.encodeEmailHeaders false &&
+ git format-patch -1 --stdout >patch &&
+ grep ^Subject: patch >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
+Subject: [PATCH] =?UTF-8?q?Fo=C3=B6?=
+EOF
+test_expect_success '--encode-email-headers overrides format.encodeEmailHeaders' '
+ echo content >>file &&
+ git add file &&
+ git commit -m "Foö" &&
+ git config format.encodeEmailHeaders false &&
+ git format-patch --encode-email-headers -1 --stdout >patch &&
+ grep ^Subject: patch >actual &&
+ test_cmp expect actual
+'
+
+cat >expect <<'EOF'
Subject: header with . in it
EOF
test_expect_success 'subject lines do not have 822 atom-quoting' '
diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh
index 4f4b541..0b78573 100755
--- a/t/t4057-diff-combined-paths.sh
+++ b/t/t4057-diff-combined-paths.sh
@@ -14,7 +14,7 @@ diffc_verify () {
test_expect_success 'trivial merge - combine-diff empty' '
for i in $(test_seq 1 9)
do
- echo $i >$i.txt &&
+ echo $i >$i.txt &&
git add $i.txt
done &&
git commit -m "init" &&
diff --git a/t/t4061-diff-indent.sh b/t/t4061-diff-indent.sh
index 2affd7a..0f7a6d9 100755
--- a/t/t4061-diff-indent.sh
+++ b/t/t4061-diff-indent.sh
@@ -17,7 +17,7 @@ compare_diff () {
# Compare blame output using the expectation for a diff as reference.
# Only look for the lines coming from non-boundary commits.
compare_blame () {
- sed -n -e "1,4d" -e "s/^\+//p" <"$1" >.tmp-1
+ sed -n -e "1,4d" -e "s/^+//p" <"$1" >.tmp-1
sed -ne "s/^[^^][^)]*) *//p" <"$2" >.tmp-2
test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
}
diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh
index 4831ad3..c1ed1c2 100755
--- a/t/t4067-diff-partial-clone.sh
+++ b/t/t4067-diff-partial-clone.sh
@@ -131,4 +131,52 @@ test_expect_success 'diff with rename detection batches blobs' '
test_line_count = 1 done_lines
'
+test_expect_success 'diff does not fetch anything if inexact rename detection is not needed' '
+ test_when_finished "rm -rf server client trace" &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ printf "b\nb\nb\nb\nb\n" >server/b &&
+ git -C server add a b &&
+ git -C server commit -m x &&
+ mv server/b server/c &&
+ git -C server add c &&
+ git -C server commit -a -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ # Ensure no fetches.
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD &&
+ ! test_path_exists trace
+'
+
+test_expect_success 'diff --break-rewrites fetches only if necessary, and batches blobs if it does' '
+ test_when_finished "rm -rf server client trace" &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ printf "b\nb\nb\nb\nb\n" >server/b &&
+ git -C server add a b &&
+ git -C server commit -m x &&
+ printf "c\nc\nc\nc\nc\n" >server/b &&
+ git -C server commit -a -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ # Ensure no fetches.
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD &&
+ ! test_path_exists trace &&
+
+ # But with --break-rewrites, ensure that there is exactly 1 negotiation
+ # by checking that there is only 1 "done" line sent. ("done" marks the
+ # end of negotiation.)
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --break-rewrites --raw -M HEAD^ HEAD &&
+ grep "git> done" trace >done_lines &&
+ test_line_count = 1 done_lines
+'
+
test_done
diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh
index 971a5a7..0ca2982 100755
--- a/t/t4124-apply-ws-rule.sh
+++ b/t/t4124-apply-ws-rule.sh
@@ -52,6 +52,13 @@ test_fix () {
# find touched lines
$DIFF file target | sed -n -e "s/^> //p" >fixed
+ # busybox's diff(1) doesn't output normal format
+ if ! test -s fixed
+ then
+ $DIFF -u file target |
+ grep -v '^+++ target' |
+ sed -ne "/^+/s/+//p" >fixed
+ fi
# the changed lines are all expected to change
fixed_cnt=$(wc -l <fixed)
diff --git a/t/t4150-am.sh b/t/t4150-am.sh
index cb45271..bda4586 100755
--- a/t/t4150-am.sh
+++ b/t/t4150-am.sh
@@ -166,7 +166,7 @@ test_expect_success setup '
test_tick &&
git commit -m third &&
- git format-patch --stdout first >patch2 &&
+ git format-patch --stdout first >patch2 &&
git checkout -b lorem &&
sed -n -e "11,\$p" msg >file &&
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
index 5eeb739..f1ea7d9 100755
--- a/t/t4202-log.sh
+++ b/t/t4202-log.sh
@@ -742,7 +742,23 @@ test_expect_success 'decorate-refs with glob' '
octopus-a (octopus-a)
reach
EOF
+ cat >expect.no-decorate <<-\EOF &&
+ Merge-tag-reach
+ Merge-tags-octopus-a-and-octopus-b
+ seventh
+ octopus-b
+ octopus-a
+ reach
+ EOF
+ git log -n6 --decorate=short --pretty="tformat:%f%d" \
+ --decorate-refs="heads/octopus*" >actual &&
+ test_cmp expect.decorate actual &&
git log -n6 --decorate=short --pretty="tformat:%f%d" \
+ --decorate-refs-exclude="heads/octopus*" \
+ --decorate-refs="heads/octopus*" >actual &&
+ test_cmp expect.no-decorate actual &&
+ git -c log.excludeDecoration="heads/octopus*" log \
+ -n6 --decorate=short --pretty="tformat:%f%d" \
--decorate-refs="heads/octopus*" >actual &&
test_cmp expect.decorate actual
'
@@ -787,6 +803,9 @@ test_expect_success 'decorate-refs-exclude with glob' '
EOF
git log -n6 --decorate=short --pretty="tformat:%f%d" \
--decorate-refs-exclude="heads/octopus*" >actual &&
+ test_cmp expect.decorate actual &&
+ git -c log.excludeDecoration="heads/octopus*" log \
+ -n6 --decorate=short --pretty="tformat:%f%d" >actual &&
test_cmp expect.decorate actual
'
@@ -801,6 +820,9 @@ test_expect_success 'decorate-refs-exclude without globs' '
EOF
git log -n6 --decorate=short --pretty="tformat:%f%d" \
--decorate-refs-exclude="tags/reach" >actual &&
+ test_cmp expect.decorate actual &&
+ git -c log.excludeDecoration="tags/reach" log \
+ -n6 --decorate=short --pretty="tformat:%f%d" >actual &&
test_cmp expect.decorate actual
'
@@ -816,11 +838,19 @@ test_expect_success 'multiple decorate-refs-exclude' '
git log -n6 --decorate=short --pretty="tformat:%f%d" \
--decorate-refs-exclude="heads/octopus*" \
--decorate-refs-exclude="tags/reach" >actual &&
+ test_cmp expect.decorate actual &&
+ git -c log.excludeDecoration="heads/octopus*" \
+ -c log.excludeDecoration="tags/reach" log \
+ -n6 --decorate=short --pretty="tformat:%f%d" >actual &&
+ test_cmp expect.decorate actual &&
+ git -c log.excludeDecoration="heads/octopus*" log \
+ --decorate-refs-exclude="tags/reach" \
+ -n6 --decorate=short --pretty="tformat:%f%d" >actual &&
test_cmp expect.decorate actual
'
test_expect_success 'decorate-refs and decorate-refs-exclude' '
- cat >expect.decorate <<-\EOF &&
+ cat >expect.no-decorate <<-\EOF &&
Merge-tag-reach (master)
Merge-tags-octopus-a-and-octopus-b
seventh
@@ -831,6 +861,21 @@ test_expect_success 'decorate-refs and decorate-refs-exclude' '
git log -n6 --decorate=short --pretty="tformat:%f%d" \
--decorate-refs="heads/*" \
--decorate-refs-exclude="heads/oc*" >actual &&
+ test_cmp expect.no-decorate actual
+'
+
+test_expect_success 'deocrate-refs and log.excludeDecoration' '
+ cat >expect.decorate <<-\EOF &&
+ Merge-tag-reach (master)
+ Merge-tags-octopus-a-and-octopus-b
+ seventh
+ octopus-b (octopus-b)
+ octopus-a (octopus-a)
+ reach (reach)
+ EOF
+ git -c log.excludeDecoration="heads/oc*" log \
+ --decorate-refs="heads/*" \
+ -n6 --decorate=short --pretty="tformat:%f%d" >actual &&
test_cmp expect.decorate actual
'
@@ -846,6 +891,10 @@ test_expect_success 'decorate-refs-exclude and simplify-by-decoration' '
git log -n6 --decorate=short --pretty="tformat:%f%d" \
--decorate-refs-exclude="*octopus*" \
--simplify-by-decoration >actual &&
+ test_cmp expect.decorate actual &&
+ git -c log.excludeDecoration="*octopus*" log \
+ -n6 --decorate=short --pretty="tformat:%f%d" \
+ --simplify-by-decoration >actual &&
test_cmp expect.decorate actual
'
diff --git a/t/t4208-log-magic-pathspec.sh b/t/t4208-log-magic-pathspec.sh
index 4c8f3b8..6cdbe47 100755
--- a/t/t4208-log-magic-pathspec.sh
+++ b/t/t4208-log-magic-pathspec.sh
@@ -55,6 +55,10 @@ test_expect_success '"git log -- :/a" should not be ambiguous' '
git log -- :/a
'
+test_expect_success '"git log :/any/path/" should not segfault' '
+ test_must_fail git log :/any/path/
+'
+
# This differs from the ":/a" check above in that :/in looks like a pathspec,
# but doesn't match an actual file.
test_expect_success '"git log :/in" should not be ambiguous' '
diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh
index 106eddb..3b76d2e 100755
--- a/t/t5003-archive-zip.sh
+++ b/t/t5003-archive-zip.sh
@@ -7,12 +7,12 @@ test_description='git archive --format=zip test'
SUBSTFORMAT=%H%n
test_lazy_prereq UNZIP_SYMLINKS '
- (
- mkdir unzip-symlinks &&
- cd unzip-symlinks &&
- "$GIT_UNZIP" "$TEST_DIRECTORY"/t5003/infozip-symlinks.zip &&
- test -h symlink
- )
+ "$GIT_UNZIP" "$TEST_DIRECTORY"/t5003/infozip-symlinks.zip &&
+ test -h symlink
+'
+
+test_lazy_prereq UNZIP_CONVERT '
+ "$GIT_UNZIP" -a "$TEST_DIRECTORY"/t5003/infozip-symlinks.zip
'
check_zip() {
@@ -39,33 +39,33 @@ check_zip() {
extracted=${dir_with_prefix}a
original=a
- test_expect_success UNZIP " extract ZIP archive with EOL conversion" '
+ test_expect_success UNZIP_CONVERT " extract ZIP archive with EOL conversion" '
(mkdir $dir && cd $dir && "$GIT_UNZIP" -a ../$zipfile)
'
- test_expect_success UNZIP " validate that text files are converted" "
+ test_expect_success UNZIP_CONVERT " validate that text files are converted" "
test_cmp_bin $extracted/text.cr $extracted/text.crlf &&
test_cmp_bin $extracted/text.cr $extracted/text.lf
"
- test_expect_success UNZIP " validate that binary files are unchanged" "
+ test_expect_success UNZIP_CONVERT " validate that binary files are unchanged" "
test_cmp_bin $original/binary.cr $extracted/binary.cr &&
test_cmp_bin $original/binary.crlf $extracted/binary.crlf &&
test_cmp_bin $original/binary.lf $extracted/binary.lf
"
- test_expect_success UNZIP " validate that diff files are converted" "
+ test_expect_success UNZIP_CONVERT " validate that diff files are converted" "
test_cmp_bin $extracted/diff.cr $extracted/diff.crlf &&
test_cmp_bin $extracted/diff.cr $extracted/diff.lf
"
- test_expect_success UNZIP " validate that -diff files are unchanged" "
+ test_expect_success UNZIP_CONVERT " validate that -diff files are unchanged" "
test_cmp_bin $original/nodiff.cr $extracted/nodiff.cr &&
test_cmp_bin $original/nodiff.crlf $extracted/nodiff.crlf &&
test_cmp_bin $original/nodiff.lf $extracted/nodiff.lf
"
- test_expect_success UNZIP " validate that custom diff is unchanged " "
+ test_expect_success UNZIP_CONVERT " validate that custom diff is unchanged " "
test_cmp_bin $original/custom.cr $extracted/custom.cr &&
test_cmp_bin $original/custom.crlf $extracted/custom.crlf &&
test_cmp_bin $original/custom.lf $extracted/custom.lf
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 43a7a66..030a722 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -42,10 +42,15 @@ test_expect_success 'setup' '
EOF
'
-test_expect_success 'write midx with no packs' '
- test_when_finished rm -f pack/multi-pack-index &&
- git multi-pack-index --object-dir=. write &&
- midx_read_expect 0 0 4 .
+test_expect_success "don't write midx with no packs" '
+ test_must_fail git multi-pack-index --object-dir=. write &&
+ test_path_is_missing pack/multi-pack-index
+'
+
+test_expect_success "Warn if a midx contains no oid" '
+ cp "$TEST_DIRECTORY"/t5319/no-objects.midx $objdir/pack/multi-pack-index &&
+ test_must_fail git multi-pack-index verify &&
+ rm $objdir/pack/multi-pack-index
'
generate_objects () {
@@ -521,10 +526,10 @@ test_expect_success 'repack with minimum size does not alter existing packs' '
cd dup &&
rm -rf .git/objects/pack &&
mv .git/objects/pack-backup .git/objects/pack &&
- touch -m -t 201901010000 .git/objects/pack/pack-D* &&
- touch -m -t 201901010001 .git/objects/pack/pack-C* &&
- touch -m -t 201901010002 .git/objects/pack/pack-B* &&
- touch -m -t 201901010003 .git/objects/pack/pack-A* &&
+ test-tool chmtime =-5 .git/objects/pack/pack-D* &&
+ test-tool chmtime =-4 .git/objects/pack/pack-C* &&
+ test-tool chmtime =-3 .git/objects/pack/pack-B* &&
+ test-tool chmtime =-2 .git/objects/pack/pack-A* &&
ls .git/objects/pack >expect &&
MINSIZE=$(test-tool path-utils file-size .git/objects/pack/*pack | sort -n | head -n 1) &&
git multi-pack-index repack --batch-size=$MINSIZE &&
diff --git a/t/t5319/no-objects.midx b/t/t5319/no-objects.midx
new file mode 100644
index 0000000..e466b8e
--- /dev/null
+++ b/t/t5319/no-objects.midx
Binary files differ
diff --git a/t/t5322-pack-objects-sparse.sh b/t/t5322-pack-objects-sparse.sh
index 7124b55..a581eaf 100755
--- a/t/t5322-pack-objects-sparse.sh
+++ b/t/t5322-pack-objects-sparse.sh
@@ -105,14 +105,16 @@ test_expect_success 'non-sparse pack-objects' '
test_cmp required_objects.txt nonsparse_required_objects.txt
'
+# --sparse is enabled by default by pack.useSparse
test_expect_success 'sparse pack-objects' '
+ GIT_TEST_PACK_SPARSE=-1 &&
git rev-parse \
topic1 \
topic1^{tree} \
topic1:f3 \
topic1:f3/f4 \
topic1:f3/f4/data.txt | sort >expect_sparse_objects.txt &&
- git pack-objects --stdout --revs --sparse <packinput.txt >sparse.pack &&
+ git pack-objects --stdout --revs <packinput.txt >sparse.pack &&
git index-pack -o sparse.idx sparse.pack &&
git show-index <sparse.idx | awk "{print \$2}" >sparse_objects.txt &&
test_cmp expect_sparse_objects.txt sparse_objects.txt
diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh
index 53b2e6b..b8b208f 100755
--- a/t/t5324-split-commit-graph.sh
+++ b/t/t5324-split-commit-graph.sh
@@ -210,8 +210,14 @@ test_expect_success 'test merge stragety constants' '
git config core.commitGraph true &&
test_line_count = 2 $graphdir/commit-graph-chain &&
test_commit 15 &&
- git commit-graph write --reachable --split --size-multiple=10 --expire-time=1980-01-01 &&
+ touch $graphdir/to-delete.graph $graphdir/to-keep.graph &&
+ test-tool chmtime =1546362000 $graphdir/to-delete.graph &&
+ test-tool chmtime =1546362001 $graphdir/to-keep.graph &&
+ git commit-graph write --reachable --split --size-multiple=10 \
+ --expire-time="2019-01-01 12:00 -05:00" &&
test_line_count = 1 $graphdir/commit-graph-chain &&
+ test_path_is_missing $graphdir/to-delete.graph &&
+ test_path_is_file $graphdir/to-keep.graph &&
ls $graphdir/graph-*.graph >graph-files &&
test_line_count = 3 graph-files
) &&
diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh
index 645b4c7..a32efe2 100755
--- a/t/t5504-fetch-receive-strict.sh
+++ b/t/t5504-fetch-receive-strict.sh
@@ -65,6 +65,7 @@ test_expect_success 'fetch with transfer.fsckobjects' '
cat >exp <<EOF
To dst
! refs/heads/master:refs/heads/test [remote rejected] (missing necessary objects)
+Done
EOF
test_expect_success 'push without strict' '
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index 04b3540..e98c3a0 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -4,6 +4,14 @@ test_description='git ls-remote'
. ./test-lib.sh
+generate_references () {
+ for ref
+ do
+ oid=$(git rev-parse "$ref") &&
+ printf '%s\t%s\n' "$oid" "$ref" || return 1
+ done
+}
+
test_expect_success setup '
>file &&
git add file &&
@@ -13,11 +21,11 @@ test_expect_success setup '
git tag mark1.1 &&
git tag mark1.2 &&
git tag mark1.10 &&
- git show-ref --tags -d | sed -e "s/ / /" >expected.tag &&
- (
- echo "$(git rev-parse HEAD) HEAD" &&
- git show-ref -d | sed -e "s/ / /"
- ) >expected.all &&
+ git show-ref --tags -d >expected.tag.raw &&
+ sed -e "s/ / /" expected.tag.raw >expected.tag &&
+ generate_references HEAD >expected.all &&
+ git show-ref -d >refs &&
+ sed -e "s/ / /" refs >>expected.all &&
git remote add self "$(pwd)/.git"
'
@@ -43,34 +51,31 @@ test_expect_success 'ls-remote self' '
'
test_expect_success 'ls-remote --sort="version:refname" --tags self' '
- cat >expect <<-EOF &&
- $(git rev-parse mark) refs/tags/mark
- $(git rev-parse mark1.1) refs/tags/mark1.1
- $(git rev-parse mark1.2) refs/tags/mark1.2
- $(git rev-parse mark1.10) refs/tags/mark1.10
- EOF
+ generate_references \
+ refs/tags/mark \
+ refs/tags/mark1.1 \
+ refs/tags/mark1.2 \
+ refs/tags/mark1.10 >expect &&
git ls-remote --sort="version:refname" --tags self >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote --sort="-version:refname" --tags self' '
- cat >expect <<-EOF &&
- $(git rev-parse mark1.10) refs/tags/mark1.10
- $(git rev-parse mark1.2) refs/tags/mark1.2
- $(git rev-parse mark1.1) refs/tags/mark1.1
- $(git rev-parse mark) refs/tags/mark
- EOF
+ generate_references \
+ refs/tags/mark1.10 \
+ refs/tags/mark1.2 \
+ refs/tags/mark1.1 \
+ refs/tags/mark >expect &&
git ls-remote --sort="-version:refname" --tags self >actual &&
test_cmp expect actual
'
test_expect_success 'ls-remote --sort="-refname" --tags self' '
- cat >expect <<-EOF &&
- $(git rev-parse mark1.2) refs/tags/mark1.2
- $(git rev-parse mark1.10) refs/tags/mark1.10
- $(git rev-parse mark1.1) refs/tags/mark1.1
- $(git rev-parse mark) refs/tags/mark
- EOF
+ generate_references \
+ refs/tags/mark1.2 \
+ refs/tags/mark1.10 \
+ refs/tags/mark1.1 \
+ refs/tags/mark >expect &&
git ls-remote --sort="-refname" --tags self >actual &&
test_cmp expect actual
'
@@ -92,7 +97,7 @@ test_expect_success 'use "origin" when no remote specified' '
test_expect_success 'suppress "From <url>" with -q' '
git ls-remote -q 2>actual_err &&
- test_must_fail test_cmp exp_err actual_err
+ ! test_cmp exp_err actual_err
'
test_expect_success 'use branch.<name>.remote if possible' '
@@ -180,8 +185,8 @@ do
test_config $configsection.hiderefs refs/tags &&
git ls-remote . >actual &&
test_unconfig $configsection.hiderefs &&
- git ls-remote . |
- sed -e "/ refs\/tags\//d" >expect &&
+ git ls-remote . >expect.raw &&
+ sed -e "/ refs\/tags\//d" expect.raw >expect &&
test_cmp expect actual
'
@@ -212,17 +217,18 @@ test_expect_success 'protocol v2 supports hiderefs' '
test_expect_success 'ls-remote --symref' '
git fetch origin &&
- cat >expect <<-EOF &&
- ref: refs/heads/master HEAD
- $(git rev-parse HEAD) HEAD
- $(git rev-parse refs/heads/master) refs/heads/master
- $(git rev-parse HEAD) refs/remotes/origin/HEAD
- $(git rev-parse refs/remotes/origin/master) refs/remotes/origin/master
- $(git rev-parse refs/tags/mark) refs/tags/mark
- $(git rev-parse refs/tags/mark1.1) refs/tags/mark1.1
- $(git rev-parse refs/tags/mark1.10) refs/tags/mark1.10
- $(git rev-parse refs/tags/mark1.2) refs/tags/mark1.2
- EOF
+ echo "ref: refs/heads/master HEAD" >expect &&
+ generate_references \
+ HEAD \
+ refs/heads/master >>expect &&
+ oid=$(git rev-parse HEAD) &&
+ echo "$oid refs/remotes/origin/HEAD" >>expect &&
+ generate_references \
+ refs/remotes/origin/master \
+ refs/tags/mark \
+ refs/tags/mark1.1 \
+ refs/tags/mark1.10 \
+ refs/tags/mark1.2 >>expect &&
# Protocol v2 supports sending symrefs for refs other than HEAD, so use
# protocol v0 here.
GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref >actual &&
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 9ff041a..9c6218f 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1066,6 +1066,7 @@ test_expect_success 'push --porcelain rejected' '
echo >.git/foo "To testrepo" &&
echo >>.git/foo "! refs/heads/master:refs/heads/master [remote rejected] (branch is currently checked out)" &&
+ echo >>.git/foo "Done" &&
test_must_fail git push >.git/bar --porcelain testrepo refs/heads/master:refs/heads/master &&
test_cmp .git/foo .git/bar
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 2f86fca..37535d6 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -10,11 +10,13 @@ modify () {
}
test_pull_autostash () {
+ expect_parent_num="$1" &&
+ shift &&
git reset --hard before-rebase &&
echo dirty >new_file &&
git add new_file &&
git pull "$@" . copy &&
- test_cmp_rev HEAD^ copy &&
+ test_cmp_rev HEAD^"$expect_parent_num" copy &&
echo dirty >expect &&
test_cmp expect new_file &&
echo "modified again" >expect &&
@@ -26,7 +28,7 @@ test_pull_autostash_fail () {
echo dirty >new_file &&
git add new_file &&
test_must_fail git pull "$@" . copy 2>err &&
- test_i18ngrep "uncommitted changes." err
+ test_i18ngrep "\(uncommitted changes.\)\|\(overwritten by merge:\)" err
}
test_expect_success setup '
@@ -369,22 +371,22 @@ test_expect_success '--rebase fails with multiple branches' '
test_expect_success 'pull --rebase succeeds with dirty working directory and rebase.autostash set' '
test_config rebase.autostash true &&
- test_pull_autostash --rebase
+ test_pull_autostash 1 --rebase
'
test_expect_success 'pull --rebase --autostash & rebase.autostash=true' '
test_config rebase.autostash true &&
- test_pull_autostash --rebase --autostash
+ test_pull_autostash 1 --rebase --autostash
'
test_expect_success 'pull --rebase --autostash & rebase.autostash=false' '
test_config rebase.autostash false &&
- test_pull_autostash --rebase --autostash
+ test_pull_autostash 1 --rebase --autostash
'
test_expect_success 'pull --rebase --autostash & rebase.autostash unset' '
test_unconfig rebase.autostash &&
- test_pull_autostash --rebase --autostash
+ test_pull_autostash 1 --rebase --autostash
'
test_expect_success 'pull --rebase --no-autostash & rebase.autostash=true' '
@@ -402,13 +404,40 @@ test_expect_success 'pull --rebase --no-autostash & rebase.autostash unset' '
test_pull_autostash_fail --rebase --no-autostash
'
-for i in --autostash --no-autostash
-do
- test_expect_success "pull $i (without --rebase) is illegal" '
- test_must_fail git pull $i . copy 2>err &&
- test_i18ngrep "only valid with --rebase" err
- '
-done
+test_expect_success 'pull succeeds with dirty working directory and merge.autostash set' '
+ test_config merge.autostash true &&
+ test_pull_autostash 2
+'
+
+test_expect_success 'pull --autostash & merge.autostash=true' '
+ test_config merge.autostash true &&
+ test_pull_autostash 2 --autostash
+'
+
+test_expect_success 'pull --autostash & merge.autostash=false' '
+ test_config merge.autostash false &&
+ test_pull_autostash 2 --autostash
+'
+
+test_expect_success 'pull --autostash & merge.autostash unset' '
+ test_unconfig merge.autostash &&
+ test_pull_autostash 2 --autostash
+'
+
+test_expect_success 'pull --no-autostash & merge.autostash=true' '
+ test_config merge.autostash true &&
+ test_pull_autostash_fail --no-autostash
+'
+
+test_expect_success 'pull --no-autostash & merge.autostash=false' '
+ test_config merge.autostash false &&
+ test_pull_autostash_fail --no-autostash
+'
+
+test_expect_success 'pull --no-autostash & merge.autostash unset' '
+ test_unconfig merge.autostash &&
+ test_pull_autostash_fail --no-autostash
+'
test_expect_success 'pull.rebase' '
git reset --hard before-rebase &&
@@ -422,7 +451,7 @@ test_expect_success 'pull.rebase' '
test_expect_success 'pull --autostash & pull.rebase=true' '
test_config pull.rebase true &&
- test_pull_autostash --autostash
+ test_pull_autostash 1 --autostash
'
test_expect_success 'pull --no-autostash & pull.rebase=true' '
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 4f681db..b57209c 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -131,7 +131,7 @@ test_expect_success 'fetch that requires changes in .git/shallow is filtered' '
git init notshallow &&
(
cd notshallow &&
- git fetch ../shallow/.git refs/heads/*:refs/remotes/shallow/*&&
+ git fetch ../shallow/.git refs/heads/*:refs/remotes/shallow/* &&
git for-each-ref --format="%(refname)" >actual.refs &&
cat <<EOF >expect.refs &&
refs/remotes/shallow/no-shallow
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 23be8ce..afc680d 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -177,6 +177,9 @@ test_expect_success 'push (chunked)' '
test $HEAD = $(git rev-parse --verify HEAD))
'
+## References of remote: atomic1(1) master(2) collateral(2) other(2)
+## References of local : atomic2(2) master(1) collateral(3) other(2) collateral1(3) atomic(1)
+## Atomic push : master(1) collateral(3) atomic(1)
test_expect_success 'push --atomic also prevents branch creation, reports collateral' '
# Setup upstream repo - empty for now
d=$HTTPD_DOCUMENT_ROOT_PATH/atomic-branches.git &&
@@ -189,7 +192,8 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
test_commit atomic2 &&
git branch collateral &&
git branch other &&
- git push "$up" master collateral other &&
+ git push "$up" atomic1 master collateral other &&
+ git tag -d atomic1 &&
# collateral is a valid push, but should be failed by atomic push
git checkout collateral &&
@@ -224,7 +228,11 @@ test_expect_success 'push --atomic also prevents branch creation, reports collat
# the collateral failure refs should be indicated to the user
grep "^ ! .*rejected.* atomic -> atomic .*atomic push failed" output &&
- grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output
+ grep "^ ! .*rejected.* collateral -> collateral .*atomic push failed" output &&
+
+ # never report what we do not push
+ ! grep "^ ! .*rejected.* atomic1 " output &&
+ ! grep "^ ! .*rejected.* other " output
'
test_expect_success 'push --atomic fails on server-side errors' '
diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
index 7079bcf..620c30d 100755
--- a/t/t5543-atomic-push.sh
+++ b/t/t5543-atomic-push.sh
@@ -27,6 +27,12 @@ test_refs () {
test_cmp expect actual
}
+fmt_status_report () {
+ sed -n \
+ -e "/^To / { s/ */ /g; p; }" \
+ -e "/^ ! / { s/ */ /g; p; }"
+}
+
test_expect_success 'atomic push works for a single branch' '
mk_repo_pair &&
(
@@ -191,4 +197,87 @@ test_expect_success 'atomic push is not advertised if configured' '
test_refs master HEAD@{1}
'
+# References in upstream : master(1) one(1) foo(1)
+# References in workbench: master(2) foo(1) two(2) bar(2)
+# Atomic push : master(2) two(2) bar(2)
+test_expect_success 'atomic push reports (reject by update hook)' '
+ mk_repo_pair &&
+ (
+ cd workbench &&
+ test_commit one &&
+ git branch foo &&
+ git push up master one foo &&
+ git tag -d one
+ ) &&
+ (
+ mkdir -p upstream/.git/hooks &&
+ cat >upstream/.git/hooks/update <<-EOF &&
+ #!/bin/sh
+
+ if test "\$1" = "refs/heads/bar"
+ then
+ echo >&2 "Pusing to branch bar is prohibited"
+ exit 1
+ fi
+ EOF
+ chmod a+x upstream/.git/hooks/update
+ ) &&
+ (
+ cd workbench &&
+ test_commit two &&
+ git branch bar
+ ) &&
+ test_must_fail git -C workbench \
+ push --atomic up master two bar >out 2>&1 &&
+ fmt_status_report <out >actual &&
+ cat >expect <<-EOF &&
+ To ../upstream
+ ! [remote rejected] master -> master (atomic push failure)
+ ! [remote rejected] two -> two (atomic push failure)
+ ! [remote rejected] bar -> bar (hook declined)
+ EOF
+ test_cmp expect actual
+'
+
+# References in upstream : master(1) one(1) foo(1)
+# References in workbench: master(2) foo(1) two(2) bar(2)
+test_expect_success 'atomic push reports (mirror, but reject by update hook)' '
+ (
+ cd workbench &&
+ git remote remove up &&
+ git remote add up ../upstream
+ ) &&
+ test_must_fail git -C workbench \
+ push --atomic --mirror up >out 2>&1 &&
+ fmt_status_report <out >actual &&
+ cat >expect <<-EOF &&
+ To ../upstream
+ ! [remote rejected] master -> master (atomic push failure)
+ ! [remote rejected] one (atomic push failure)
+ ! [remote rejected] bar -> bar (hook declined)
+ ! [remote rejected] two -> two (atomic push failure)
+ EOF
+ test_cmp expect actual
+'
+
+# References in upstream : master(2) one(1) foo(1)
+# References in workbench: master(1) foo(1) two(2) bar(2)
+test_expect_success 'atomic push reports (reject by non-ff)' '
+ rm upstream/.git/hooks/update &&
+ (
+ cd workbench &&
+ git push up master &&
+ git reset --hard HEAD^
+ ) &&
+ test_must_fail git -C workbench \
+ push --atomic up master foo bar >out 2>&1 &&
+ fmt_status_report <out >actual &&
+ cat >expect <<-EOF &&
+ To ../upstream
+ ! [rejected] master -> master (non-fast-forward)
+ ! [rejected] bar -> bar (atomic push failed)
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t5548-push-porcelain.sh b/t/t5548-push-porcelain.sh
new file mode 100755
index 0000000..1b19b3e
--- /dev/null
+++ b/t/t5548-push-porcelain.sh
@@ -0,0 +1,279 @@
+#!/bin/sh
+#
+# Copyright (c) 2020 Jiang Xin
+#
+test_description='Test git push porcelain output'
+
+. ./test-lib.sh
+
+# Create commits in <repo> and assign each commit's oid to shell variables
+# given in the arguments (A, B, and C). E.g.:
+#
+# create_commits_in <repo> A B C
+#
+# NOTE: Never calling this function from a subshell since variable
+# assignments will disappear when subshell exits.
+create_commits_in () {
+ repo="$1" &&
+ if ! parent=$(git -C "$repo" rev-parse HEAD^{} --)
+ then
+ parent=
+ fi &&
+ T=$(git -C "$repo" write-tree) &&
+ shift &&
+ while test $# -gt 0
+ do
+ name=$1 &&
+ test_tick &&
+ if test -z "$parent"
+ then
+ oid=$(echo $name | git -C "$repo" commit-tree $T)
+ else
+ oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T)
+ fi &&
+ eval $name=$oid &&
+ parent=$oid &&
+ shift ||
+ return 1
+ done &&
+ git -C "$repo" update-ref refs/heads/master $oid
+}
+
+# Format the output of git-push, git-show-ref and other commands to make a
+# user-friendly and stable text. We can easily prepare the expect text
+# without having to worry about future changes of the commit ID and spaces
+# of the output.
+make_user_friendly_and_stable_output () {
+ sed \
+ -e "s/ *\$//" \
+ -e "s/ */ /g" \
+ -e "s/ / /g" \
+ -e "s/$A/<COMMIT-A>/g" \
+ -e "s/$B/<COMMIT-B>/g" \
+ -e "s/$ZERO_OID/<ZERO-OID>/g" \
+ -e "s/$(echo $A | cut -c1-7)[0-9a-f]*/<OID-A>/g" \
+ -e "s/$(echo $B | cut -c1-7)[0-9a-f]*/<OID-B>/g" \
+ -e "s#To $URL_PREFIX/upstream.git#To <URL/of/upstream.git>#"
+}
+
+setup_upstream_and_workbench () {
+ # Upstream after setup : master(B) foo(A) bar(A) baz(A)
+ # Workbench after setup : master(A)
+ test_expect_success "setup upstream repository and workbench" '
+ rm -rf upstream.git workbench &&
+ git init --bare upstream.git &&
+ git init workbench &&
+ create_commits_in workbench A B &&
+ (
+ cd workbench &&
+ # Try to make a stable fixed width for abbreviated commit ID,
+ # this fixed-width oid will be replaced with "<OID>".
+ git config core.abbrev 7 &&
+ git remote add origin ../upstream.git &&
+ git update-ref refs/heads/master $A &&
+ git push origin \
+ $B:refs/heads/master \
+ $A:refs/heads/foo \
+ $A:refs/heads/bar \
+ $A:refs/heads/baz
+ ) &&
+ git -C "workbench" config advice.pushUpdateRejected false &&
+ upstream=upstream.git
+ '
+}
+
+run_git_push_porcelain_output_test() {
+ case $1 in
+ http)
+ PROTOCOL="HTTP protocol"
+ URL_PREFIX="http://.*"
+ ;;
+ file)
+ PROTOCOL="builtin protocol"
+ URL_PREFIX="\.\."
+ ;;
+ esac
+
+ # Refs of upstream : master(B) foo(A) bar(A) baz(A)
+ # Refs of workbench: master(A) baz(A) next(A)
+ # git-push : master(A) NULL (B) baz(A) next(A)
+ test_expect_success "porcelain output of successful git-push ($PROTOCOL)" '
+ (
+ cd workbench &&
+ git update-ref refs/heads/master $A &&
+ git update-ref refs/heads/baz $A &&
+ git update-ref refs/heads/next $A &&
+ git push --porcelain --force origin \
+ master \
+ :refs/heads/foo \
+ $B:bar \
+ baz \
+ next
+ ) >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ To <URL/of/upstream.git>
+ = refs/heads/baz:refs/heads/baz [up to date]
+ <COMMIT-B>:refs/heads/bar <OID-A>..<OID-B>
+ - :refs/heads/foo [deleted]
+ + refs/heads/master:refs/heads/master <OID-B>...<OID-A> (forced update)
+ * refs/heads/next:refs/heads/next [new branch]
+ Done
+ EOF
+ test_cmp expect actual &&
+
+ git -C "$upstream" show-ref >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ <COMMIT-B> refs/heads/bar
+ <COMMIT-A> refs/heads/baz
+ <COMMIT-A> refs/heads/master
+ <COMMIT-A> refs/heads/next
+ EOF
+ test_cmp expect actual
+ '
+
+ # Refs of upstream : master(A) bar(B) baz(A) next(A)
+ # Refs of workbench: master(B) bar(A) baz(A) next(A)
+ # git-push : master(B) bar(A) NULL next(A)
+ test_expect_success "atomic push failed ($PROTOCOL)" '
+ (
+ cd workbench &&
+ git update-ref refs/heads/master $B &&
+ git update-ref refs/heads/bar $A &&
+ test_must_fail git push --atomic --porcelain origin \
+ master \
+ bar \
+ :baz \
+ next
+ ) >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ To <URL/of/upstream.git>
+ = refs/heads/next:refs/heads/next [up to date]
+ ! refs/heads/bar:refs/heads/bar [rejected] (non-fast-forward)
+ ! (delete):refs/heads/baz [rejected] (atomic push failed)
+ ! refs/heads/master:refs/heads/master [rejected] (atomic push failed)
+ Done
+ EOF
+ test_cmp expect actual &&
+
+ git -C "$upstream" show-ref >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ <COMMIT-B> refs/heads/bar
+ <COMMIT-A> refs/heads/baz
+ <COMMIT-A> refs/heads/master
+ <COMMIT-A> refs/heads/next
+ EOF
+ test_cmp expect actual
+ '
+ test_expect_success "prepare pre-receive hook ($PROTOCOL)" '
+ write_script "$upstream/hooks/pre-receive" <<-EOF
+ exit 1
+ EOF
+ '
+
+ # Refs of upstream : master(A) bar(B) baz(A) next(A)
+ # Refs of workbench: master(B) bar(A) baz(A) next(A)
+ # git-push : master(B) bar(A) NULL next(A)
+ test_expect_success "pre-receive hook declined ($PROTOCOL)" '
+ (
+ cd workbench &&
+ git update-ref refs/heads/master $B &&
+ git update-ref refs/heads/bar $A &&
+ test_must_fail git push --porcelain --force origin \
+ master \
+ bar \
+ :baz \
+ next
+ ) >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ To <URL/of/upstream.git>
+ = refs/heads/next:refs/heads/next [up to date]
+ ! refs/heads/bar:refs/heads/bar [remote rejected] (pre-receive hook declined)
+ ! :refs/heads/baz [remote rejected] (pre-receive hook declined)
+ ! refs/heads/master:refs/heads/master [remote rejected] (pre-receive hook declined)
+ Done
+ EOF
+ test_cmp expect actual &&
+
+ git -C "$upstream" show-ref >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ <COMMIT-B> refs/heads/bar
+ <COMMIT-A> refs/heads/baz
+ <COMMIT-A> refs/heads/master
+ <COMMIT-A> refs/heads/next
+ EOF
+ test_cmp expect actual
+ '
+
+ test_expect_success "remove pre-receive hook ($PROTOCOL)" '
+ rm "$upstream/hooks/pre-receive"
+ '
+
+ # Refs of upstream : master(A) bar(B) baz(A) next(A)
+ # Refs of workbench: master(B) bar(A) baz(A) next(A)
+ # git-push : master(B) bar(A) NULL next(A)
+ test_expect_success "non-fastforward push ($PROTOCOL)" '
+ (
+ cd workbench &&
+ test_must_fail git push --porcelain origin \
+ master \
+ bar \
+ :baz \
+ next
+ ) >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ To <URL/of/upstream.git>
+ = refs/heads/next:refs/heads/next [up to date]
+ - :refs/heads/baz [deleted]
+ refs/heads/master:refs/heads/master <OID-A>..<OID-B>
+ ! refs/heads/bar:refs/heads/bar [rejected] (non-fast-forward)
+ Done
+ EOF
+ test_cmp expect actual &&
+
+ git -C "$upstream" show-ref >out &&
+ make_user_friendly_and_stable_output <out >actual &&
+ cat >expect <<-EOF &&
+ <COMMIT-B> refs/heads/bar
+ <COMMIT-B> refs/heads/master
+ <COMMIT-A> refs/heads/next
+ EOF
+ test_cmp expect actual
+ '
+}
+
+# Initialize the upstream repository and local workbench.
+setup_upstream_and_workbench
+
+# Run git-push porcelain test on builtin protocol
+run_git_push_porcelain_output_test file
+
+ROOT_PATH="$PWD"
+. "$TEST_DIRECTORY"/lib-gpg.sh
+. "$TEST_DIRECTORY"/lib-httpd.sh
+. "$TEST_DIRECTORY"/lib-terminal.sh
+start_httpd
+
+# Re-initialize the upstream repository and local workbench.
+setup_upstream_and_workbench
+
+test_expect_success "setup for http" '
+ git -C upstream.git config http.receivepack true &&
+ upstream="$HTTPD_DOCUMENT_ROOT_PATH/upstream.git" &&
+ mv upstream.git "$upstream" &&
+
+ git -C workbench remote set-url origin $HTTPD_URL/smart/upstream.git
+'
+
+setup_askpass_helper
+
+# Run git-push porcelain test on HTTP protocol
+run_git_push_porcelain_output_test http
+
+test_done
diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
index b811d89..5048530 100755
--- a/t/t5550-http-fetch-dumb.sh
+++ b/t/t5550-http-fetch-dumb.sh
@@ -248,9 +248,7 @@ test_expect_success 'fetch can handle previously-fetched .idx files' '
'
test_expect_success 'did not use upload-pack service' '
- test_might_fail grep '/git-upload-pack' <"$HTTPD_ROOT_PATH"/access.log >act &&
- : >exp &&
- test_cmp exp act
+ ! grep "/git-upload-pack" "$HTTPD_ROOT_PATH/access.log"
'
test_expect_success 'git client shows text/plain errors' '
@@ -321,11 +319,17 @@ test_expect_success 'git client does not send an empty Accept-Language' '
'
test_expect_success 'remote-http complains cleanly about malformed urls' '
- # do not actually issue "list" or other commands, as we do not
- # want to rely on what curl would actually do with such a broken
- # URL. This is just about making sure we do not segfault during
- # initialization.
- test_must_fail git remote-http http::/example.com/repo.git
+ test_must_fail git remote-http http::/example.com/repo.git 2>stderr &&
+ test_i18ngrep "url has no scheme" stderr
+'
+
+# NEEDSWORK: Writing commands to git-remote-curl can race against the latter
+# erroring out, producing SIGPIPE. Remove "ok=sigpipe" once transport-helper has
+# learned to handle early remote helper failures more cleanly.
+test_expect_success 'remote-http complains cleanly about empty scheme' '
+ test_must_fail ok=sigpipe git ls-remote \
+ http::${HTTPD_URL#http}/dumb/repo.git 2>stderr &&
+ test_i18ngrep "url has no scheme" stderr
'
test_expect_success 'redirects can be forbidden/allowed' '
diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh
index 4a110b3..3f4ac71 100755
--- a/t/t5562-http-backend-content-length.sh
+++ b/t/t5562-http-backend-content-length.sh
@@ -53,15 +53,20 @@ test_expect_success 'setup' '
test_commit c1 &&
hash_head=$(git rev-parse HEAD) &&
hash_prev=$(git rev-parse HEAD~1) &&
- printf "want %s" "$hash_head" | packetize >fetch_body &&
- printf 0000 >>fetch_body &&
- printf "have %s" "$hash_prev" | packetize >>fetch_body &&
- printf done | packetize >>fetch_body &&
+ {
+ packetize "want $hash_head" &&
+ printf 0000 &&
+ packetize "have $hash_prev" &&
+ packetize "done"
+ } >fetch_body &&
test_copy_bytes 10 <fetch_body >fetch_body.trunc &&
hash_next=$(git commit-tree -p HEAD -m next HEAD^{tree}) &&
- printf "%s %s refs/heads/newbranch\\0report-status\\n" "$ZERO_OID" "$hash_next" | packetize >push_body &&
- printf 0000 >>push_body &&
- echo "$hash_next" | git pack-objects --stdout >>push_body &&
+ {
+ printf "%s %s refs/heads/newbranch\\0report-status\\n" \
+ "$ZERO_OID" "$hash_next" | packetize &&
+ printf 0000 &&
+ echo "$hash_next" | git pack-objects --stdout
+ } >push_body &&
test_copy_bytes 10 <push_body >push_body.trunc &&
: >empty_body
'
diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh
index 0c74b4e..2f7be23 100755
--- a/t/t5604-clone-reference.sh
+++ b/t/t5604-clone-reference.sh
@@ -175,7 +175,7 @@ test_expect_success 'clone using repo pointed at by gitfile as reference' '
test_expect_success 'clone and dissociate from reference' '
git init P &&
(
- cd P && test_commit one
+ cd P && test_commit one
) &&
git clone P Q &&
(
diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh
index 9108ff6..6d5a977 100755
--- a/t/t5607-clone-bundle.sh
+++ b/t/t5607-clone-bundle.sh
@@ -16,7 +16,7 @@ test_expect_success 'setup' '
test_expect_success '"verify" needs a worktree' '
git bundle create tip.bundle -1 master &&
- test_must_fail nongit git bundle verify ../tip.bundle 2>err &&
+ nongit test_must_fail git bundle verify ../tip.bundle 2>err &&
test_i18ngrep "need a repository" err
'
diff --git a/t/t5611-clone-config.sh b/t/t5611-clone-config.sh
index 60c1ba9..8e0fd39 100755
--- a/t/t5611-clone-config.sh
+++ b/t/t5611-clone-config.sh
@@ -92,24 +92,17 @@ test_expect_success 'clone -c remote.<remote>.fetch=<refspec> --origin=<name>' '
test_cmp expect actual
'
-# Tests for the hidden file attribute on windows
-is_hidden () {
- # Use the output of `attrib`, ignore the absolute path
- case "$(attrib "$1")" in *H*?:*) return 0;; esac
- return 1
-}
-
test_expect_success MINGW 'clone -c core.hideDotFiles' '
test_commit attributes .gitattributes "" &&
rm -rf child &&
git clone -c core.hideDotFiles=false . child &&
- ! is_hidden child/.gitattributes &&
+ ! test_path_is_hidden child/.gitattributes &&
rm -rf child &&
git clone -c core.hideDotFiles=dotGitOnly . child &&
- ! is_hidden child/.gitattributes &&
+ ! test_path_is_hidden child/.gitattributes &&
rm -rf child &&
git clone -c core.hideDotFiles=true . child &&
- is_hidden child/.gitattributes
+ test_path_is_hidden child/.gitattributes
'
test_done
diff --git a/t/t5612-clone-refspec.sh b/t/t5612-clone-refspec.sh
index e36ac01..e3b436d 100755
--- a/t/t5612-clone-refspec.sh
+++ b/t/t5612-clone-refspec.sh
@@ -71,9 +71,9 @@ test_expect_success 'by default all branches will be kept updated' '
(
cd dir_all &&
git fetch &&
- git for-each-ref refs/remotes/origin |
+ git for-each-ref refs/remotes/origin >refs &&
sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
+ -e "s|/remotes/origin/|/heads/|" refs >../actual
) &&
# follow both master and side
git for-each-ref refs/heads >expect &&
@@ -87,7 +87,7 @@ test_expect_success 'by default no tags will be kept updated' '
git for-each-ref refs/tags >../actual
) &&
git for-each-ref refs/tags >expect &&
- test_must_fail test_cmp expect actual &&
+ ! test_cmp expect actual &&
test_line_count = 2 actual
'
@@ -104,9 +104,9 @@ test_expect_success '--single-branch while HEAD pointing at master' '
(
cd dir_master &&
git fetch --force &&
- git for-each-ref refs/remotes/origin |
+ git for-each-ref refs/remotes/origin >refs &&
sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
+ -e "s|/remotes/origin/|/heads/|" refs >../actual
) &&
# only follow master
git for-each-ref refs/heads/master >expect &&
@@ -126,9 +126,9 @@ test_expect_success '--single-branch while HEAD pointing at master and --no-tags
(
cd dir_master_no_tags &&
git fetch &&
- git for-each-ref refs/remotes/origin |
+ git for-each-ref refs/remotes/origin >refs &&
sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
+ -e "s|/remotes/origin/|/heads/|" refs >../actual
) &&
# only follow master
git for-each-ref refs/heads/master >expect &&
@@ -156,9 +156,9 @@ test_expect_success '--single-branch while HEAD pointing at side' '
(
cd dir_side &&
git fetch &&
- git for-each-ref refs/remotes/origin |
+ git for-each-ref refs/remotes/origin >refs &&
sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
+ -e "s|/remotes/origin/|/heads/|" refs >../actual
) &&
# only follow side
git for-each-ref refs/heads/side >expect &&
@@ -169,9 +169,9 @@ test_expect_success '--single-branch with explicit --branch side' '
(
cd dir_side2 &&
git fetch &&
- git for-each-ref refs/remotes/origin |
+ git for-each-ref refs/remotes/origin >refs &&
sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
+ -e "s|/remotes/origin/|/heads/|" refs >../actual
) &&
# only follow side
git for-each-ref refs/heads/side >expect &&
@@ -223,9 +223,9 @@ test_expect_success '--single-branch with detached' '
(
cd dir_detached &&
git fetch &&
- git for-each-ref refs/remotes/origin |
+ git for-each-ref refs/remotes/origin >refs &&
sed -e "/HEAD$/d" \
- -e "s|/remotes/origin/|/heads/|" >../actual
+ -e "s|/remotes/origin/|/heads/|" refs >../actual
) &&
# nothing
test_must_be_empty actual
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 77bb91e..88002b2 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -49,7 +49,7 @@ test_expect_success 'do partial clone 1' '
test_expect_success 'verify that .promisor file contains refs fetched' '
ls pc1/.git/objects/pack/pack-*.promisor >promisorlist &&
test_line_count = 1 promisorlist &&
- git -C srv.bare rev-list HEAD >headhash &&
+ git -C srv.bare rev-parse --verify HEAD >headhash &&
grep "$(cat headhash) HEAD" $(cat promisorlist) &&
grep "$(cat headhash) refs/heads/master" $(cat promisorlist)
'
@@ -415,6 +415,14 @@ test_expect_success 'verify fetch downloads only one pack when updating refs' '
test_line_count = 3 pack-list
'
+test_expect_success 'single-branch tag following respects partial clone' '
+ git clone --single-branch -b B --filter=blob:none \
+ "file://$(pwd)/srv.bare" single &&
+ git -C single rev-parse --verify refs/tags/B &&
+ git -C single rev-parse --verify refs/tags/A &&
+ test_must_fail git -C single rev-parse --verify refs/tags/C
+'
+
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index 7fba306..a34460f 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -13,10 +13,7 @@ get_actual_refs () {
}
get_actual_commits () {
- sed -n -e '/packfile/,/0000/{
- /packfile/d
- p
- }' <out | test-tool pkt-line unpack-sideband >o.pack &&
+ test-tool pkt-line unpack-sideband <out >o.pack &&
git index-pack o.pack &&
git verify-pack -v o.idx >objs &&
grep commit objs | cut -d" " -f1 | sort >actual_commits
diff --git a/t/t5704-protocol-violations.sh b/t/t5704-protocol-violations.sh
new file mode 100755
index 0000000..950cfb2
--- /dev/null
+++ b/t/t5704-protocol-violations.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+test_description='Test responses to violations of the network protocol. In most
+of these cases it will generally be acceptable for one side to break off
+communications if the other side says something unexpected. We are mostly
+making sure that we do not segfault or otherwise behave badly.'
+. ./test-lib.sh
+
+test_expect_success 'extra delim packet in v2 ls-refs args' '
+ {
+ packetize command=ls-refs &&
+ printf 0001 &&
+ # protocol expects 0000 flush here
+ printf 0001
+ } >input &&
+ test_must_fail env GIT_PROTOCOL=version=2 \
+ git upload-pack . <input 2>err &&
+ test_i18ngrep "expected flush after ls-refs arguments" err
+'
+
+test_expect_success 'extra delim packet in v2 fetch args' '
+ {
+ packetize command=fetch &&
+ printf 0001 &&
+ # protocol expects 0000 flush here
+ printf 0001
+ } >input &&
+ test_must_fail env GIT_PROTOCOL=version=2 \
+ git upload-pack . <input 2>err &&
+ test_i18ngrep "expected flush after fetch arguments" err
+'
+
+test_done
diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index 121e5c6..0f04b6c 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -11,9 +11,15 @@ test_description='Test remote-helper import and export commands'
PATH="$TEST_DIRECTORY/t5801:$PATH"
compare_refs() {
+ fail= &&
+ if test "x$1" = 'x!'
+ then
+ fail='!' &&
+ shift
+ fi &&
git --git-dir="$1/.git" rev-parse --verify $2 >expect &&
git --git-dir="$3/.git" rev-parse --verify $4 >actual &&
- test_cmp expect actual
+ eval $fail test_cmp expect actual
}
test_expect_success 'setup repository' '
@@ -189,7 +195,7 @@ test_expect_success GPG 'push signed tag' '
git push origin signed-tag
) &&
compare_refs local signed-tag^{} server signed-tag^{} &&
- test_must_fail compare_refs local signed-tag server signed-tag
+ compare_refs ! local signed-tag server signed-tag
'
test_expect_success GPG 'push signed tag with signed-tags capability' '
diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh
index a10f0df..b6fa43a 100755
--- a/t/t6012-rev-list-simplify.sh
+++ b/t/t6012-rev-list-simplify.sh
@@ -154,4 +154,124 @@ test_expect_success '--full-diff is not affected by --parents' '
test_cmp expected actual
'
+#
+# Create a new history to demonstrate the value of --show-pulls
+# with respect to the subtleties of simplified history, --full-history,
+# and --simplify-merges.
+#
+# .-A---M-----C--N---O---P
+# / / \ \ \/ / /
+# I B \ R-'`-Z' /
+# \ / \/ /
+# \ / /\ /
+# `---X--' `---Y--'
+#
+# This example is explained in Documentation/rev-list-options.txt
+
+test_expect_success 'rebuild repo' '
+ rm -rf .git * &&
+ git init &&
+ git switch -c main &&
+
+ echo base >file &&
+ git add file &&
+ test_commit I &&
+
+ echo A >file &&
+ git add file &&
+ test_commit A &&
+
+ git switch -c branchB I &&
+ echo B >file &&
+ git add file &&
+ test_commit B &&
+
+ git switch main &&
+ test_must_fail git merge -m "M" B &&
+ echo A >file &&
+ echo B >>file &&
+ git add file &&
+ git merge --continue &&
+ note M &&
+
+ echo C >other &&
+ git add other &&
+ test_commit C &&
+
+ git switch -c branchX I &&
+ echo X >file &&
+ git add file &&
+ test_commit X &&
+
+ git switch -c branchR M &&
+ git merge -m R -Xtheirs X &&
+ note R &&
+
+ git switch main &&
+ git merge -m N R &&
+ note N &&
+
+ git switch -c branchY M &&
+ echo Y >y &&
+ git add y &&
+ test_commit Y &&
+
+ git switch -c branchZ C &&
+ echo Z >z &&
+ git add z &&
+ test_commit Z &&
+
+ git switch main &&
+ git merge -m O Z &&
+ note O &&
+
+ git merge -m P Y &&
+ note P
+'
+
+check_result 'X I' -- file
+check_result 'N R X I' --show-pulls -- file
+
+check_result 'P O N R X M B A I' --full-history --topo-order -- file
+check_result 'N R X M B A I' --simplify-merges --topo-order --show-pulls -- file
+check_result 'R X M B A I' --simplify-merges --topo-order -- file
+check_result 'N M A I' --first-parent -- file
+check_result 'N M A I' --first-parent --show-pulls -- file
+
+# --ancestry-path implies --full-history
+check_result 'P O N R M' --topo-order \
+ --ancestry-path A..HEAD -- file
+check_result 'P O N R M' --topo-order \
+ --show-pulls \
+ --ancestry-path A..HEAD -- file
+check_result 'P O N R M' --topo-order \
+ --full-history \
+ --ancestry-path A..HEAD -- file
+check_result 'R M' --topo-order \
+ --simplify-merges \
+ --ancestry-path A..HEAD -- file
+check_result 'N R M' --topo-order \
+ --simplify-merges --show-pulls \
+ --ancestry-path A..HEAD -- file
+
+test_expect_success 'log --graph --simplify-merges --show-pulls' '
+ cat >expect <<-\EOF &&
+ * N
+ * R
+ |\
+ | * X
+ * | M
+ |\ \
+ | * | B
+ | |/
+ * / A
+ |/
+ * I
+ EOF
+ git log --graph --pretty="%s" \
+ --simplify-merges --show-pulls \
+ -- file >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7063-status-untracked-cache.sh b/t/t7063-status-untracked-cache.sh
index 190ae14..428cff9 100755
--- a/t/t7063-status-untracked-cache.sh
+++ b/t/t7063-status-untracked-cache.sh
@@ -18,7 +18,7 @@ GIT_FORCE_UNTRACKED_CACHE=true
export GIT_FORCE_UNTRACKED_CACHE
sync_mtime () {
- find . -type d -ls >/dev/null
+ find . -type d -exec ls -ld {} + >/dev/null
}
avoid_racy() {
@@ -30,6 +30,30 @@ status_is_clean() {
test_must_be_empty ../status.actual
}
+# Ignore_Untracked_Cache, abbreviated to 3 letters because then people can
+# compare commands side-by-side, e.g.
+# iuc status --porcelain >expect &&
+# git status --porcelain >actual &&
+# test_cmp expect actual
+iuc () {
+ git ls-files -s >../current-index-entries
+ git ls-files -t | sed -ne s/^S.//p >../current-sparse-entries
+
+ GIT_INDEX_FILE=.git/tmp_index
+ export GIT_INDEX_FILE
+ git update-index --index-info <../current-index-entries
+ git update-index --skip-worktree $(cat ../current-sparse-entries)
+
+ git -c core.untrackedCache=false "$@"
+ ret=$?
+
+ rm ../current-index-entries
+ rm $GIT_INDEX_FILE
+ unset GIT_INDEX_FILE
+
+ return $ret
+}
+
test_lazy_prereq UNTRACKED_CACHE '
{ git update-index --test-untracked-cache; ret=$?; } &&
test $ret -ne 1
@@ -95,6 +119,8 @@ test_expect_success 'status first time (empty cache)' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 3
@@ -115,6 +141,8 @@ test_expect_success 'status second time (fully populated cache)' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -136,6 +164,7 @@ test_expect_success 'modify in root directory, one dir invalidation' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
A done/one
A one
@@ -145,6 +174,7 @@ A two
?? four
?? three
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -183,6 +213,7 @@ test_expect_success 'new .gitignore invalidates recursively' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
A done/one
A one
@@ -192,6 +223,7 @@ A two
?? dtwo/
?? three
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -230,6 +262,7 @@ test_expect_success 'new info/exclude invalidates everything' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
A done/one
A one
@@ -237,6 +270,7 @@ A two
?? .gitignore
?? dtwo/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -286,6 +320,7 @@ test_expect_success 'status after the move' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
A done/one
A one
@@ -293,6 +328,7 @@ A one
?? dtwo/
?? two
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -343,6 +379,7 @@ test_expect_success 'status after the move' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
A done/one
A one
@@ -350,6 +387,7 @@ A two
?? .gitignore
?? dtwo/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -390,10 +428,12 @@ test_expect_success 'status after commit' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
?? .gitignore
?? dtwo/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -447,12 +487,14 @@ test_expect_success 'test sparse status with untracked cache' '
avoid_racy &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../status.actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
M done/two
?? .gitignore
?? done/five
?? dtwo/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../status.actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -487,12 +529,14 @@ test_expect_success 'test sparse status again with untracked cache' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../status.actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
M done/two
?? .gitignore
?? done/five
?? dtwo/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../status.actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -514,6 +558,7 @@ test_expect_success 'test sparse status with untracked cache and subdir' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../status.actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
M done/two
?? .gitignore
@@ -521,6 +566,7 @@ test_expect_success 'test sparse status with untracked cache and subdir' '
?? done/sub/
?? dtwo/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../status.actual &&
cat >../trace.expect <<EOF &&
node creation: 2
@@ -560,6 +606,8 @@ test_expect_success 'test sparse status again with untracked cache and subdir' '
: >../trace &&
GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
git status --porcelain >../status.actual &&
+ iuc status --porcelain >../status.iuc &&
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../status.actual &&
cat >../trace.expect <<EOF &&
node creation: 0
@@ -573,6 +621,7 @@ EOF
test_expect_success 'move entry in subdir from untracked to cached' '
git add dtwo/two &&
git status --porcelain >../status.actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
M done/two
A dtwo/two
@@ -580,12 +629,14 @@ A dtwo/two
?? done/five
?? done/sub/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../status.actual
'
test_expect_success 'move entry in subdir from cached to untracked' '
git rm --cached dtwo/two &&
git status --porcelain >../status.actual &&
+ iuc status --porcelain >../status.iuc &&
cat >../status.expect <<EOF &&
M done/two
?? .gitignore
@@ -593,6 +644,7 @@ test_expect_success 'move entry in subdir from cached to untracked' '
?? done/sub/
?? dtwo/
EOF
+ test_cmp ../status.expect ../status.iuc &&
test_cmp ../status.expect ../status.actual
'
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index e3e2aab..956e17a 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -938,7 +938,7 @@ test_expect_success 'submodule add --name allows to replace a submodule with ano
echo "repo" >expect &&
test_must_fail git config -f .gitmodules submodule.repo.path &&
git config -f .gitmodules submodule.repo_new.path >actual &&
- test_cmp expect actual&&
+ test_cmp expect actual &&
echo "$submodurl/repo" >expect &&
test_must_fail git config -f .gitmodules submodule.repo.url &&
echo "$submodurl/bare.git" >expect &&
@@ -1010,7 +1010,7 @@ test_expect_success 'submodule add with an existing name fails unless forced' '
test -d repo &&
echo "repo" >expect &&
git config -f .gitmodules submodule.repo_new.path >actual &&
- test_cmp expect actual&&
+ test_cmp expect actual &&
echo "$submodurl/repo.git" >expect &&
git config -f .gitmodules submodule.repo_new.url >actual &&
test_cmp expect actual &&
diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh
index 5ba041f..eec96e0 100755
--- a/t/t7416-submodule-dash-url.sh
+++ b/t/t7416-submodule-dash-url.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='check handling of .gitmodule url with dash'
+test_description='check handling of disallowed .gitmodule urls'
. ./test-lib.sh
test_expect_success 'create submodule with protected dash in url' '
@@ -60,4 +60,145 @@ test_expect_success 'trailing backslash is handled correctly' '
test_i18ngrep ! "unknown option" err
'
+test_expect_success 'fsck rejects missing URL scheme' '
+ git checkout --orphan missing-scheme &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = http::one.example.com/foo.git
+ EOF
+ git add .gitmodules &&
+ test_tick &&
+ git commit -m "gitmodules with missing URL scheme" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
+test_expect_success 'fsck rejects relative URL resolving to missing scheme' '
+ git checkout --orphan relative-missing-scheme &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = "..\\../.\\../:one.example.com/foo.git"
+ EOF
+ git add .gitmodules &&
+ test_tick &&
+ git commit -m "gitmodules with relative URL that strips off scheme" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
+test_expect_success 'fsck rejects empty URL scheme' '
+ git checkout --orphan empty-scheme &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = http::://one.example.com/foo.git
+ EOF
+ git add .gitmodules &&
+ test_tick &&
+ git commit -m "gitmodules with empty URL scheme" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
+test_expect_success 'fsck rejects relative URL resolving to empty scheme' '
+ git checkout --orphan relative-empty-scheme &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = ../../../:://one.example.com/foo.git
+ EOF
+ git add .gitmodules &&
+ test_tick &&
+ git commit -m "relative gitmodules URL resolving to empty scheme" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
+test_expect_success 'fsck rejects empty hostname' '
+ git checkout --orphan empty-host &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = http:///one.example.com/foo.git
+ EOF
+ git add .gitmodules &&
+ test_tick &&
+ git commit -m "gitmodules with extra slashes" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
+test_expect_success 'fsck rejects relative url that produced empty hostname' '
+ git checkout --orphan messy-relative &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = ../../..//one.example.com/foo.git
+ EOF
+ git add .gitmodules &&
+ test_tick &&
+ git commit -m "gitmodules abusing relative_path" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
+test_expect_success 'fsck permits embedded newline with unrecognized scheme' '
+ git checkout --orphan newscheme &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = "data://acjbkd%0akajfdickajkd"
+ EOF
+ git add .gitmodules &&
+ git commit -m "gitmodules with unrecognized scheme" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ git push dst HEAD
+'
+
+test_expect_success 'fsck rejects embedded newline in url' '
+ # create an orphan branch to avoid existing .gitmodules objects
+ git checkout --orphan newline &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = "https://one.example.com?%0ahost=two.example.com/foo.git"
+ EOF
+ git add .gitmodules &&
+ git commit -m "gitmodules with newline" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
+test_expect_success 'fsck rejects embedded newline in relative url' '
+ git checkout --orphan relative-newline &&
+ cat >.gitmodules <<-\EOF &&
+ [submodule "foo"]
+ url = "./%0ahost=two.example.com/foo.git"
+ EOF
+ git add .gitmodules &&
+ git commit -m "relative url with newline" &&
+ test_when_finished "rm -rf dst" &&
+ git init --bare dst &&
+ git -C dst config transfer.fsckObjects true &&
+ test_must_fail git push dst HEAD 2>err &&
+ grep gitmodulesUrl err
+'
+
test_done
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 1326088..5883a6a 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -29,15 +29,19 @@ Testing basic merge operations/option parsing.
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-gpg.sh
-printf '%s\n' 1 2 3 4 5 6 7 8 9 >file
-printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >file.1
-printf '%s\n' 1 2 3 4 '5 X' 6 7 8 9 >file.5
-printf '%s\n' 1 2 3 4 5 6 7 8 '9 X' >file.9
-printf '%s\n' 1 2 3 4 5 6 7 8 '9 Y' >file.9y
-printf '%s\n' '1 X' 2 3 4 5 6 7 8 9 >result.1
-printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 9 >result.1-5
-printf '%s\n' '1 X' 2 3 4 '5 X' 6 7 8 '9 X' >result.1-5-9
-printf '%s\n' 1 2 3 4 5 6 7 8 '9 Z' >result.9z
+test_write_lines 1 2 3 4 5 6 7 8 9 >file
+cp file file.orig
+test_write_lines '1 X' 2 3 4 5 6 7 8 9 >file.1
+test_write_lines 1 2 '3 X' 4 5 6 7 8 9 >file.3
+test_write_lines 1 2 3 4 '5 X' 6 7 8 9 >file.5
+test_write_lines 1 2 3 4 5 6 7 8 '9 X' >file.9
+test_write_lines 1 2 3 4 5 6 7 8 '9 Y' >file.9y
+test_write_lines '1 X' 2 3 4 5 6 7 8 9 >result.1
+test_write_lines '1 X' 2 3 4 '5 X' 6 7 8 9 >result.1-5
+test_write_lines '1 X' 2 3 4 5 6 7 8 '9 X' >result.1-9
+test_write_lines '1 X' 2 3 4 '5 X' 6 7 8 '9 X' >result.1-5-9
+test_write_lines '1 X' 2 '3 X' 4 '5 X' 6 7 8 '9 X' >result.1-3-5-9
+test_write_lines 1 2 3 4 5 6 7 8 '9 Z' >result.9z
create_merge_msgs () {
echo "Merge tag 'c2'" >msg.1-5 &&
@@ -81,7 +85,7 @@ verify_head () {
}
verify_parents () {
- printf '%s\n' "$@" >parents.expected &&
+ test_write_lines "$@" >parents.expected &&
>parents.actual &&
i=1 &&
while test $i -le $#
@@ -95,7 +99,7 @@ verify_parents () {
}
verify_mergeheads () {
- printf '%s\n' "$@" >mergehead.expected &&
+ test_write_lines "$@" >mergehead.expected &&
while read sha1 rest
do
git rev-parse $sha1
@@ -675,6 +679,134 @@ test_expect_success 'refresh the index before merging' '
git merge c3
'
+test_expect_success 'merge with --autostash' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9 &&
+ git merge --autostash c2 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ git show HEAD:file >merge-result &&
+ test_cmp result.1-5 merge-result &&
+ test_cmp result.1-5-9 file
+'
+
+test_expect_success 'merge with merge.autoStash' '
+ test_config merge.autoStash true &&
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9 &&
+ git merge c2 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ git show HEAD:file >merge-result &&
+ test_cmp result.1-5 merge-result &&
+ test_cmp result.1-5-9 file
+'
+
+test_expect_success 'fast-forward merge with --autostash' '
+ git reset --hard c0 &&
+ git merge-file file file.orig file.5 &&
+ git merge --autostash c1 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ test_cmp result.1-5 file
+'
+
+test_expect_success 'octopus merge with --autostash' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.3 &&
+ git merge --autostash c2 c3 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ git show HEAD:file >merge-result &&
+ test_cmp result.1-5-9 merge-result &&
+ test_cmp result.1-3-5-9 file
+'
+
+test_expect_success 'conflicted merge with --autostash, --abort restores stash' '
+ git reset --hard c3 &&
+ cp file.1 file &&
+ test_must_fail git merge --autostash c7 &&
+ git merge --abort 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ test_cmp file.1 file
+'
+
+test_expect_success 'completed merge (git commit) with --no-commit and --autostash' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9 &&
+ git diff >expect &&
+ git merge --no-commit --autostash c2 &&
+ git stash show -p MERGE_AUTOSTASH >actual &&
+ test_cmp expect actual &&
+ git commit 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ git show HEAD:file >merge-result &&
+ test_cmp result.1-5 merge-result &&
+ test_cmp result.1-5-9 file
+'
+
+test_expect_success 'completed merge (git merge --continue) with --no-commit and --autostash' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9 &&
+ git diff >expect &&
+ git merge --no-commit --autostash c2 &&
+ git stash show -p MERGE_AUTOSTASH >actual &&
+ test_cmp expect actual &&
+ git merge --continue 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ git show HEAD:file >merge-result &&
+ test_cmp result.1-5 merge-result &&
+ test_cmp result.1-5-9 file
+'
+
+test_expect_success 'aborted merge (merge --abort) with --no-commit and --autostash' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9 &&
+ git diff >expect &&
+ git merge --no-commit --autostash c2 &&
+ git stash show -p MERGE_AUTOSTASH >actual &&
+ test_cmp expect actual &&
+ git merge --abort 2>err &&
+ test_i18ngrep "Applied autostash." err &&
+ git diff >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'aborted merge (reset --hard) with --no-commit and --autostash' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9 &&
+ git diff >expect &&
+ git merge --no-commit --autostash c2 &&
+ git stash show -p MERGE_AUTOSTASH >actual &&
+ test_cmp expect actual &&
+ git reset --hard 2>err &&
+ test_i18ngrep "Autostash exists; creating a new stash entry." err &&
+ git diff --exit-code
+'
+
+test_expect_success 'quit merge with --no-commit and --autostash' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9 &&
+ git diff >expect &&
+ git merge --no-commit --autostash c2 &&
+ git stash show -p MERGE_AUTOSTASH >actual &&
+ test_cmp expect actual &&
+ git diff HEAD >expect &&
+ git merge --quit 2>err &&
+ test_i18ngrep "Autostash exists; creating a new stash entry." err &&
+ git diff HEAD >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'merge with conflicted --autostash changes' '
+ git reset --hard c1 &&
+ git merge-file file file.orig file.9y &&
+ git diff >expect &&
+ test_when_finished "test_might_fail git stash drop" &&
+ git merge --autostash c3 2>err &&
+ test_i18ngrep "Applying autostash resulted in conflicts." err &&
+ git show HEAD:file >merge-result &&
+ test_cmp result.1-9 merge-result &&
+ git stash show -p >actual &&
+ test_cmp expect actual
+'
+
cat >expected.branch <<\EOF
Merge branch 'c5-branch' (early part)
EOF
diff --git a/t/t7609-merge-co-error-msgs.sh b/t/t7609-merge-co-error-msgs.sh
index e904132..5c8894d 100755
--- a/t/t7609-merge-co-error-msgs.sh
+++ b/t/t7609-merge-co-error-msgs.sh
@@ -126,7 +126,7 @@ test_expect_success 'not_uptodate_dir porcelain checkout error' '
git rm rep2 -r &&
>rep &&
>rep2 &&
- git add rep rep2&&
+ git add rep rep2 &&
git commit -m "added test as a file" &&
git checkout master &&
>rep/untracked-file &&
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 7d7b396..991d5bd 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -72,6 +72,11 @@ test_expect_success setup '
# Still a no-op.
function dummy() {}
EOF
+ if test_have_prereq FUNNYNAMES
+ then
+ echo unusual >"\"unusual\" pathname" &&
+ echo unusual >"t/nested \"unusual\" pathname"
+ fi &&
git add . &&
test_tick &&
git commit -m initial
@@ -481,6 +486,48 @@ do
git grep --count -h -e b $H -- ab >actual &&
test_cmp expected actual
'
+
+ test_expect_success FUNNYNAMES "grep $L should quote unusual pathnames" '
+ cat >expected <<-EOF &&
+ ${HC}"\"unusual\" pathname":unusual
+ ${HC}"t/nested \"unusual\" pathname":unusual
+ EOF
+ git grep unusual $H >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success FUNNYNAMES "grep $L in subdir should quote unusual relative pathnames" '
+ cat >expected <<-EOF &&
+ ${HC}"nested \"unusual\" pathname":unusual
+ EOF
+ (
+ cd t &&
+ git grep unusual $H
+ ) >actual &&
+ test_cmp expected actual
+ '
+
+ test_expect_success FUNNYNAMES "grep -z $L with unusual pathnames" '
+ cat >expected <<-EOF &&
+ ${HC}"unusual" pathname:unusual
+ ${HC}t/nested "unusual" pathname:unusual
+ EOF
+ git grep -z unusual $H >actual &&
+ tr "\0" ":" <actual >actual-replace-null &&
+ test_cmp expected actual-replace-null
+ '
+
+ test_expect_success FUNNYNAMES "grep -z $L in subdir with unusual relative pathnames" '
+ cat >expected <<-EOF &&
+ ${HC}nested "unusual" pathname:unusual
+ EOF
+ (
+ cd t &&
+ git grep -z unusual $H
+ ) >actual &&
+ tr "\0" ":" <actual >actual-replace-null &&
+ test_cmp expected actual-replace-null
+ '
done
cat >expected <<EOF
diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh
index c90fdc5..83f8f5c 100755
--- a/t/t9010-svn-fe.sh
+++ b/t/t9010-svn-fe.sh
@@ -486,7 +486,7 @@ test_expect_success 'NUL in property value' '
{
properties \
unimportant "something with a NUL (Q)" \
- svn:log "commit message"&&
+ svn:log "commit message" &&
echo PROPS-END
} |
q_to_nul >props &&
diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh
index cc8d463..267ddc9 100755
--- a/t/t9500-gitweb-standalone-no-errors.sh
+++ b/t/t9500-gitweb-standalone-no-errors.sh
@@ -53,7 +53,7 @@ test_expect_success \
test_expect_success \
'Make initial commit' \
- 'echo "Not an empty file." > file &&
+ 'echo "Not an empty file." >file &&
git add file &&
git commit -a -m "Initial commit." &&
git branch b'
@@ -139,7 +139,7 @@ test_expect_success \
test_expect_success \
'commitdiff(0): file added' \
- 'echo "New file" > new_file &&
+ 'echo "New file" >new_file &&
git add new_file &&
git commit -a -m "File added." &&
gitweb_run "p=.git;a=commitdiff"'
@@ -179,7 +179,7 @@ test_expect_success \
test_expect_success \
'commitdiff(0): mode change and modified' \
- 'echo "New line" >> file2 &&
+ 'echo "New line" >>file2 &&
test_chmod +x file2 &&
git commit -a -m "Mode change and modification." &&
gitweb_run "p=.git;a=commitdiff"'
@@ -197,14 +197,14 @@ propter nomen suum.
EOF
git commit -a -m "File added." &&
git mv file2 file3 &&
- echo "Propter nomen suum." >> file3 &&
+ echo "Propter nomen suum." >>file3 &&
git commit -a -m "File rename and modification." &&
gitweb_run "p=.git;a=commitdiff"'
test_expect_success \
'commitdiff(0): renamed, mode change and modified' \
'git mv file3 file2 &&
- echo "Propter nomen suum." >> file2 &&
+ echo "Propter nomen suum." >>file2 &&
test_chmod +x file2 &&
git commit -a -m "File rename, mode change and modification." &&
gitweb_run "p=.git;a=commitdiff"'
@@ -213,8 +213,8 @@ test_expect_success \
# commitdiff testing (taken from t4114-apply-typechange.sh)
test_expect_success 'setup typechange commits' '
- echo "hello world" > foo &&
- echo "hi planet" > bar &&
+ echo "hello world" >foo &&
+ echo "hi planet" >bar &&
git update-index --add foo bar &&
git commit -m initial &&
git branch initial &&
@@ -223,18 +223,18 @@ test_expect_success 'setup typechange commits' '
git commit -m "foo symlinked to bar" &&
git branch foo-symlinked-to-bar &&
rm -f foo &&
- echo "how far is the sun?" > foo &&
+ echo "how far is the sun?" >foo &&
git update-index foo &&
git commit -m "foo back to file" &&
git branch foo-back-to-file &&
rm -f foo &&
git update-index --remove foo &&
mkdir foo &&
- echo "if only I knew" > foo/baz &&
+ echo "if only I knew" >foo/baz &&
git update-index --add foo/baz &&
git commit -m "foo becomes a directory" &&
git branch "foo-becomes-a-directory" &&
- echo "hello world" > foo/baz &&
+ echo "hello world" >foo/baz &&
git update-index foo/baz &&
git commit -m "foo/baz is the original foo" &&
git branch foo-baz-renamed-from-foo
@@ -324,7 +324,7 @@ test_expect_success 'commitdiff(1): removal of incomplete line' '
test_expect_success \
'Create a merge' \
'git checkout b &&
- echo "Branch" >> b &&
+ echo "Branch" >>b &&
git add b &&
git commit -a -m "On branch" &&
git checkout master &&
@@ -342,26 +342,26 @@ test_expect_success \
test_expect_success \
'Prepare large commit' \
'git checkout b &&
- echo "To be changed" > 01-change &&
- echo "To be renamed" > 02-pure-rename-from &&
- echo "To be deleted" > 03-delete &&
- echo "To be renamed and changed" > 04-rename-from &&
- echo "To have mode changed" > 05-mode-change &&
- echo "File to symlink" > 06-file-or-symlink &&
- echo "To be changed and have mode changed" > 07-change-mode-change &&
+ echo "To be changed" >01-change &&
+ echo "To be renamed" >02-pure-rename-from &&
+ echo "To be deleted" >03-delete &&
+ echo "To be renamed and changed" >04-rename-from &&
+ echo "To have mode changed" >05-mode-change &&
+ echo "File to symlink" >06-file-or-symlink &&
+ echo "To be changed and have mode changed" >07-change-mode-change &&
git add 0* &&
git commit -a -m "Prepare large commit" &&
- echo "Changed" > 01-change &&
+ echo "Changed" >01-change &&
git mv 02-pure-rename-from 02-pure-rename-to &&
git rm 03-delete && rm -f 03-delete &&
- echo "A new file" > 03-new &&
+ echo "A new file" >03-new &&
git add 03-new &&
git mv 04-rename-from 04-rename-to &&
- echo "Changed" >> 04-rename-to &&
+ echo "Changed" >>04-rename-to &&
test_chmod +x 05-mode-change &&
rm -f 06-file-or-symlink &&
test_ln_s_add 01-change 06-file-or-symlink &&
- echo "Changed and have mode changed" > 07-change-mode-change &&
+ echo "Changed and have mode changed" >07-change-mode-change &&
test_chmod +x 07-change-mode-change &&
git commit -a -m "Large commit" &&
git checkout master'
@@ -444,7 +444,7 @@ test_expect_success \
test_expect_success \
'logs: history (implicit HEAD, deleted file)' \
'git checkout master &&
- echo "to be deleted" > deleted_file &&
+ echo "to be deleted" >deleted_file &&
git add deleted_file &&
git commit -m "Add file to be deleted" &&
git rm deleted_file &&
@@ -522,7 +522,7 @@ test_expect_success \
'. "$TEST_DIRECTORY"/t3901/utf8.txt &&
test_when_finished "GIT_AUTHOR_NAME=\"A U Thor\"" &&
test_when_finished "GIT_COMMITTER_NAME=\"C O Mitter\"" &&
- echo "UTF-8" >> file &&
+ echo "UTF-8" >>file &&
git add file &&
git commit -F "$TEST_DIRECTORY"/t3900/1-UTF-8.txt &&
gitweb_run "p=.git;a=commit"'
@@ -532,7 +532,7 @@ test_expect_success \
'. "$TEST_DIRECTORY"/t3901/8859-1.txt &&
test_when_finished "GIT_AUTHOR_NAME=\"A U Thor\"" &&
test_when_finished "GIT_COMMITTER_NAME=\"C O Mitter\"" &&
- echo "ISO-8859-1" >> file &&
+ echo "ISO-8859-1" >>file &&
git add file &&
test_config i18n.commitencoding ISO-8859-1 &&
git commit -F "$TEST_DIRECTORY"/t3900/ISO8859-1.txt &&
@@ -675,8 +675,8 @@ test_expect_success \
test_expect_success \
'README.html with non-ASCII characters (utf-8)' \
- 'echo "<b>UTF-8 example:</b><br />" > .git/README.html &&
- cat "$TEST_DIRECTORY"/t3900/1-UTF-8.txt >> .git/README.html &&
+ 'echo "<b>UTF-8 example:</b><br />" >.git/README.html &&
+ cat "$TEST_DIRECTORY"/t3900/1-UTF-8.txt >>.git/README.html &&
gitweb_run "p=.git;a=summary"'
# ----------------------------------------------------------------------
@@ -704,7 +704,7 @@ test_expect_success HIGHLIGHT \
test_expect_success HIGHLIGHT \
'syntax highlighting (highlighted, shell script)' \
'git config gitweb.highlight yes &&
- echo "#!/usr/bin/sh" > test.sh &&
+ echo "#!/usr/bin/sh" >test.sh &&
git add test.sh &&
git commit -m "Add test.sh" &&
gitweb_run "p=.git;a=blob;f=test.sh"'
@@ -712,7 +712,7 @@ test_expect_success HIGHLIGHT \
test_expect_success HIGHLIGHT \
'syntax highlighting (highlighter language autodetection)' \
'git config gitweb.highlight yes &&
- echo "#!/usr/bin/perl" > test &&
+ echo "#!/usr/bin/perl" >test &&
git add test &&
git commit -m "Add test" &&
gitweb_run "p=.git;a=blob;f=test"'
@@ -729,11 +729,11 @@ test_expect_success \
'git init --bare foo.git &&
git --git-dir=foo.git --work-tree=. add file &&
git --git-dir=foo.git --work-tree=. commit -m "Initial commit" &&
- echo "foo" > foo.git/description &&
+ echo "foo" >foo.git/description &&
mkdir -p foo &&
(cd foo &&
git clone --shared --bare ../foo.git foo-forked.git &&
- echo "fork of foo" > foo-forked.git/description)'
+ echo "fork of foo" >foo-forked.git/description)'
test_expect_success \
'forks: projects list' \
@@ -754,8 +754,8 @@ EOF
test_expect_success \
'ctags: tag cloud in projects list' \
'mkdir .git/ctags &&
- echo "2" > .git/ctags/foo &&
- echo "1" > .git/ctags/bar &&
+ echo "2" >.git/ctags/foo &&
+ echo "1" >.git/ctags/bar &&
gitweb_run'
test_expect_success \
@@ -769,8 +769,8 @@ test_expect_success \
test_expect_success \
'ctags: malformed tag weights' \
'mkdir -p .git/ctags &&
- echo "not-a-number" > .git/ctags/nan &&
- echo "not-a-number-2" > .git/ctags/nan2 &&
+ echo "not-a-number" >.git/ctags/nan &&
+ echo "not-a-number-2" >.git/ctags/nan2 &&
echo "0.1" >.git/ctags/floating-point &&
gitweb_run'
diff --git a/t/t9831-git-p4-triggers.sh b/t/t9831-git-p4-triggers.sh
index d743ca3..ff6c035 100755
--- a/t/t9831-git-p4-triggers.sh
+++ b/t/t9831-git-p4-triggers.sh
@@ -58,7 +58,7 @@ test_expect_success 'import with extra info lines from verbose p4 trigger' '
(
cd "$git" &&
git p4 sync
- )&&
+ ) &&
(
p4 triggers -i <<-EOF
Triggers:
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 5505e5a..3c44af6 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -1638,6 +1638,11 @@ test_expect_success 'complete files' '
echo modify > modified &&
test_completion "git add " "modified" &&
+ mkdir -p some/deep &&
+ touch some/deep/path &&
+ test_completion "git add some/" "some/deep" &&
+ git clean -f some &&
+
touch untracked &&
: TODO .gitignore should not be here &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 352c213..3103be8 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -905,7 +905,7 @@ test_expect_code () {
# - not all diff versions understand "-u"
test_cmp() {
- $GIT_TEST_CMP "$@"
+ eval "$GIT_TEST_CMP" '"$@"'
}
# Check that the given config key has the expected value.
@@ -1362,14 +1362,22 @@ nongit () {
)
} 7>&2 2>&4
-# convert stdin to pktline representation; note that empty input becomes an
-# empty packet, not a flush packet (for that you can just print 0000 yourself).
+# 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).
packetize() {
- cat >packetize.tmp &&
- len=$(wc -c <packetize.tmp) &&
- printf '%04x%s' "$(($len + 4))" &&
- cat packetize.tmp &&
- rm -f packetize.tmp
+ 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;
+ '
+ fi
}
# Parse the input as a series of pktlines, writing the result to stdout.
@@ -1543,3 +1551,13 @@ test_bitmap_traversal () {
test_cmp "$1.normalized" "$2.normalized" &&
rm -f "$1.normalized" "$2.normalized"
}
+
+# Tests for the hidden file attribute on Windows
+test_path_is_hidden () {
+ test_have_prereq MINGW ||
+ BUG "test_path_is_hidden can only be used on Windows"
+
+ # Use the output of `attrib`, ignore the absolute path
+ case "$("$SYSTEMROOT"/system32/attrib "$1")" in *H*?:*) return 0;; esac
+ return 1
+}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 9fe390b..13ba00d 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -78,20 +78,23 @@ then
exit 1
fi
-# Parse options while taking care to leave $@ intact, so we will still
-# have all the original command line options when executing the test
-# script again for '--tee' and '--verbose-log' below.
store_arg_to=
-prev_opt=
-for opt
-do
- if test -n "$store_arg_to"
+opt_required_arg=
+# $1: option string
+# $2: name of the var where the arg will be stored
+mark_option_requires_arg () {
+ if test -n "$opt_required_arg"
then
- eval $store_arg_to=\$opt
- store_arg_to=
- prev_opt=
- continue
+ echo "error: options that require args cannot be bundled" \
+ "together: '$opt_required_arg' and '$1'" >&2
+ exit 1
fi
+ opt_required_arg=$1
+ store_arg_to=$2
+}
+
+parse_option () {
+ local opt="$1"
case "$opt" in
-d|--d|--de|--deb|--debu|--debug)
@@ -101,7 +104,7 @@ do
-l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
GIT_TEST_LONG=t; export GIT_TEST_LONG ;;
-r)
- store_arg_to=run_list
+ mark_option_requires_arg "$opt" run_list
;;
--run=*)
run_list=${opt#--*=} ;;
@@ -185,12 +188,42 @@ do
*)
echo "error: unknown test option '$opt'" >&2; exit 1 ;;
esac
+}
- prev_opt=$opt
+# Parse options while taking care to leave $@ intact, so we will still
+# have all the original command line options when executing the test
+# script again for '--tee' and '--verbose-log' later.
+for opt
+do
+ if test -n "$store_arg_to"
+ then
+ eval $store_arg_to=\$opt
+ store_arg_to=
+ opt_required_arg=
+ continue
+ fi
+
+ case "$opt" in
+ --*|-?)
+ parse_option "$opt" ;;
+ -?*)
+ # bundled short options must be fed separately to parse_option
+ opt=${opt#-}
+ while test -n "$opt"
+ do
+ extra=${opt#?}
+ this=${opt%$extra}
+ opt=$extra
+ parse_option "-$this"
+ done
+ ;;
+ *)
+ echo "error: unknown test option '$opt'" >&2; exit 1 ;;
+ esac
done
if test -n "$store_arg_to"
then
- echo "error: $prev_opt requires an argument" >&2
+ echo "error: $opt_required_arg requires an argument" >&2
exit 1
fi
@@ -642,6 +675,18 @@ die () {
fi
}
+file_lineno () {
+ test -z "$GIT_TEST_FRAMEWORK_SELFTEST" && test -n "$BASH" || return 0
+ local i
+ for i in ${!BASH_SOURCE[*]}
+ do
+ case $i,"${BASH_SOURCE[$i]##*/}" in
+ 0,t[0-9]*.sh) echo "t/${BASH_SOURCE[$i]}:$LINENO: ${1+$1: }"; return;;
+ *,t[0-9]*.sh) echo "t/${BASH_SOURCE[$i]}:${BASH_LINENO[$(($i-1))]}: ${1+$1: }"; return;;
+ esac
+ done
+}
+
GIT_EXIT_OK=
trap 'die' EXIT
# Disable '-x' tracing, because with some shells, notably dash, it
@@ -687,7 +732,7 @@ test_failure_ () {
write_junit_xml_testcase "$1" " $junit_insert"
fi
test_failure=$(($test_failure + 1))
- say_color error "not ok $test_count - $1"
+ say_color error "$(file_lineno error)not ok $test_count - $1"
shift
printf '%s\n' "$*" | sed -e 's/^/# /'
test "$immediate" = "" || { finalize_junit_xml; GIT_EXIT_OK=t; exit 1; }
@@ -867,6 +912,7 @@ maybe_setup_valgrind () {
fi
}
+trace_level_=0
want_trace () {
test "$trace" = t && {
test "$verbose" = t || test "$verbose_log" = t
@@ -880,7 +926,7 @@ want_trace () {
test_eval_inner_ () {
# Do not add anything extra (including LF) after '$*'
eval "
- want_trace && set -x
+ want_trace && trace_level_=$(($trace_level_+1)) && set -x
$*"
}
@@ -911,7 +957,8 @@ test_eval_ () {
test_eval_ret_=$?
if want_trace
then
- set +x
+ test 1 = $trace_level_ && set +x
+ trace_level_=$(($trace_level_-1))
fi
} 2>/dev/null 4>&2
@@ -1070,6 +1117,7 @@ finalize_junit_xml () {
junit_time=$(test-tool date getnanos $junit_suite_start)
sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \
-e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \
+ -e '/^ *<\/testsuite/d' \
<"$junit_xml_path" >"$junit_xml_path.new"
mv "$junit_xml_path.new" "$junit_xml_path"