summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/.gitattributes1
-rw-r--r--t/README33
-rwxr-xr-xt/check-non-portable-shell.pl1
-rw-r--r--t/helper/test-parse-options.c2
-rw-r--r--t/helper/test-prio-queue.c26
-rw-r--r--t/helper/test-reach.c34
-rw-r--r--t/helper/test-sigchain.c3
-rw-r--r--t/helper/test-submodule-nested-repo-config.c30
-rw-r--r--t/helper/test-tool.c1
-rw-r--r--t/helper/test-tool.h1
-rw-r--r--t/lib-gettext.sh9
-rw-r--r--t/lib-git-daemon.sh18
-rw-r--r--t/lib-git-p4.sh9
-rw-r--r--t/lib-git-svn.sh2
-rw-r--r--t/lib-gpg/keyring.gpg62
-rw-r--r--t/lib-httpd.sh2
-rwxr-xr-xt/lib-submodule-update.sh5
-rwxr-xr-xt/perf/p3400-rebase.sh10
-rw-r--r--t/perf/perf-lib.sh4
-rwxr-xr-xt/t0000-basic.sh2
-rwxr-xr-xt/t0001-init.sh4
-rwxr-xr-xt/t0006-date.sh2
-rwxr-xr-xt/t0009-prio-queue.sh14
-rwxr-xr-xt/t0027-auto-crlf.sh4
-rwxr-xr-xt/t0029-core-unsetenvvars.sh30
-rwxr-xr-xt/t0030-stripspace.sh12
-rwxr-xr-xt/t0040-parse-options.sh26
-rwxr-xr-xt/t0060-path-utils.sh2
-rwxr-xr-xt/t0061-run-command.sh19
-rwxr-xr-xt/t0205-gettext-poison.sh8
-rwxr-xr-xt/t0410-partial-clone.sh17
-rwxr-xr-xt/t1060-object-corruption.sh4
-rwxr-xr-xt/t1300-config.sh79
-rwxr-xr-xt/t1410-reflog.sh21
-rwxr-xr-xt/t1415-worktree-refs.sh79
-rwxr-xr-xt/t1450-fsck.sh110
-rwxr-xr-xt/t1700-split-index.sh31
-rwxr-xr-xt/t2024-checkout-dwim.sh31
-rwxr-xr-xt/t2028-worktree-move.sh37
-rwxr-xr-xt/t2029-worktree-config.sh79
-rwxr-xr-xt/t3070-wildmatch.sh4
-rwxr-xr-xt/t3206-range-diff.sh50
-rwxr-xr-xt/t3404-rebase-interactive.sh23
-rwxr-xr-xt/t3406-rebase-message.sh45
-rwxr-xr-xt/t3408-rebase-multi-line.sh2
-rwxr-xr-xt/t3409-rebase-preserve-merges.sh5
-rwxr-xr-xt/t3410-rebase-preserve-dropped-merges.sh5
-rwxr-xr-xt/t3411-rebase-preserve-around-merges.sh5
-rwxr-xr-xt/t3412-rebase-root.sh12
-rwxr-xr-xt/t3414-rebase-preserve-onto.sh5
-rwxr-xr-xt/t3418-rebase-continue.sh5
-rwxr-xr-xt/t3420-rebase-autostash.sh8
-rwxr-xr-xt/t3421-rebase-topology-linear.sh36
-rwxr-xr-xt/t3425-rebase-topology-merges.sh5
-rwxr-xr-xt/t3430-rebase-merges.sh16
-rwxr-xr-xt/t3502-cherry-pick-merge.sh12
-rwxr-xr-xt/t3506-cherry-pick-ff.sh6
-rwxr-xr-xt/t3510-cherry-pick-sequence.sh8
-rwxr-xr-xt/t3903-stash.sh28
-rwxr-xr-xt/t4013-diff-various.sh2
-rwxr-xr-xt/t4015-diff-whitespace.sh18
-rwxr-xr-xt/t4052-stat-output.sh48
-rwxr-xr-xt/t4136-apply-check.sh12
-rwxr-xr-xt/t4209-log-pickaxe.sh35
-rwxr-xr-xt/t4211-line-log.sh2
-rwxr-xr-xt/t5004-archive-corner-cases.sh17
-rwxr-xr-xt/t5300-pack-object.sh47
-rwxr-xr-xt/t5310-pack-bitmaps.sh1
-rwxr-xr-xt/t5319-multi-pack-index.sh2
-rwxr-xr-xt/t5409-colorize-remote-messages.sh2
-rwxr-xr-xt/t5505-remote.sh55
-rwxr-xr-xt/t5512-ls-remote.sh26
-rwxr-xr-xt/t5516-fetch-push.sh2
-rwxr-xr-xt/t5520-pull.sh6
-rwxr-xr-xt/t5526-fetch-submodules.sh2
-rwxr-xr-xt/t5562-http-backend-content-length.sh1
-rw-r--r--[-rwxr-xr-x]t/t5562/invoke-with-content-length.pl1
-rwxr-xr-xt/t5570-git-daemon.sh13
-rwxr-xr-xt/t5573-pull-verify-signatures.sh7
-rwxr-xr-xt/t5601-clone.sh4
-rwxr-xr-xt/t5607-clone-bundle.sh6
-rwxr-xr-xt/t5611-clone-config.sh47
-rwxr-xr-xt/t5616-partial-clone.sh2
-rwxr-xr-xt/t5702-protocol-v2.sh50
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh4
-rwxr-xr-xt/t6000-rev-list-misc.sh7
-rwxr-xr-xt/t6012-rev-list-simplify.sh45
-rwxr-xr-xt/t6018-rev-list-glob.sh72
-rwxr-xr-xt/t6036-recursive-corner-cases.sh430
-rwxr-xr-xt/t6042-merge-rename-corner-cases.sh333
-rwxr-xr-xt/t6043-merge-rename-directories.sh144
-rwxr-xr-xt/t6050-replace.sh9
-rwxr-xr-xt/t6132-pathspec-exclude.sh17
-rwxr-xr-xt/t6135-pathspec-with-attrs.sh58
-rwxr-xr-xt/t6600-test-reach.sh148
-rwxr-xr-xt/t7201-co.sh6
-rwxr-xr-xt/t7400-submodule-basic.sh5
-rwxr-xr-xt/t7411-submodule-config.sh141
-rwxr-xr-xt/t7412-submodule-absorbgitdirs.sh7
-rwxr-xr-xt/t7415-submodule-names.sh6
-rwxr-xr-xt/t7418-submodule-sparse-gitmodules.sh122
-rwxr-xr-xt/t7505-prepare-commit-msg-hook.sh2
-rwxr-xr-xt/t7506-status-submodule.sh3
-rwxr-xr-xt/t7510-signed-commit.sh22
-rwxr-xr-xt/t7517-per-repo-email.sh6
-rwxr-xr-xt/t7612-merge-verify-signatures.sh7
-rwxr-xr-xt/t7800-difftool.sh2
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh16
-rwxr-xr-xt/t9001-send-email.sh15
-rwxr-xr-xt/t9300-fast-import.sh2
-rwxr-xr-xt/t9350-fast-export.sh80
-rwxr-xr-xt/t9902-completion.sh20
-rw-r--r--t/test-lib-functions.sh118
-rw-r--r--t/test-lib.sh421
114 files changed, 3197 insertions, 623 deletions
diff --git a/t/.gitattributes b/t/.gitattributes
index e7acedabe1..df05434d32 100644
--- a/t/.gitattributes
+++ b/t/.gitattributes
@@ -16,6 +16,7 @@ t[0-9][0-9][0-9][0-9]/* -whitespace
/t4135/* eol=lf
/t4211/* eol=lf
/t4252/* eol=lf
+/t4256/1/* eol=lf
/t5100/* eol=lf
/t5515/* eol=lf
/t556x_common eol=lf
diff --git a/t/README b/t/README
index 2e9bef2852..11ce7675e3 100644
--- a/t/README
+++ b/t/README
@@ -186,6 +186,22 @@ appropriately before running "make".
this feature by setting the GIT_TEST_CHAIN_LINT environment
variable to "1" or "0", respectively.
+--stress::
+--stress=<N>::
+ Run the test script repeatedly in multiple parallel jobs until
+ one of them fails. Useful for reproducing rare failures in
+ flaky tests. The number of parallel jobs is, in order of
+ precedence: <N>, or the value of the GIT_TEST_STRESS_LOAD
+ environment variable, or twice the number of available
+ processors (as shown by the 'getconf' utility), or 8.
+ Implies `--verbose -x --immediate` to get the most information
+ about the failure. Note that the verbose output of each test
+ job is saved to 't/test-results/$TEST_NAME.stress-<nr>.out',
+ and only the output of the failed test job is shown on the
+ terminal. The names of the trash directories get a
+ '.stress-<nr>' suffix, and the trash directory of the failed
+ test job is renamed to end with a '.stress-failed' suffix.
+
You can also set the GIT_TEST_INSTALLED environment variable to
the bindir of an existing git installation to test that installation.
You still need to have built this git sandbox, from which various
@@ -302,6 +318,12 @@ that cannot be easily covered by a few specific test cases. These
could be enabled by running the test suite with correct GIT_TEST_
environment set.
+GIT_TEST_GETTEXT_POISON=<non-empty?> turns all strings marked for
+translation into gibberish if non-empty (think "test -n"). Used for
+spotting those tests that need to be marked with a C_LOCALE_OUTPUT
+prerequisite when adding more strings for translation. See "Testing
+marked strings" in po/README for details.
+
GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
test suite. Accept any boolean values that are accepted by git-config.
@@ -339,11 +361,19 @@ for the index version specified. Can be set to any valid version
GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
by overriding the minimum number of cache entries required per thread.
+GIT_TEST_REBASE_USE_BUILTIN=<boolean>, when false, disables the
+builtin version of git-rebase. See 'rebase.useBuiltin' in
+git-config(1).
+
GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading
of the index for the whole test suite by bypassing the default number of
cache entries and thread minimums. Setting this to 1 will make the
index loading single threaded.
+GIT_TEST_MULTI_PACK_INDEX=<boolean>, when true, forces the multi-pack-
+index to be written after every 'git repack' command, and overrides the
+'core.multiPackIndex' setting to true.
+
Naming Tests
------------
@@ -411,7 +441,8 @@ This test harness library does the following things:
- Creates an empty test directory with an empty .git/objects database
and chdir(2) into it. This directory is 't/trash
directory.$test_name_without_dotsh', with t/ subject to change by
- the --root option documented above.
+ the --root option documented above, and a '.stress-<N>' suffix
+ appended by the --stress option.
- Defines standard test helper functions for your scripts to
use. These functions are designed to make all scripts behave
diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl
index b45bdac688..8037eef777 100755
--- a/t/check-non-portable-shell.pl
+++ b/t/check-non-portable-shell.pl
@@ -35,6 +35,7 @@ while (<>) {
chomp;
}
+ /\bcp\s+-a/ and err 'cp -a is not portable';
/\bsed\s+-i/ and err 'sed -i is not portable';
/\becho\s+-[neE]/ and err 'echo with option is not portable (use printf)';
/^\s*declare\s+/ and err 'arrays/declare not portable';
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index 9cb8a0ea0f..47fee660b8 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -36,6 +36,7 @@ static int length_callback(const struct option *opt, const char *arg, int unset)
static int number_callback(const struct option *opt, const char *arg, int unset)
{
+ BUG_ON_OPT_NEG(unset);
*(int *)opt->value = strtol(arg, NULL, 10);
return 0;
}
@@ -119,7 +120,6 @@ int cmd__parse_options(int argc, const char **argv)
OPT_INTEGER('j', NULL, &integer, "get a integer, too"),
OPT_MAGNITUDE('m', "magnitude", &magnitude, "get a magnitude"),
OPT_SET_INT(0, "set23", &integer, "set integer to 23", 23),
- OPT_DATE('t', NULL, &timestamp, "get timestamp of <time>"),
OPT_CALLBACK('L', "length", &integer, "str",
"get length of <str>", length_callback),
OPT_FILENAME('F', "file", &file, "set file to <file>"),
diff --git a/t/helper/test-prio-queue.c b/t/helper/test-prio-queue.c
index 9807b649b1..5bc9c46ea5 100644
--- a/t/helper/test-prio-queue.c
+++ b/t/helper/test-prio-queue.c
@@ -22,14 +22,24 @@ int cmd__prio_queue(int argc, const char **argv)
struct prio_queue pq = { intcmp };
while (*++argv) {
- if (!strcmp(*argv, "get"))
- show(prio_queue_get(&pq));
- else if (!strcmp(*argv, "dump")) {
- int *v;
- while ((v = prio_queue_get(&pq)))
- show(v);
- }
- else {
+ if (!strcmp(*argv, "get")) {
+ void *peek = prio_queue_peek(&pq);
+ void *get = prio_queue_get(&pq);
+ if (peek != get)
+ BUG("peek and get results do not match");
+ show(get);
+ } else if (!strcmp(*argv, "dump")) {
+ void *peek;
+ void *get;
+ while ((peek = prio_queue_peek(&pq))) {
+ get = prio_queue_get(&pq);
+ if (peek != get)
+ BUG("peek and get results do not match");
+ show(get);
+ }
+ } else if (!strcmp(*argv, "stack")) {
+ pq.compare = NULL;
+ } else {
int *v = malloc(sizeof(*v));
*v = atoi(*argv);
prio_queue_put(&pq, v);
diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c
index 08d2ea68e8..a0272178b7 100644
--- a/t/helper/test-reach.c
+++ b/t/helper/test-reach.c
@@ -32,8 +32,8 @@ int cmd__reach(int ac, const char **av)
struct commit *A, *B;
struct commit_list *X, *Y;
struct object_array X_obj = OBJECT_ARRAY_INIT;
- struct commit **X_array;
- int X_nr, X_alloc;
+ struct commit **X_array, **Y_array;
+ int X_nr, X_alloc, Y_nr, Y_alloc;
struct strbuf buf = STRBUF_INIT;
struct repository *r = the_repository;
@@ -44,9 +44,10 @@ int cmd__reach(int ac, const char **av)
A = B = NULL;
X = Y = NULL;
- X_nr = 0;
- X_alloc = 16;
+ X_nr = Y_nr = 0;
+ X_alloc = Y_alloc = 16;
ALLOC_ARRAY(X_array, X_alloc);
+ ALLOC_ARRAY(Y_array, Y_alloc);
while (strbuf_getline(&buf, stdin) != EOF) {
struct object_id oid;
@@ -92,6 +93,8 @@ int cmd__reach(int ac, const char **av)
case 'Y':
commit_list_insert(c, &Y);
+ ALLOC_GROW(Y_array, Y_nr + 1, Y_alloc);
+ Y_array[Y_nr++] = c;
break;
default:
@@ -136,6 +139,29 @@ int cmd__reach(int ac, const char **av)
filter.with_commit_tag_algo = 0;
printf("%s(_,A,X,_):%d\n", av[1], commit_contains(&filter, A, X, &cache));
+ } else if (!strcmp(av[1], "get_reachable_subset")) {
+ const int reachable_flag = 1;
+ int i, count = 0;
+ struct commit_list *current;
+ struct commit_list *list = get_reachable_subset(X_array, X_nr,
+ Y_array, Y_nr,
+ reachable_flag);
+ printf("get_reachable_subset(X,Y)\n");
+ for (current = list; current; current = current->next) {
+ if (!(list->item->object.flags & reachable_flag))
+ die(_("commit %s is not marked reachable"),
+ oid_to_hex(&list->item->object.oid));
+ count++;
+ }
+ for (i = 0; i < Y_nr; i++) {
+ if (Y_array[i]->object.flags & reachable_flag)
+ count--;
+ }
+
+ if (count < 0)
+ die(_("too many commits marked reachable"));
+
+ print_sorted_commit_ids(list);
}
exit(0);
diff --git a/t/helper/test-sigchain.c b/t/helper/test-sigchain.c
index 77ac5bc33f..d013bccdda 100644
--- a/t/helper/test-sigchain.c
+++ b/t/helper/test-sigchain.c
@@ -14,7 +14,8 @@ X(two)
X(three)
#undef X
-int cmd__sigchain(int argc, const char **argv) {
+int cmd__sigchain(int argc, const char **argv)
+{
sigchain_push(SIGTERM, one);
sigchain_push(SIGTERM, two);
sigchain_push(SIGTERM, three);
diff --git a/t/helper/test-submodule-nested-repo-config.c b/t/helper/test-submodule-nested-repo-config.c
new file mode 100644
index 0000000000..a31e2a9bea
--- /dev/null
+++ b/t/helper/test-submodule-nested-repo-config.c
@@ -0,0 +1,30 @@
+#include "test-tool.h"
+#include "submodule-config.h"
+
+static void die_usage(int argc, const char **argv, const char *msg)
+{
+ fprintf(stderr, "%s\n", msg);
+ fprintf(stderr, "Usage: %s <submodulepath> <config name>\n", argv[0]);
+ exit(1);
+}
+
+int cmd__submodule_nested_repo_config(int argc, const char **argv)
+{
+ struct repository submodule;
+
+ if (argc < 3)
+ die_usage(argc, argv, "Wrong number of arguments.");
+
+ setup_git_directory();
+
+ if (repo_submodule_init(&submodule, the_repository, argv[1])) {
+ die_usage(argc, argv, "Submodule not found.");
+ }
+
+ /* Read the config of _child_ submodules. */
+ print_config_from_gitmodules(&submodule, argv[2]);
+
+ submodule_free(the_repository);
+
+ return 0;
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 5df8b682aa..bfb195b1a8 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -46,6 +46,7 @@ static struct test_cmd cmds[] = {
{ "strcmp-offset", cmd__strcmp_offset },
{ "string-list", cmd__string_list },
{ "submodule-config", cmd__submodule_config },
+ { "submodule-nested-repo-config", cmd__submodule_nested_repo_config },
{ "subprocess", cmd__subprocess },
{ "urlmatch-normalization", cmd__urlmatch_normalization },
{ "wildmatch", cmd__wildmatch },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index 71f470b871..042f12464b 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -42,6 +42,7 @@ int cmd__sigchain(int argc, const char **argv);
int cmd__strcmp_offset(int argc, const char **argv);
int cmd__string_list(int argc, const char **argv);
int cmd__submodule_config(int argc, const char **argv);
+int cmd__submodule_nested_repo_config(int argc, const char **argv);
int cmd__subprocess(int argc, const char **argv);
int cmd__urlmatch_normalization(int argc, const char **argv);
int cmd__wildmatch(int argc, const char **argv);
diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh
index eec757f104..2139b427ca 100644
--- a/t/lib-gettext.sh
+++ b/t/lib-gettext.sh
@@ -10,9 +10,14 @@ GIT_TEXTDOMAINDIR="$GIT_BUILD_DIR/po/build/locale"
GIT_PO_PATH="$GIT_BUILD_DIR/po"
export GIT_TEXTDOMAINDIR GIT_PO_PATH
-. "$GIT_BUILD_DIR"/git-sh-i18n
+if test -n "$GIT_TEST_INSTALLED"
+then
+ . "$(git --exec-path)"/git-sh-i18n
+else
+ . "$GIT_BUILD_DIR"/git-sh-i18n
+fi
-if test_have_prereq GETTEXT && ! test_have_prereq GETTEXT_POISON
+if test_have_prereq GETTEXT && test_have_prereq C_LOCALE_OUTPUT
then
# is_IS.UTF-8 on Solaris and FreeBSD, is_IS.utf8 on Debian
is_IS_locale=$(locale -a 2>/dev/null |
diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
index edbea2d986..79db3b7ae5 100644
--- a/t/lib-git-daemon.sh
+++ b/t/lib-git-daemon.sh
@@ -28,7 +28,7 @@ then
test_skip_or_die $GIT_TEST_GIT_DAEMON "file system does not support FIFOs"
fi
-LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-${this_test#t}}
+test_set_port LIB_GIT_DAEMON_PORT
GIT_DAEMON_PID=
GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo
@@ -54,19 +54,11 @@ start_git_daemon() {
"$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
>&3 2>git_daemon_output &
GIT_DAEMON_PID=$!
- >daemon.log
{
read -r line <&7
- printf "%s\n" "$line"
- printf >&4 "%s\n" "$line"
- (
- while read -r line <&7
- do
- printf "%s\n" "$line"
- printf >&4 "%s\n" "$line"
- done
- ) &
- } 7<git_daemon_output >>"$TRASH_DIRECTORY/daemon.log" &&
+ printf "%s\n" "$line" >&4
+ cat <&7 >&4 &
+ } 7<git_daemon_output &&
# Check expected output
if test x"$(expr "$line" : "\[[0-9]*\] \(.*\)")" != x"Ready to rumble"
@@ -92,7 +84,7 @@ stop_git_daemon() {
kill "$GIT_DAEMON_PID"
wait "$GIT_DAEMON_PID" >&3 2>&4
ret=$?
- if test_match_signal 15 $?
+ if ! test_match_signal 15 $ret
then
error "git daemon exited with status: $ret"
fi
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index c27599474c..b3be3ba011 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -53,14 +53,7 @@ time_in_seconds () {
(cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
}
-# Try to pick a unique port: guess a large number, then hope
-# no more than one of each test is running.
-#
-# This does not handle the case where somebody else is running the
-# same tests and has chosen the same ports.
-testid=${this_test#t}
-git_p4_test_start=9800
-P4DPORT=$((10669 + ($testid - $git_p4_test_start)))
+test_set_port P4DPORT
P4PORT=localhost:$P4DPORT
P4CLIENT=client
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index a8130f9119..f3b478c307 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -13,6 +13,7 @@ fi
GIT_DIR=$PWD/.git
GIT_SVN_DIR=$GIT_DIR/svn/refs/remotes/git-svn
SVN_TREE=$GIT_SVN_DIR/svn-tree
+test_set_port SVNSERVE_PORT
svn >/dev/null 2>&1
if test $? -ne 1
@@ -119,7 +120,6 @@ require_svnserve () {
}
start_svnserve () {
- SVNSERVE_PORT=${SVNSERVE_PORT-${this_test#t}}
svnserve --listen-port $SVNSERVE_PORT \
--root "$rawsvnrepo" \
--listen-once \
diff --git a/t/lib-gpg/keyring.gpg b/t/lib-gpg/keyring.gpg
index d4754a1f19..918dfce332 100644
--- a/t/lib-gpg/keyring.gpg
+++ b/t/lib-gpg/keyring.gpg
@@ -30,7 +30,6 @@ Cezx4Q2khACcCs+/LtE8Lb9hC+2cvr3uH5p82AI=
=aEiU
-----END PGP PRIVATE KEY BLOCK-----
-----BEGIN PGP PRIVATE KEY BLOCK-----
-Version: GnuPG v1
lQOYBFFMlkcBCADJi/xnAF8yI34PHilSCbM7VtOFO17oFMkpu4cgN2QpPuM5MVjy
cvrzKSguZFvPCDLzeAFJW1uPxL4SHaHSkisCrFhijH7OJWcOPNPSFCwu+inAoAsv
@@ -83,11 +82,43 @@ fn1sY/IG5atoKK+ypmV/TlBlMZqFQzuPIJQT8VLbmxtLlDhJG04LbI6c8axIZxOO
ZKLy5nTTSy16ztqEeS7eifHLPZg1UFFyEEIQ1XW0CNDAeuWKh90ERjyl4Cg7PnWS
Z9Ei+zj6JD5Pcdi3BJhQo9WOLOVEJ0NHmewTYqk9QVXH/0v1Hdl4LMJtgcbdbDWk
4UTkXbg9pn3umCgkNJ3Vs8fWnIWO9Izdr2/wrFY2JvUT7Yvl+wsNIWatvOEzGy7n
-BOW78WUxzhu0YJTLKy+iKCjg5HS5dx6OC+e4aEEgfhNPCMkbvDsJjtQ=
-=hieJ
+BOW78WUxzhu0YJTLKy+iKCjg5HS5dx6OC+e4aEEgfhNPCMkbvDsJjtSdA5gEW967
+3AEIAKjseT0sTQjyN39fOn0fzxWp89REMUUKgLigb01MKuuNI3cedBZsz3hpFOKV
+cii5rldw8uf3yS3Okht2DfHPSD4NrGzLGEzSTpQ10S8N2q0DUYwyLU6C0U8HnMZm
+/n+lCGBbUoxvnruohAvKAjpHO3rmJ8D4De9hlWg/fwdAxQQ0Sve0kN8Vwk2p1GuO
+OWQKV1SU9c+kBiou7dewQmbilPRanKmP5ZSU4emhpTOMlJFXF+kmYSODQk1cMvWW
+Ob3ttll2llX0Gul7Sjf+haq/FcRyRk7Tw5MHwZjr5aWiCny0/0+byvfF6SBIfzyE
+qlyWURQ2gHZUqSiG3QPMZiYr04cAEQEAAQAH/Am4rv/oQF6wodgz5y4zc6JJiTDA
+4+nKdIuR7OKqUxk1oo7eZjJML/xvMumygNyUvJ9nodl1SlMKilOhdAswfkKj9gJY
+BdDJLm1OufhW3pJwy6ahbjeqEgwJFVENtSPF0zkuyED9kElrpbD2ZTGfzwdM0e9D
+10ZDFWtODCw8rzOFcijujgI8oilLtxSNrkkTKW+25WJFRNPSHgIkMIm8UlPAG+rj
+3Yj9UqodeXTSvXwG2zceOxjFJadV77sOFJDgwWslN6J8El4+GcgwFVepJxoZEj7e
+cKkmVr0Dc9/Q04D5dWATc1FYcIhZbTu3oImCAh45ep4u9WYLUV5PGyeMviEEAMwo
+mJbYBxWuPjpNa722HQcbvMUiZWWDwHfLCib/SaP0AgfDahid8/PcZwxOPHPByBrm
+GDi0z7ibn/pgJr07kpp1Cic9ntfc2FvkI0QMzG0EuiekzQyPEnzjoDHF+V4nJIj2
+GWVjLYYqlZWEmhsfKt1CnlPXBunKoDJ30ABPcHJ/BADT0WxAIVKF4lO2HlrDVP44
+bufBEG9Ct7dl/G08Qve4Ag3VEZpT82vEFp0LzX0mTCDIUKJUYAYLxAIPhP7IvIfc
+EZXrwyDUxU7YSgKTHMKo9nFC6fIc1GeGPRalIF1gmTY32qlYJC6y5BTDhZNV5ydG
+u8QL2P/orP7XuRrJyeyK+QP/XTekr/DS6Jkct826MPA52ciIkWVgYLatH5fO4HCq
+ssDU8vz7FbbvGs0G1Xn7GA4m9dNYVOZtKwX++3nf2IEOpgPiZVTn/nP2u3HutpJb
+/HMLlcfZGiGdxS6n/vdz6wsEobJoi6STkHkA+VFNOSZmdsw6eKl3X911tpCTYfOG
+2U47/IkCbAQYAQgAIBYhBNS+IjEa0xMeXtoppGEJLoW3InGJBQJb3rvcAhsCAUAJ
+EGEJLoW3InGJwHQgBBkBCAAdFiEE+DZKWeB//p9NYwBaZaDuoC4wytcFAlveu9wA
+CgkQZaDuoC4wytcD9gf/WigtHl7lFyl8RaE/uqROFEelZyM00v1h55fd/IGRG88E
+tN0Lr4FaqBqPkMZjU/LN9UMBaTd+748vHlHaweZqljXJu99CO9Id7Y4w7WzF3C3Y
+yQsGZ92EGxthsPK0+rhHV0MbaINupI1oO9gATFglSxq17o83FJatGRjaXCZau8jr
+57/By1MGtjk+Iq1NkzGkrX778LdRQGLKDw2Qa7lsdHY8d3lUPAH8mbb97ELmIc9t
+PG2aM7ATJL7nBmFuTHo6hmEcIw32Ei9KK1zxM0ZylEYkjBjHAlklWmKb9MiayMC5
+uHW7Iyhjl+NbgbIEr2JTamW/9tL6UrIIxiDEdqaHNfCaB/9D+V31Upcohc9azwB4
+AF8diQwt5nfiVpnVeF/W8+eS1By2W6QrwLNthNRabYFnuSf9USHAY6atDWe+egId
+MLIv4ce0i3ykoczSu0oMoUCMxdl9kQrsNHZCqWX/OiDDLSb05u/P/3he900y6tSB
+15MbIPA6i5Bw/693nHguqxS1ASbBB/LiIu3vCXdFEs9RMvIJ+qkP3xQA96oImQiK
+R3U6OGv593eONKijUINNqHRq6+UxIyJ+OCAi+L2QTidAhJLRCp6EZD96u02cthYq
+8KA8j1+rx9BcbeacVVHepeG1JsgxsXX8BTJ7ZuS5VVndZOjag8URW/9nJMf01w/h
+el64
+=Iv7W
-----END PGP PRIVATE KEY BLOCK-----
-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1
mQGiBEZnyykRBACzCPjIpTYNL7Y2tQqlEGTTDlvZcWNLjF5f7ZzuyOqNOidLUgFD
36qch1LZLSZkShdR3Gae+bsolyjxrlFuFP0eXRPMtqK20aLw7WZvPFpEV1ThMne+
@@ -137,6 +168,25 @@ bGPyBuWraCivsqZlf05QZTGahUM7jyCUE/FS25sbS5Q4SRtOC2yOnPGsSGcTjmSi
8uZ000stes7ahHku3onxyz2YNVBRchBCENV1tAjQwHrliofdBEY8peAoOz51kmfR
Ivs4+iQ+T3HYtwSYUKPVjizlRCdDR5nsE2KpPUFVx/9L9R3ZeCzCbYHG3Ww1pOFE
5F24PaZ97pgoJDSd1bPH1pyFjvSM3a9v8KxWNib1E+2L5fsLDSFmrbzhMxsu5wTl
-u/FlMc4btGCUyysvoigo4OR0uXcejgvnuGhBIH4TTwjJG7w7CY7U
-=iYv/
+u/FlMc4btGCUyysvoigo4OR0uXcejgvnuGhBIH4TTwjJG7w7CY7UuQENBFveu9wB
+CACo7Hk9LE0I8jd/Xzp9H88VqfPURDFFCoC4oG9NTCrrjSN3HnQWbM94aRTilXIo
+ua5XcPLn98ktzpIbdg3xz0g+DaxsyxhM0k6UNdEvDdqtA1GMMi1OgtFPB5zGZv5/
+pQhgW1KMb567qIQLygI6Rzt65ifA+A3vYZVoP38HQMUENEr3tJDfFcJNqdRrjjlk
+CldUlPXPpAYqLu3XsEJm4pT0Wpypj+WUlOHpoaUzjJSRVxfpJmEjg0JNXDL1ljm9
+7bZZdpZV9Brpe0o3/oWqvxXEckZO08OTB8GY6+Wlogp8tP9Pm8r3xekgSH88hKpc
+llEUNoB2VKkoht0DzGYmK9OHABEBAAGJAmwEGAEIACAWIQTUviIxGtMTHl7aKaRh
+CS6FtyJxiQUCW9673AIbAgFACRBhCS6FtyJxicB0IAQZAQgAHRYhBPg2Slngf/6f
+TWMAWmWg7qAuMMrXBQJb3rvcAAoJEGWg7qAuMMrXA/YH/1ooLR5e5RcpfEWhP7qk
+ThRHpWcjNNL9YeeX3fyBkRvPBLTdC6+BWqgaj5DGY1PyzfVDAWk3fu+PLx5R2sHm
+apY1ybvfQjvSHe2OMO1sxdwt2MkLBmfdhBsbYbDytPq4R1dDG2iDbqSNaDvYAExY
+JUsate6PNxSWrRkY2lwmWrvI6+e/wctTBrY5PiKtTZMxpK1++/C3UUBiyg8NkGu5
+bHR2PHd5VDwB/Jm2/exC5iHPbTxtmjOwEyS+5wZhbkx6OoZhHCMN9hIvSitc8TNG
+cpRGJIwYxwJZJVpim/TImsjAubh1uyMoY5fjW4GyBK9iU2plv/bS+lKyCMYgxHam
+hzXwmgf/Q/ld9VKXKIXPWs8AeABfHYkMLeZ34laZ1Xhf1vPnktQctlukK8CzbYTU
+Wm2BZ7kn/VEhwGOmrQ1nvnoCHTCyL+HHtIt8pKHM0rtKDKFAjMXZfZEK7DR2Qqll
+/zogwy0m9Obvz/94XvdNMurUgdeTGyDwOouQcP+vd5x4LqsUtQEmwQfy4iLt7wl3
+RRLPUTLyCfqpD98UAPeqCJkIikd1Ojhr+fd3jjSoo1CDTah0auvlMSMifjggIvi9
+kE4nQISS0QqehGQ/ertNnLYWKvCgPI9fq8fQXG3mnFVR3qXhtSbIMbF1/AUye2bk
+uVVZ3WTo2oPFEVv/ZyTH9NcP4XpeuA==
+=KRyT
-----END PGP PUBLIC KEY BLOCK-----
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index a8729f8232..e465116ef9 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -82,7 +82,7 @@ case $(uname) in
esac
LIB_HTTPD_PATH=${LIB_HTTPD_PATH-"$DEFAULT_HTTPD_PATH"}
-LIB_HTTPD_PORT=${LIB_HTTPD_PORT-${this_test#t}}
+test_set_port LIB_HTTPD_PORT
TEST_PATH="$TEST_DIRECTORY"/lib-httpd
HTTPD_ROOT_PATH="$PWD"/httpd
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 016391723c..5b56b23166 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -235,7 +235,7 @@ reset_work_tree_to_interested () {
then
mkdir -p submodule_update/.git/modules/sub1/modules &&
cp -r submodule_update_repo/.git/modules/sub1/modules/sub2 submodule_update/.git/modules/sub1/modules/sub2
- GIT_WORK_TREE=. git -C submodule_update/.git/modules/sub1/modules/sub2 config --unset core.worktree
+ # core.worktree is unset for sub2 as it is not checked out
fi &&
# indicate we are interested in the submodule:
git -C submodule_update config submodule.sub1.url "bogus" &&
@@ -709,7 +709,8 @@ test_submodule_recursing_with_args_common() {
git branch -t remove_sub1 origin/remove_sub1 &&
$command remove_sub1 &&
test_superproject_content origin/remove_sub1 &&
- ! test -e sub1
+ ! test -e sub1 &&
+ test_must_fail git config -f .git/modules/sub1/config core.worktree
)
'
# ... absorbing a .git directory along the way.
diff --git a/t/perf/p3400-rebase.sh b/t/perf/p3400-rebase.sh
index ce271ca4c1..d202aaed06 100755
--- a/t/perf/p3400-rebase.sh
+++ b/t/perf/p3400-rebase.sh
@@ -6,9 +6,9 @@ test_description='Tests rebase performance'
test_perf_default_repo
test_expect_success 'setup rebasing on top of a lot of changes' '
- git checkout -f -b base &&
- git checkout -b to-rebase &&
- git checkout -b upstream &&
+ git checkout -f -B base &&
+ git checkout -B to-rebase &&
+ git checkout -B upstream &&
for i in $(seq 100)
do
# simulate huge diffs
@@ -35,8 +35,8 @@ test_perf 'rebase on top of a lot of unrelated changes' '
test_expect_success 'setup rebasing many changes without split-index' '
git config core.splitIndex false &&
- git checkout -b upstream2 to-rebase &&
- git checkout -b to-rebase2 upstream
+ git checkout -B upstream2 to-rebase &&
+ git checkout -B to-rebase2 upstream
'
test_perf 'rebase a lot of unrelated changes without split-index' '
diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh
index 11d1922cf5..2e33ab3ec3 100644
--- a/t/perf/perf-lib.sh
+++ b/t/perf/perf-lib.sh
@@ -82,7 +82,7 @@ test_perf_do_repo_symlink_config_ () {
test_perf_create_repo_from () {
test "$#" = 2 ||
- error "bug in the test script: not 2 parameters to test-create-repo"
+ BUG "not 2 parameters to test-create-repo"
repo="$1"
source="$2"
source_git="$("$MODERN_GIT" -C "$source" rev-parse --git-dir)"
@@ -184,7 +184,7 @@ test_wrapper_ () {
test_start_
test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
test "$#" = 2 ||
- error "bug in the test script: not 2 or 3 parameters to test-expect-success"
+ BUG "not 2 or 3 parameters to test-expect-success"
export test_prereq
if ! test_skip "$@"
then
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index 4d23373526..b6566003dd 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -274,7 +274,7 @@ test_expect_success 'pretend we have a mix of all possible results' "
EOF
"
-test_expect_success 'test --verbose' '
+test_expect_success C_LOCALE_OUTPUT 'test --verbose' '
test_must_fail run_sub_test_lib_test \
test-verbose "test verbose" --verbose <<-\EOF &&
test_expect_success "passing test" true
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index 182da069f1..42a263cada 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -319,14 +319,14 @@ test_lazy_prereq GETCWD_IGNORES_PERMS '
base=GETCWD_TEST_BASE_DIR &&
mkdir -p $base/dir &&
chmod 100 $base ||
- error "bug in test script: cannot prepare $base"
+ BUG "cannot prepare $base"
(cd $base/dir && /bin/pwd -P)
status=$?
chmod 700 $base &&
rm -rf $base ||
- error "bug in test script: cannot clean $base"
+ BUG "cannot clean $base"
return $status
'
diff --git a/t/t0006-date.sh b/t/t0006-date.sh
index 64ff86df8e..ffb2975e48 100755
--- a/t/t0006-date.sh
+++ b/t/t0006-date.sh
@@ -113,6 +113,8 @@ check_approxidate '3:00' '2009-08-30 03:00:00'
check_approxidate '15:00' '2009-08-30 15:00:00'
check_approxidate 'noon today' '2009-08-30 12:00:00'
check_approxidate 'noon yesterday' '2009-08-29 12:00:00'
+check_approxidate 'January 5th noon pm' '2009-01-05 12:00:00'
+check_approxidate '10am noon' '2009-08-29 12:00:00'
check_approxidate 'last tuesday' '2009-08-25 19:20:00'
check_approxidate 'July 5th' '2009-07-05 19:20:00'
diff --git a/t/t0009-prio-queue.sh b/t/t0009-prio-queue.sh
index e56dfce668..3941ad2528 100755
--- a/t/t0009-prio-queue.sh
+++ b/t/t0009-prio-queue.sh
@@ -47,4 +47,18 @@ test_expect_success 'notice empty queue' '
test_cmp expect actual
'
+cat >expect <<'EOF'
+3
+2
+6
+4
+5
+1
+8
+EOF
+test_expect_success 'stack order' '
+ test-tool prio-queue stack 8 1 5 4 6 2 3 dump >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index beb5927f77..3587e454f1 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -293,9 +293,9 @@ checkout_files () {
do
rm crlf_false_attr__$f.txt &&
if test -z "$ceol"; then
- git checkout crlf_false_attr__$f.txt
+ git checkout -- crlf_false_attr__$f.txt
else
- git -c core.eol=$ceol checkout crlf_false_attr__$f.txt
+ git -c core.eol=$ceol checkout -- crlf_false_attr__$f.txt
fi
done
diff --git a/t/t0029-core-unsetenvvars.sh b/t/t0029-core-unsetenvvars.sh
new file mode 100755
index 0000000000..24ce46a6ea
--- /dev/null
+++ b/t/t0029-core-unsetenvvars.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+test_description='test the Windows-only core.unsetenvvars setting'
+
+. ./test-lib.sh
+
+if ! test_have_prereq MINGW
+then
+ skip_all='skipping Windows-specific tests'
+ test_done
+fi
+
+test_expect_success 'setup' '
+ mkdir -p "$TRASH_DIRECTORY/.git/hooks" &&
+ write_script "$TRASH_DIRECTORY/.git/hooks/pre-commit" <<-\EOF
+ echo $HOBBES >&2
+ EOF
+'
+
+test_expect_success 'core.unsetenvvars works' '
+ HOBBES=Calvin &&
+ export HOBBES &&
+ git commit --allow-empty -m with 2>err &&
+ grep Calvin err &&
+ git -c core.unsetenvvars=FINDUS,HOBBES,CALVIN \
+ commit --allow-empty -m without 2>err &&
+ ! grep Calvin err
+'
+
+test_done
diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh
index 5ce47e8af5..0c24a0f9a3 100755
--- a/t/t0030-stripspace.sh
+++ b/t/t0030-stripspace.sh
@@ -430,9 +430,15 @@ test_expect_success '-c with changed comment char' '
test_expect_success '-c with comment char defined in .git/config' '
test_config core.commentchar = &&
printf "= foo\n" >expect &&
- printf "foo" | (
- mkdir sub && cd sub && git stripspace -c
- ) >actual &&
+ rm -fr sub &&
+ mkdir sub &&
+ printf "foo" | git -C sub stripspace -c >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success '-c outside git repository' '
+ printf "# foo\n" >expect &&
+ printf "foo" | nongit git stripspace -c >actual &&
test_cmp expect actual
'
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index 17d0c18feb..b8f366c442 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -23,7 +23,6 @@ usage: test-tool parse-options <options>
-j <n> get a integer, too
-m, --magnitude <n> get a magnitude
--set23 set integer to 23
- -t <time> get timestamp of <time>
-L, --length <str> get length of <str>
-F, --file <file> set file to <file>
@@ -228,7 +227,7 @@ EOF
test_expect_success 'detect possible typos' '
test_must_fail test-tool parse-options -boolean >output 2>output.err &&
test_must_be_empty output &&
- test_cmp typo.err output.err
+ test_i18ncmp typo.err output.err
'
cat >typo.err <<\EOF
@@ -238,7 +237,7 @@ EOF
test_expect_success 'detect possible typos' '
test_must_fail test-tool parse-options -ambiguous >output 2>output.err &&
test_must_be_empty output &&
- test_cmp typo.err output.err
+ test_i18ncmp typo.err output.err
'
test_expect_success 'keep some options as arguments' '
@@ -246,27 +245,6 @@ test_expect_success 'keep some options as arguments' '
'
cat >expect <<\EOF
-boolean: 0
-integer: 0
-magnitude: 0
-timestamp: 1
-string: (not set)
-abbrev: 7
-verbose: -1
-quiet: 1
-dry run: no
-file: (not set)
-arg 00: foo
-EOF
-
-test_expect_success 'OPT_DATE() works' '
- test-tool parse-options -t "1970-01-01 00:00:01 +0000" \
- foo -q >output 2>output.err &&
- test_must_be_empty output.err &&
- test_cmp expect output
-'
-
-cat >expect <<\EOF
Callback: "four", 0
boolean: 5
integer: 4
diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh
index cd74c0a471..c7b53e494b 100755
--- a/t/t0060-path-utils.sh
+++ b/t/t0060-path-utils.sh
@@ -306,6 +306,8 @@ test_git_path GIT_COMMON_DIR=bar hooks/me bar/hooks/me
test_git_path GIT_COMMON_DIR=bar config bar/config
test_git_path GIT_COMMON_DIR=bar packed-refs bar/packed-refs
test_git_path GIT_COMMON_DIR=bar shallow bar/shallow
+test_git_path GIT_COMMON_DIR=bar common bar/common
+test_git_path GIT_COMMON_DIR=bar common/file bar/common/file
# In the tests below, $(pwd) must be used because it is a native path on
# Windows and avoids MSYS's path mangling (which simplifies "foo/../bar" and
diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh
index cf932c8514..99a614bc7c 100755
--- a/t/t0061-run-command.sh
+++ b/t/t0061-run-command.sh
@@ -13,11 +13,13 @@ cat >hello-script <<-EOF
EOF
test_expect_success 'start_command reports ENOENT (slash)' '
- test-tool run-command start-command-ENOENT ./does-not-exist
+ test-tool run-command start-command-ENOENT ./does-not-exist 2>err &&
+ test_i18ngrep "\./does-not-exist" err
'
test_expect_success 'start_command reports ENOENT (no slash)' '
- test-tool run-command start-command-ENOENT does-not-exist
+ test-tool run-command start-command-ENOENT does-not-exist 2>err &&
+ test_i18ngrep "does-not-exist" err
'
test_expect_success 'run_command can run a command' '
@@ -29,11 +31,20 @@ test_expect_success 'run_command can run a command' '
test_must_be_empty err
'
-test_expect_success 'run_command is restricted to PATH' '
+
+test_lazy_prereq RUNS_COMMANDS_FROM_PWD '
+ write_script runs-commands-from-pwd <<-\EOF &&
+ true
+ EOF
+ runs-commands-from-pwd >/dev/null 2>&1
+'
+
+test_expect_success !RUNS_COMMANDS_FROM_PWD 'run_command is restricted to PATH' '
write_script should-not-run <<-\EOF &&
echo yikes
EOF
- test_must_fail test-tool run-command run-command should-not-run
+ test_must_fail test-tool run-command run-command should-not-run 2>err &&
+ test_i18ngrep "should-not-run" err
'
test_expect_success !MINGW 'run_command can run a script without a #! line' '
diff --git a/t/t0205-gettext-poison.sh b/t/t0205-gettext-poison.sh
index 438e778d6a..a06269f38a 100755
--- a/t/t0205-gettext-poison.sh
+++ b/t/t0205-gettext-poison.sh
@@ -5,13 +5,15 @@
test_description='Gettext Shell poison'
+GIT_TEST_GETTEXT_POISON=YesPlease
+export GIT_TEST_GETTEXT_POISON
. ./lib-gettext.sh
-test_expect_success GETTEXT_POISON 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
+test_expect_success 'sanity: $GIT_INTERNAL_GETTEXT_SH_SCHEME" is poison' '
test "$GIT_INTERNAL_GETTEXT_SH_SCHEME" = "poison"
'
-test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison semantics' '
+test_expect_success 'gettext: our gettext() fallback has poison semantics' '
printf "# GETTEXT POISON #" >expect &&
gettext "test" >actual &&
test_cmp expect actual &&
@@ -20,7 +22,7 @@ test_expect_success GETTEXT_POISON 'gettext: our gettext() fallback has poison s
test_cmp expect actual
'
-test_expect_success GETTEXT_POISON 'eval_gettext: our eval_gettext() fallback has poison semantics' '
+test_expect_success 'eval_gettext: our eval_gettext() fallback has poison semantics' '
printf "# GETTEXT POISON #" >expect &&
eval_gettext "test" >actual &&
test_cmp expect actual &&
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh
index ba3887f178..bce02788e6 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -349,7 +349,7 @@ test_expect_success 'rev-list stops traversal at promisor commit, tree, and blob
grep $(git -C repo rev-parse bar) out # sanity check that some walking was done
'
-test_expect_success 'rev-list accepts missing and promised objects on command line' '
+test_expect_success 'rev-list dies for missing objects on cmd line' '
rm -rf repo &&
test_create_repo repo &&
test_commit -C repo foo &&
@@ -366,7 +366,19 @@ test_expect_success 'rev-list accepts missing and promised objects on command li
git -C repo config core.repositoryformatversion 1 &&
git -C repo config extensions.partialclone "arbitrary string" &&
- git -C repo rev-list --exclude-promisor-objects --objects "$COMMIT" "$TREE" "$BLOB"
+
+ for OBJ in "$COMMIT" "$TREE" "$BLOB"; do
+ test_must_fail git -C repo rev-list --objects \
+ --exclude-promisor-objects "$OBJ" &&
+ test_must_fail git -C repo rev-list --objects-edge-aggressive \
+ --exclude-promisor-objects "$OBJ" &&
+
+ # Do not die or crash when --ignore-missing is passed.
+ git -C repo rev-list --ignore-missing --objects \
+ --exclude-promisor-objects "$OBJ" &&
+ git -C repo rev-list --ignore-missing --objects-edge-aggressive \
+ --exclude-promisor-objects "$OBJ"
+ done
'
test_expect_success 'gc repacks promisor objects separately from non-promisor objects' '
@@ -480,7 +492,6 @@ test_expect_success 'gc stops traversal when a missing but promised object is re
! grep "$TREE_HASH" out
'
-LIB_HTTPD_PORT=12345 # default port, 410, cannot be used as non-root
. "$TEST_DIRECTORY"/lib-httpd.sh
start_httpd
diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh
index ac1f189fd2..4feb65157d 100755
--- a/t/t1060-object-corruption.sh
+++ b/t/t1060-object-corruption.sh
@@ -117,8 +117,10 @@ test_expect_failure 'clone --local detects misnamed objects' '
'
test_expect_success 'fetch into corrupted repo with index-pack' '
+ cp -R bit-error bit-error-cp &&
+ test_when_finished "rm -rf bit-error-cp" &&
(
- cd bit-error &&
+ cd bit-error-cp &&
test_must_fail git -c transfer.unpackLimit=1 \
fetch ../no-bit-error 2>stderr &&
test_i18ngrep ! -i collision stderr
diff --git a/t/t1300-config.sh b/t/t1300-config.sh
index e2cd50ecfc..9652b241c7 100755
--- a/t/t1300-config.sh
+++ b/t/t1300-config.sh
@@ -76,15 +76,11 @@ EOF
test_expect_success 'non-match result' 'test_cmp expect .git/config'
test_expect_success 'find mixed-case key by canonical name' '
- echo Second >expect &&
- git config cores.whatever >actual &&
- test_cmp expect actual
+ test_cmp_config Second cores.whatever
'
test_expect_success 'find mixed-case key by non-canonical name' '
- echo Second >expect &&
- git config CoReS.WhAtEvEr >actual &&
- test_cmp expect actual
+ test_cmp_config Second CoReS.WhAtEvEr
'
test_expect_success 'subsections are not canonicalized by git-config' '
@@ -94,12 +90,8 @@ test_expect_success 'subsections are not canonicalized by git-config' '
[section "SubSection"]
key = two
EOF
- echo one >expect &&
- git config section.subsection.key >actual &&
- test_cmp expect actual &&
- echo two >expect &&
- git config section.SubSection.key >actual &&
- test_cmp expect actual
+ test_cmp_config one section.subsection.key &&
+ test_cmp_config two section.SubSection.key
'
cat > .git/config <<\EOF
@@ -212,9 +204,7 @@ test_expect_success 'really really mean test' '
'
test_expect_success 'get value' '
- echo alpha >expect &&
- git config beta.haha >actual &&
- test_cmp expect actual
+ test_cmp_config alpha beta.haha
'
cat > expect << EOF
@@ -251,15 +241,11 @@ test_expect_success 'non-match' '
'
test_expect_success 'non-match value' '
- echo wow >expect &&
- git config --get nextsection.nonewline !for >actual &&
- test_cmp expect actual
+ test_cmp_config wow --get nextsection.nonewline !for
'
test_expect_success 'multi-valued get returns final one' '
- echo "wow2 for me" >expect &&
- git config --get nextsection.nonewline >actual &&
- test_cmp expect actual
+ test_cmp_config "wow2 for me" --get nextsection.nonewline
'
test_expect_success 'multi-valued get-all returns all' '
@@ -520,21 +506,11 @@ test_expect_success 'editing stdin is an error' '
test_expect_success 'refer config from subdirectory' '
mkdir x &&
- (
- cd x &&
- echo strasse >expect &&
- git config --get --file ../other-config ein.bahn >actual &&
- test_cmp expect actual
- )
-
+ test_cmp_config -C x strasse --get --file ../other-config ein.bahn
'
test_expect_success 'refer config from subdirectory via --file' '
- (
- cd x &&
- git config --file=../other-config --get ein.bahn >actual &&
- test_cmp expect actual
- )
+ test_cmp_config -C x strasse --file=../other-config --get ein.bahn
'
cat > expect << EOF
@@ -688,16 +664,13 @@ test_expect_success numbers '
test_expect_success '--int is at least 64 bits' '
git config giga.watts 121g &&
- echo 129922760704 >expect &&
- git config --int --get giga.watts >actual &&
- test_cmp expect actual
+ echo >expect &&
+ test_cmp_config 129922760704 --int --get giga.watts
'
test_expect_success 'invalid unit' '
git config aninvalid.unit "1auto" &&
- echo 1auto >expect &&
- git config aninvalid.unit >actual &&
- test_cmp expect actual &&
+ test_cmp_config 1auto aninvalid.unit &&
test_must_fail git config --int --get aninvalid.unit 2>actual &&
test_i18ngrep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
'
@@ -1039,9 +1012,7 @@ test_expect_success '--null --get-regexp' '
test_expect_success 'inner whitespace kept verbatim' '
git config section.val "foo bar" &&
- echo "foo bar" >expect &&
- git config section.val >actual &&
- test_cmp expect actual
+ test_cmp_config "foo bar" section.val
'
test_expect_success SYMLINKS 'symlinked configuration' '
@@ -1809,21 +1780,15 @@ big = 1M
EOF
test_expect_success 'identical modern --type specifiers are allowed' '
- git config --type=int --type=int core.big >actual &&
- echo 1048576 >expect &&
- test_cmp expect actual
+ test_cmp_config 1048576 --type=int --type=int core.big
'
test_expect_success 'identical legacy --type specifiers are allowed' '
- git config --int --int core.big >actual &&
- echo 1048576 >expect &&
- test_cmp expect actual
+ test_cmp_config 1048576 --int --int core.big
'
test_expect_success 'identical mixed --type specifiers are allowed' '
- git config --int --type=int core.big >actual &&
- echo 1048576 >expect &&
- test_cmp expect actual
+ test_cmp_config 1048576 --int --type=int core.big
'
test_expect_success 'non-identical modern --type specifiers are not allowed' '
@@ -1842,21 +1807,15 @@ test_expect_success 'non-identical mixed --type specifiers are not allowed' '
'
test_expect_success '--type allows valid type specifiers' '
- echo "true" >expect &&
- git config --type=bool core.foo >actual &&
- test_cmp expect actual
+ test_cmp_config true --type=bool core.foo
'
test_expect_success '--no-type unsets type specifiers' '
- echo "10" >expect &&
- git config --type=bool --no-type core.number >actual &&
- test_cmp expect actual
+ test_cmp_config 10 --type=bool --no-type core.number
'
test_expect_success 'unset type specifiers may be reset to conflicting ones' '
- echo 1048576 >expect &&
- git config --type=bool --no-type --type=int core.big >actual &&
- test_cmp expect actual
+ test_cmp_config 1048576 --type=bool --no-type --type=int core.big
'
test_expect_success '--type rejects unknown specifiers' '
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index 388b0611d8..ae8a448e34 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -20,12 +20,12 @@ check_have () {
}
check_fsck () {
- output=$(git fsck --full)
+ git fsck --full >fsck.output
case "$1" in
'')
- test -z "$output" ;;
+ test_must_be_empty fsck.output ;;
*)
- echo "$output" | grep "$1" ;;
+ test_i18ngrep "$1" fsck.output ;;
esac
}
@@ -368,4 +368,19 @@ test_expect_success 'continue walking past root commits' '
)
'
+test_expect_success 'expire with multiple worktrees' '
+ git init main-wt &&
+ (
+ cd main-wt &&
+ test_tick &&
+ test_commit foo &&
+ git worktree add link-wt &&
+ test_tick &&
+ test_commit -C link-wt foobar &&
+ test_tick &&
+ git reflog expire --verbose --all --expire=$test_tick &&
+ test_must_be_empty .git/worktrees/link-wt/logs/HEAD
+ )
+'
+
test_done
diff --git a/t/t1415-worktree-refs.sh b/t/t1415-worktree-refs.sh
new file mode 100755
index 0000000000..b664e51250
--- /dev/null
+++ b/t/t1415-worktree-refs.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+test_description='per-worktree refs'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit initial &&
+ test_commit wt1 &&
+ test_commit wt2 &&
+ git worktree add wt1 wt1 &&
+ git worktree add wt2 wt2 &&
+ git checkout initial &&
+ git update-ref refs/worktree/foo HEAD &&
+ git -C wt1 update-ref refs/worktree/foo HEAD &&
+ git -C wt2 update-ref refs/worktree/foo HEAD
+'
+
+test_expect_success 'refs/worktree must not be packed' '
+ git pack-refs --all &&
+ test_path_is_missing .git/refs/tags/wt1 &&
+ test_path_is_file .git/refs/worktree/foo &&
+ test_path_is_file .git/worktrees/wt1/refs/worktree/foo &&
+ test_path_is_file .git/worktrees/wt2/refs/worktree/foo
+'
+
+test_expect_success 'refs/worktree are per-worktree' '
+ test_cmp_rev worktree/foo initial &&
+ ( cd wt1 && test_cmp_rev worktree/foo wt1 ) &&
+ ( cd wt2 && test_cmp_rev worktree/foo wt2 )
+'
+
+test_expect_success 'resolve main-worktree/HEAD' '
+ test_cmp_rev main-worktree/HEAD initial &&
+ ( cd wt1 && test_cmp_rev main-worktree/HEAD initial ) &&
+ ( cd wt2 && test_cmp_rev main-worktree/HEAD initial )
+'
+
+test_expect_success 'ambiguous main-worktree/HEAD' '
+ mkdir -p .git/refs/heads/main-worktree &&
+ test_when_finished rm -f .git/refs/heads/main-worktree/HEAD &&
+ cp .git/HEAD .git/refs/heads/main-worktree/HEAD &&
+ git rev-parse main-worktree/HEAD 2>warn &&
+ grep "main-worktree/HEAD.*ambiguous" warn
+'
+
+test_expect_success 'resolve worktrees/xx/HEAD' '
+ test_cmp_rev worktrees/wt1/HEAD wt1 &&
+ ( cd wt1 && test_cmp_rev worktrees/wt1/HEAD wt1 ) &&
+ ( cd wt2 && test_cmp_rev worktrees/wt1/HEAD wt1 )
+'
+
+test_expect_success 'ambiguous worktrees/xx/HEAD' '
+ mkdir -p .git/refs/heads/worktrees/wt1 &&
+ test_when_finished rm -f .git/refs/heads/worktrees/wt1/HEAD &&
+ cp .git/HEAD .git/refs/heads/worktrees/wt1/HEAD &&
+ git rev-parse worktrees/wt1/HEAD 2>warn &&
+ grep "worktrees/wt1/HEAD.*ambiguous" warn
+'
+
+test_expect_success 'reflog of main-worktree/HEAD' '
+ git reflog HEAD | sed "s/HEAD/main-worktree\/HEAD/" >expected &&
+ git reflog main-worktree/HEAD >actual &&
+ test_cmp expected actual &&
+ git -C wt1 reflog main-worktree/HEAD >actual.wt1 &&
+ test_cmp expected actual.wt1
+'
+
+test_expect_success 'reflog of worktrees/xx/HEAD' '
+ git -C wt2 reflog HEAD | sed "s/HEAD/worktrees\/wt2\/HEAD/" >expected &&
+ git reflog worktrees/wt2/HEAD >actual &&
+ test_cmp expected actual &&
+ git -C wt1 reflog worktrees/wt2/HEAD >actual.wt1 &&
+ test_cmp expected actual.wt1 &&
+ git -C wt2 reflog worktrees/wt2/HEAD >actual.wt2 &&
+ test_cmp expected actual.wt2
+'
+
+test_done
diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh
index 0f2dd26f74..2e5e979336 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -70,7 +70,7 @@ test_expect_success 'object with bad sha1' '
test_must_fail git fsck 2>out &&
cat out &&
- grep "$sha.*corrupt" out
+ test_i18ngrep "$sha.*corrupt" out
'
test_expect_success 'branch pointing to non-commit' '
@@ -78,7 +78,7 @@ test_expect_success 'branch pointing to non-commit' '
test_when_finished "git update-ref -d refs/heads/invalid" &&
test_must_fail git fsck 2>out &&
cat out &&
- grep "not a commit" out
+ test_i18ngrep "not a commit" out
'
test_expect_success 'HEAD link pointing at a funny object' '
@@ -88,7 +88,7 @@ test_expect_success 'HEAD link pointing at a funny object' '
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
cat out &&
- grep "detached HEAD points" out
+ test_i18ngrep "detached HEAD points" out
'
test_expect_success 'HEAD link pointing at a funny place' '
@@ -98,7 +98,42 @@ test_expect_success 'HEAD link pointing at a funny place' '
# avoid corrupt/broken HEAD from interfering with repo discovery
test_must_fail env GIT_DIR=.git git fsck 2>out &&
cat out &&
- grep "HEAD points to something strange" out
+ test_i18ngrep "HEAD points to something strange" out
+'
+
+test_expect_success 'HEAD link pointing at a funny object (from different wt)' '
+ test_when_finished "mv .git/SAVED_HEAD .git/HEAD" &&
+ test_when_finished "rm -rf .git/worktrees wt" &&
+ git worktree add wt &&
+ mv .git/HEAD .git/SAVED_HEAD &&
+ echo $ZERO_OID >.git/HEAD &&
+ # avoid corrupt/broken HEAD from interfering with repo discovery
+ test_must_fail git -C wt fsck 2>out &&
+ test_i18ngrep "main-worktree/HEAD: detached HEAD points" out
+'
+
+test_expect_success 'other worktree HEAD link pointing at a funny object' '
+ test_when_finished "rm -rf .git/worktrees other" &&
+ git worktree add other &&
+ echo $ZERO_OID >.git/worktrees/other/HEAD &&
+ test_must_fail git fsck 2>out &&
+ test_i18ngrep "worktrees/other/HEAD: detached HEAD points" out
+'
+
+test_expect_success 'other worktree HEAD link pointing at missing object' '
+ test_when_finished "rm -rf .git/worktrees other" &&
+ git worktree add other &&
+ echo "Contents missing from repo" | git hash-object --stdin >.git/worktrees/other/HEAD &&
+ test_must_fail git fsck 2>out &&
+ test_i18ngrep "worktrees/other/HEAD: invalid sha1 pointer" out
+'
+
+test_expect_success 'other worktree HEAD link pointing at a funny place' '
+ test_when_finished "rm -rf .git/worktrees other" &&
+ git worktree add other &&
+ echo "ref: refs/funny/place" >.git/worktrees/other/HEAD &&
+ test_must_fail git fsck 2>out &&
+ test_i18ngrep "worktrees/other/HEAD points to something strange" out
'
test_expect_success 'email without @ is okay' '
@@ -122,7 +157,7 @@ test_expect_success 'email with embedded > is not okay' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
cat out &&
- grep "error in commit $new" out
+ test_i18ngrep "error in commit $new" out
'
test_expect_success 'missing < email delimiter is reported nicely' '
@@ -134,7 +169,7 @@ test_expect_success 'missing < email delimiter is reported nicely' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
cat out &&
- grep "error in commit $new.* - bad name" out
+ test_i18ngrep "error in commit $new.* - bad name" out
'
test_expect_success 'missing email is reported nicely' '
@@ -146,7 +181,7 @@ test_expect_success 'missing email is reported nicely' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
cat out &&
- grep "error in commit $new.* - missing email" out
+ test_i18ngrep "error in commit $new.* - missing email" out
'
test_expect_success '> in name is reported' '
@@ -158,7 +193,7 @@ test_expect_success '> in name is reported' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
cat out &&
- grep "error in commit $new" out
+ test_i18ngrep "error in commit $new" out
'
# date is 2^64 + 1
@@ -172,7 +207,7 @@ test_expect_success 'integer overflow in timestamps is reported' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
cat out &&
- grep "error in commit $new.*integer overflow" out
+ test_i18ngrep "error in commit $new.*integer overflow" out
'
test_expect_success 'commit with NUL in header' '
@@ -184,7 +219,7 @@ test_expect_success 'commit with NUL in header' '
test_when_finished "git update-ref -d refs/heads/bogus" &&
test_must_fail git fsck 2>out &&
cat out &&
- grep "error in commit $new.*unterminated header: NUL at offset" out
+ test_i18ngrep "error in commit $new.*unterminated header: NUL at offset" out
'
test_expect_success 'tree object with duplicate entries' '
@@ -205,7 +240,7 @@ test_expect_success 'tree object with duplicate entries' '
git hash-object -w -t tree --stdin
) &&
test_must_fail git fsck 2>out &&
- grep "error in tree .*contains duplicate file entries" out
+ test_i18ngrep "error in tree .*contains duplicate file entries" out
'
test_expect_success 'unparseable tree object' '
@@ -259,7 +294,7 @@ test_expect_success 'tag pointing to nonexistent' '
test_when_finished "git update-ref -d refs/tags/invalid" &&
test_must_fail git fsck --tags >out &&
cat out &&
- grep "broken link" out
+ test_i18ngrep "broken link" out
'
test_expect_success 'tag pointing to something else than its type' '
@@ -301,7 +336,7 @@ test_expect_success 'tag with incorrect tag name & missing tagger' '
warning in tag $tag: badTagName: invalid '\''tag'\'' name: wrong name format
warning in tag $tag: missingTaggerEntry: invalid format - expected '\''tagger'\'' line
EOF
- test_cmp expect out
+ test_i18ncmp expect out
'
test_expect_success 'tag with bad tagger' '
@@ -320,7 +355,7 @@ test_expect_success 'tag with bad tagger' '
echo $tag >.git/refs/tags/wrong &&
test_when_finished "git update-ref -d refs/tags/wrong" &&
test_must_fail git fsck --tags 2>out &&
- grep "error in tag .*: invalid author/committer" out
+ test_i18ngrep "error in tag .*: invalid author/committer" out
'
test_expect_success 'tag with NUL in header' '
@@ -340,7 +375,7 @@ test_expect_success 'tag with NUL in header' '
test_when_finished "git update-ref -d refs/tags/wrong" &&
test_must_fail git fsck --tags 2>out &&
cat out &&
- grep "error in tag $tag.*unterminated header: NUL at offset" out
+ test_i18ngrep "error in tag $tag.*unterminated header: NUL at offset" out
'
test_expect_success 'cleaned up' '
@@ -396,7 +431,7 @@ test_expect_success 'fsck notices blob entry pointing to null sha1' '
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
cat out &&
- grep "warning.*null sha1" out
+ test_i18ngrep "warning.*null sha1" out
)
'
@@ -407,7 +442,7 @@ test_expect_success 'fsck notices submodule entry pointing to null sha1' '
git hash-object -w --stdin -t tree) &&
git fsck 2>out &&
cat out &&
- grep "warning.*null sha1" out
+ test_i18ngrep "warning.*null sha1" out
)
'
@@ -428,7 +463,7 @@ while read name path pretty; do
bad_tree=$(git mktree <bad) &&
git fsck 2>out &&
cat out &&
- grep "warning.*tree $bad_tree" out
+ test_i18ngrep "warning.*tree $bad_tree" out
)'
done <<-\EOF
100644 blob
@@ -474,9 +509,9 @@ test_expect_success 'NUL in commit' '
git branch bad $(cat name) &&
test_must_fail git -c fsck.nulInCommit=error fsck 2>warn.1 &&
- grep nulInCommit warn.1 &&
+ test_i18ngrep nulInCommit warn.1 &&
git fsck 2>warn.2 &&
- grep nulInCommit warn.2
+ test_i18ngrep nulInCommit warn.2
)
'
@@ -594,7 +629,7 @@ test_expect_success 'fsck --name-objects' '
remove_object $(git rev-parse julius:caesar.t) &&
test_must_fail git fsck --name-objects >out &&
tree=$(git rev-parse --verify julius:) &&
- egrep "$tree \((refs/heads/master|HEAD)@\{[0-9]*\}:" out
+ test_i18ngrep -E "$tree \((refs/heads/master|HEAD)@\{[0-9]*\}:" out
)
'
@@ -605,7 +640,7 @@ test_expect_success 'alternate objects are correctly blamed' '
mkdir alt.git/objects/12 &&
>alt.git/objects/12/34567890123456789012345678901234567890 &&
test_must_fail git fsck >out 2>&1 &&
- grep alt.git out
+ test_i18ngrep alt.git out
'
test_expect_success 'fsck errors in packed objects' '
@@ -624,8 +659,8 @@ test_expect_success 'fsck errors in packed objects' '
remove_object $one &&
remove_object $two &&
test_must_fail git fsck 2>out &&
- grep "error in commit $one.* - bad name" out &&
- grep "error in commit $two.* - bad name" out &&
+ test_i18ngrep "error in commit $one.* - bad name" out &&
+ test_i18ngrep "error in commit $two.* - bad name" out &&
! grep corrupt out
'
@@ -673,16 +708,35 @@ test_expect_success 'fsck detects trailing loose garbage (commit)' '
test_i18ngrep "garbage.*$commit" out
'
-test_expect_success 'fsck detects trailing loose garbage (blob)' '
+test_expect_success 'fsck detects trailing loose garbage (large blob)' '
blob=$(echo trailing | git hash-object -w --stdin) &&
file=$(sha1_file $blob) &&
test_when_finished "remove_object $blob" &&
chmod +w "$file" &&
echo garbage >>"$file" &&
- test_must_fail git fsck 2>out &&
+ test_must_fail git -c core.bigfilethreshold=5 fsck 2>out &&
test_i18ngrep "garbage.*$blob" out
'
+test_expect_success 'fsck detects truncated loose object' '
+ # make it big enough that we know we will truncate in the data
+ # portion, not the header
+ test-tool genrandom truncate 4096 >file &&
+ blob=$(git hash-object -w file) &&
+ file=$(sha1_file $blob) &&
+ test_when_finished "remove_object $blob" &&
+ test_copy_bytes 1024 <"$file" >tmp &&
+ rm "$file" &&
+ mv -f tmp "$file" &&
+
+ # check both regular and streaming code paths
+ test_must_fail git fsck 2>out &&
+ test_i18ngrep corrupt.*$blob out &&
+
+ test_must_fail git -c core.bigfilethreshold=128 fsck 2>out &&
+ test_i18ngrep corrupt.*$blob out
+'
+
# for each of type, we have one version which is referenced by another object
# (and so while unreachable, not dangling), and another variant which really is
# dangling.
@@ -706,7 +760,7 @@ test_expect_success 'fsck notices dangling objects' '
git fsck >actual &&
# the output order is non-deterministic, as it comes from a hash
sort <actual >actual.sorted &&
- test_cmp expect actual.sorted
+ test_i18ncmp expect actual.sorted
)
'
@@ -754,7 +808,7 @@ test_expect_success 'detect corrupt index file in fsck' '
test_when_finished "mv .git/index.backup .git/index" &&
corrupt_index_checksum &&
test_must_fail git fsck --cache 2>errors &&
- grep "bad index file" errors
+ test_i18ngrep "bad index file" errors
'
test_done
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index 2ac47aa0e4..4667e1a190 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -25,14 +25,17 @@ test_expect_success 'enable split index' '
git update-index --split-index &&
test-tool dump-split-index .git/index >actual &&
indexversion=$(test-tool index-version <.git/index) &&
+
+ # NEEDSWORK: Stop hard-coding checksums.
if test "$indexversion" = "4"
then
- own=3527df833c6c100d3d1d921a9a782d62a8be4b58
- base=746f7ab2ed44fb839efdfbffcf399d0b113fb4cb
+ own=432ef4b63f32193984f339431fd50ca796493569
+ base=508851a7f0dfa8691e9f69c7f055865389012491
else
- own=5e9b60117ece18da410ddecc8b8d43766a0e4204
- base=4370042739b31cd17a5c5cd6043a77c9a00df113
+ own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
+ base=39d890139ee5356c7ef572216cebcd27aa41f9df
fi &&
+
cat >expect <<-EOF &&
own $own
base $base
@@ -381,6 +384,26 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"
test $(ls .git/sharedindex.* | wc -l) -le 2
'
+test_expect_success POSIXPERM 'same mode for index & split index' '
+ git init same-mode &&
+ (
+ cd same-mode &&
+ test_commit A &&
+ test_modebits .git/index >index_mode &&
+ test_must_fail git config core.sharedRepository &&
+ git -c core.splitIndex=true status &&
+ shared=$(ls .git/sharedindex.*) &&
+ case "$shared" in
+ *" "*)
+ # we have more than one???
+ false ;;
+ *)
+ test_modebits "$shared" >split_index_mode &&
+ test_cmp index_mode split_index_mode ;;
+ esac
+ )
+'
+
while read -r mode modebits
do
test_expect_success POSIXPERM "split index respects core.sharedrepository $mode" '
diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh
index 69b6774d10..fa0718c730 100755
--- a/t/t2024-checkout-dwim.sh
+++ b/t/t2024-checkout-dwim.sh
@@ -278,4 +278,35 @@ test_expect_success 'loosely defined local base branch is reported correctly' '
test_cmp expect actual
'
+test_expect_success 'reject when arg could be part of dwim branch' '
+ git remote add foo file://non-existent-place &&
+ git update-ref refs/remotes/foo/dwim-arg HEAD &&
+ echo foo >dwim-arg &&
+ git add dwim-arg &&
+ echo bar >dwim-arg &&
+ test_must_fail git checkout dwim-arg &&
+ test_must_fail git rev-parse refs/heads/dwim-arg -- &&
+ grep bar dwim-arg
+'
+
+test_expect_success 'disambiguate dwim branch and checkout path (1)' '
+ git update-ref refs/remotes/foo/dwim-arg1 HEAD &&
+ echo foo >dwim-arg1 &&
+ git add dwim-arg1 &&
+ echo bar >dwim-arg1 &&
+ git checkout -- dwim-arg1 &&
+ test_must_fail git rev-parse refs/heads/dwim-arg1 -- &&
+ grep foo dwim-arg1
+'
+
+test_expect_success 'disambiguate dwim branch and checkout path (2)' '
+ git update-ref refs/remotes/foo/dwim-arg2 HEAD &&
+ echo foo >dwim-arg2 &&
+ git add dwim-arg2 &&
+ echo bar >dwim-arg2 &&
+ git checkout dwim-arg2 -- &&
+ git rev-parse refs/heads/dwim-arg2 -- &&
+ grep bar dwim-arg2
+'
+
test_done
diff --git a/t/t2028-worktree-move.sh b/t/t2028-worktree-move.sh
index 33c0337733..939d18d728 100755
--- a/t/t2028-worktree-move.sh
+++ b/t/t2028-worktree-move.sh
@@ -112,6 +112,26 @@ test_expect_success 'move locked worktree (force)' '
git worktree move --force --force flump ploof
'
+test_expect_success 'move a repo with uninitialized submodule' '
+ git init withsub &&
+ (
+ cd withsub &&
+ test_commit initial &&
+ git submodule add "$PWD"/.git sub &&
+ git commit -m withsub &&
+ git worktree add second HEAD &&
+ git worktree move second third
+ )
+'
+
+test_expect_success 'not move a repo with initialized submodule' '
+ (
+ cd withsub &&
+ git -C third submodule update &&
+ test_must_fail git worktree move third forth
+ )
+'
+
test_expect_success 'remove main worktree' '
test_must_fail git worktree remove .
'
@@ -185,4 +205,21 @@ test_expect_success 'remove cleans up .git/worktrees when empty' '
)
'
+test_expect_success 'remove a repo with uninitialized submodule' '
+ (
+ cd withsub &&
+ git worktree add to-remove HEAD &&
+ git worktree remove to-remove
+ )
+'
+
+test_expect_success 'not remove a repo with initialized submodule' '
+ (
+ cd withsub &&
+ git worktree add to-remove HEAD &&
+ git -C to-remove submodule update &&
+ test_must_fail git worktree remove to-remove
+ )
+'
+
test_done
diff --git a/t/t2029-worktree-config.sh b/t/t2029-worktree-config.sh
new file mode 100755
index 0000000000..286121d8de
--- /dev/null
+++ b/t/t2029-worktree-config.sh
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+test_description="config file in multi worktree"
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit start
+'
+
+test_expect_success 'config --worktree in single worktree' '
+ git config --worktree foo.bar true &&
+ test_cmp_config true foo.bar
+'
+
+test_expect_success 'add worktrees' '
+ git worktree add wt1 &&
+ git worktree add wt2
+'
+
+test_expect_success 'config --worktree without extension' '
+ test_must_fail git config --worktree foo.bar false
+'
+
+test_expect_success 'enable worktreeConfig extension' '
+ git config extensions.worktreeConfig true &&
+ test_cmp_config true extensions.worktreeConfig
+'
+
+test_expect_success 'config is shared as before' '
+ git config this.is shared &&
+ test_cmp_config shared this.is &&
+ test_cmp_config -C wt1 shared this.is &&
+ test_cmp_config -C wt2 shared this.is
+'
+
+test_expect_success 'config is shared (set from another worktree)' '
+ git -C wt1 config that.is also-shared &&
+ test_cmp_config also-shared that.is &&
+ test_cmp_config -C wt1 also-shared that.is &&
+ test_cmp_config -C wt2 also-shared that.is
+'
+
+test_expect_success 'config private to main worktree' '
+ git config --worktree this.is for-main &&
+ test_cmp_config for-main this.is &&
+ test_cmp_config -C wt1 shared this.is &&
+ test_cmp_config -C wt2 shared this.is
+'
+
+test_expect_success 'config private to linked worktree' '
+ git -C wt1 config --worktree this.is for-wt1 &&
+ test_cmp_config for-main this.is &&
+ test_cmp_config -C wt1 for-wt1 this.is &&
+ test_cmp_config -C wt2 shared this.is
+'
+
+test_expect_success 'core.bare no longer for main only' '
+ test_config core.bare true &&
+ test "$(git rev-parse --is-bare-repository)" = true &&
+ test "$(git -C wt1 rev-parse --is-bare-repository)" = true &&
+ test "$(git -C wt2 rev-parse --is-bare-repository)" = true
+'
+
+test_expect_success 'per-worktree core.bare is picked up' '
+ git -C wt1 config --worktree core.bare true &&
+ test "$(git rev-parse --is-bare-repository)" = false &&
+ test "$(git -C wt1 rev-parse --is-bare-repository)" = true &&
+ test "$(git -C wt2 rev-parse --is-bare-repository)" = false
+'
+
+test_expect_success 'config.worktree no longer read without extension' '
+ git config --unset extensions.worktreeConfig &&
+ test_cmp_config shared this.is &&
+ test_cmp_config -C wt1 shared this.is &&
+ test_cmp_config -C wt2 shared this.is
+'
+
+test_done
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index 46aca0af10..891d4d7cb9 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -237,7 +237,7 @@ match 0 0 0 0 foobar 'foo\*bar'
match 1 1 1 1 'f\oo' 'f\\oo'
match 1 1 1 1 ball '*[al]?'
match 0 0 0 0 ten '[ten]'
-match 0 0 1 1 ten '**[!te]'
+match 1 1 1 1 ten '**[!te]'
match 0 0 0 0 ten '**[!ten]'
match 1 1 1 1 ten 't[a-g]n'
match 0 0 0 0 ten 't[!a-g]n'
@@ -253,7 +253,7 @@ match 1 1 1 1 ']' ']'
# Extended slash-matching features
match 0 0 1 1 'foo/baz/bar' 'foo*bar'
match 0 0 1 1 'foo/baz/bar' 'foo**bar'
-match 0 0 1 1 'foobazbar' 'foo**bar'
+match 1 1 1 1 'foobazbar' 'foo**bar'
match 1 1 1 1 'foo/baz/bar' 'foo/**/bar'
match 1 1 0 0 'foo/baz/bar' 'foo/**/**/bar'
match 1 1 1 1 'foo/b/a/z/bar' 'foo/**/bar'
diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh
index 6aae364171..048feaf6dd 100755
--- a/t/t3206-range-diff.sh
+++ b/t/t3206-range-diff.sh
@@ -122,6 +122,36 @@ test_expect_success 'changed commit' '
test_cmp expected actual
'
+test_expect_success 'changed commit with --no-patch diff option' '
+ git range-diff --no-color --no-patch topic...changed >actual &&
+ cat >expected <<-EOF &&
+ 1: 4de457d = 1: a4b3333 s/5/A/
+ 2: fccce22 = 2: f51d370 s/4/A/
+ 3: 147e64e ! 3: 0559556 s/11/B/
+ 4: a63e992 ! 4: d966c5c s/12/B/
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'changed commit with --stat diff option' '
+ git range-diff --no-color --stat topic...changed >actual &&
+ cat >expected <<-EOF &&
+ 1: 4de457d = 1: a4b3333 s/5/A/
+ a => b | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ 2: fccce22 = 2: f51d370 s/4/A/
+ a => b | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ 3: 147e64e ! 3: 0559556 s/11/B/
+ a => b | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ 4: a63e992 ! 4: d966c5c s/12/B/
+ a => b | 0
+ 1 file changed, 0 insertions(+), 0 deletions(-)
+ EOF
+ test_cmp expected actual
+'
+
test_expect_success 'changed commit with sm config' '
git range-diff --no-color --submodule=log topic...changed >actual &&
cat >expected <<-EOF &&
@@ -218,18 +248,24 @@ test_expect_success 'dual-coloring' '
for prev in topic master..topic
do
test_expect_success "format-patch --range-diff=$prev" '
- git format-patch --stdout --cover-letter --range-diff=$prev \
+ git format-patch --cover-letter --range-diff=$prev \
master..unmodified >actual &&
- grep "= 1: .* s/5/A" actual &&
- grep "= 2: .* s/4/A" actual &&
- grep "= 3: .* s/11/B" actual &&
- grep "= 4: .* s/12/B" actual
+ test_when_finished "rm 000?-*" &&
+ test_line_count = 5 actual &&
+ test_i18ngrep "^Range-diff:$" 0000-* &&
+ grep "= 1: .* s/5/A" 0000-* &&
+ grep "= 2: .* s/4/A" 0000-* &&
+ grep "= 3: .* s/11/B" 0000-* &&
+ grep "= 4: .* s/12/B" 0000-*
'
done
test_expect_success 'format-patch --range-diff as commentary' '
- git format-patch --stdout --range-diff=HEAD~1 HEAD~1 >actual &&
- test_i18ngrep "^Range-diff:$" actual
+ git format-patch --range-diff=HEAD~1 HEAD~1 >actual &&
+ test_when_finished "rm 0001-*" &&
+ test_line_count = 1 actual &&
+ test_i18ngrep "^Range-diff:$" 0001-* &&
+ grep "> 1: .* new message" 0001-*
'
test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index f6737e162f..7a440e08d8 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -322,7 +322,7 @@ test_expect_success 'retain authorship when squashing' '
git show HEAD | grep "^Author: Twerp Snog"
'
-test_expect_success '-p handles "no changes" gracefully' '
+test_expect_success REBASE_P '-p handles "no changes" gracefully' '
HEAD=$(git rev-parse HEAD) &&
set_fake_editor &&
git rebase -i -p HEAD^ &&
@@ -332,7 +332,7 @@ test_expect_success '-p handles "no changes" gracefully' '
test $HEAD = $(git rev-parse HEAD)
'
-test_expect_failure 'exchange two commits with -p' '
+test_expect_failure REBASE_P 'exchange two commits with -p' '
git checkout H &&
set_fake_editor &&
FAKE_LINES="2 1" git rebase -i -p HEAD~2 &&
@@ -340,7 +340,7 @@ test_expect_failure 'exchange two commits with -p' '
test G = $(git cat-file commit HEAD | sed -ne \$p)
'
-test_expect_success 'preserve merges with -p' '
+test_expect_success REBASE_P 'preserve merges with -p' '
git checkout -b to-be-preserved master^ &&
: > unrelated-file &&
git add unrelated-file &&
@@ -383,7 +383,7 @@ test_expect_success 'preserve merges with -p' '
test $(git show HEAD:unrelated-file) = 1
'
-test_expect_success 'edit ancestor with -p' '
+test_expect_success REBASE_P 'edit ancestor with -p' '
set_fake_editor &&
FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3 &&
echo 2 > unrelated-file &&
@@ -397,6 +397,7 @@ test_expect_success 'edit ancestor with -p' '
'
test_expect_success '--continue tries to commit' '
+ git reset --hard D &&
test_tick &&
set_fake_editor &&
test_must_fail git rebase -i --onto new-branch1 HEAD^ &&
@@ -436,7 +437,7 @@ test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '
git rebase -i $base &&
test $base = $(git rev-parse HEAD^) &&
test 0 = $(git show | grep NEVER | wc -l) &&
- git checkout to-be-rebased &&
+ git checkout @{-1} &&
git branch -D multi-fixup
'
@@ -451,7 +452,7 @@ test_expect_success 'commit message used after conflict' '
git rebase --continue &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
- git checkout to-be-rebased &&
+ git checkout @{-1} &&
git branch -D conflict-fixup
'
@@ -466,7 +467,7 @@ test_expect_success 'commit message retained after conflict' '
git rebase --continue &&
test $base = $(git rev-parse HEAD^) &&
test 2 = $(git show | grep TWICE | wc -l) &&
- git checkout to-be-rebased &&
+ git checkout @{-1} &&
git branch -D conflict-squash
'
@@ -491,7 +492,7 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa
grep "^# This is a combination of 3 commits\." &&
git cat-file commit HEAD@{3} |
grep "^# This is a combination of 2 commits\." &&
- git checkout to-be-rebased &&
+ git checkout @{-1} &&
git branch -D squash-fixup
'
@@ -504,7 +505,7 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '
git rebase -i $base &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
- git checkout to-be-rebased &&
+ git checkout @{-1} &&
git branch -D skip-comments
'
@@ -517,7 +518,7 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '
git rebase -i $base &&
test $base = $(git rev-parse HEAD^) &&
test 1 = $(git show | grep ONCE | wc -l) &&
- git checkout to-be-rebased &&
+ git checkout @{-1} &&
git branch -D skip-blank-lines
'
@@ -658,7 +659,7 @@ test_expect_success 'rebase with a file named HEAD in worktree' '
) &&
set_fake_editor &&
- FAKE_LINES="1 squash 2" git rebase -i to-be-rebased &&
+ FAKE_LINES="1 squash 2" git rebase -i @{-1} &&
test "$(git show -s --pretty=format:%an)" = "Squashed Away"
'
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 0392e36d23..f64b130cb8 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -77,11 +77,54 @@ test_expect_success 'rebase -n overrides config rebase.stat config' '
# "Does not point to a valid commit: invalid-ref"
#
# NEEDSWORK: This "grep" is fine in real non-C locales, but
-# GETTEXT_POISON poisons the refname along with the enclosing
+# GIT_TEST_GETTEXT_POISON poisons the refname along with the enclosing
# error message.
test_expect_success 'rebase --onto outputs the invalid ref' '
test_must_fail git rebase --onto invalid-ref HEAD HEAD 2>err &&
test_i18ngrep "invalid-ref" err
'
+test_expect_success 'error out early upon -C<n> or --whitespace=<bad>' '
+ test_must_fail git rebase -Cnot-a-number HEAD 2>err &&
+ test_i18ngrep "numerical value" err &&
+ test_must_fail git rebase --whitespace=bad HEAD 2>err &&
+ test_i18ngrep "Invalid whitespace option" err
+'
+
+test_expect_success 'GIT_REFLOG_ACTION' '
+ git checkout start &&
+ test_commit reflog-onto &&
+ git checkout -b reflog-topic start &&
+ test_commit reflog-to-rebase &&
+
+ 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
+ EOF
+ test_cmp expect actual &&
+
+ git checkout -b reflog-prefix reflog-to-rebase &&
+ 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
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'rebase -i onto unrelated history' '
+ git init unrelated &&
+ test_commit -C unrelated 1 &&
+ git -C unrelated remote add -f origin "$PWD" &&
+ git -C unrelated branch --set-upstream-to=origin/master &&
+ git -C unrelated -c core.editor=true rebase -i -v --stat >actual &&
+ test_i18ngrep "Changes to " actual &&
+ test_i18ngrep "5 files changed" actual
+'
+
test_done
diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh
index e7292f5b9b..d2bd7c17b0 100755
--- a/t/t3408-rebase-multi-line.sh
+++ b/t/t3408-rebase-multi-line.sh
@@ -52,7 +52,7 @@ test_expect_success rebase '
test_cmp expect actual
'
-test_expect_success rebasep '
+test_expect_success REBASE_P rebasep '
git checkout side-merge &&
git rebase -p side &&
diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh
index 8c251c57a6..3b340f1ece 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -8,6 +8,11 @@ Run "git rebase -p" and check that merges are properly carried along
'
. ./test-lib.sh
+if ! test_have_prereq REBASE_P; then
+ skip_all='skipping git rebase -p tests, as asked for'
+ test_done
+fi
+
GIT_AUTHOR_EMAIL=bogus_email_address
export GIT_AUTHOR_EMAIL
diff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh
index 6f73b95558..2e29866993 100755
--- a/t/t3410-rebase-preserve-dropped-merges.sh
+++ b/t/t3410-rebase-preserve-dropped-merges.sh
@@ -11,6 +11,11 @@ rewritten.
'
. ./test-lib.sh
+if ! test_have_prereq REBASE_P; then
+ skip_all='skipping git rebase -p tests, as asked for'
+ test_done
+fi
+
# set up two branches like this:
#
# A - B - C - D - E
diff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh
index dc81bf27eb..fb45e7bf7b 100755
--- a/t/t3411-rebase-preserve-around-merges.sh
+++ b/t/t3411-rebase-preserve-around-merges.sh
@@ -10,6 +10,11 @@ a merge to before the merge.
'
. ./test-lib.sh
+if ! test_have_prereq REBASE_P; then
+ skip_all='skipping git rebase -p tests, as asked for'
+ test_done
+fi
+
. "$TEST_DIRECTORY"/lib-rebase.sh
set_fake_editor
diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh
index 73a39f2923..21632a984e 100755
--- a/t/t3412-rebase-root.sh
+++ b/t/t3412-rebase-root.sh
@@ -86,14 +86,14 @@ test_expect_success 'pre-rebase got correct input (4)' '
test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work4
'
-test_expect_success 'rebase -i -p with linear history' '
+test_expect_success REBASE_P 'rebase -i -p with linear history' '
git checkout -b work5 other &&
git rebase -i -p --root --onto master &&
git log --pretty=tformat:"%s" > rebased5 &&
test_cmp expect rebased5
'
-test_expect_success 'pre-rebase got correct input (5)' '
+test_expect_success REBASE_P 'pre-rebase got correct input (5)' '
test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,
'
@@ -120,7 +120,7 @@ commit work6~4
1
EOF
-test_expect_success 'rebase -i -p with merge' '
+test_expect_success REBASE_P 'rebase -i -p with merge' '
git checkout -b work6 other &&
git rebase -i -p --root --onto master &&
log_with_names work6 > rebased6 &&
@@ -155,7 +155,7 @@ commit work7~5
1
EOF
-test_expect_success 'rebase -i -p with two roots' '
+test_expect_success REBASE_P 'rebase -i -p with two roots' '
git checkout -b work7 other &&
git rebase -i -p --root --onto master &&
log_with_names work7 > rebased7 &&
@@ -261,7 +261,7 @@ commit conflict3~6
1
EOF
-test_expect_success 'rebase -i -p --root with conflict (first part)' '
+test_expect_success REBASE_P 'rebase -i -p --root with conflict (first part)' '
git checkout -b conflict3 other &&
test_must_fail git rebase -i -p --root --onto master &&
git ls-files -u | grep "B$"
@@ -272,7 +272,7 @@ test_expect_success 'fix the conflict' '
git add B
'
-test_expect_success 'rebase -i -p --root with conflict (second part)' '
+test_expect_success REBASE_P 'rebase -i -p --root with conflict (second part)' '
git rebase --continue &&
log_with_names conflict3 >out &&
test_cmp expect-conflict-p out
diff --git a/t/t3414-rebase-preserve-onto.sh b/t/t3414-rebase-preserve-onto.sh
index ee0a6cccfd..72e04b5386 100755
--- a/t/t3414-rebase-preserve-onto.sh
+++ b/t/t3414-rebase-preserve-onto.sh
@@ -10,6 +10,11 @@ aren'"'"'t on top of $ONTO, even if they are on top of $UPSTREAM.
'
. ./test-lib.sh
+if ! test_have_prereq REBASE_P; then
+ skip_all='skipping git rebase -p tests, as asked for'
+ test_done
+fi
+
. "$TEST_DIRECTORY"/lib-rebase.sh
# Set up branches like this:
diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh
index 4c3f7d8dfe..0210b2ac6f 100755
--- a/t/t3418-rebase-continue.sh
+++ b/t/t3418-rebase-continue.sh
@@ -106,7 +106,7 @@ test_expect_success 'rebase -i --continue handles merge strategy and options' '
test -f funny.was.run
'
-test_expect_success 'rebase passes merge strategy options correctly' '
+test_expect_success REBASE_P 'rebase passes merge strategy options correctly' '
rm -fr .git/rebase-* &&
git reset --hard commit-new-file-F3-on-topic-branch &&
test_commit theirs-to-merge &&
@@ -177,6 +177,7 @@ test_expect_success 'setup rerere database' '
git checkout master &&
test_commit "commit-new-file-F3" F3 3 &&
test_config rerere.enabled true &&
+ git update-ref refs/heads/topic commit-new-file-F3-on-topic-branch &&
test_must_fail git rebase -m master topic &&
echo "Resolved" >F2 &&
cp F2 expected-F2 &&
@@ -240,7 +241,7 @@ test_rerere_autoupdate
test_rerere_autoupdate -m
GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR
test_rerere_autoupdate -i
-test_rerere_autoupdate --preserve-merges
+test_have_prereq !REBASE_P || test_rerere_autoupdate --preserve-merges
unset GIT_SEQUENCE_EDITOR
test_expect_success 'the todo command "break" works' '
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index f355c6825a..4c7494cc8f 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -361,4 +361,12 @@ test_expect_success 'autostash with dirty submodules' '
git rebase -i --autostash HEAD
'
+test_expect_success 'branch is left alone when possible' '
+ git checkout -b unchanged-branch &&
+ echo changed >file0 &&
+ git rebase --autostash unchanged-branch &&
+ test changed = "$(cat file0)" &&
+ test unchanged-branch = "$(git rev-parse --abbrev-ref HEAD)"
+'
+
test_done
diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh
index 99b2aac921..23ad4cff35 100755
--- a/t/t3421-rebase-topology-linear.sh
+++ b/t/t3421-rebase-topology-linear.sh
@@ -29,7 +29,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -43,7 +43,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -59,7 +59,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
@@ -73,7 +73,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
# f
# /
@@ -113,7 +113,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase failure -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -128,7 +128,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase failure -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -143,7 +143,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase failure -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -158,7 +158,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
# a---b---c---j!
# \
@@ -186,7 +186,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -201,7 +201,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
@@ -216,7 +216,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase success --rebase-merges
# m
@@ -256,7 +256,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -271,7 +271,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
@@ -286,7 +286,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase failure -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_run_rebase () {
result=$1
@@ -302,7 +302,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
@@ -317,7 +317,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase failure -m
test_run_rebase success -i
-test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
@@ -331,7 +331,7 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase failure -p
+test_have_prereq !REBASE_P || test_run_rebase failure -p
test_run_rebase () {
result=$1
@@ -346,6 +346,6 @@ test_run_rebase () {
test_run_rebase success ''
test_run_rebase success -m
test_run_rebase success -i
-test_run_rebase success -p
+test_have_prereq !REBASE_P || test_run_rebase success -p
test_done
diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh
index 846f85c27e..5f892e33d7 100755
--- a/t/t3425-rebase-topology-merges.sh
+++ b/t/t3425-rebase-topology-merges.sh
@@ -109,6 +109,11 @@ test_run_rebase success 'd e n o' ''
test_run_rebase success 'd e n o' -m
test_run_rebase success 'd n o e' -i
+if ! test_have_prereq REBASE_P; then
+ skip_all='skipping git rebase -p tests, as asked for'
+ test_done
+fi
+
test_expect_success "rebase -p is no-op in non-linear history" "
reset_rebase &&
git rebase -p d w &&
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index aa7bfc88ec..cc5646836f 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -396,4 +396,20 @@ test_expect_success 'with --autosquash and --exec' '
grep "G: +G" actual
'
+test_expect_success '--continue after resolving conflicts after a merge' '
+ git checkout -b already-has-g E &&
+ git cherry-pick E..G &&
+ test_commit H2 &&
+
+ git checkout -b conflicts-in-merge H &&
+ test_commit H2 H2.t conflicts H2-conflict &&
+ test_must_fail git rebase -r already-has-g &&
+ grep conflicts H2.t &&
+ echo resolved >H2.t &&
+ git add -u &&
+ git rebase --continue &&
+ test_must_fail git rev-parse --verify HEAD^2 &&
+ test_path_is_missing .git/MERGE_HEAD
+'
+
test_done
diff --git a/t/t3502-cherry-pick-merge.sh b/t/t3502-cherry-pick-merge.sh
index b1602718f8..8b635a196d 100755
--- a/t/t3502-cherry-pick-merge.sh
+++ b/t/t3502-cherry-pick-merge.sh
@@ -40,12 +40,12 @@ test_expect_success 'cherry-pick -m complains of bogus numbers' '
test_expect_code 129 git cherry-pick -m 0 b
'
-test_expect_success 'cherry-pick a non-merge with -m should fail' '
+test_expect_success 'cherry-pick explicit first parent of a non-merge' '
git reset --hard &&
git checkout a^0 &&
- test_expect_code 128 git cherry-pick -m 1 b &&
- git diff --exit-code a --
+ git cherry-pick -m 1 b &&
+ git diff --exit-code c --
'
@@ -84,12 +84,12 @@ test_expect_success 'cherry pick a merge relative to nonexistent parent should f
'
-test_expect_success 'revert a non-merge with -m should fail' '
+test_expect_success 'revert explicit first parent of a non-merge' '
git reset --hard &&
git checkout c^0 &&
- test_must_fail git revert -m 1 b &&
- git diff --exit-code c
+ git revert -m 1 b &&
+ git diff --exit-code a --
'
diff --git a/t/t3506-cherry-pick-ff.sh b/t/t3506-cherry-pick-ff.sh
index fb889ac6f0..127dd0082f 100755
--- a/t/t3506-cherry-pick-ff.sh
+++ b/t/t3506-cherry-pick-ff.sh
@@ -64,10 +64,10 @@ test_expect_success 'merge setup' '
git checkout -b new A
'
-test_expect_success 'cherry-pick a non-merge with --ff and -m should fail' '
+test_expect_success 'cherry-pick explicit first parent of a non-merge with --ff' '
git reset --hard A -- &&
- test_must_fail git cherry-pick --ff -m 1 B &&
- git diff --exit-code A --
+ git cherry-pick --ff -m 1 B &&
+ git diff --exit-code C --
'
test_expect_success 'cherry pick a merge with --ff but without -m should fail' '
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index c84eeefdc9..941d5026da 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -61,7 +61,11 @@ test_expect_success 'cherry-pick mid-cherry-pick-sequence' '
test_expect_success 'cherry-pick persists opts correctly' '
pristine_detach initial &&
- test_expect_code 128 git cherry-pick -s -m 1 --strategy=recursive -X patience -X ours initial..anotherpick &&
+ # to make sure that the session to cherry-pick a sequence
+ # gets interrupted, use a high-enough number that is larger
+ # than the number of parents of any commit we have created
+ mainline=4 &&
+ test_expect_code 128 git cherry-pick -s -m $mainline --strategy=recursive -X patience -X ours initial..anotherpick &&
test_path_is_dir .git/sequencer &&
test_path_is_file .git/sequencer/head &&
test_path_is_file .git/sequencer/todo &&
@@ -69,7 +73,7 @@ test_expect_success 'cherry-pick persists opts correctly' '
echo "true" >expect &&
git config --file=.git/sequencer/opts --get-all options.signoff >actual &&
test_cmp expect actual &&
- echo "1" >expect &&
+ echo "$mainline" >expect &&
git config --file=.git/sequencer/opts --get-all options.mainline >actual &&
test_cmp expect actual &&
echo "recursive" >expect &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index cd216655b9..5f8272b6f9 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -1096,4 +1096,32 @@ test_expect_success 'stash -- <subdir> works with binary files' '
test_path_is_file subdir/untracked
'
+test_expect_success 'stash works when user.name and user.email are not set' '
+ git reset &&
+ >1 &&
+ git add 1 &&
+ echo "$GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" >expect &&
+ git stash &&
+ git show -s --format="%an <%ae>" refs/stash >actual &&
+ test_cmp expect actual &&
+ >2 &&
+ git add 2 &&
+ test_config user.useconfigonly true &&
+ test_config stash.usebuiltin true &&
+ (
+ sane_unset GIT_AUTHOR_NAME &&
+ sane_unset GIT_AUTHOR_EMAIL &&
+ sane_unset GIT_COMMITTER_NAME &&
+ sane_unset GIT_COMMITTER_EMAIL &&
+ test_unconfig user.email &&
+ test_unconfig user.name &&
+ test_must_fail git commit -m "should fail" &&
+ echo "git stash <git@stash>" >expect &&
+ >2 &&
+ git stash &&
+ git show -s --format="%an <%ae>" refs/stash >actual &&
+ test_cmp expect actual
+ )
+'
+
test_done
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 73f7038253..7d985ff6b1 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -129,7 +129,7 @@ do
case "$magic" in
noellipses) ;;
*)
- die "bug in t4103: unknown magic $magic" ;;
+ BUG "unknown magic $magic" ;;
esac ;;
*)
cmd="$magic $cmd" magic=
diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh
index a9fb226c5a..9a3e4fdfec 100755
--- a/t/t4015-diff-whitespace.sh
+++ b/t/t4015-diff-whitespace.sh
@@ -1890,6 +1890,24 @@ test_expect_success 'compare whitespace delta across moved blocks' '
test_cmp expected actual
'
+test_expect_success 'bogus settings in move detection erroring out' '
+ test_must_fail git diff --color-moved=bogus 2>err &&
+ test_i18ngrep "must be one of" err &&
+ test_i18ngrep bogus err &&
+
+ test_must_fail git -c diff.colormoved=bogus diff 2>err &&
+ test_i18ngrep "must be one of" err &&
+ test_i18ngrep "from command-line config" err &&
+
+ test_must_fail git diff --color-moved-ws=bogus 2>err &&
+ test_i18ngrep "possible values" err &&
+ test_i18ngrep bogus err &&
+
+ test_must_fail git -c diff.colormovedws=bogus diff 2>err &&
+ test_i18ngrep "possible values" err &&
+ test_i18ngrep "from command-line config" err
+'
+
test_expect_success 'compare whitespace delta incompatible with other space options' '
test_must_fail git diff \
--color-moved-ws=allow-indentation-change,ignore-all-space \
diff --git a/t/t4052-stat-output.sh b/t/t4052-stat-output.sh
index 6e2cf933f7..28c053849a 100755
--- a/t/t4052-stat-output.sh
+++ b/t/t4052-stat-output.sh
@@ -44,42 +44,50 @@ show --stat
log -1 --stat
EOF
-while read cmd args
+cat >expect.60 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+cat >expect.6030 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+cat >expect2.60 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+cat >expect2.6030 <<-'EOF'
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+ ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
+EOF
+while read expect cmd args
do
- cat >expect <<-'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
- EOF
test_expect_success "$cmd --stat=width: a long name is given more room when the bar is short" '
git $cmd $args --stat=40 >output &&
grep " | " output >actual &&
- test_cmp expect actual
+ test_cmp $expect.60 actual
'
test_expect_success "$cmd --stat-width=width with long name" '
git $cmd $args --stat-width=40 >output &&
grep " | " output >actual &&
- test_cmp expect actual
+ test_cmp $expect.60 actual
'
- cat >expect <<-'EOF'
- ...aaaaaaaaaaaaaaaaaaaaaaaaaaa | 1 +
- EOF
test_expect_success "$cmd --stat=...,name-width with long name" '
git $cmd $args --stat=60,30 >output &&
grep " | " output >actual &&
- test_cmp expect actual
+ test_cmp $expect.6030 actual
'
test_expect_success "$cmd --stat-name-width with long name" '
git $cmd $args --stat-name-width=30 >output &&
grep " | " output >actual &&
- test_cmp expect actual
+ test_cmp $expect.6030 actual
'
done <<\EOF
-format-patch -1 --stdout
-diff HEAD^ HEAD --stat
-show --stat
-log -1 --stat
+expect2 format-patch --cover-letter -1 --stdout
+expect diff HEAD^ HEAD --stat
+expect show --stat
+expect log -1 --stat
EOF
@@ -97,6 +105,16 @@ test_expect_success 'preparation for big change tests' '
cat >expect72 <<'EOF'
abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EOF
+test_expect_success "format-patch --cover-letter ignores COLUMNS (big change)" '
+ COLUMNS=200 git format-patch -1 --stdout --cover-letter >output &&
+ grep " | " output >actual &&
+ test_cmp expect72 actual
+'
+
+cat >expect72 <<'EOF'
+ abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
EOF
cat >expect72-graph <<'EOF'
| abcd | 1000 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/t/t4136-apply-check.sh b/t/t4136-apply-check.sh
index 6d92872318..4c3f264a63 100755
--- a/t/t4136-apply-check.sh
+++ b/t/t4136-apply-check.sh
@@ -29,6 +29,18 @@ test_expect_success 'apply exits non-zero with no-op patch' '
test_must_fail git apply --check input
'
+test_expect_success '`apply --recount` allows no-op patch' '
+ echo 1 >1 &&
+ git apply --recount --check <<-\EOF
+ diff --get a/1 b/1
+ index 6696ea4..606eddd 100644
+ --- a/1
+ +++ b/1
+ @@ -1,1 +1,1 @@
+ 1
+ EOF
+'
+
test_expect_success 'invalid combination: create and copy' '
test_must_fail git apply --check - <<-\EOF
diff --git a/1 b/2
diff --git a/t/t4209-log-pickaxe.sh b/t/t4209-log-pickaxe.sh
index 844df760f7..5d06f5f45e 100755
--- a/t/t4209-log-pickaxe.sh
+++ b/t/t4209-log-pickaxe.sh
@@ -106,4 +106,39 @@ test_expect_success 'log -S --no-textconv (missing textconv tool)' '
rm .gitattributes
'
+test_expect_success 'setup log -[GS] binary & --text' '
+ git checkout --orphan GS-binary-and-text &&
+ git read-tree --empty &&
+ printf "a\na\0a\n" >data.bin &&
+ git add data.bin &&
+ git commit -m "create binary file" data.bin &&
+ printf "a\na\0a\n" >>data.bin &&
+ git commit -m "modify binary file" data.bin &&
+ git rm data.bin &&
+ git commit -m "delete binary file" data.bin &&
+ git log >full-log
+'
+
+test_expect_success 'log -G ignores binary files' '
+ git log -Ga >log &&
+ test_must_be_empty log
+'
+
+test_expect_success 'log -G looks into binary files with -a' '
+ git log -a -Ga >log &&
+ test_cmp log full-log
+'
+
+test_expect_success 'log -G looks into binary files with textconv filter' '
+ test_when_finished "rm .gitattributes" &&
+ echo "* diff=bin" >.gitattributes &&
+ git -c diff.bin.textconv=cat log -Ga >log &&
+ test_cmp log full-log
+'
+
+test_expect_success 'log -S looks into binary files' '
+ git log -Sa >log &&
+ test_cmp log full-log
+'
+
test_done
diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh
index ef1322148e..bd5fe4d148 100755
--- a/t/t4211-line-log.sh
+++ b/t/t4211-line-log.sh
@@ -25,7 +25,7 @@ canned_test_failure () {
test_bad_opts () {
test_expect_success "invalid args: $1" "
test_must_fail git log $1 2>errors &&
- grep '$2' errors
+ test_i18ngrep '$2' errors
"
}
diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh
index ced44355ca..271eb5a1fd 100755
--- a/t/t5004-archive-corner-cases.sh
+++ b/t/t5004-archive-corner-cases.sh
@@ -3,8 +3,12 @@
test_description='test corner cases of git-archive'
. ./test-lib.sh
-test_expect_success 'create commit with empty tree' '
- git commit --allow-empty -m foo
+# the 10knuls.tar file is used to test for an empty git generated tar
+# without having to invoke tar because an otherwise valid empty GNU tar
+# will be considered broken by {Open,Net}BSD tar
+test_expect_success 'create commit with empty tree and fake empty tar' '
+ git commit --allow-empty -m foo &&
+ perl -e "print \"\\0\" x 10240" >10knuls.tar
'
# Make a dir and clean it up afterwards
@@ -47,7 +51,6 @@ test_expect_success HEADER_ONLY_TAR_OK 'tar archive of commit with empty tree' '
test_expect_success 'tar archive of empty tree is empty' '
git archive --format=tar HEAD: >empty.tar &&
- perl -e "print \"\\0\" x 10240" >10knuls.tar &&
test_cmp_bin 10knuls.tar empty.tar
'
@@ -106,16 +109,12 @@ test_expect_success 'create a commit with an empty subtree' '
test_expect_success 'archive empty subtree with no pathspec' '
git archive --format=tar $root_tree >subtree-all.tar &&
- make_dir extract &&
- "$TAR" xf subtree-all.tar -C extract &&
- check_dir extract
+ test_cmp_bin 10knuls.tar subtree-all.tar
'
test_expect_success 'archive empty subtree by direct pathspec' '
git archive --format=tar $root_tree -- sub >subtree-path.tar &&
- make_dir extract &&
- "$TAR" xf subtree-path.tar -C extract &&
- check_dir extract
+ test_cmp_bin 10knuls.tar subtree-path.tar
'
ZIPINFO=zipinfo
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index 6c620cd540..410a09b0dd 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -468,29 +468,32 @@ test_expect_success 'pack-objects in too-many-packs mode' '
git fsck
'
-#
-# WARNING!
-#
-# The following test is destructive. Please keep the next
-# two tests at the end of this file.
-#
-
-test_expect_success \
- 'fake a SHA1 hash collision' \
- 'long_a=$(git hash-object a | sed -e "s!^..!&/!") &&
- long_b=$(git hash-object b | sed -e "s!^..!&/!") &&
- test -f .git/objects/$long_b &&
- cp -f .git/objects/$long_a \
- .git/objects/$long_b'
+test_expect_success 'setup: fake a SHA1 hash collision' '
+ git init corrupt &&
+ (
+ cd corrupt &&
+ long_a=$(git hash-object -w ../a | sed -e "s!^..!&/!") &&
+ long_b=$(git hash-object -w ../b | sed -e "s!^..!&/!") &&
+ test -f .git/objects/$long_b &&
+ cp -f .git/objects/$long_a \
+ .git/objects/$long_b
+ )
+'
-test_expect_success \
- 'make sure index-pack detects the SHA1 collision' \
- 'test_must_fail git index-pack -o bad.idx test-3.pack 2>msg &&
- test_i18ngrep "SHA1 COLLISION FOUND" msg'
+test_expect_success 'make sure index-pack detects the SHA1 collision' '
+ (
+ cd corrupt &&
+ test_must_fail git index-pack -o ../bad.idx ../test-3.pack 2>msg &&
+ test_i18ngrep "SHA1 COLLISION FOUND" msg
+ )
+'
-test_expect_success \
- 'make sure index-pack detects the SHA1 collision (large blobs)' \
- 'test_must_fail git -c core.bigfilethreshold=1 index-pack -o bad.idx test-3.pack 2>msg &&
- test_i18ngrep "SHA1 COLLISION FOUND" msg'
+test_expect_success 'make sure index-pack detects the SHA1 collision (large blobs)' '
+ (
+ cd corrupt &&
+ test_must_fail git -c core.bigfilethreshold=1 index-pack -o ../bad.idx ../test-3.pack 2>msg &&
+ test_i18ngrep "SHA1 COLLISION FOUND" msg
+ )
+'
test_done
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index 1be3459c5b..82d7f7f6a5 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -191,6 +191,7 @@ test_expect_success 'pack-objects respects --honor-pack-keep (local bitmapped pa
test_expect_success 'pack-objects respects --local (non-local bitmapped pack)' '
mv .git/objects/pack/$packbitmap.* alt.git/objects/pack/ &&
+ rm -f .git/objects/pack/multi-pack-index &&
test_when_finished "mv alt.git/objects/pack/$packbitmap.* .git/objects/pack/" &&
echo HEAD | git pack-objects --local --stdout --revs >3b.pack &&
git index-pack 3b.pack &&
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index bd8e841b81..70926b5bc0 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -271,7 +271,7 @@ test_expect_success 'git-fsck incorrect offset' '
test_expect_success 'repack removes multi-pack-index' '
test_path_is_file $objdir/pack/multi-pack-index &&
- git repack -adf &&
+ GIT_TEST_MULTI_PACK_INDEX=0 git repack -adf &&
test_path_is_missing $objdir/pack/multi-pack-index
'
diff --git a/t/t5409-colorize-remote-messages.sh b/t/t5409-colorize-remote-messages.sh
index f81b6813c0..2a8c449661 100755
--- a/t/t5409-colorize-remote-messages.sh
+++ b/t/t5409-colorize-remote-messages.sh
@@ -17,6 +17,7 @@ test_expect_success 'setup' '
echo " " "error: leading space"
echo " "
echo Err
+ echo SUCCESS
exit 0
EOF
echo 1 >file &&
@@ -35,6 +36,7 @@ test_expect_success 'keywords' '
grep "<BOLD;RED>error<RESET>: error" decoded &&
grep "<YELLOW>hint<RESET>:" decoded &&
grep "<BOLD;GREEN>success<RESET>:" decoded &&
+ grep "<BOLD;GREEN>SUCCESS<RESET>" decoded &&
grep "<BOLD;YELLOW>warning<RESET>:" decoded
'
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index d2a2cdd453..883b32efa0 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -1222,4 +1222,59 @@ test_expect_success 'add remote matching the "insteadOf" URL' '
git remote add backup xyz@example.com
'
+test_expect_success 'unqualified <dst> refspec DWIM and advice' '
+ test_when_finished "(cd test && git tag -d some-tag)" &&
+ (
+ cd test &&
+ git tag -a -m "Some tag" some-tag master &&
+ exit_with=true &&
+ for type in commit tag tree blob
+ do
+ if test "$type" = "blob"
+ then
+ oid=$(git rev-parse some-tag:file)
+ else
+ oid=$(git rev-parse some-tag^{$type})
+ fi &&
+ test_must_fail git push origin $oid:dst 2>err &&
+ test_i18ngrep "error: The destination you" err &&
+ test_i18ngrep "hint: Did you mean" err &&
+ test_must_fail git -c advice.pushUnqualifiedRefName=false \
+ push origin $oid:dst 2>err &&
+ test_i18ngrep "error: The destination you" err &&
+ test_i18ngrep ! "hint: Did you mean" err ||
+ exit_with=false
+ done &&
+ $exit_with
+ )
+'
+
+test_expect_success 'refs/remotes/* <src> refspec and unqualified <dst> DWIM and advice' '
+ (
+ cd two &&
+ git tag -a -m "Some tag" my-tag master &&
+ git update-ref refs/trees/my-head-tree HEAD^{tree} &&
+ git update-ref refs/blobs/my-file-blob HEAD:file
+ ) &&
+ (
+ cd test &&
+ git config --add remote.two.fetch "+refs/tags/*:refs/remotes/tags-from-two/*" &&
+ git config --add remote.two.fetch "+refs/trees/*:refs/remotes/trees-from-two/*" &&
+ git config --add remote.two.fetch "+refs/blobs/*:refs/remotes/blobs-from-two/*" &&
+ git fetch --no-tags two &&
+
+ test_must_fail git push origin refs/remotes/two/another:dst 2>err &&
+ test_i18ngrep "error: The destination you" err &&
+
+ test_must_fail git push origin refs/remotes/tags-from-two/my-tag:dst-tag 2>err &&
+ test_i18ngrep "error: The destination you" err &&
+
+ test_must_fail git push origin refs/remotes/trees-from-two/my-head-tree:dst-tree 2>err &&
+ test_i18ngrep "error: The destination you" err &&
+
+ test_must_fail git push origin refs/remotes/blobs-from-two/my-file-blob:dst-blob 2>err &&
+ test_i18ngrep "error: The destination you" err
+ )
+'
+
test_done
diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
index bc5703ff9b..cd9e60632d 100755
--- a/t/t5512-ls-remote.sh
+++ b/t/t5512-ls-remote.sh
@@ -260,7 +260,7 @@ test_lazy_prereq GIT_DAEMON '
# This test spawns a daemon, so run it only if the user would be OK with
# testing with git-daemon.
test_expect_success PIPE,JGIT,GIT_DAEMON 'indicate no refs in standards-compliant empty remote' '
- JGIT_DAEMON_PORT=${JGIT_DAEMON_PORT-${this_test#t}} &&
+ test_set_port JGIT_DAEMON_PORT &&
JGIT_DAEMON_PID= &&
git init --bare empty.git &&
>empty.git/git-daemon-export-ok &&
@@ -302,4 +302,28 @@ test_expect_success 'ls-remote works outside repository' '
nongit git ls-remote dst.git
'
+test_expect_success 'ls-remote --sort fails gracefully outside repository' '
+ # Use a sort key that requires access to the referenced objects.
+ nongit test_must_fail git ls-remote --sort=authordate "$TRASH_DIRECTORY" 2>err &&
+ test_i18ngrep "^fatal: not a git repository, but the field '\''authordate'\'' requires access to object data" err
+'
+
+test_expect_success 'ls-remote patterns work with all protocol versions' '
+ git for-each-ref --format="%(objectname) %(refname)" \
+ refs/heads/master refs/remotes/origin/master >expect &&
+ git -c protocol.version=1 ls-remote . master >actual.v1 &&
+ test_cmp expect actual.v1 &&
+ git -c protocol.version=2 ls-remote . master >actual.v2 &&
+ test_cmp expect actual.v2
+'
+
+test_expect_success 'ls-remote prefixes work with all protocol versions' '
+ git for-each-ref --format="%(objectname) %(refname)" \
+ refs/heads/ refs/tags/ >expect &&
+ git -c protocol.version=1 ls-remote --heads --tags . >actual.v1 &&
+ test_cmp expect actual.v1 &&
+ git -c protocol.version=2 ls-remote --heads --tags . >actual.v2 &&
+ test_cmp expect actual.v2
+'
+
test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 7316365a24..37e8e80893 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -95,7 +95,7 @@ mk_child() {
check_push_result () {
test $# -ge 3 ||
- error "bug in the test script: check_push_result requires at least 3 parameters"
+ BUG "check_push_result requires at least 3 parameters"
repo_name="$1"
shift
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index 5e501c8b08..cf4cc32fd0 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -461,7 +461,8 @@ test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' '
test file3 = "$(git show HEAD:file3.t)"
'
-test_expect_success 'pull.rebase=preserve rebases and merges keep-merge' '
+test_expect_success REBASE_P \
+ 'pull.rebase=preserve rebases and merges keep-merge' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase preserve &&
git pull . copy &&
@@ -514,7 +515,8 @@ test_expect_success '--rebase=true rebases and flattens keep-merge' '
test file3 = "$(git show HEAD:file3.t)"
'
-test_expect_success '--rebase=preserve rebases and merges keep-merge' '
+test_expect_success REBASE_P \
+ '--rebase=preserve rebases and merges keep-merge' '
git reset --hard before-preserve-rebase &&
test_config pull.rebase true &&
git pull --rebase=preserve . copy &&
diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh
index 6c2f9b2ba2..a0317556c6 100755
--- a/t/t5526-fetch-submodules.sh
+++ b/t/t5526-fetch-submodules.sh
@@ -524,6 +524,8 @@ test_expect_success 'fetching submodules respects parallel settings' '
git config fetch.recurseSubmodules true &&
(
cd downstream &&
+ GIT_TRACE=$(pwd)/trace.out git fetch &&
+ grep "1 tasks" trace.out &&
GIT_TRACE=$(pwd)/trace.out git fetch --jobs 7 &&
grep "7 tasks" trace.out &&
git config submodule.fetchJobs 8 &&
diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh
index b24d8b05a4..90d890d02f 100755
--- a/t/t5562-http-backend-content-length.sh
+++ b/t/t5562-http-backend-content-length.sh
@@ -31,6 +31,7 @@ test_http_env() {
PATH_TRANSLATED="$PWD/.git/git-$handler_type-pack" \
GIT_HTTP_EXPORT_ALL=TRUE \
REQUEST_METHOD=POST \
+ "$PERL_PATH" \
"$TEST_DIRECTORY"/t5562/invoke-with-content-length.pl \
"$request_body" git http-backend >act.out 2>act.err
}
diff --git a/t/t5562/invoke-with-content-length.pl b/t/t5562/invoke-with-content-length.pl
index 6c2aae7692..0943474af2 100755..100644
--- a/t/t5562/invoke-with-content-length.pl
+++ b/t/t5562/invoke-with-content-length.pl
@@ -1,4 +1,3 @@
-#!/usr/bin/perl
use 5.008;
use strict;
use warnings;
diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
index 7466aad111..58ee787685 100755
--- a/t/t5570-git-daemon.sh
+++ b/t/t5570-git-daemon.sh
@@ -183,19 +183,6 @@ test_expect_success 'hostname cannot break out of directory' '
git ls-remote "$GIT_DAEMON_URL/escape.git"
'
-test_expect_success 'daemon log records all attributes' '
- cat >expect <<-\EOF &&
- Extended attribute "host": localhost
- Extended attribute "protocol": version=1
- EOF
- >daemon.log &&
- GIT_OVERRIDE_VIRTUAL_HOST=localhost \
- git -c protocol.version=1 \
- ls-remote "$GIT_DAEMON_URL/interp.git" &&
- grep -i extended.attribute daemon.log | cut -d" " -f2- >actual &&
- test_cmp expect actual
-'
-
test_expect_success FAKENC 'hostname interpolation works after LF-stripping' '
{
printf "git-upload-pack /interp.git\n\0host=localhost" | packetize
diff --git a/t/t5573-pull-verify-signatures.sh b/t/t5573-pull-verify-signatures.sh
index 747775c147..3e9876e197 100755
--- a/t/t5573-pull-verify-signatures.sh
+++ b/t/t5573-pull-verify-signatures.sh
@@ -78,4 +78,11 @@ test_expect_success GPG 'pull commit with bad signature with --no-verify-signatu
git pull --ff-only --no-verify-signatures bad 2>pullerror
'
+test_expect_success GPG 'pull unsigned commit into unborn branch' '
+ git init empty-repo &&
+ test_must_fail \
+ git -C empty-repo pull --verify-signatures .. 2>pullerror &&
+ test_i18ngrep "does not have a GPG signature" pullerror
+'
+
test_done
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index f1a49e94f5..d6948cbdab 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -487,7 +487,7 @@ test_clone_url () {
expect_ssh "$@"
}
-test_expect_success !MINGW 'clone c:temp is ssl' '
+test_expect_success !MINGW,!CYGWIN 'clone c:temp is ssl' '
test_clone_url c:temp c temp
'
@@ -628,7 +628,7 @@ test_expect_success 'clone on case-insensitive fs' '
)
'
-test_expect_success !MINGW,!CYGWIN,CASE_INSENSITIVE_FS 'colliding file detection' '
+test_expect_success CASE_INSENSITIVE_FS 'colliding file detection' '
grep X icasefs/warning &&
grep x icasefs/warning &&
test_i18ngrep "the following paths have collided" icasefs/warning
diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh
index 348d9b3bc7..cf39e9e243 100755
--- a/t/t5607-clone-bundle.sh
+++ b/t/t5607-clone-bundle.sh
@@ -71,4 +71,10 @@ test_expect_success 'prerequisites with an empty commit message' '
git bundle verify bundle
'
+test_expect_success 'failed bundle creation does not leave cruft' '
+ # This fails because the bundle would be empty.
+ test_must_fail git bundle create fail.bundle master..master &&
+ test_path_is_missing fail.bundle.lock
+'
+
test_done
diff --git a/t/t5611-clone-config.sh b/t/t5611-clone-config.sh
index 39329eb7a8..60c1ba951b 100755
--- a/t/t5611-clone-config.sh
+++ b/t/t5611-clone-config.sh
@@ -45,6 +45,53 @@ test_expect_success 'clone -c config is available during clone' '
test_cmp expect child/file
'
+test_expect_success 'clone -c remote.origin.fetch=<refspec> works' '
+ rm -rf child &&
+ git update-ref refs/grab/it refs/heads/master &&
+ git update-ref refs/leave/out refs/heads/master &&
+ git clone -c "remote.origin.fetch=+refs/grab/*:refs/grab/*" . child &&
+ git -C child for-each-ref --format="%(refname)" >actual &&
+
+ cat >expect <<-\EOF &&
+ refs/grab/it
+ refs/heads/master
+ refs/remotes/origin/HEAD
+ refs/remotes/origin/master
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'git -c remote.origin.fetch=<refspec> clone works' '
+ rm -rf child &&
+ git -c "remote.origin.fetch=+refs/grab/*:refs/grab/*" clone . child &&
+ git -C child for-each-ref --format="%(refname)" >actual &&
+
+ cat >expect <<-\EOF &&
+ refs/grab/it
+ refs/heads/master
+ refs/remotes/origin/HEAD
+ refs/remotes/origin/master
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'clone -c remote.<remote>.fetch=<refspec> --origin=<name>' '
+ rm -rf child &&
+ git clone --origin=upstream \
+ -c "remote.upstream.fetch=+refs/grab/*:refs/grab/*" \
+ -c "remote.origin.fetch=+refs/leave/*:refs/leave/*" \
+ . child &&
+ git -C child for-each-ref --format="%(refname)" >actual &&
+
+ cat >expect <<-\EOF &&
+ refs/grab/it
+ refs/heads/master
+ refs/remotes/upstream/HEAD
+ refs/remotes/upstream/master
+ EOF
+ test_cmp expect actual
+'
+
# Tests for the hidden file attribute on windows
is_hidden () {
# Use the output of `attrib`, ignore the absolute path
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 336f02a41a..9643acb161 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -281,7 +281,7 @@ test_expect_success 'upon cloning, check that all refs point to objects' '
test_must_fail git -c protocol.version=2 clone \
--filter=blob:none $HTTPD_URL/one_time_sed/server repo 2>err &&
- grep "did not send all necessary objects" err &&
+ test_i18ngrep "did not send all necessary objects" err &&
# Ensure that the one-time-sed script was used.
! test -e "$HTTPD_ROOT_PATH/one-time-sed"
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index 6ab8dea8cd..0f2b09ebb8 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -537,6 +537,56 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' '
! grep "git< version 2" log
'
+test_expect_success 'when server sends "ready", expect DELIM' '
+ rm -rf "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" http_child &&
+
+ git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
+ test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one &&
+
+ git clone "$HTTPD_URL/smart/http_parent" http_child &&
+
+ test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
+
+ # After "ready" in the acknowledgments section, pretend that a FLUSH
+ # (0000) was sent instead of a DELIM (0001).
+ printf "/ready/,$ s/0001/0000/" \
+ >"$HTTPD_ROOT_PATH/one-time-sed" &&
+
+ test_must_fail git -C http_child -c protocol.version=2 \
+ fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
+ test_i18ngrep "expected packfile to be sent after .ready." err
+'
+
+test_expect_success 'when server does not send "ready", expect FLUSH' '
+ rm -rf "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" http_child log &&
+
+ git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
+ test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one &&
+
+ git clone "$HTTPD_URL/smart/http_parent" http_child &&
+
+ test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
+
+ # Create many commits to extend the negotiation phase across multiple
+ # requests, so that the server does not send "ready" in the first
+ # request.
+ for i in $(test_seq 1 32)
+ do
+ test_commit -C http_child c$i
+ done &&
+
+ # After the acknowledgments section, pretend that a DELIM
+ # (0001) was sent instead of a FLUSH (0000).
+ printf "/acknowledgments/,$ s/0000/0001/" \
+ >"$HTTPD_ROOT_PATH/one-time-sed" &&
+
+ test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" git -C http_child \
+ -c protocol.version=2 \
+ fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err &&
+ grep "fetch< acknowledgments" log &&
+ ! grep "fetch< ready" log &&
+ test_i18ngrep "expected no other sections to be sent after no .ready." err
+'
stop_httpd
diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index 3f58f05cbb..7053899cb5 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -208,7 +208,7 @@ test_expect_success 'server is initially ahead - no ref in want' '
cp -r "$LOCAL_PRISTINE" local &&
inconsistency master 1234567890123456789012345678901234567890 &&
test_must_fail git -C local fetch 2>err &&
- grep "ERR upload-pack: not our ref" err
+ test_i18ngrep "ERR upload-pack: not our ref" err
'
test_expect_success 'server is initially ahead - ref in want' '
@@ -254,7 +254,7 @@ test_expect_success 'server loses a ref - ref in want' '
echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" &&
test_must_fail git -C local fetch 2>err &&
- grep "ERR unknown ref refs/heads/raster" err
+ test_i18ngrep "ERR unknown ref refs/heads/raster" err
'
stop_httpd
diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh
index fb4d295aa0..0507999729 100755
--- a/t/t6000-rev-list-misc.sh
+++ b/t/t6000-rev-list-misc.sh
@@ -90,11 +90,18 @@ test_expect_success 'rev-list can show index objects' '
9200b628cf9dc883a85a7abc8d6e6730baee589c two
EOF
echo only-in-index >only-in-index &&
+ test_when_finished "git reset --hard" &&
git add only-in-index &&
git rev-list --objects --indexed-objects >actual &&
test_cmp expect actual
'
+test_expect_success 'rev-list can negate index objects' '
+ git rev-parse HEAD >expect &&
+ git rev-list -1 --objects HEAD --not --indexed-objects >actual &&
+ test_cmp expect actual
+'
+
test_expect_success '--bisect and --first-parent can not be combined' '
test_must_fail git rev-list --bisect --first-parent HEAD
'
diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh
index b5a1190ffe..a10f0df02b 100755
--- a/t/t6012-rev-list-simplify.sh
+++ b/t/t6012-rev-list-simplify.sh
@@ -12,6 +12,22 @@ unnote () {
git name-rev --tags --stdin | sed -e "s|$OID_REGEX (tags/\([^)]*\)) |\1 |g"
}
+#
+# Create a test repo with interesting commit graph:
+#
+# A--B----------G--H--I--K--L
+# \ \ / /
+# \ \ / /
+# C------E---F J
+# \_/
+#
+# The commits are laid out from left-to-right starting with
+# the root commit A and terminating at the tip commit L.
+#
+# There are a few places where we adjust the commit date or
+# author date to make the --topo-order, --date-order, and
+# --author-date-order flags produce different output.
+
test_expect_success setup '
echo "Hi there" >file &&
echo "initial" >lost &&
@@ -21,10 +37,18 @@ test_expect_success setup '
git branch other-branch &&
+ git symbolic-ref HEAD refs/heads/unrelated &&
+ git rm -f "*" &&
+ echo "Unrelated branch" >side &&
+ git add side &&
+ test_tick && git commit -m "Side root" &&
+ note J &&
+ git checkout master &&
+
echo "Hello" >file &&
echo "second" >lost &&
git add file lost &&
- test_tick && git commit -m "Modified file and lost" &&
+ test_tick && GIT_AUTHOR_DATE=$(($test_tick + 120)) git commit -m "Modified file and lost" &&
note B &&
git checkout other-branch &&
@@ -63,13 +87,6 @@ test_expect_success setup '
test_tick && git commit -a -m "Final change" &&
note I &&
- git symbolic-ref HEAD refs/heads/unrelated &&
- git rm -f "*" &&
- echo "Unrelated branch" >side &&
- git add side &&
- test_tick && git commit -m "Side root" &&
- note J &&
-
git checkout master &&
test_tick && git merge --allow-unrelated-histories -m "Coolest" unrelated &&
note K &&
@@ -103,14 +120,24 @@ check_result () {
check_outcome success "$@"
}
-check_result 'L K J I H G F E D C B A' --full-history
+check_result 'L K J I H F E D C G B A' --full-history --topo-order
+check_result 'L K I H G F E D C B J A' --full-history
+check_result 'L K I H G F E D C B J A' --full-history --date-order
+check_result 'L K I H G F E D B C J A' --full-history --author-date-order
check_result 'K I H E C B A' --full-history -- file
check_result 'K I H E C B A' --full-history --topo-order -- file
check_result 'K I H E C B A' --full-history --date-order -- file
+check_result 'K I H E B C A' --full-history --author-date-order -- file
check_result 'I E C B A' --simplify-merges -- file
+check_result 'I E C B A' --simplify-merges --topo-order -- file
+check_result 'I E C B A' --simplify-merges --date-order -- file
+check_result 'I E B C A' --simplify-merges --author-date-order -- file
check_result 'I B A' -- file
check_result 'I B A' --topo-order -- file
+check_result 'I B A' --date-order -- file
+check_result 'I B A' --author-date-order -- file
check_result 'H' --first-parent -- another-file
+check_result 'H' --first-parent --topo-order -- another-file
check_result 'E C B A' --full-history E -- lost
test_expect_success 'full history simplification without parent' '
diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh
index db8a7834d8..bb5aeac07f 100755
--- a/t/t6018-rev-list-glob.sh
+++ b/t/t6018-rev-list-glob.sh
@@ -36,7 +36,13 @@ test_expect_success 'setup' '
git tag foo/bar master &&
commit master3 &&
git update-ref refs/remotes/foo/baz master &&
- commit master4
+ commit master4 &&
+ git update-ref refs/remotes/upstream/one subspace/one &&
+ git update-ref refs/remotes/upstream/two subspace/two &&
+ git update-ref refs/remotes/upstream/x subspace-x &&
+ git tag qux/one subspace/one &&
+ git tag qux/two subspace/two &&
+ git tag qux/x subspace-x
'
test_expect_success 'rev-parse --glob=refs/heads/subspace/*' '
@@ -141,6 +147,66 @@ test_expect_success 'rev-parse accumulates multiple --exclude' '
compare rev-parse "--exclude=refs/remotes/* --exclude=refs/tags/* --all" --branches
'
+test_expect_success 'rev-parse --branches clears --exclude' '
+ compare rev-parse "--exclude=* --branches --branches" "--branches"
+'
+
+test_expect_success 'rev-parse --tags clears --exclude' '
+ compare rev-parse "--exclude=* --tags --tags" "--tags"
+'
+
+test_expect_success 'rev-parse --all clears --exclude' '
+ compare rev-parse "--exclude=* --all --all" "--all"
+'
+
+test_expect_success 'rev-parse --exclude=glob with --branches=glob' '
+ compare rev-parse "--exclude=subspace-* --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-parse --exclude=glob with --tags=glob' '
+ compare rev-parse "--exclude=qux/? --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-parse --exclude=glob with --remotes=glob' '
+ compare rev-parse "--exclude=upstream/? --remotes=upstream/*" "upstream/one upstream/two"
+'
+
+test_expect_success 'rev-parse --exclude=ref with --branches=glob' '
+ compare rev-parse "--exclude=subspace-x --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-parse --exclude=ref with --tags=glob' '
+ compare rev-parse "--exclude=qux/x --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-parse --exclude=ref with --remotes=glob' '
+ compare rev-parse "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two"
+'
+
+test_expect_success 'rev-list --exclude=glob with --branches=glob' '
+ compare rev-list "--exclude=subspace-* --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-list --exclude=glob with --tags=glob' '
+ compare rev-list "--exclude=qux/? --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-list --exclude=glob with --remotes=glob' '
+ compare rev-list "--exclude=upstream/? --remotes=upstream/*" "upstream/one upstream/two"
+'
+
+test_expect_success 'rev-list --exclude=ref with --branches=glob' '
+ compare rev-list "--exclude=subspace-x --branches=sub*" "subspace/one subspace/two"
+'
+
+test_expect_success 'rev-list --exclude=ref with --tags=glob' '
+ compare rev-list "--exclude=qux/x --tags=qux/*" "qux/one qux/two"
+'
+
+test_expect_success 'rev-list --exclude=ref with --remotes=glob' '
+ compare rev-list "--exclude=upstream/x --remotes=upstream/*" "upstream/one upstream/two"
+'
+
test_expect_success 'rev-list --glob=refs/heads/subspace/*' '
compare rev-list "subspace/one subspace/two" "--glob=refs/heads/subspace/*"
@@ -233,7 +299,7 @@ test_expect_success 'rev-list --tags=foo' '
test_expect_success 'rev-list --tags' '
- compare rev-list "foo/bar" "--tags"
+ compare rev-list "foo/bar qux/x qux/two qux/one" "--tags"
'
@@ -292,7 +358,7 @@ test_expect_success 'shortlog accepts --glob/--tags/--remotes' '
"master other/three someref subspace-x subspace/one subspace/two" \
"--glob=heads/*" &&
compare shortlog foo/bar --tags=foo &&
- compare shortlog foo/bar --tags &&
+ compare shortlog "foo/bar qux/one qux/two qux/x" --tags &&
compare shortlog foo/baz --remotes=foo
'
diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh
index e1cef58f2a..d23b948f27 100755
--- a/t/t6036-recursive-corner-cases.sh
+++ b/t/t6036-recursive-corner-cases.sh
@@ -64,15 +64,12 @@ test_expect_success 'merge simple rename+criss-cross with no modifications' '
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >expect \
- L2:three R2:three \
L2:three R2:three &&
git rev-parse >actual \
:2:three :3:three &&
- git hash-object >>actual \
- three~HEAD three~R2^0 &&
test_cmp expect actual
)
'
@@ -140,15 +137,12 @@ test_expect_success 'merge criss-cross + rename merges with basic modification'
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >expect \
- L2:three R2:three \
L2:three R2:three &&
git rev-parse >actual \
:2:three :3:three &&
- git hash-object >>actual \
- three~HEAD three~R2^0 &&
test_cmp expect actual
)
'
@@ -185,7 +179,7 @@ test_expect_success 'setup differently handled merges of rename/add conflict' '
git branch B &&
git checkout -b C &&
echo 10 >>a &&
- echo "other content" >>new_a &&
+ test_write_lines 0 1 2 3 4 5 6 7 foobar >new_a &&
git add a new_a &&
test_tick && git commit -m C &&
@@ -195,14 +189,14 @@ test_expect_success 'setup differently handled merges of rename/add conflict' '
git checkout B^0 &&
test_must_fail git merge C &&
- git clean -f &&
+ git show :2:new_a >new_a &&
+ git add new_a &&
test_tick && git commit -m D &&
git tag D &&
git checkout C^0 &&
test_must_fail git merge B &&
- rm new_a~HEAD new_a &&
- printf "Incorrectly merged content" >>new_a &&
+ test_write_lines 0 1 2 3 4 5 6 7 bad_merge >new_a &&
git add -u &&
test_tick && git commit -m E &&
git tag E
@@ -225,21 +219,74 @@ test_expect_success 'git detects differently handled merges conflict' '
test_line_count = 1 out &&
git rev-parse >expect \
- D:new_a E:new_a &&
+ C:new_a D:new_a E:new_a &&
git rev-parse >actual \
- :2:new_a :3:new_a &&
+ :1:new_a :2:new_a :3:new_a &&
test_cmp expect actual &&
- git cat-file -p C:new_a >ours &&
- git cat-file -p B:new_a >theirs &&
+ # Test that the two-way merge in new_a is as expected
+ git cat-file -p D:new_a >ours &&
+ git cat-file -p E:new_a >theirs &&
>empty &&
test_must_fail git merge-file \
- -L "Temporary merge branch 1" \
+ -L "HEAD" \
-L "" \
- -L "Temporary merge branch 2" \
+ -L "E^0" \
ours empty theirs &&
sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect &&
- git cat-file -p :1:new_a >actual &&
+ git hash-object new_a >actual &&
+ git hash-object ours >expect &&
+ test_cmp expect actual
+ )
+'
+
+# Repeat the above testcase with precisely the same setup, other than with
+# the two merge bases having different orderings of commit timestamps so
+# that they are reversed in the order they are provided to merge-recursive,
+# so that we can improve code coverage.
+test_expect_success 'git detects differently handled merges conflict, swapped' '
+ (
+ cd rename-add &&
+
+ # Difference #1: Do cleanup from previous testrun
+ git reset --hard &&
+ git clean -fdqx &&
+
+ # Difference #2: Change commit timestamps
+ btime=$(git log --no-walk --date=raw --format=%cd B | awk "{print \$1}") &&
+ ctime=$(git log --no-walk --date=raw --format=%cd C | awk "{print \$1}") &&
+ newctime=$(($btime+1)) &&
+ git fast-export --no-data --all | sed -e s/$ctime/$newctime/ | git fast-import --force --quiet &&
+ # End of differences; rest is copy-paste of last test
+
+ git checkout D^0 &&
+ test_must_fail git merge -s recursive E^0 &&
+
+ git ls-files -s >out &&
+ test_line_count = 3 out &&
+ git ls-files -u >out &&
+ test_line_count = 3 out &&
+ git ls-files -o >out &&
+ test_line_count = 1 out &&
+
+ git rev-parse >expect \
+ C:new_a D:new_a E:new_a &&
+ git rev-parse >actual \
+ :1:new_a :2:new_a :3:new_a &&
+ test_cmp expect actual &&
+
+ # Test that the two-way merge in new_a is as expected
+ git cat-file -p D:new_a >ours &&
+ git cat-file -p E:new_a >theirs &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "E^0" \
+ ours empty theirs &&
+ sed -e "s/^\([<=>]\)/\1\1\1/" ours >expect &&
+ git hash-object new_a >actual &&
+ git hash-object ours >expect &&
test_cmp expect actual
)
'
@@ -1402,4 +1449,349 @@ test_expect_failure 'check conflicting modes for regular file' '
)
'
+# Setup:
+# L1---L2
+# / \ / \
+# master X ?
+# \ / \ /
+# R1---R2
+#
+# Where:
+# master has two files, named 'b' and 'a'
+# branches L1 and R1 both modify each of the two files in conflicting ways
+#
+# L2 is a merge of R1 into L1; more on it later.
+# R2 is a merge of L1 into R1; more on it later.
+#
+# X is an auto-generated merge-base used when merging L2 and R2.
+# since X is a merge of L1 and R1, it has conflicting versions of each file
+#
+# More about L2 and R2:
+# - both resolve the conflicts in 'b' and 'a' differently
+# - L2 renames 'b' to 'm'
+# - R2 renames 'a' to 'm'
+#
+# In the end, in file 'm' we have four different conflicting files (from
+# two versions of 'b' and two of 'a'). In addition, if
+# merge.conflictstyle is diff3, then the base version also has
+# conflict markers of its own, leading to a total of three levels of
+# conflict markers. This is a pretty weird corner case, but we just want
+# to ensure that we handle it as well as practical.
+
+test_expect_success 'setup nested conflicts' '
+ test_create_repo nested_conflicts &&
+ (
+ cd nested_conflicts &&
+
+ # Create some related files now
+ for i in $(test_seq 1 10)
+ do
+ echo Random base content line $i
+ done >initial &&
+
+ cp initial b_L1 &&
+ cp initial b_R1 &&
+ cp initial b_L2 &&
+ cp initial b_R2 &&
+ cp initial a_L1 &&
+ cp initial a_R1 &&
+ cp initial a_L2 &&
+ cp initial a_R2 &&
+
+ test_write_lines b b_L1 >>b_L1 &&
+ test_write_lines b b_R1 >>b_R1 &&
+ test_write_lines b b_L2 >>b_L2 &&
+ test_write_lines b b_R2 >>b_R2 &&
+ test_write_lines a a_L1 >>a_L1 &&
+ test_write_lines a a_R1 >>a_R1 &&
+ test_write_lines a a_L2 >>a_L2 &&
+ test_write_lines a a_R2 >>a_R2 &&
+
+ # Setup original commit (or merge-base), consisting of
+ # files named "b" and "a"
+ cp initial b &&
+ cp initial a &&
+ echo b >>b &&
+ echo a >>a &&
+ git add b a &&
+ test_tick && git commit -m initial &&
+
+ git branch L &&
+ git branch R &&
+
+ # Handle the left side
+ git checkout L &&
+ mv -f b_L1 b &&
+ mv -f a_L1 a &&
+ git add b a &&
+ test_tick && git commit -m "version L1 of files" &&
+ git tag L1 &&
+
+ # Handle the right side
+ git checkout R &&
+ mv -f b_R1 b &&
+ mv -f a_R1 a &&
+ git add b a &&
+ test_tick && git commit -m "verson R1 of files" &&
+ git tag R1 &&
+
+ # Create first merge on left side
+ git checkout L &&
+ test_must_fail git merge R1 &&
+ mv -f b_L2 b &&
+ mv -f a_L2 a &&
+ git add b a &&
+ git mv b m &&
+ test_tick && git commit -m "left merge, rename b->m" &&
+ git tag L2 &&
+
+ # Create first merge on right side
+ git checkout R &&
+ test_must_fail git merge L1 &&
+ mv -f b_R2 b &&
+ mv -f a_R2 a &&
+ git add b a &&
+ git mv a m &&
+ test_tick && git commit -m "right merge, rename a->m" &&
+ git tag R2
+ )
+'
+
+test_expect_success 'check nested conflicts' '
+ (
+ cd nested_conflicts &&
+
+ git clean -f &&
+ git checkout L2^0 &&
+
+ # Merge must fail; there is a conflict
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R2^0 &&
+
+ # Make sure the index has the right number of entries
+ git ls-files -s >out &&
+ test_line_count = 2 out &&
+ git ls-files -u >out &&
+ test_line_count = 2 out &&
+ # Ensure we have the correct number of untracked files
+ git ls-files -o >out &&
+ test_line_count = 1 out &&
+
+ # Create a and b from virtual merge base X
+ git cat-file -p master:a >base &&
+ git cat-file -p L1:a >ours &&
+ git cat-file -p R1:a >theirs &&
+ test_must_fail git merge-file --diff3 \
+ -L "Temporary merge branch 1" \
+ -L "merged common ancestors" \
+ -L "Temporary merge branch 2" \
+ ours \
+ base \
+ theirs &&
+ sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_a &&
+
+ git cat-file -p master:b >base &&
+ git cat-file -p L1:b >ours &&
+ git cat-file -p R1:b >theirs &&
+ test_must_fail git merge-file --diff3 \
+ -L "Temporary merge branch 1" \
+ -L "merged common ancestors" \
+ -L "Temporary merge branch 2" \
+ ours \
+ base \
+ theirs &&
+ sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_b &&
+
+ # Compare :2:m to expected values
+ git cat-file -p L2:m >ours &&
+ git cat-file -p R2:b >theirs &&
+ test_must_fail git merge-file --diff3 \
+ -L "HEAD:m" \
+ -L "merged common ancestors:b" \
+ -L "R2^0:b" \
+ ours \
+ vmb_b \
+ theirs &&
+ sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_2 &&
+ git cat-file -p :2:m >actual &&
+ test_cmp m_stage_2 actual &&
+
+ # Compare :3:m to expected values
+ git cat-file -p L2:a >ours &&
+ git cat-file -p R2:m >theirs &&
+ test_must_fail git merge-file --diff3 \
+ -L "HEAD:a" \
+ -L "merged common ancestors:a" \
+ -L "R2^0:m" \
+ ours \
+ vmb_a \
+ theirs &&
+ sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_3 &&
+ git cat-file -p :3:m >actual &&
+ test_cmp m_stage_3 actual &&
+
+ # Compare m to expected contents
+ >empty &&
+ cp m_stage_2 expected_final_m &&
+ test_must_fail git merge-file --diff3 \
+ -L "HEAD" \
+ -L "merged common ancestors" \
+ -L "R2^0" \
+ expected_final_m \
+ empty \
+ m_stage_3 &&
+ test_cmp expected_final_m m
+ )
+'
+
+# Setup:
+# L1---L2---L3
+# / \ / \ / \
+# master X1 X2 ?
+# \ / \ / \ /
+# R1---R2---R3
+#
+# Where:
+# master has one file named 'content'
+# branches L1 and R1 both modify each of the two files in conflicting ways
+#
+# L<n> (n>1) is a merge of R<n-1> into L<n-1>
+# R<n> (n>1) is a merge of L<n-1> into R<n-1>
+# L<n> and R<n> resolve the conflicts differently.
+#
+# X<n> is an auto-generated merge-base used when merging L<n+1> and R<n+1>.
+# By construction, X1 has conflict markers due to conflicting versions.
+# X2, due to using merge.conflictstyle=3, has nested conflict markers.
+#
+# So, merging R3 into L3 using merge.conflictstyle=3 should show the
+# nested conflict markers from X2 in the base version -- that means we
+# have three levels of conflict markers. Can we distinguish all three?
+
+test_expect_success 'setup virtual merge base with nested conflicts' '
+ test_create_repo virtual_merge_base_has_nested_conflicts &&
+ (
+ cd virtual_merge_base_has_nested_conflicts &&
+
+ # Create some related files now
+ for i in $(test_seq 1 10)
+ do
+ echo Random base content line $i
+ done >content &&
+
+ # Setup original commit
+ git add content &&
+ test_tick && git commit -m initial &&
+
+ git branch L &&
+ git branch R &&
+
+ # Create L1
+ git checkout L &&
+ echo left >>content &&
+ git add content &&
+ test_tick && git commit -m "version L1 of content" &&
+ git tag L1 &&
+
+ # Create R1
+ git checkout R &&
+ echo right >>content &&
+ git add content &&
+ test_tick && git commit -m "verson R1 of content" &&
+ git tag R1 &&
+
+ # Create L2
+ git checkout L &&
+ test_must_fail git -c merge.conflictstyle=diff3 merge R1 &&
+ git checkout L1 content &&
+ test_tick && git commit -m "version L2 of content" &&
+ git tag L2 &&
+
+ # Create R2
+ git checkout R &&
+ test_must_fail git -c merge.conflictstyle=diff3 merge L1 &&
+ git checkout R1 content &&
+ test_tick && git commit -m "version R2 of content" &&
+ git tag R2 &&
+
+ # Create L3
+ git checkout L &&
+ test_must_fail git -c merge.conflictstyle=diff3 merge R2 &&
+ git checkout L1 content &&
+ test_tick && git commit -m "version L3 of content" &&
+ git tag L3 &&
+
+ # Create R3
+ git checkout R &&
+ test_must_fail git -c merge.conflictstyle=diff3 merge L2 &&
+ git checkout R1 content &&
+ test_tick && git commit -m "version R3 of content" &&
+ git tag R3
+ )
+'
+
+test_expect_success 'check virtual merge base with nested conflicts' '
+ (
+ cd virtual_merge_base_has_nested_conflicts &&
+
+ git checkout L3^0 &&
+
+ # Merge must fail; there is a conflict
+ test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R3^0 &&
+
+ # Make sure the index has the right number of entries
+ git ls-files -s >out &&
+ test_line_count = 3 out &&
+ git ls-files -u >out &&
+ test_line_count = 3 out &&
+ # Ensure we have the correct number of untracked files
+ git ls-files -o >out &&
+ test_line_count = 1 out &&
+
+ # Compare :[23]:content to expected values
+ git rev-parse L1:content R1:content >expect &&
+ git rev-parse :2:content :3:content >actual &&
+ test_cmp expect actual &&
+
+ # Imitate X1 merge base, except without long enough conflict
+ # markers because a subsequent sed will modify them. Put
+ # result into vmb.
+ git cat-file -p master:content >base &&
+ git cat-file -p L:content >left &&
+ git cat-file -p R:content >right &&
+ cp left merged-once &&
+ test_must_fail git merge-file --diff3 \
+ -L "Temporary merge branch 1" \
+ -L "merged common ancestors" \
+ -L "Temporary merge branch 2" \
+ merged-once \
+ base \
+ right &&
+ sed -e "s/^\([<|=>]\)/\1\1\1/" merged-once >vmb &&
+
+ # Imitate X2 merge base, overwriting vmb. Note that we
+ # extend both sets of conflict markers to make them longer
+ # with the sed command.
+ cp left merged-twice &&
+ test_must_fail git merge-file --diff3 \
+ -L "Temporary merge branch 1" \
+ -L "merged common ancestors" \
+ -L "Temporary merge branch 2" \
+ merged-twice \
+ vmb \
+ right &&
+ sed -e "s/^\([<|=>]\)/\1\1\1/" merged-twice >vmb &&
+
+ # Compare :1:content to expected value
+ git cat-file -p :1:content >actual &&
+ test_cmp vmb actual &&
+
+ # Determine expected content in final outer merge, compare to
+ # what the merge generated.
+ cp -f left expect &&
+ test_must_fail git merge-file --diff3 \
+ -L "HEAD" -L "merged common ancestors" -L "R3^0" \
+ expect vmb right &&
+ test_cmp expect content
+ )
+'
+
test_done
diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh
index b97aca7fa2..7cc34e7579 100755
--- a/t/t6042-merge-rename-corner-cases.sh
+++ b/t/t6042-merge-rename-corner-cases.sh
@@ -464,17 +464,28 @@ test_expect_success 'handle rename/rename (2to1) conflict correctly' '
git ls-files -u c >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
test_path_is_missing a &&
test_path_is_missing b &&
- test_path_is_file c~HEAD &&
- test_path_is_file c~C^0 &&
- git rev-parse >expect \
- C:a B:b &&
- git hash-object >actual \
- c~HEAD c~C^0 &&
+ git rev-parse >expect \
+ C:a B:b &&
+ git rev-parse >actual \
+ :2:c :3:c &&
+ test_cmp expect actual &&
+
+ # Test that the two-way merge in new_a is as expected
+ git cat-file -p :2:c >>ours &&
+ git cat-file -p :3:c >>theirs &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "C^0" \
+ ours empty theirs &&
+ git hash-object c >actual &&
+ git hash-object ours >expect &&
test_cmp expect actual
)
'
@@ -673,7 +684,7 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting
git ls-files -u c >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 5 out &&
+ test_line_count = 1 out &&
git rev-parse >expect \
A:a C:b B:b C:c B:c &&
@@ -681,14 +692,27 @@ test_expect_success 'rename/rename/add-dest merge still knows about conflicting
:1:a :2:b :3:b :2:c :3:c &&
test_cmp expect actual &&
- git rev-parse >expect \
- C:c B:c C:b B:b &&
- git hash-object >actual \
- c~HEAD c~B\^0 b~HEAD b~B\^0 &&
- test_cmp expect actual &&
+ # Record some contents for re-doing merges
+ git cat-file -p A:a >stuff &&
+ git cat-file -p C:b >important_info &&
+ git cat-file -p B:c >precious_data &&
+ >empty &&
- test_path_is_missing b &&
- test_path_is_missing c
+ # Test the merge in b
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ important_info empty stuff &&
+ test_cmp important_info b &&
+
+ # Test the merge in c
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ stuff empty precious_data &&
+ test_cmp stuff c
)
'
@@ -937,4 +961,283 @@ test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename
)
'
+test_conflicts_with_adds_and_renames() {
+ sideL=$1
+ sideR=$2
+
+ # Setup:
+ # L
+ # / \
+ # master ?
+ # \ /
+ # R
+ #
+ # Where:
+ # Both L and R have files named 'three' which collide. Each of
+ # the colliding files could have been involved in a rename, in
+ # which case there was a file named 'one' or 'two' that was
+ # modified on the opposite side of history and renamed into the
+ # collision on this side of history.
+ #
+ # Questions:
+ # 1) The index should contain both a stage 2 and stage 3 entry
+ # for the colliding file. Does it?
+ # 2) When renames are involved, the content merges are clean, so
+ # the index should reflect the content merges, not merely the
+ # version of the colliding file from the prior commit. Does
+ # it?
+ # 3) There should be a file in the worktree named 'three'
+ # containing the two-way merged contents of the content-merged
+ # versions of 'three' from each of the two colliding
+ # files. Is it present?
+ # 4) There should not be any three~* files in the working
+ # tree
+ test_expect_success "setup simple $sideL/$sideR conflict" '
+ test_create_repo simple_${sideL}_${sideR} &&
+ (
+ cd simple_${sideL}_${sideR} &&
+
+ # Create some related files now
+ for i in $(test_seq 1 10)
+ do
+ echo Random base content line $i
+ done >file_v1 &&
+ cp file_v1 file_v2 &&
+ echo modification >>file_v2 &&
+
+ cp file_v1 file_v3 &&
+ echo more stuff >>file_v3 &&
+ cp file_v3 file_v4 &&
+ echo yet more stuff >>file_v4 &&
+
+ # Use a tag to record both these files for simple
+ # access, and clean out these untracked files
+ git tag file_v1 $(git hash-object -w file_v1) &&
+ git tag file_v2 $(git hash-object -w file_v2) &&
+ git tag file_v3 $(git hash-object -w file_v3) &&
+ git tag file_v4 $(git hash-object -w file_v4) &&
+ git clean -f &&
+
+ # Setup original commit (or merge-base), consisting of
+ # files named "one" and "two" if renames were involved.
+ touch irrelevant_file &&
+ git add irrelevant_file &&
+ if [ $sideL = "rename" ]
+ then
+ git show file_v1 >one &&
+ git add one
+ fi &&
+ if [ $sideR = "rename" ]
+ then
+ git show file_v3 >two &&
+ git add two
+ fi &&
+ test_tick && git commit -m initial &&
+
+ git branch L &&
+ git branch R &&
+
+ # Handle the left side
+ git checkout L &&
+ if [ $sideL = "rename" ]
+ then
+ git mv one three
+ else
+ git show file_v2 >three &&
+ git add three
+ fi &&
+ if [ $sideR = "rename" ]
+ then
+ git show file_v4 >two &&
+ git add two
+ fi &&
+ test_tick && git commit -m L &&
+
+ # Handle the right side
+ git checkout R &&
+ if [ $sideL = "rename" ]
+ then
+ git show file_v2 >one &&
+ git add one
+ fi &&
+ if [ $sideR = "rename" ]
+ then
+ git mv two three
+ else
+ git show file_v4 >three &&
+ git add three
+ fi &&
+ test_tick && git commit -m R
+ )
+ '
+
+ test_expect_success "check simple $sideL/$sideR conflict" '
+ (
+ cd simple_${sideL}_${sideR} &&
+
+ git checkout L^0 &&
+
+ # Merge must fail; there is a conflict
+ test_must_fail git merge -s recursive R^0 &&
+
+ # Make sure the index has the right number of entries
+ git ls-files -s >out &&
+ test_line_count = 3 out &&
+ git ls-files -u >out &&
+ test_line_count = 2 out &&
+ # Ensure we have the correct number of untracked files
+ git ls-files -o >out &&
+ test_line_count = 1 out &&
+
+ # Nothing should have touched irrelevant_file
+ git rev-parse >actual \
+ :0:irrelevant_file \
+ :2:three \
+ :3:three &&
+ git rev-parse >expected \
+ master:irrelevant_file \
+ file_v2 \
+ file_v4 &&
+ test_cmp expected actual &&
+
+ # Make sure we have the correct merged contents for
+ # three
+ git show file_v1 >expected &&
+ cat <<-\EOF >>expected &&
+ <<<<<<< HEAD
+ modification
+ =======
+ more stuff
+ yet more stuff
+ >>>>>>> R^0
+ EOF
+
+ test_cmp expected three
+ )
+ '
+}
+
+test_conflicts_with_adds_and_renames rename rename
+test_conflicts_with_adds_and_renames rename add
+test_conflicts_with_adds_and_renames add rename
+test_conflicts_with_adds_and_renames add add
+
+# Setup:
+# L
+# / \
+# master ?
+# \ /
+# R
+#
+# Where:
+# master has two files, named 'one' and 'two'.
+# branches L and R both modify 'one', in conflicting ways.
+# branches L and R both modify 'two', in conflicting ways.
+# branch L also renames 'one' to 'three'.
+# branch R also renames 'two' to 'three'.
+#
+# So, we have four different conflicting files that all end up at path
+# 'three'.
+test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
+ test_create_repo nested_conflicts_from_rename_rename &&
+ (
+ cd nested_conflicts_from_rename_rename &&
+
+ # Create some related files now
+ for i in $(test_seq 1 10)
+ do
+ echo Random base content line $i
+ done >file_v1 &&
+
+ cp file_v1 file_v2 &&
+ cp file_v1 file_v3 &&
+ cp file_v1 file_v4 &&
+ cp file_v1 file_v5 &&
+ cp file_v1 file_v6 &&
+
+ echo one >>file_v1 &&
+ echo uno >>file_v2 &&
+ echo eins >>file_v3 &&
+
+ echo two >>file_v4 &&
+ echo dos >>file_v5 &&
+ echo zwei >>file_v6 &&
+
+ # Setup original commit (or merge-base), consisting of
+ # files named "one" and "two".
+ mv file_v1 one &&
+ mv file_v4 two &&
+ git add one two &&
+ test_tick && git commit -m english &&
+
+ git branch L &&
+ git branch R &&
+
+ # Handle the left side
+ git checkout L &&
+ git mv one three &&
+ mv -f file_v2 three &&
+ mv -f file_v5 two &&
+ git add two three &&
+ test_tick && git commit -m spanish &&
+
+ # Handle the right side
+ git checkout R &&
+ git mv two three &&
+ mv -f file_v3 one &&
+ mv -f file_v6 three &&
+ git add one three &&
+ test_tick && git commit -m german
+ )
+'
+
+test_expect_success 'check nested conflicts from rename/rename(2to1)' '
+ (
+ cd nested_conflicts_from_rename_rename &&
+
+ git checkout L^0 &&
+
+ # Merge must fail; there is a conflict
+ test_must_fail git merge -s recursive R^0 &&
+
+ # Make sure the index has the right number of entries
+ git ls-files -s >out &&
+ test_line_count = 2 out &&
+ git ls-files -u >out &&
+ test_line_count = 2 out &&
+ # Ensure we have the correct number of untracked files
+ git ls-files -o >out &&
+ test_line_count = 1 out &&
+
+ # Compare :2:three to expected values
+ git cat-file -p master:one >base &&
+ git cat-file -p L:three >ours &&
+ git cat-file -p R:one >theirs &&
+ test_must_fail git merge-file \
+ -L "HEAD:three" -L "" -L "R^0:one" \
+ ours base theirs &&
+ sed -e "s/^\([<=>]\)/\1\1/" ours >L-three &&
+ git cat-file -p :2:three >expect &&
+ test_cmp expect L-three &&
+
+ # Compare :2:three to expected values
+ git cat-file -p master:two >base &&
+ git cat-file -p L:two >ours &&
+ git cat-file -p R:three >theirs &&
+ test_must_fail git merge-file \
+ -L "HEAD:two" -L "" -L "R^0:three" \
+ ours base theirs &&
+ sed -e "s/^\([<=>]\)/\1\1/" ours >R-three &&
+ git cat-file -p :3:three >expect &&
+ test_cmp expect R-three &&
+
+ # Compare three to expected contents
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" -L "" -L "R^0" \
+ L-three empty R-three &&
+ test_cmp three L-three
+ )
+'
+
test_done
diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh
index 4a71f17edd..62c564707b 100755
--- a/t/t6043-merge-rename-directories.sh
+++ b/t/t6043-merge-rename-directories.sh
@@ -278,7 +278,7 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >actual \
:0:x/b :0:x/c :0:x/d :0:x/e :0:x/m :0:x/n &&
@@ -293,15 +293,16 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con
A:y/wham B:z/wham &&
test_cmp expect actual &&
- test_path_is_missing x/wham &&
- test_path_is_file x/wham~HEAD &&
- test_path_is_file x/wham~B^0 &&
-
- git hash-object >actual \
- x/wham~HEAD x/wham~B^0 &&
- git rev-parse >expect \
- A:y/wham B:z/wham &&
- test_cmp expect actual
+ # Test that the two-way merge in x/wham is as expected
+ git cat-file -p :2:x/wham >expect &&
+ git cat-file -p :3:x/wham >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect x/wham
)
'
@@ -1077,7 +1078,7 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam
git ls-files -u >out &&
test_line_count = 6 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:y/e &&
@@ -1093,9 +1094,9 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam
test_cmp expect actual &&
git hash-object >actual \
- w/d~HEAD w/d~B^0 z/d &&
+ z/d &&
git rev-parse >expect \
- O:x/d B:w/d O:x/d &&
+ O:x/d &&
test_cmp expect actual &&
test_path_is_missing x/d &&
test_path_is_file y/d &&
@@ -1670,7 +1671,7 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :2:y/d :3:y/d &&
@@ -1678,15 +1679,16 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r
O:z/b O:z/c O:w/d O:x/d &&
test_cmp expect actual &&
- test_path_is_missing y/d &&
- test_path_is_file y/d~HEAD &&
- test_path_is_file y/d~B^0 &&
-
- git hash-object >actual \
- y/d~HEAD y/d~B^0 &&
- git rev-parse >expect \
- O:w/d O:x/d &&
- test_cmp expect actual
+ # Test that the two-way merge in y/d is as expected
+ git cat-file -p :2:y/d >expect &&
+ git cat-file -p :3:y/d >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect y/d
)
'
@@ -3161,11 +3163,48 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
)
'
+test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2), other direction' '
+ (
+ cd 10c &&
+
+ git reset --hard &&
+ git clean -fdqx &&
+
+ git checkout B^0 &&
+ mkdir y &&
+ echo important >y/c &&
+
+ test_must_fail git merge -s recursive A^0 >out 2>err &&
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
+ test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~HEAD instead" out &&
+
+ git ls-files -s >out &&
+ test_line_count = 6 out &&
+ git ls-files -u >out &&
+ test_line_count = 3 out &&
+ git ls-files -o >out &&
+ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ :0:y/a :0:y/b :0:x/d :1:x/c :3:w/c :2:y/c &&
+ git rev-parse >expect \
+ O:z/a O:z/b O:x/d O:x/c O:x/c O:x/c &&
+ test_cmp expect actual &&
+
+ git hash-object y/c~HEAD >actual &&
+ git rev-parse O:x/c >expect &&
+ test_cmp expect actual &&
+
+ echo important >expect &&
+ test_cmp expect y/c
+ )
+'
+
# Testcase 10d, Delete untracked w/ dir rename/rename(2to1)
# Commit O: z/{a,b,c_1}, x/{d,e,f_2}
# Commit A: y/{a,b}, x/{d,e,f_2,wham_1} + untracked y/wham
# Commit B: z/{a,b,c_1,wham_2}, y/{d,e}
-# Expected: Failed Merge; y/{a,b,d,e} + untracked y/{wham,wham~B^0,wham~HEAD}+
+# Expected: Failed Merge; y/{a,b,d,e} + untracked y/{wham,wham~merged}+
# CONFLICT(rename/rename) z/c_1 vs x/f_2 -> y/wham
# ERROR_MSG(Refusing to lose untracked file at y/wham)
@@ -3219,7 +3258,7 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 4 out &&
+ test_line_count = 3 out &&
git rev-parse >actual \
:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&
@@ -3232,11 +3271,16 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
echo important >expect &&
test_cmp expect y/wham &&
- git hash-object >actual \
- y/wham~B^0 y/wham~HEAD &&
- git rev-parse >expect \
- O:x/f O:z/c &&
- test_cmp expect actual
+ # Test that the two-way merge in y/wham~merged is as expected
+ git cat-file -p :2:y/wham >expect &&
+ git cat-file -p :3:y/wham >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect y/wham~merged
)
'
@@ -3665,7 +3709,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
git ls-files -u >out &&
test_line_count = 4 out &&
git ls-files -o >out &&
- test_line_count = 4 out &&
+ test_line_count = 3 out &&
echo different >expected &&
echo mods >>expected &&
@@ -3677,11 +3721,17 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
O:z/a O:z/b O:x/d O:x/c O:x/c A:y/c O:x/c &&
test_cmp expect actual &&
- git hash-object >actual \
- y/c~B^0 y/c~HEAD &&
- git rev-parse >expect \
- O:x/c A:y/c &&
- test_cmp expect actual
+ # See if y/c~merged has expected contents; requires manually
+ # doing the expected file merge
+ git cat-file -p A:y/c >c1 &&
+ git cat-file -p B:z/c >c2 &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ c1 empty c2 &&
+ test_cmp c1 y/c~merged
)
'
@@ -3689,7 +3739,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
# Commit O: z/{a,b}, x/{c_1,d_2}
# Commit A: y/{a,b,wham_1}, x/d_2, except y/wham has uncommitted mods
# Commit B: z/{a,b,wham_2}, x/c_1
-# Expected: Failed Merge; y/{a,b} + untracked y/{wham~B^0,wham~B^HEAD} +
+# Expected: Failed Merge; y/{a,b} + untracked y/{wham~merged} +
# y/wham with dirty changes from before merge +
# CONFLICT(rename/rename) x/c vs x/d -> y/wham
# ERROR_MSG(Refusing to lose dirty file at y/wham)
@@ -3741,24 +3791,30 @@ test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rena
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 4 out &&
+ test_line_count = 3 out &&
test_seq 1 10 >expected &&
echo important >>expected &&
test_cmp expected y/wham &&
test_must_fail git rev-parse :1:y/wham &&
- git hash-object >actual \
- y/wham~B^0 y/wham~HEAD &&
- git rev-parse >expect \
- O:x/d O:x/c &&
- test_cmp expect actual &&
git rev-parse >actual \
:0:y/a :0:y/b :2:y/wham :3:y/wham &&
git rev-parse >expect \
O:z/a O:z/b O:x/c O:x/d &&
- test_cmp expect actual
+ test_cmp expect actual &&
+
+ # Test that the two-way merge in y/wham~merged is as expected
+ git cat-file -p :2:y/wham >expect &&
+ git cat-file -p :3:y/wham >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect y/wham~merged
)
'
diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh
index 86374a9c52..d638119750 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -133,8 +133,8 @@ test_expect_success 'tag replaced commit' '
test_expect_success '"git fsck" works' '
git fsck master >fsck_master.out &&
- grep "dangling commit $R" fsck_master.out &&
- grep "dangling tag $(cat .git/refs/tags/mytag)" fsck_master.out &&
+ test_i18ngrep "dangling commit $R" fsck_master.out &&
+ test_i18ngrep "dangling tag $(cat .git/refs/tags/mytag)" fsck_master.out &&
test -z "$(git fsck)"
'
@@ -461,7 +461,10 @@ test_expect_success '--convert-graft-file' '
printf "%s\n%s %s\n\n# comment\n%s\n" \
$(git rev-parse HEAD^^ HEAD^ HEAD^^ HEAD^2) \
>.git/info/grafts &&
- git replace --convert-graft-file &&
+ git status 2>stderr &&
+ test_i18ngrep "hint:.*grafts is deprecated" stderr &&
+ git replace --convert-graft-file 2>stderr &&
+ test_i18ngrep ! "hint:.*grafts is deprecated" stderr &&
test_path_is_missing .git/info/grafts &&
: verify that the history is now "grafted" &&
diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh
index eb829fce97..2462b19ddd 100755
--- a/t/t6132-pathspec-exclude.sh
+++ b/t/t6132-pathspec-exclude.sh
@@ -194,4 +194,21 @@ test_expect_success 'multiple exclusions' '
test_cmp expect actual
'
+test_expect_success 't_e_i() exclude case #8' '
+ git init case8 &&
+ (
+ cd case8 &&
+ echo file >file1 &&
+ echo file >file2 &&
+ git add file1 file2 &&
+ git commit -m twofiles &&
+ git grep -l file HEAD :^file2 >actual &&
+ echo HEAD:file1 >expected &&
+ test_cmp expected actual &&
+ git grep -l file HEAD :^file1 >actual &&
+ echo HEAD:file2 >expected &&
+ test_cmp expected actual
+ )
+'
+
test_done
diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh
index e436a73962..457cc167c7 100755
--- a/t/t6135-pathspec-with-attrs.sh
+++ b/t/t6135-pathspec-with-attrs.sh
@@ -31,7 +31,7 @@ test_expect_success 'setup a tree' '
mkdir sub &&
while read path
do
- : >$path &&
+ echo content >$path &&
git add $path || return 1
done <expect &&
git commit -m "initial commit" &&
@@ -48,6 +48,10 @@ test_expect_success 'pathspec with labels and non existent .gitattributes' '
test_must_be_empty actual
'
+test_expect_success 'pathspec with labels and non existent .gitattributes (2)' '
+ test_must_fail git grep content HEAD -- ":(attr:label)"
+'
+
test_expect_success 'setup .gitattributes' '
cat <<-\EOF >.gitattributes &&
fileA labelA
@@ -74,6 +78,15 @@ test_expect_success 'check specific set attr' '
test_cmp expect actual
'
+test_expect_success 'check specific set attr (2)' '
+ cat <<-\EOF >expect &&
+ HEAD:fileSetLabel
+ HEAD:sub/fileSetLabel
+ EOF
+ git grep -l content HEAD ":(attr:label)" >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'check specific unset attr' '
cat <<-\EOF >expect &&
fileUnsetLabel
@@ -83,6 +96,15 @@ test_expect_success 'check specific unset attr' '
test_cmp expect actual
'
+test_expect_success 'check specific unset attr (2)' '
+ cat <<-\EOF >expect &&
+ HEAD:fileUnsetLabel
+ HEAD:sub/fileUnsetLabel
+ EOF
+ git grep -l content HEAD ":(attr:-label)" >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'check specific value attr' '
cat <<-\EOF >expect &&
fileValue
@@ -94,6 +116,16 @@ test_expect_success 'check specific value attr' '
test_must_be_empty actual
'
+test_expect_success 'check specific value attr (2)' '
+ cat <<-\EOF >expect &&
+ HEAD:fileValue
+ HEAD:sub/fileValue
+ EOF
+ git grep -l content HEAD ":(attr:label=foo)" >actual &&
+ test_cmp expect actual &&
+ test_must_fail git grep -l content HEAD ":(attr:label=bar)"
+'
+
test_expect_success 'check unspecified attr' '
cat <<-\EOF >expect &&
.gitattributes
@@ -118,6 +150,30 @@ test_expect_success 'check unspecified attr' '
test_cmp expect actual
'
+test_expect_success 'check unspecified attr (2)' '
+ cat <<-\EOF >expect &&
+ HEAD:.gitattributes
+ HEAD:fileA
+ HEAD:fileAB
+ HEAD:fileAC
+ HEAD:fileB
+ HEAD:fileBC
+ HEAD:fileC
+ HEAD:fileNoLabel
+ HEAD:fileWrongLabel
+ HEAD:sub/fileA
+ HEAD:sub/fileAB
+ HEAD:sub/fileAC
+ HEAD:sub/fileB
+ HEAD:sub/fileBC
+ HEAD:sub/fileC
+ HEAD:sub/fileNoLabel
+ HEAD:sub/fileWrongLabel
+ EOF
+ git grep -l ^ HEAD ":(attr:!label)" >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'check multiple unspecified attr' '
cat <<-\EOF >expect &&
.gitattributes
diff --git a/t/t6600-test-reach.sh b/t/t6600-test-reach.sh
index ae94b27f70..b24d850036 100755
--- a/t/t6600-test-reach.sh
+++ b/t/t6600-test-reach.sh
@@ -56,18 +56,22 @@ test_expect_success 'setup' '
git config core.commitGraph true
'
-test_three_modes () {
+run_three_modes () {
test_when_finished rm -rf .git/objects/info/commit-graph &&
- test-tool reach $1 <input >actual &&
+ "$@" <input >actual &&
test_cmp expect actual &&
cp commit-graph-full .git/objects/info/commit-graph &&
- test-tool reach $1 <input >actual &&
+ "$@" <input >actual &&
test_cmp expect actual &&
cp commit-graph-half .git/objects/info/commit-graph &&
- test-tool reach $1 <input >actual &&
+ "$@" <input >actual &&
test_cmp expect actual
}
+test_three_modes () {
+ run_three_modes test-tool reach "$@"
+}
+
test_expect_success 'ref_newer:miss' '
cat >input <<-\EOF &&
A:commit-5-7
@@ -265,4 +269,140 @@ test_expect_success 'commit_contains:miss' '
test_three_modes commit_contains --tag
'
+test_expect_success 'rev-list: basic topo-order' '
+ git rev-parse \
+ commit-6-6 commit-5-6 commit-4-6 commit-3-6 commit-2-6 commit-1-6 \
+ commit-6-5 commit-5-5 commit-4-5 commit-3-5 commit-2-5 commit-1-5 \
+ commit-6-4 commit-5-4 commit-4-4 commit-3-4 commit-2-4 commit-1-4 \
+ commit-6-3 commit-5-3 commit-4-3 commit-3-3 commit-2-3 commit-1-3 \
+ commit-6-2 commit-5-2 commit-4-2 commit-3-2 commit-2-2 commit-1-2 \
+ commit-6-1 commit-5-1 commit-4-1 commit-3-1 commit-2-1 commit-1-1 \
+ >expect &&
+ run_three_modes git rev-list --topo-order commit-6-6
+'
+
+test_expect_success 'rev-list: first-parent topo-order' '
+ git rev-parse \
+ commit-6-6 \
+ commit-6-5 \
+ commit-6-4 \
+ commit-6-3 \
+ commit-6-2 \
+ commit-6-1 commit-5-1 commit-4-1 commit-3-1 commit-2-1 commit-1-1 \
+ >expect &&
+ run_three_modes git rev-list --first-parent --topo-order commit-6-6
+'
+
+test_expect_success 'rev-list: range topo-order' '
+ git rev-parse \
+ commit-6-6 commit-5-6 commit-4-6 commit-3-6 commit-2-6 commit-1-6 \
+ commit-6-5 commit-5-5 commit-4-5 commit-3-5 commit-2-5 commit-1-5 \
+ commit-6-4 commit-5-4 commit-4-4 commit-3-4 commit-2-4 commit-1-4 \
+ commit-6-3 commit-5-3 commit-4-3 \
+ commit-6-2 commit-5-2 commit-4-2 \
+ commit-6-1 commit-5-1 commit-4-1 \
+ >expect &&
+ run_three_modes git rev-list --topo-order commit-3-3..commit-6-6
+'
+
+test_expect_success 'rev-list: range topo-order' '
+ git rev-parse \
+ commit-6-6 commit-5-6 commit-4-6 \
+ commit-6-5 commit-5-5 commit-4-5 \
+ commit-6-4 commit-5-4 commit-4-4 \
+ commit-6-3 commit-5-3 commit-4-3 \
+ commit-6-2 commit-5-2 commit-4-2 \
+ commit-6-1 commit-5-1 commit-4-1 \
+ >expect &&
+ run_three_modes git rev-list --topo-order commit-3-8..commit-6-6
+'
+
+test_expect_success 'rev-list: first-parent range topo-order' '
+ git rev-parse \
+ commit-6-6 \
+ commit-6-5 \
+ commit-6-4 \
+ commit-6-3 \
+ commit-6-2 \
+ commit-6-1 commit-5-1 commit-4-1 \
+ >expect &&
+ run_three_modes git rev-list --first-parent --topo-order commit-3-8..commit-6-6
+'
+
+test_expect_success 'rev-list: ancestry-path topo-order' '
+ git rev-parse \
+ commit-6-6 commit-5-6 commit-4-6 commit-3-6 \
+ commit-6-5 commit-5-5 commit-4-5 commit-3-5 \
+ commit-6-4 commit-5-4 commit-4-4 commit-3-4 \
+ commit-6-3 commit-5-3 commit-4-3 \
+ >expect &&
+ run_three_modes git rev-list --topo-order --ancestry-path commit-3-3..commit-6-6
+'
+
+test_expect_success 'rev-list: symmetric difference topo-order' '
+ git rev-parse \
+ commit-6-6 commit-5-6 commit-4-6 \
+ commit-6-5 commit-5-5 commit-4-5 \
+ commit-6-4 commit-5-4 commit-4-4 \
+ commit-6-3 commit-5-3 commit-4-3 \
+ commit-6-2 commit-5-2 commit-4-2 \
+ commit-6-1 commit-5-1 commit-4-1 \
+ commit-3-8 commit-2-8 commit-1-8 \
+ commit-3-7 commit-2-7 commit-1-7 \
+ >expect &&
+ run_three_modes git rev-list --topo-order commit-3-8...commit-6-6
+'
+
+test_expect_success 'get_reachable_subset:all' '
+ cat >input <<-\EOF &&
+ X:commit-9-1
+ X:commit-8-3
+ X:commit-7-5
+ X:commit-6-6
+ X:commit-1-7
+ Y:commit-3-3
+ Y:commit-1-7
+ Y:commit-5-6
+ EOF
+ (
+ echo "get_reachable_subset(X,Y)" &&
+ git rev-parse commit-3-3 \
+ commit-1-7 \
+ commit-5-6 | sort
+ ) >expect &&
+ test_three_modes get_reachable_subset
+'
+
+test_expect_success 'get_reachable_subset:some' '
+ cat >input <<-\EOF &&
+ X:commit-9-1
+ X:commit-8-3
+ X:commit-7-5
+ X:commit-1-7
+ Y:commit-3-3
+ Y:commit-1-7
+ Y:commit-5-6
+ EOF
+ (
+ echo "get_reachable_subset(X,Y)" &&
+ git rev-parse commit-3-3 \
+ commit-1-7 | sort
+ ) >expect &&
+ test_three_modes get_reachable_subset
+'
+
+test_expect_success 'get_reachable_subset:none' '
+ cat >input <<-\EOF &&
+ X:commit-9-1
+ X:commit-8-3
+ X:commit-7-5
+ X:commit-1-7
+ Y:commit-9-3
+ Y:commit-7-6
+ Y:commit-2-8
+ EOF
+ echo "get_reachable_subset(X,Y)" >expect &&
+ test_three_modes get_reachable_subset
+'
+
test_done
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 826987ca80..72b9b375ba 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -254,9 +254,9 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' '
test_expect_success 'checkout to detach HEAD' '
git config advice.detachedHead true &&
git checkout -f renamer && git clean -f &&
- git checkout renamer^ 2>messages &&
- test_i18ngrep "HEAD is now at 7329388" messages &&
- (test_line_count -gt 1 messages || test -n "$GETTEXT_POISON") &&
+ GIT_TEST_GETTEXT_POISON= git checkout renamer^ 2>messages &&
+ grep "HEAD is now at 7329388" messages &&
+ test_line_count -gt 1 messages &&
H=$(git rev-parse --verify HEAD) &&
M=$(git show-ref -s --verify refs/heads/master) &&
test "z$H" = "z$M" &&
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index 76a7cb0af7..aba2d4d6ee 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -984,6 +984,11 @@ test_expect_success 'submodule deinit should remove the whole submodule section
rmdir init
'
+test_expect_success 'submodule deinit should unset core.worktree' '
+ test_path_is_file .git/modules/example/config &&
+ test_must_fail git config -f .git/modules/example/config core.worktree
+'
+
test_expect_success 'submodule deinit from subdirectory' '
git submodule update --init &&
git config submodule.example.foo bar &&
diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh
index 0bde5850ac..89690b7adb 100755
--- a/t/t7411-submodule-config.sh
+++ b/t/t7411-submodule-config.sh
@@ -82,29 +82,23 @@ Submodule name: 'a' for path 'b'
Submodule name: 'submodule' for path 'submodule'
EOF
-test_expect_success 'error in one submodule config lets continue' '
+test_expect_success 'error in history of one submodule config lets continue, stderr message contains blob ref' '
+ ORIG=$(git -C super rev-parse HEAD) &&
+ test_when_finished "git -C super reset --hard $ORIG" &&
(cd super &&
cp .gitmodules .gitmodules.bak &&
echo " value = \"" >>.gitmodules &&
git add .gitmodules &&
mv .gitmodules.bak .gitmodules &&
git commit -m "add error" &&
- test-tool submodule-config \
- HEAD b \
- HEAD submodule \
- >actual &&
- test_cmp expect_error actual
- )
-'
-
-test_expect_success 'error message contains blob reference' '
- (cd super &&
sha1=$(git rev-parse HEAD) &&
test-tool submodule-config \
HEAD b \
HEAD submodule \
- 2>actual_err &&
- test_i18ngrep "submodule-blob $sha1:.gitmodules" actual_err >/dev/null
+ >actual \
+ 2>actual_stderr &&
+ test_cmp expect_error actual &&
+ test_i18ngrep "submodule-blob $sha1:.gitmodules" actual_stderr >/dev/null
)
'
@@ -123,6 +117,8 @@ test_expect_success 'using different treeishs works' '
'
test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
+ ORIG=$(git -C super rev-parse HEAD) &&
+ test_when_finished "git -C super reset --hard $ORIG" &&
(cd super &&
git config -f .gitmodules \
submodule.submodule.fetchrecursesubmodules blabla &&
@@ -134,8 +130,123 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
HEAD b \
HEAD submodule \
>actual &&
- test_cmp expect_error actual &&
- git reset --hard HEAD^
+ test_cmp expect_error actual
+ )
+'
+
+test_expect_success 'reading submodules config from the working tree with "submodule--helper config"' '
+ (cd super &&
+ echo "../submodule" >expect &&
+ git submodule--helper config submodule.submodule.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'writing submodules config with "submodule--helper config"' '
+ (cd super &&
+ echo "new_url" >expect &&
+ git submodule--helper config submodule.submodule.url "new_url" &&
+ git submodule--helper config submodule.submodule.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'overwriting unstaged submodules config with "submodule--helper config"' '
+ test_when_finished "git -C super checkout .gitmodules" &&
+ (cd super &&
+ echo "newer_url" >expect &&
+ git submodule--helper config submodule.submodule.url "newer_url" &&
+ git submodule--helper config submodule.submodule.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'writeable .gitmodules when it is in the working tree' '
+ git -C super submodule--helper config --check-writeable
+'
+
+test_expect_success 'writeable .gitmodules when it is nowhere in the repository' '
+ ORIG=$(git -C super rev-parse HEAD) &&
+ test_when_finished "git -C super reset --hard $ORIG" &&
+ (cd super &&
+ git rm .gitmodules &&
+ git commit -m "remove .gitmodules from the current branch" &&
+ git submodule--helper config --check-writeable
+ )
+'
+
+test_expect_success 'non-writeable .gitmodules when it is in the index but not in the working tree' '
+ test_when_finished "git -C super checkout .gitmodules" &&
+ (cd super &&
+ rm -f .gitmodules &&
+ test_must_fail git submodule--helper config --check-writeable
+ )
+'
+
+test_expect_success 'non-writeable .gitmodules when it is in the current branch but not in the index' '
+ ORIG=$(git -C super rev-parse HEAD) &&
+ test_when_finished "git -C super reset --hard $ORIG" &&
+ (cd super &&
+ git rm .gitmodules &&
+ test_must_fail git submodule--helper config --check-writeable
+ )
+'
+
+test_expect_success 'reading submodules config from the index when .gitmodules is not in the working tree' '
+ ORIG=$(git -C super rev-parse HEAD) &&
+ test_when_finished "git -C super reset --hard $ORIG" &&
+ (cd super &&
+ git submodule--helper config submodule.submodule.url "staged_url" &&
+ git add .gitmodules &&
+ rm -f .gitmodules &&
+ echo "staged_url" >expect &&
+ git submodule--helper config submodule.submodule.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'reading submodules config from the current branch when .gitmodules is not in the index' '
+ ORIG=$(git -C super rev-parse HEAD) &&
+ test_when_finished "git -C super reset --hard $ORIG" &&
+ (cd super &&
+ git rm .gitmodules &&
+ echo "../submodule" >expect &&
+ git submodule--helper config submodule.submodule.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'reading nested submodules config' '
+ (cd super &&
+ git init submodule/nested_submodule &&
+ echo "a" >submodule/nested_submodule/a &&
+ git -C submodule/nested_submodule add a &&
+ git -C submodule/nested_submodule commit -m "add a" &&
+ git -C submodule submodule add ./nested_submodule &&
+ git -C submodule add nested_submodule &&
+ git -C submodule commit -m "added nested_submodule" &&
+ git add submodule &&
+ git commit -m "updated submodule" &&
+ echo "./nested_submodule" >expect &&
+ test-tool submodule-nested-repo-config \
+ submodule submodule.nested_submodule.url >actual &&
+ test_cmp expect actual
+ )
+'
+
+# When this test eventually passes, before turning it into
+# test_expect_success, remember to replace the test_i18ngrep below with
+# a "test_must_be_empty warning" to be sure that the warning is actually
+# removed from the code.
+test_expect_failure 'reading nested submodules config when .gitmodules is not in the working tree' '
+ test_when_finished "git -C super/submodule checkout .gitmodules" &&
+ (cd super &&
+ echo "./nested_submodule" >expect &&
+ rm submodule/.gitmodules &&
+ test-tool submodule-nested-repo-config \
+ submodule submodule.nested_submodule.url >actual 2>warning &&
+ test_i18ngrep "nested submodules without %s in the working tree are not supported yet" warning &&
+ test_cmp expect actual
)
'
diff --git a/t/t7412-submodule-absorbgitdirs.sh b/t/t7412-submodule-absorbgitdirs.sh
index ce74c12da2..1cfa150768 100755
--- a/t/t7412-submodule-absorbgitdirs.sh
+++ b/t/t7412-submodule-absorbgitdirs.sh
@@ -75,7 +75,12 @@ test_expect_success 're-setup nested submodule' '
GIT_WORK_TREE=../../../nested git -C sub1/.git/modules/nested config \
core.worktree "../../../nested" &&
# make sure this re-setup is correct
- git status --ignore-submodules=none
+ git status --ignore-submodules=none &&
+
+ # also make sure this old setup does not regress
+ git submodule update --init --recursive >out 2>err &&
+ test_must_be_empty out &&
+ test_must_be_empty err
'
test_expect_success 'absorb the git dir in a nested submodule' '
diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh
index 293e2e1963..49a37efe9c 100755
--- a/t/t7415-submodule-names.sh
+++ b/t/t7415-submodule-names.sh
@@ -154,7 +154,7 @@ test_expect_success 'fsck detects symlinked .gitmodules file' '
# symlink detector; this grep string comes from the config
# variable name and will not be translated.
test_must_fail git fsck 2>output &&
- grep gitmodulesSymlink output
+ test_i18ngrep gitmodulesSymlink output
)
'
@@ -172,7 +172,7 @@ test_expect_success 'fsck detects non-blob .gitmodules' '
git ls-tree HEAD | sed s/subdir/.gitmodules/ | git mktree &&
test_must_fail git fsck 2>output &&
- grep gitmodulesBlob output
+ test_i18ngrep gitmodulesBlob output
)
'
@@ -186,7 +186,7 @@ test_expect_success 'fsck detects corrupt .gitmodules' '
git commit -m "broken gitmodules" &&
git fsck 2>output &&
- grep gitmodulesParse output &&
+ test_i18ngrep gitmodulesParse output &&
test_i18ngrep ! "bad config" output
)
'
diff --git a/t/t7418-submodule-sparse-gitmodules.sh b/t/t7418-submodule-sparse-gitmodules.sh
new file mode 100755
index 0000000000..3f7f271883
--- /dev/null
+++ b/t/t7418-submodule-sparse-gitmodules.sh
@@ -0,0 +1,122 @@
+#!/bin/sh
+#
+# Copyright (C) 2018 Antonio Ospite <ao2@ao2.it>
+#
+
+test_description='Test reading/writing .gitmodules when not in the working tree
+
+This test verifies that, when .gitmodules is in the current branch but is not
+in the working tree reading from it still works but writing to it does not.
+
+The test setup uses a sparse checkout, however the same scenario can be set up
+also by committing .gitmodules and then just removing it from the filesystem.
+'
+
+. ./test-lib.sh
+
+test_expect_success 'sparse checkout setup which hides .gitmodules' '
+ git init upstream &&
+ git init submodule &&
+ (cd submodule &&
+ echo file >file &&
+ git add file &&
+ test_tick &&
+ git commit -m "Add file"
+ ) &&
+ (cd upstream &&
+ git submodule add ../submodule &&
+ test_tick &&
+ git commit -m "Add submodule"
+ ) &&
+ git clone upstream super &&
+ (cd super &&
+ cat >.git/info/sparse-checkout <<-\EOF &&
+ /*
+ !/.gitmodules
+ EOF
+ git config core.sparsecheckout true &&
+ git read-tree -m -u HEAD &&
+ test_path_is_missing .gitmodules
+ )
+'
+
+test_expect_success 'reading gitmodules config file when it is not checked out' '
+ echo "../submodule" >expect &&
+ git -C super submodule--helper config submodule.submodule.url >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'not writing gitmodules config file when it is not checked out' '
+ test_must_fail git -C super submodule--helper config submodule.submodule.url newurl &&
+ test_path_is_missing super/.gitmodules
+'
+
+test_expect_success 'initialising submodule when the gitmodules config is not checked out' '
+ test_must_fail git -C super config submodule.submodule.url &&
+ git -C super submodule init &&
+ git -C super config submodule.submodule.url >actual &&
+ echo "$(pwd)/submodule" >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'updating submodule when the gitmodules config is not checked out' '
+ test_path_is_missing super/submodule/file &&
+ git -C super submodule update &&
+ test_cmp submodule/file super/submodule/file
+'
+
+ORIG_SUBMODULE=$(git -C submodule rev-parse HEAD)
+ORIG_UPSTREAM=$(git -C upstream rev-parse HEAD)
+ORIG_SUPER=$(git -C super rev-parse HEAD)
+
+test_expect_success 're-updating submodule when the gitmodules config is not checked out' '
+ test_when_finished "git -C submodule reset --hard $ORIG_SUBMODULE;
+ git -C upstream reset --hard $ORIG_UPSTREAM;
+ git -C super reset --hard $ORIG_SUPER;
+ git -C upstream submodule update --remote;
+ git -C super pull;
+ git -C super submodule update --remote" &&
+ (cd submodule &&
+ echo file2 >file2 &&
+ git add file2 &&
+ test_tick &&
+ git commit -m "Add file2 to submodule"
+ ) &&
+ (cd upstream &&
+ git submodule update --remote &&
+ git add submodule &&
+ test_tick &&
+ git commit -m "Update submodule"
+ ) &&
+ git -C super pull &&
+ # The --for-status options reads the gitmodules config
+ git -C super submodule summary --for-status >actual &&
+ rev1=$(git -C submodule rev-parse --short HEAD) &&
+ rev2=$(git -C submodule rev-parse --short HEAD^) &&
+ cat >expect <<-EOF &&
+ * submodule ${rev1}...${rev2} (1):
+ < Add file2 to submodule
+
+ EOF
+ test_cmp expect actual &&
+ # Test that the update actually succeeds
+ test_path_is_missing super/submodule/file2 &&
+ git -C super submodule update &&
+ test_cmp submodule/file2 super/submodule/file2 &&
+ git -C super status --short >output &&
+ test_must_be_empty output
+'
+
+test_expect_success 'not adding submodules when the gitmodules config is not checked out' '
+ git clone submodule new_submodule &&
+ test_must_fail git -C super submodule add ../new_submodule &&
+ test_path_is_missing .gitmodules
+'
+
+# This test checks that the previous "git submodule add" did not leave the
+# repository in a spurious state when it failed.
+test_expect_success 'init submodule still works even after the previous add failed' '
+ git -C super submodule init
+'
+
+test_done
diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh
index 1f43b3cd4c..ebfcad9c4c 100755
--- a/t/t7505-prepare-commit-msg-hook.sh
+++ b/t/t7505-prepare-commit-msg-hook.sh
@@ -253,7 +253,7 @@ test_rebase () {
}
test_rebase success -i
-test_rebase success -p
+test_have_prereq !REBASE_P || test_rebase success -p
test_expect_success 'with hook (cherry-pick)' '
test_when_finished "git checkout -f master" &&
diff --git a/t/t7506-status-submodule.sh b/t/t7506-status-submodule.sh
index 943708fb04..08629a6e70 100755
--- a/t/t7506-status-submodule.sh
+++ b/t/t7506-status-submodule.sh
@@ -325,7 +325,8 @@ test_expect_success 'setup superproject with untracked file in nested submodule'
(
cd super &&
git clean -dfx &&
- rm .gitmodules &&
+ git rm .gitmodules &&
+ git commit -m "remove .gitmodules" &&
git submodule add -f ./sub1 &&
git submodule add -f ./sub2 &&
git submodule add -f ./sub1 sub3 &&
diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh
index 19ccae2869..86d3f93fa2 100755
--- a/t/t7510-signed-commit.sh
+++ b/t/t7510-signed-commit.sh
@@ -176,8 +176,9 @@ test_expect_success GPG 'show good signature with custom format' '
13B6F51ECDDE430D
C O Mitter <committer@example.com>
73D758744BE721698EC54E8713B6F51ECDDE430D
+ 73D758744BE721698EC54E8713B6F51ECDDE430D
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF" sixth-signed >actual &&
+ git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual &&
test_cmp expect actual
'
@@ -187,30 +188,33 @@ test_expect_success GPG 'show bad signature with custom format' '
13B6F51ECDDE430D
C O Mitter <committer@example.com>
+
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF" $(cat forged1.commit) >actual &&
+ git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat forged1.commit) >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show untrusted signature with custom format' '
cat >expect <<-\EOF &&
U
- 61092E85B7227189
+ 65A0EEA02E30CAD7
Eris Discordia <discord@example.net>
+ F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7
D4BE22311AD3131E5EDA29A461092E85B7227189
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF" eighth-signed-alt >actual &&
+ git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
test_cmp expect actual
'
test_expect_success GPG 'show unknown signature with custom format' '
cat >expect <<-\EOF &&
E
- 61092E85B7227189
+ 65A0EEA02E30CAD7
+
EOF
- GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GK%n%GS%n%GF" eighth-signed-alt >actual &&
+ GNUPGHOME="$GNUPGHOME_NOT_USED" git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual &&
test_cmp expect actual
'
@@ -220,8 +224,9 @@ test_expect_success GPG 'show lack of signature with custom format' '
+
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF" seventh-unsigned >actual &&
+ git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" seventh-unsigned >actual &&
test_cmp expect actual
'
@@ -261,8 +266,9 @@ test_expect_success GPG 'show double signature with custom format' '
+
EOF
- git log -1 --format="%G?%n%GK%n%GS%n%GF" $(cat double-commit.commit) >actual &&
+ git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat double-commit.commit) >actual &&
test_cmp expect actual
'
diff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh
index 2a22fa7588..231b8cc19d 100755
--- a/t/t7517-per-repo-email.sh
+++ b/t/t7517-per-repo-email.sh
@@ -72,12 +72,14 @@ test_expect_success 'noop interactive rebase does not care about ident' '
git rebase -i HEAD^
'
-test_expect_success 'fast-forward rebase does not care about ident (preserve)' '
+test_expect_success REBASE_P \
+ 'fast-forward rebase does not care about ident (preserve)' '
git checkout -B tmp side-without-commit &&
git rebase -p master
'
-test_expect_success 'non-fast-forward rebase refuses to write commits (preserve)' '
+test_expect_success REBASE_P \
+ 'non-fast-forward rebase refuses to write commits (preserve)' '
test_when_finished "git rebase --abort || true" &&
git checkout -B tmp side-with-commit &&
test_must_fail git rebase -p master
diff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh
index e2b1df817a..d99218a725 100755
--- a/t/t7612-merge-verify-signatures.sh
+++ b/t/t7612-merge-verify-signatures.sh
@@ -103,4 +103,11 @@ test_expect_success GPG 'merge commit with bad signature with merge.verifySignat
git merge --no-verify-signatures $(cat forged.commit)
'
+test_expect_success GPG 'merge unsigned commit into unborn branch' '
+ test_when_finished "git checkout initial" &&
+ git checkout --orphan unborn &&
+ test_must_fail git merge --verify-signatures side-unsigned 2>mergeerror &&
+ test_i18ngrep "does not have a GPG signature" mergeerror
+'
+
test_done
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index 562bd215a5..22b9199d59 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -332,7 +332,7 @@ test_expect_success 'difftool --extcmd cat arg1' '
test_expect_success 'difftool --extcmd cat arg2' '
echo branch >expect &&
git difftool --no-prompt \
- --extcmd sh\ -c\ \"cat\ \$2\" branch >actual &&
+ --extcmd sh\ -c\ \"cat\ \\\"\$2\\\"\" branch >actual &&
test_cmp expect actual
'
diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index 7184113b9b..fa475d52fa 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -380,4 +380,20 @@ test_expect_success 'grep --recurse-submodules should pass the pattern type alon
fi
'
+# Recursing down into nested submodules which do not have .gitmodules in their
+# working tree does not work yet. This is because config_from_gitmodules()
+# uses get_oid() and the latter is still not able to get objects from an
+# arbitrary repository (the nested submodule, in this case).
+test_expect_failure 'grep --recurse-submodules with submodules without .gitmodules in the working tree' '
+ test_when_finished "git -C submodule checkout .gitmodules" &&
+ rm submodule/.gitmodules &&
+ git grep --recurse-submodules -e "(.|.)[\d]" >actual &&
+ cat >expect <<-\EOF &&
+ a:(1|2)d(3|4)
+ submodule/a:(1|2)d(3|4)
+ submodule/sub/a:(1|2)d(3|4)
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 1ef1a19003..ee1efcc59d 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -492,6 +492,21 @@ do
--validate \
$patches longline.patch
'
+
+done
+
+for enc in 7bit 8bit quoted-printable base64
+do
+ test_expect_success $PREREQ "--transfer-encoding=$enc produces correct header" '
+ clean_fake_sendmail &&
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --transfer-encoding=$enc \
+ $patches &&
+ grep "Content-Transfer-Encoding: $enc" msgtxt1
+ '
done
test_expect_success $PREREQ 'Invalid In-Reply-To' '
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 40fe7e4976..59a13b6a77 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -1558,7 +1558,7 @@ test_expect_success 'O: blank lines not necessary after other commands' '
INPUT_END
git fast-import <input &&
- test 8 = $(find .git/objects/pack -type f | wc -l) &&
+ test 8 = $(find .git/objects/pack -type f | grep -v multi-pack-index | wc -l) &&
test $(git rev-parse refs/tags/O3-2nd) = $(git rev-parse O3^) &&
git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual &&
test_cmp expect actual
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 6a392e87bc..5690fe2810 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -66,6 +66,34 @@ test_expect_success 'fast-export master~2..master' '
'
+test_expect_success 'fast-export --reference-excluded-parents master~2..master' '
+
+ git fast-export --reference-excluded-parents master~2..master >actual &&
+ grep commit.refs/heads/master actual >commit-count &&
+ test_line_count = 2 commit-count &&
+ sed "s/master/rewrite/" actual |
+ (cd new &&
+ git fast-import &&
+ test $MASTER = $(git rev-parse --verify refs/heads/rewrite))
+'
+
+test_expect_success 'fast-export --show-original-ids' '
+
+ git fast-export --show-original-ids master >output &&
+ grep ^original-oid output| sed -e s/^original-oid.// | sort >actual &&
+ git rev-list --objects master muss >objects-and-names &&
+ awk "{print \$1}" objects-and-names | sort >commits-trees-blobs &&
+ comm -23 actual commits-trees-blobs >unfound &&
+ test_must_be_empty unfound
+'
+
+test_expect_success 'fast-export --show-original-ids | git fast-import' '
+
+ git fast-export --show-original-ids master muss | git fast-import --quiet &&
+ test $MASTER = $(git rev-parse --verify refs/heads/master) &&
+ test $MUSS = $(git rev-parse --verify refs/tags/muss)
+'
+
test_expect_success 'iso-8859-1' '
git config i18n.commitencoding ISO8859-1 &&
@@ -325,6 +353,22 @@ test_expect_success 'rewriting tag of filtered out object' '
)
'
+test_expect_success 'rewrite tag predating pathspecs to nothing' '
+ test_create_repo rewrite_tag_predating_pathspecs &&
+ (
+ cd rewrite_tag_predating_pathspecs &&
+
+ test_commit initial &&
+
+ git tag -a -m "Some old tag" v0.0.0.0.0.0.1 &&
+
+ test_commit bar &&
+
+ git fast-export --tag-of-filtered-object=rewrite --all -- bar.t >output &&
+ grep from.$ZERO_OID output
+ )
+'
+
cat > limit-by-paths/expected << EOF
blob
mark :1
@@ -366,6 +410,26 @@ test_expect_success 'path limiting with import-marks does not lose unmodified fi
grep file0 actual
'
+test_expect_success 'avoid corrupt stream with non-existent mark' '
+ test_create_repo avoid_non_existent_mark &&
+ (
+ cd avoid_non_existent_mark &&
+
+ test_commit important-path &&
+
+ test_commit ignored &&
+
+ git branch A &&
+ git branch B &&
+
+ echo foo >>important-path.t &&
+ git add important-path.t &&
+ test_commit more changes &&
+
+ git fast-export --all -- important-path.t | git fast-import --force
+ )
+'
+
test_expect_success 'full-tree re-shows unmodified files' '
git checkout -f simple &&
git fast-export --full-tree simple >actual &&
@@ -508,10 +572,20 @@ test_expect_success 'use refspec' '
test_cmp expected actual
'
-test_expect_success 'delete refspec' '
+test_expect_success 'delete ref because entire history excluded' '
git branch to-delete &&
- git fast-export --refspec :refs/heads/to-delete to-delete ^to-delete > actual &&
- cat > expected <<-EOF &&
+ git fast-export to-delete ^to-delete >actual &&
+ cat >expected <<-EOF &&
+ reset refs/heads/to-delete
+ from 0000000000000000000000000000000000000000
+
+ EOF
+ test_cmp expected actual
+'
+
+test_expect_success 'delete refspec' '
+ git fast-export --refspec :refs/heads/to-delete >actual &&
+ cat >expected <<-EOF &&
reset refs/heads/to-delete
from 0000000000000000000000000000000000000000
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 175f83d704..3a2c6326d8 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -1249,7 +1249,7 @@ test_expect_success 'teardown after ref completion' '
test_path_completion ()
{
- test $# = 2 || error "bug in the test script: not 2 parameters to test_path_completion"
+ test $# = 2 || BUG "not 2 parameters to test_path_completion"
local cur="$1" expected="$2"
echo "$expected" >expected &&
@@ -1434,7 +1434,8 @@ test_expect_success 'double dash "git checkout"' '
--ignore-other-worktrees Z
--recurse-submodules Z
--progress Z
- --no-quiet Z
+ --guess Z
+ --no-guess Z
--no-... Z
EOF
'
@@ -1515,8 +1516,8 @@ test_expect_success 'show completes all refs' '
test_expect_success '<ref>: completes paths' '
test_completion "git show mytag:f" <<-\EOF
- file1 Z
- file2 Z
+ file1Z
+ file2Z
EOF
'
@@ -1525,7 +1526,7 @@ test_expect_success 'complete tree filename with spaces' '
git add "name with spaces" &&
git commit -m spaces &&
test_completion "git show HEAD:nam" <<-\EOF
- name with spaces Z
+ name with spacesZ
EOF
'
@@ -1534,12 +1535,12 @@ test_expect_success 'complete tree filename with metacharacters' '
git add "name with \${meta}" &&
git commit -m meta &&
test_completion "git show HEAD:nam" <<-\EOF
- name with ${meta} Z
- name with spaces Z
+ name with ${meta}Z
+ name with spacesZ
EOF
'
-test_expect_success 'send-email' '
+test_expect_success PERL 'send-email' '
test_completion "git send-email --cov" "--cover-letter " &&
test_completion "git send-email ma" "master "
'
@@ -1697,7 +1698,8 @@ test_expect_success 'sourcing the completion script clears cached commands' '
verbose test -z "$__git_all_commands"
'
-test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
+test_expect_success 'sourcing the completion script clears cached merge strategies' '
+ GIT_TEST_GETTEXT_POISON= &&
__git_compute_merge_strategies &&
verbose test -n "$__git_merge_strategies" &&
. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 78d8c3783b..92cf8f812c 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -418,14 +418,14 @@ test_declared_prereq () {
test_verify_prereq () {
test -z "$test_prereq" ||
expr >/dev/null "$test_prereq" : '[A-Z0-9_,!]*$' ||
- error "bug in the test script: '$test_prereq' does not look like a prereq"
+ BUG "'$test_prereq' does not look like a prereq"
}
test_expect_failure () {
test_start_
test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
test "$#" = 2 ||
- error "bug in the test script: not 2 or 3 parameters to test-expect-failure"
+ BUG "not 2 or 3 parameters to test-expect-failure"
test_verify_prereq
export test_prereq
if ! test_skip "$@"
@@ -445,7 +445,7 @@ test_expect_success () {
test_start_
test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq=
test "$#" = 2 ||
- error "bug in the test script: not 2 or 3 parameters to test-expect-success"
+ BUG "not 2 or 3 parameters to test-expect-success"
test_verify_prereq
export test_prereq
if ! test_skip "$@"
@@ -472,7 +472,7 @@ test_expect_success () {
test_external () {
test "$#" = 4 && { test_prereq=$1; shift; } || test_prereq=
test "$#" = 3 ||
- error >&5 "bug in the test script: not 3 or 4 parameters to test_external"
+ BUG "not 3 or 4 parameters to test_external"
descr="$1"
shift
test_verify_prereq
@@ -613,7 +613,7 @@ test_path_is_missing () {
test_line_count () {
if test $# != 3
then
- error "bug in the test script: not 3 parameters to test_line_count"
+ BUG "not 3 parameters to test_line_count"
elif ! test $(wc -l <"$3") "$1" "$2"
then
echo "test_line_count: line count for $3 !$1 $2"
@@ -747,6 +747,29 @@ test_cmp() {
$GIT_TEST_CMP "$@"
}
+# Check that the given config key has the expected value.
+#
+# test_cmp_config [-C <dir>] <expected-value>
+# [<git-config-options>...] <config-key>
+#
+# for example to check that the value of core.bar is foo
+#
+# test_cmp_config foo core.bar
+#
+test_cmp_config() {
+ local GD &&
+ if test "$1" = "-C"
+ then
+ shift &&
+ GD="-C $1" &&
+ shift
+ fi &&
+ printf "%s\n" "$1" >expect.config &&
+ shift &&
+ git $GD config "$@" >actual.config &&
+ test_cmp expect.config actual.config
+}
+
# test_cmp_bin - helper to compare binary files
test_cmp_bin() {
@@ -755,31 +778,30 @@ test_cmp_bin() {
# Use this instead of test_cmp to compare files that contain expected and
# actual output from git commands that can be translated. When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
# results.
test_i18ncmp () {
- test -n "$GETTEXT_POISON" || test_cmp "$@"
+ ! test_have_prereq C_LOCALE_OUTPUT || test_cmp "$@"
}
# Use this instead of "grep expected-string actual" to see if the
# output from a git command that can be translated either contains an
# expected string, or does not contain an unwanted one. When running
-# under GETTEXT_POISON this pretends that the command produced expected
+# under GIT_TEST_GETTEXT_POISON this pretends that the command produced expected
# results.
test_i18ngrep () {
eval "last_arg=\${$#}"
test -f "$last_arg" ||
- error "bug in the test script: test_i18ngrep requires a file" \
- "to read as the last parameter"
+ BUG "test_i18ngrep requires a file to read as the last parameter"
if test $# -lt 2 ||
{ test "x!" = "x$1" && test $# -lt 3 ; }
then
- error "bug in the test script: too few parameters to test_i18ngrep"
+ BUG "too few parameters to test_i18ngrep"
fi
- if test -n "$GETTEXT_POISON"
+ if test_have_prereq !C_LOCALE_OUTPUT
then
# pretend success
return 0
@@ -831,9 +853,23 @@ test_must_be_empty () {
# Tests that its two parameters refer to the same revision
test_cmp_rev () {
- git rev-parse --verify "$1" >expect.rev &&
- git rev-parse --verify "$2" >actual.rev &&
- test_cmp expect.rev actual.rev
+ if test $# != 2
+ then
+ error "bug in the test script: test_cmp_rev requires two revisions, but got $#"
+ else
+ local r1 r2
+ r1=$(git rev-parse --verify "$1") &&
+ r2=$(git rev-parse --verify "$2") &&
+ if test "$r1" != "$r2"
+ then
+ cat >&4 <<-EOF
+ error: two revisions point to different objects:
+ '$1': $r1
+ '$2': $r2
+ EOF
+ return 1
+ fi
+ fi
}
# Print a sequence of integers in increasing order, either with
@@ -848,7 +884,7 @@ test_seq () {
case $# in
1) set 1 "$@" ;;
2) ;;
- *) error "bug in the test script: not 1 or 2 parameters to test_seq" ;;
+ *) BUG "not 1 or 2 parameters to test_seq" ;;
esac
test_seq_counter__=$1
while test "$test_seq_counter__" -le "$2"
@@ -886,7 +922,7 @@ test_when_finished () {
# doing so on Bash is better than nothing (the test will
# silently pass on other shells).
test "${BASH_SUBSHELL-0}" = 0 ||
- error "bug in test script: test_when_finished does nothing in a subshell"
+ BUG "test_when_finished does nothing in a subshell"
test_cleanup="{ $*
} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
}
@@ -895,12 +931,13 @@ test_when_finished () {
# Usage: test_create_repo <directory>
test_create_repo () {
test "$#" = 1 ||
- error "bug in the test script: not 1 parameter to test-create-repo"
+ BUG "not 1 parameter to test-create-repo"
repo="$1"
mkdir -p "$repo"
(
cd "$repo" || error "Cannot setup test environment"
- "$GIT_EXEC_PATH/git-init" "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
+ "${GIT_TEST_INSTALLED:-$GIT_EXEC_PATH}/git$X" init \
+ "--template=$GIT_BUILD_DIR/templates/blt/" >&3 2>&4 ||
error "cannot run git init -- have you built things yet?"
mv .git/hooks .git/hooks-disabled
) || exit
@@ -1207,7 +1244,7 @@ test_oid_cache () {
if ! expr "$k" : '[a-z0-9][a-z0-9]*$' >/dev/null
then
- error 'bug in the test script: bad hash algorithm'
+ BUG 'bad hash algorithm'
fi &&
eval "test_oid_${k}_$tag=\"\$v\""
done
@@ -1222,7 +1259,46 @@ test_oid () {
# key-hash pair, so exit with an error.
if eval "test -z \"\${$var+set}\""
then
- error "bug in the test script: undefined key '$1'" >&2
+ BUG "undefined key '$1'"
fi &&
eval "printf '%s' \"\${$var}\""
}
+
+# Choose a port number based on the test script's number and store it in
+# the given variable name, unless that variable already contains a number.
+test_set_port () {
+ local var=$1 port
+
+ if test $# -ne 1 || test -z "$var"
+ then
+ BUG "test_set_port requires a variable name"
+ fi
+
+ eval port=\$$var
+ case "$port" in
+ "")
+ # No port is set in the given env var, use the test
+ # number as port number instead.
+ # Remove not only the leading 't', but all leading zeros
+ # as well, so the arithmetic below won't (mis)interpret
+ # a test number like '0123' as an octal value.
+ port=${this_test#${this_test%%[1-9]*}}
+ if test "${port:-0}" -lt 1024
+ then
+ # root-only port, use a larger one instead.
+ port=$(($port + 10000))
+ fi
+ ;;
+ *[^0-9]*|0*)
+ error >&7 "invalid port number: $port"
+ ;;
+ *)
+ # The user has specified the port.
+ ;;
+ esac
+
+ # Make sure that parallel '--stress' test jobs get different
+ # ports.
+ port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0}))
+ eval $var=$port
+}
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 47a99aa0ed..a1abb1177a 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -49,31 +49,244 @@ export ASAN_OPTIONS
: ${LSAN_OPTIONS=abort_on_error=1}
export LSAN_OPTIONS
+if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+then
+ echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).'
+ exit 1
+fi
+. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
+export PERL_PATH SHELL_PATH
+
################################################################
# It appears that people try to run tests without building...
-"$GIT_BUILD_DIR/git" >/dev/null
+"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null
if test $? != 1
then
- echo >&2 'error: you do not seem to have built git yet.'
+ if test -n "$GIT_TEST_INSTALLED"
+ then
+ echo >&2 "error: there is no working Git at '$GIT_TEST_INSTALLED'"
+ else
+ echo >&2 'error: you do not seem to have built git yet.'
+ fi
exit 1
fi
-. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
-export PERL_PATH SHELL_PATH
+# 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"
+ then
+ eval $store_arg_to=\$opt
+ store_arg_to=
+ prev_opt=
+ continue
+ fi
+
+ case "$opt" in
+ -d|--d|--de|--deb|--debu|--debug)
+ debug=t ;;
+ -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
+ immediate=t ;;
+ -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
+ ;;
+ --run=*)
+ run_list=${opt#--*=} ;;
+ -h|--h|--he|--hel|--help)
+ help=t ;;
+ -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+ verbose=t ;;
+ --verbose-only=*)
+ verbose_only=${opt#--*=}
+ ;;
+ -q|--q|--qu|--qui|--quie|--quiet)
+ # Ignore --quiet under a TAP::Harness. Saying how many tests
+ # passed without the ok/not ok details is always an error.
+ test -z "$HARNESS_ACTIVE" && quiet=t ;;
+ --with-dashes)
+ with_dashes=t ;;
+ --no-color)
+ color= ;;
+ --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
+ valgrind=memcheck
+ tee=t
+ ;;
+ --valgrind=*)
+ valgrind=${opt#--*=}
+ tee=t
+ ;;
+ --valgrind-only=*)
+ valgrind_only=${opt#--*=}
+ tee=t
+ ;;
+ --tee)
+ tee=t ;;
+ --root=*)
+ root=${opt#--*=} ;;
+ --chain-lint)
+ GIT_TEST_CHAIN_LINT=1 ;;
+ --no-chain-lint)
+ GIT_TEST_CHAIN_LINT=0 ;;
+ -x)
+ trace=t ;;
+ -V|--verbose-log)
+ verbose_log=t
+ tee=t
+ ;;
+ --stress)
+ stress=t ;;
+ --stress=*)
+ stress=${opt#--*=}
+ case "$stress" in
+ *[^0-9]*|0*|"")
+ echo "error: --stress=<N> requires the number of jobs to run" >&2
+ exit 1
+ ;;
+ *) # Good.
+ ;;
+ esac
+ ;;
+ *)
+ echo "error: unknown test option '$opt'" >&2; exit 1 ;;
+ esac
+
+ prev_opt=$opt
+done
+if test -n "$store_arg_to"
+then
+ echo "error: $prev_opt requires an argument" >&2
+ exit 1
+fi
+
+if test -n "$valgrind_only"
+then
+ test -z "$valgrind" && valgrind=memcheck
+ test -z "$verbose" && verbose_only="$valgrind_only"
+elif test -n "$valgrind"
+then
+ test -z "$verbose_log" && verbose=t
+fi
+
+if test -n "$stress"
+then
+ verbose=t
+ trace=t
+ immediate=t
+fi
+
+TEST_STRESS_JOB_SFX="${GIT_TEST_STRESS_JOB_NR:+.stress-$GIT_TEST_STRESS_JOB_NR}"
+TEST_NAME="$(basename "$0" .sh)"
+TEST_RESULTS_DIR="$TEST_OUTPUT_DIRECTORY/test-results"
+TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX"
+TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX"
+test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
+case "$TRASH_DIRECTORY" in
+/*) ;; # absolute path is good
+ *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
+esac
+
+# If --stress was passed, run this test repeatedly in several parallel loops.
+if test "$GIT_TEST_STRESS_STARTED" = "done"
+then
+ : # Don't stress test again.
+elif test -n "$stress"
+then
+ if test "$stress" != t
+ then
+ job_count=$stress
+ elif test -n "$GIT_TEST_STRESS_LOAD"
+ then
+ job_count="$GIT_TEST_STRESS_LOAD"
+ elif job_count=$(getconf _NPROCESSORS_ONLN 2>/dev/null) &&
+ test -n "$job_count"
+ then
+ job_count=$((2 * $job_count))
+ else
+ job_count=8
+ fi
+
+ mkdir -p "$TEST_RESULTS_DIR"
+ stressfail="$TEST_RESULTS_BASE.stress-failed"
+ rm -f "$stressfail"
+
+ stress_exit=0
+ trap '
+ kill $job_pids 2>/dev/null
+ wait
+ stress_exit=1
+ ' TERM INT HUP
+
+ job_pids=
+ job_nr=0
+ while test $job_nr -lt "$job_count"
+ do
+ (
+ GIT_TEST_STRESS_STARTED=done
+ GIT_TEST_STRESS_JOB_NR=$job_nr
+ export GIT_TEST_STRESS_STARTED GIT_TEST_STRESS_JOB_NR
+
+ trap '
+ kill $test_pid 2>/dev/null
+ wait
+ exit 1
+ ' TERM INT
+
+ cnt=0
+ while ! test -e "$stressfail"
+ do
+ $TEST_SHELL_PATH "$0" "$@" >"$TEST_RESULTS_BASE.stress-$job_nr.out" 2>&1 &
+ test_pid=$!
+
+ if wait $test_pid
+ then
+ printf "OK %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
+ else
+ echo $GIT_TEST_STRESS_JOB_NR >>"$stressfail"
+ printf "FAIL %2d.%d\n" $GIT_TEST_STRESS_JOB_NR $cnt
+ fi
+ cnt=$(($cnt + 1))
+ done
+ ) &
+ job_pids="$job_pids $!"
+ job_nr=$(($job_nr + 1))
+ done
+
+ wait
+
+ if test -f "$stressfail"
+ then
+ echo "Log(s) of failed test run(s):"
+ for failed_job_nr in $(sort -n "$stressfail")
+ do
+ echo "Contents of '$TEST_RESULTS_BASE.stress-$failed_job_nr.out':"
+ cat "$TEST_RESULTS_BASE.stress-$failed_job_nr.out"
+ done
+ rm -rf "$TRASH_DIRECTORY.stress-failed"
+ # Move the last one.
+ mv "$TRASH_DIRECTORY.stress-$failed_job_nr" "$TRASH_DIRECTORY.stress-failed"
+ fi
+
+ exit $stress_exit
+fi
# if --tee was passed, write the output not only to the terminal, but
# additionally to the file test-results/$BASENAME.out, too.
-case "$GIT_TEST_TEE_STARTED, $* " in
-done,*)
- # do not redirect again
- ;;
-*' --tee '*|*' --va'*|*' -V '*|*' --verbose-log '*)
- mkdir -p "$TEST_OUTPUT_DIRECTORY/test-results"
- BASE="$TEST_OUTPUT_DIRECTORY/test-results/$(basename "$0" .sh)"
+if test "$GIT_TEST_TEE_STARTED" = "done"
+then
+ : # do not redirect again
+elif test -n "$tee"
+then
+ mkdir -p "$TEST_RESULTS_DIR"
# Make this filename available to the sub-process in case it is using
# --verbose-log.
- GIT_TEST_TEE_OUTPUT_FILE=$BASE.out
+ GIT_TEST_TEE_OUTPUT_FILE=$TEST_RESULTS_BASE.out
export GIT_TEST_TEE_OUTPUT_FILE
# Truncate before calling "tee -a" to get rid of the results
@@ -81,11 +294,38 @@ done,*)
>"$GIT_TEST_TEE_OUTPUT_FILE"
(GIT_TEST_TEE_STARTED=done ${TEST_SHELL_PATH} "$0" "$@" 2>&1;
- echo $? >"$BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
- test "$(cat "$BASE.exit")" = 0
+ echo $? >"$TEST_RESULTS_BASE.exit") | tee -a "$GIT_TEST_TEE_OUTPUT_FILE"
+ test "$(cat "$TEST_RESULTS_BASE.exit")" = 0
exit
- ;;
-esac
+fi
+
+if test -n "$trace" && test -n "$test_untraceable"
+then
+ # '-x' tracing requested, but this test script can't be reliably
+ # traced, unless it is run with a Bash version supporting
+ # BASH_XTRACEFD (introduced in Bash v4.1).
+ #
+ # Perform this version check _after_ the test script was
+ # potentially re-executed with $TEST_SHELL_PATH for '--tee' or
+ # '--verbose-log', so the right shell is checked and the
+ # warning is issued only once.
+ if test -n "$BASH_VERSION" && eval '
+ test ${BASH_VERSINFO[0]} -gt 4 || {
+ test ${BASH_VERSINFO[0]} -eq 4 &&
+ test ${BASH_VERSINFO[1]} -ge 1
+ }
+ '
+ then
+ : Executed by a Bash version supporting BASH_XTRACEFD. Good.
+ else
+ echo >&2 "warning: ignoring -x; '$0' is untraceable without BASH_XTRACEFD"
+ trace=
+ fi
+fi
+if test -n "$trace" && test -z "$verbose_log"
+then
+ verbose=t
+fi
# For repeatability, reset the environment to known value.
# TERM is sanitized below, after saving color control sequences.
@@ -95,6 +335,16 @@ PAGER=cat
TZ=UTC
export LANG LC_ALL PAGER TZ
EDITOR=:
+
+# GIT_TEST_GETTEXT_POISON should not influence git commands executed
+# during initialization of test-lib and the test repo. Back it up,
+# unset and then restore after initialization is finished.
+if test -n "$GIT_TEST_GETTEXT_POISON"
+then
+ GIT_TEST_GETTEXT_POISON_ORIG=$GIT_TEST_GETTEXT_POISON
+ unset GIT_TEST_GETTEXT_POISON
+fi
+
# A call to "unset" with no arguments causes at least Solaris 10
# /usr/xpg4/bin/sh and /bin/ksh to bail out. So keep the unsets
# deriving from the command substitution clustered with the other
@@ -173,7 +423,7 @@ fi
# Add libc MALLOC and MALLOC_PERTURB test
# only if we are not executing the test with valgrind
-if expr " $GIT_TEST_OPTS " : ".* --valgrind " >/dev/null ||
+if test -n "$valgrind" ||
test -n "$TEST_NO_MALLOC_CHECK"
then
setup_malloc_check () {
@@ -244,100 +494,6 @@ test "x$TERM" != "xdumb" && (
) &&
color=t
-while test "$#" -ne 0
-do
- case "$1" in
- -d|--d|--de|--deb|--debu|--debug)
- debug=t; shift ;;
- -i|--i|--im|--imm|--imme|--immed|--immedi|--immedia|--immediat|--immediate)
- immediate=t; shift ;;
- -l|--l|--lo|--lon|--long|--long-|--long-t|--long-te|--long-tes|--long-test|--long-tests)
- GIT_TEST_LONG=t; export GIT_TEST_LONG; shift ;;
- -r)
- shift; test "$#" -ne 0 || {
- echo 'error: -r requires an argument' >&2;
- exit 1;
- }
- run_list=$1; shift ;;
- --run=*)
- run_list=${1#--*=}; shift ;;
- -h|--h|--he|--hel|--help)
- help=t; shift ;;
- -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
- verbose=t; shift ;;
- --verbose-only=*)
- verbose_only=${1#--*=}
- shift ;;
- -q|--q|--qu|--qui|--quie|--quiet)
- # Ignore --quiet under a TAP::Harness. Saying how many tests
- # passed without the ok/not ok details is always an error.
- test -z "$HARNESS_ACTIVE" && quiet=t; shift ;;
- --with-dashes)
- with_dashes=t; shift ;;
- --no-color)
- color=; shift ;;
- --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind)
- valgrind=memcheck
- shift ;;
- --valgrind=*)
- valgrind=${1#--*=}
- shift ;;
- --valgrind-only=*)
- valgrind_only=${1#--*=}
- shift ;;
- --tee)
- shift ;; # was handled already
- --root=*)
- root=${1#--*=}
- shift ;;
- --chain-lint)
- GIT_TEST_CHAIN_LINT=1
- shift ;;
- --no-chain-lint)
- GIT_TEST_CHAIN_LINT=0
- shift ;;
- -x)
- # Some test scripts can't be reliably traced with '-x',
- # unless the test is run with a Bash version supporting
- # BASH_XTRACEFD (introduced in Bash v4.1). Check whether
- # this test is marked as such, and ignore '-x' if it
- # isn't executed with a suitable Bash version.
- if test -z "$test_untraceable" || {
- test -n "$BASH_VERSION" && {
- test ${BASH_VERSINFO[0]} -gt 4 || {
- test ${BASH_VERSINFO[0]} -eq 4 &&
- test ${BASH_VERSINFO[1]} -ge 1
- }
- }
- }
- then
- trace=t
- else
- echo >&2 "warning: ignoring -x; '$0' is untraceable without BASH_XTRACEFD"
- fi
- shift ;;
- -V|--verbose-log)
- verbose_log=t
- shift ;;
- *)
- echo "error: unknown test option '$1'" >&2; exit 1 ;;
- esac
-done
-
-if test -n "$valgrind_only"
-then
- test -z "$valgrind" && valgrind=memcheck
- test -z "$verbose" && verbose_only="$valgrind_only"
-elif test -n "$valgrind"
-then
- test -z "$verbose_log" && verbose=t
-fi
-
-if test -n "$trace" && test -z "$verbose_log"
-then
- verbose=t
-fi
-
if test -n "$color"
then
# Save the color control sequences now rather than run tput
@@ -382,6 +538,10 @@ error () {
exit 1
}
+BUG () {
+ error >&7 "bug in the test script: $*"
+}
+
say () {
say_color info "$*"
}
@@ -452,7 +612,7 @@ die () {
GIT_EXIT_OK=
trap 'die' EXIT
-trap 'exit $?' INT
+trap 'exit $?' INT TERM HUP
# The user-facing functions are loaded from a separate file so that
# test_perf subshells can have them too
@@ -709,7 +869,7 @@ test_run_ () {
if $(printf '%s\n' "$1" | sed -f "$GIT_BUILD_DIR/t/chainlint.sed" | grep -q '?![A-Z][A-Z]*?!') ||
test "OK-117" != "$(test_eval_ "(exit 117) && $1${LF}${LF}echo OK-\$?" 3>&1)"
then
- error "bug in the test script: broken &&-chain or run-away HERE-DOC: $1"
+ BUG "broken &&-chain or run-away HERE-DOC: $1"
fi
trace=$trace_tmp
fi
@@ -794,12 +954,9 @@ test_done () {
if test -z "$HARNESS_ACTIVE"
then
- test_results_dir="$TEST_OUTPUT_DIRECTORY/test-results"
- mkdir -p "$test_results_dir"
- base=${0##*/}
- test_results_path="$test_results_dir/${base%.sh}.counts"
+ mkdir -p "$TEST_RESULTS_DIR"
- cat >"$test_results_path" <<-EOF
+ cat >"$TEST_RESULTS_BASE.counts" <<-EOF
total $test_count
success $test_success
fixed $test_fixed
@@ -957,7 +1114,7 @@ elif test -n "$GIT_TEST_INSTALLED"
then
GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) ||
error "Cannot run git from $GIT_TEST_INSTALLED."
- PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR:$PATH
+ PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH
GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH}
else # normal case, use ../bin-wrappers only unless $with_dashes:
git_bin_dir="$GIT_BUILD_DIR/bin-wrappers"
@@ -1005,12 +1162,6 @@ then
fi
# Test repository
-TRASH_DIRECTORY="trash directory.$(basename "$0" .sh)"
-test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY"
-case "$TRASH_DIRECTORY" in
-/*) ;; # absolute path is good
- *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;;
-esac
rm -fr "$TRASH_DIRECTORY" || {
GIT_EXIT_OK=t
echo >&5 "FATAL: Cannot prepare test area"
@@ -1104,13 +1255,15 @@ test -n "$USE_LIBPCRE1" && test_set_prereq LIBPCRE1
test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2
test -z "$NO_GETTEXT" && test_set_prereq GETTEXT
+if test -n "$GIT_TEST_GETTEXT_POISON_ORIG"
+then
+ GIT_TEST_GETTEXT_POISON=$GIT_TEST_GETTEXT_POISON_ORIG
+ unset GIT_TEST_GETTEXT_POISON_ORIG
+fi
+
# Can we rely on git's output in the C locale?
-if test -n "$GETTEXT_POISON"
+if test -z "$GIT_TEST_GETTEXT_POISON"
then
- GIT_GETTEXT_POISON=YesPlease
- export GIT_GETTEXT_POISON
- test_set_prereq GETTEXT_POISON
-else
test_set_prereq C_LOCALE_OUTPUT
fi
@@ -1209,7 +1362,7 @@ test_lazy_prereq SANITY '
chmod -w SANETESTD.1 &&
chmod -r SANETESTD.1/x &&
chmod -rx SANETESTD.2 ||
- error "bug in test sript: cannot prepare SANETESTD"
+ BUG "cannot prepare SANETESTD"
! test -r SANETESTD.1/x &&
! rm SANETESTD.1/x && ! test -f SANETESTD.2/x
@@ -1217,7 +1370,7 @@ test_lazy_prereq SANITY '
chmod +rwx SANETESTD.1 SANETESTD.2 &&
rm -rf SANETESTD.1 SANETESTD.2 ||
- error "bug in test sript: cannot clean SANETESTD"
+ BUG "cannot clean SANETESTD"
return $status
'
@@ -1268,3 +1421,7 @@ test_lazy_prereq CURL '
test_lazy_prereq SHA1 '
test $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
'
+
+test_lazy_prereq REBASE_P '
+ test -z "$GIT_TEST_SKIP_REBASE_P"
+'