summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README28
-rw-r--r--t/annotate-tests.sh8
-rw-r--r--t/helper/test-date.c4
-rw-r--r--t/helper/test-parse-options.c2
-rw-r--r--t/helper/test-prio-queue.c2
-rwxr-xr-xt/interop/i5500-git-daemon.sh1
-rw-r--r--t/lib-git-daemon.sh20
-rw-r--r--t/lib-git-p4.sh65
-rw-r--r--t/lib-git-svn.sh5
-rw-r--r--t/lib-httpd.sh6
-rwxr-xr-xt/lib-submodule-update.sh3
-rwxr-xr-xt/perf/p0001-rev-list.sh18
-rwxr-xr-xt/t0000-basic.sh18
-rwxr-xr-xt/t0040-parse-options.sh14
-rwxr-xr-xt/t0301-credential-cache.sh7
-rwxr-xr-xt/t0410-partial-clone.sh2
-rwxr-xr-xt/t1305-config-include.sh13
-rwxr-xr-xt/t1410-reflog.sh25
-rwxr-xr-xt/t3000-ls-files-others.sh2
-rwxr-xr-xt/t3009-ls-files-others-nonsubmodule.sh50
-rwxr-xr-xt/t3301-notes.sh5
-rwxr-xr-xt/t3401-rebase-and-am-rename.sh8
-rwxr-xr-xt/t3415-rebase-autosquash.sh2
-rwxr-xr-xt/t3430-rebase-merges.sh4
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh24
-rwxr-xr-xt/t3700-add.sh12
-rwxr-xr-xt/t3903-stash.sh224
-rwxr-xr-xt/t3905-stash-include-untracked.sh6
-rwxr-xr-xt/t3907-stash-show-config.sh83
-rwxr-xr-xt/t4053-diff-no-index.sh3
-rwxr-xr-xt/t4067-diff-partial-clone.sh103
-rwxr-xr-xt/t5317-pack-objects-filter-objects.sh44
-rwxr-xr-xt/t5318-commit-graph.sh42
-rwxr-xr-xt/t5319-multi-pack-index.sh29
-rwxr-xr-xt/t5407-post-rewrite-hook.sh4
-rwxr-xr-xt/t5500-fetch-pack.sh3
-rwxr-xr-xt/t5510-fetch.sh2
-rwxr-xr-xt/t5516-fetch-push.sh24
-rwxr-xr-xt/t5530-upload-pack-error.sh18
-rwxr-xr-xt/t5531-deep-submodule-push.sh2
-rwxr-xr-xt/t5537-fetch-shallow.sh2
-rwxr-xr-xt/t5539-fetch-http-shallow.sh1
-rwxr-xr-xt/t5540-http-push-webdav.sh2
-rwxr-xr-xt/t5541-http-push-smart.sh1
-rwxr-xr-xt/t5542-push-http-shallow.sh1
-rwxr-xr-xt/t5545-push-options.sh2
-rwxr-xr-xt/t5550-http-fetch-dumb.sh1
-rwxr-xr-xt/t5551-http-fetch-smart.sh1
-rwxr-xr-xt/t5561-http-backend.sh1
-rwxr-xr-xt/t5570-git-daemon.sh2
-rwxr-xr-xt/t5581-http-curl-verbose.sh2
-rwxr-xr-xt/t5601-clone.sh2
-rwxr-xr-xt/t5616-partial-clone.sh2
-rwxr-xr-xt/t5700-protocol-v1.sh2
-rwxr-xr-xt/t5702-protocol-v2.sh2
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh2
-rwxr-xr-xt/t5812-proto-disable-http.sh1
-rwxr-xr-xt/t6043-merge-rename-directories.sh462
-rwxr-xr-xt/t6046-merge-skip-unneeded-updates.sh8
-rwxr-xr-xt/t6500-gc.sh19
-rwxr-xr-xt/t7004-tag.sh11
-rwxr-xr-xt/t7113-post-index-change-hook.sh144
-rwxr-xr-xt/t7201-co.sh9
-rwxr-xr-xt/t7400-submodule-basic.sh11
-rwxr-xr-xt/t7407-submodule-foreach.sh10
-rwxr-xr-xt/t7411-submodule-config.sh9
-rwxr-xr-xt/t7419-submodule-set-branch.sh93
-rwxr-xr-xt/t7525-status-rename.sh8
-rwxr-xr-xt/t7800-difftool.sh10
-rwxr-xr-xt/t7810-grep.sh16
-rwxr-xr-xt/t9001-send-email.sh14
-rwxr-xr-xt/t9115-git-svn-dcommit-funky-renames.sh2
-rwxr-xr-xt/t9118-git-svn-funky-branch-names.sh2
-rwxr-xr-xt/t9120-git-svn-clone-with-percent-escapes.sh2
-rwxr-xr-xt/t9142-git-svn-shallow-clone.sh2
-rwxr-xr-xt/t9300-fast-import.sh37
-rwxr-xr-xt/t9800-git-p4-basic.sh4
-rwxr-xr-xt/t9801-git-p4-branch.sh8
-rwxr-xr-xt/t9802-git-p4-filetype.sh4
-rwxr-xr-xt/t9803-git-p4-shell-metachars.sh4
-rwxr-xr-xt/t9804-git-p4-label.sh4
-rwxr-xr-xt/t9805-git-p4-skip-submit-edit.sh4
-rwxr-xr-xt/t9806-git-p4-options.sh5
-rwxr-xr-xt/t9807-git-p4-submit.sh4
-rwxr-xr-xt/t9808-git-p4-chdir.sh4
-rwxr-xr-xt/t9809-git-p4-client-view.sh4
-rwxr-xr-xt/t9810-git-p4-rcs.sh4
-rwxr-xr-xt/t9811-git-p4-label-import.sh7
-rwxr-xr-xt/t9812-git-p4-wildcards.sh4
-rwxr-xr-xt/t9813-git-p4-preserve-users.sh4
-rwxr-xr-xt/t9814-git-p4-rename.sh4
-rwxr-xr-xt/t9815-git-p4-submit-fail.sh4
-rwxr-xr-xt/t9816-git-p4-locked.sh4
-rwxr-xr-xt/t9817-git-p4-exclude.sh4
-rwxr-xr-xt/t9818-git-p4-block.sh4
-rwxr-xr-xt/t9819-git-p4-case-folding.sh4
-rwxr-xr-xt/t9820-git-p4-editor-handling.sh4
-rwxr-xr-xt/t9821-git-p4-path-variations.sh4
-rwxr-xr-xt/t9822-git-p4-path-encoding.sh11
-rwxr-xr-xt/t9823-git-p4-mock-lfs.sh4
-rwxr-xr-xt/t9824-git-p4-git-lfs.sh4
-rwxr-xr-xt/t9825-git-p4-handle-utf16-without-bom.sh4
-rwxr-xr-xt/t9826-git-p4-keep-empty-commits.sh4
-rwxr-xr-xt/t9827-git-p4-change-filetype.sh4
-rwxr-xr-xt/t9828-git-p4-map-user.sh4
-rwxr-xr-xt/t9829-git-p4-jobs.sh4
-rwxr-xr-xt/t9830-git-p4-symlink-dir.sh4
-rwxr-xr-xt/t9831-git-p4-triggers.sh4
-rwxr-xr-xt/t9832-unshelve.sh3
-rwxr-xr-xt/t9833-errors.sh5
-rw-r--r--t/test-lib-functions.sh28
-rw-r--r--t/test-lib.sh37
112 files changed, 1582 insertions, 465 deletions
diff --git a/t/README b/t/README
index da721d3314..6404f33e19 100644
--- a/t/README
+++ b/t/README
@@ -384,6 +384,10 @@ the --no-sparse command-line argument.
GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path
by overriding the minimum number of cache entries required per thread.
+GIT_TEST_STASH_USE_BUILTIN=<boolean>, when false, disables the
+built-in version of git-stash. See 'stash.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
@@ -398,6 +402,10 @@ GIT_TEST_SIDEBAND_ALL=<boolean>, when true, overrides the
fetch-pack to not request sideband-all (even if the server advertises
sideband-all).
+GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=<boolean>, when true (which is
+the default when running tests), errors out when an abbreviated option
+is used.
+
Naming Tests
------------
@@ -863,6 +871,26 @@ library for your script to use.
...
'
+ - test_atexit <script>
+
+ Prepend <script> to a list of commands to run unconditionally to
+ clean up before the test script exits, e.g. to stop a daemon:
+
+ test_expect_success 'test git daemon' '
+ git daemon &
+ daemon_pid=$! &&
+ test_atexit 'kill $daemon_pid' &&
+ hello world
+ '
+
+ The commands will be executed before the trash directory is removed,
+ i.e. the atexit commands will still be able to access any pidfiles or
+ socket files.
+
+ Note that these commands will be run even when a test script run
+ with '--immediate' fails. Be careful with your atexit commands to
+ minimize any changes to the failed state.
+
- test_write_lines <lines>
Write <lines> on standard output, one line per argument.
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
index 6da48a2e0a..d933af5714 100644
--- a/t/annotate-tests.sh
+++ b/t/annotate-tests.sh
@@ -68,6 +68,14 @@ test_expect_success 'blame 1 author' '
check_count A 2
'
+test_expect_success 'blame in a bare repo without starting commit' '
+ git clone --bare . bare.git &&
+ (
+ cd bare.git &&
+ check_count A 2
+ )
+'
+
test_expect_success 'blame by tag objects' '
git tag -m "test tag" testTag &&
git tag -m "test tag #2" testTag2 testTag &&
diff --git a/t/helper/test-date.c b/t/helper/test-date.c
index b3253803ac..585347ea48 100644
--- a/t/helper/test-date.c
+++ b/t/helper/test-date.c
@@ -55,7 +55,7 @@ static void show_dates(const char **argv, const char *format)
}
}
-static void parse_dates(const char **argv, struct timeval *now)
+static void parse_dates(const char **argv)
{
struct strbuf result = STRBUF_INIT;
@@ -124,7 +124,7 @@ int cmd__date(int argc, const char **argv)
else if (skip_prefix(*argv, "show:", &x))
show_dates(argv+1, x);
else if (!strcmp(*argv, "parse"))
- parse_dates(argv+1, &now);
+ parse_dates(argv+1);
else if (!strcmp(*argv, "approxidate"))
parse_approxidate(argv+1, &now);
else if (!strcmp(*argv, "timestamp"))
diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c
index cc88fba057..2232b2f79e 100644
--- a/t/helper/test-parse-options.c
+++ b/t/helper/test-parse-options.c
@@ -132,7 +132,7 @@ int cmd__parse_options(int argc, const char **argv)
OPT_NOOP_NOARG(0, "obsolete"),
OPT_STRING_LIST(0, "list", &list, "str", "add str to list"),
OPT_GROUP("Magic arguments"),
- OPT_ARGUMENT("quux", "means --quux"),
+ OPT_ARGUMENT("quux", NULL, "means --quux"),
OPT_NUMBER_CALLBACK(&integer, "set integer to NUM",
number_callback),
{ OPTION_COUNTUP, '+', NULL, &boolean, NULL, "same as -b",
diff --git a/t/helper/test-prio-queue.c b/t/helper/test-prio-queue.c
index 5bc9c46ea5..f4028442e3 100644
--- a/t/helper/test-prio-queue.c
+++ b/t/helper/test-prio-queue.c
@@ -40,7 +40,7 @@ int cmd__prio_queue(int argc, const char **argv)
} else if (!strcmp(*argv, "stack")) {
pq.compare = NULL;
} else {
- int *v = malloc(sizeof(*v));
+ int *v = xmalloc(sizeof(*v));
*v = atoi(*argv);
prio_queue_put(&pq, v);
}
diff --git a/t/interop/i5500-git-daemon.sh b/t/interop/i5500-git-daemon.sh
index 1daf69420b..4d22e42f84 100755
--- a/t/interop/i5500-git-daemon.sh
+++ b/t/interop/i5500-git-daemon.sh
@@ -37,5 +37,4 @@ test_expect_success "fetch with $VERSION_B" '
test_cmp expect actual
'
-stop_git_daemon
test_done
diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh
index 79db3b7ae5..7b3407134e 100644
--- a/t/lib-git-daemon.sh
+++ b/t/lib-git-daemon.sh
@@ -13,7 +13,6 @@
#
# test_expect_success ...
#
-# stop_git_daemon
# test_done
test_tristate GIT_TEST_GIT_DAEMON
@@ -31,10 +30,12 @@ fi
test_set_port LIB_GIT_DAEMON_PORT
GIT_DAEMON_PID=
+GIT_DAEMON_PIDFILE="$PWD"/daemon.pid
GIT_DAEMON_DOCUMENT_ROOT_PATH="$PWD"/repo
GIT_DAEMON_HOST_PORT=127.0.0.1:$LIB_GIT_DAEMON_PORT
GIT_DAEMON_URL=git://$GIT_DAEMON_HOST_PORT
+registered_stop_git_daemon_atexit_handler=
start_git_daemon() {
if test -n "$GIT_DAEMON_PID"
then
@@ -43,13 +44,19 @@ start_git_daemon() {
mkdir -p "$GIT_DAEMON_DOCUMENT_ROOT_PATH"
- trap 'code=$?; stop_git_daemon; (exit $code); die' EXIT
+ # One of the test scripts stops and then re-starts 'git daemon'.
+ # Don't register and then run the same atexit handlers several times.
+ if test -z "$registered_stop_git_daemon_atexit_handler"
+ then
+ test_atexit 'stop_git_daemon'
+ registered_stop_git_daemon_atexit_handler=AlreadyDone
+ fi
say >&3 "Starting git daemon ..."
mkfifo git_daemon_output
${LIB_GIT_DAEMON_COMMAND:-git daemon} \
--listen=127.0.0.1 --port="$LIB_GIT_DAEMON_PORT" \
- --reuseaddr --verbose \
+ --reuseaddr --verbose --pid-file="$GIT_DAEMON_PIDFILE" \
--base-path="$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
"$@" "$GIT_DAEMON_DOCUMENT_ROOT_PATH" \
>&3 2>git_daemon_output &
@@ -65,7 +72,7 @@ start_git_daemon() {
then
kill "$GIT_DAEMON_PID"
wait "$GIT_DAEMON_PID"
- trap 'die' EXIT
+ unset GIT_DAEMON_PID
test_skip_or_die $GIT_TEST_GIT_DAEMON \
"git daemon failed to start"
fi
@@ -77,8 +84,6 @@ stop_git_daemon() {
return
fi
- trap 'die' EXIT
-
# kill git-daemon child of git
say >&3 "Stopping git daemon ..."
kill "$GIT_DAEMON_PID"
@@ -88,8 +93,9 @@ stop_git_daemon() {
then
error "git daemon exited with status: $ret"
fi
+ kill "$(cat "$GIT_DAEMON_PIDFILE")" 2>/dev/null
GIT_DAEMON_PID=
- rm -f git_daemon_output
+ rm -f git_daemon_output "$GIT_DAEMON_PIDFILE"
}
# A stripped-down version of a netcat client, that connects to a "host:port"
diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh
index b3be3ba011..547b9f88e1 100644
--- a/t/lib-git-p4.sh
+++ b/t/lib-git-p4.sh
@@ -44,15 +44,6 @@ native_path () {
echo "$path"
}
-# On Solaris the 'date +%s' function is not supported and therefore we
-# need this replacement.
-# Attention: This function is not safe again against time offset updates
-# at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)'
-# function could fix that but it is not in Python until 3.3.
-time_in_seconds () {
- (cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))')
-}
-
test_set_port P4DPORT
P4PORT=localhost:$P4DPORT
@@ -67,14 +58,9 @@ cli="$TRASH_DIRECTORY/cli"
git="$TRASH_DIRECTORY/git"
pidfile="$TRASH_DIRECTORY/p4d.pid"
-# Sometimes "prove" seems to hang on exit because p4d is still running
-cleanup () {
- if test -f "$pidfile"
- then
- kill -9 $(cat "$pidfile") 2>/dev/null && exit 255
- fi
+stop_p4d_and_watchdog () {
+ kill -9 $p4d_pid $watchdog_pid
}
-trap cleanup EXIT
# git p4 submit generates a temp file, which will
# not get cleaned up if the submission fails. Don't
@@ -82,7 +68,16 @@ trap cleanup EXIT
TMPDIR="$TRASH_DIRECTORY"
export TMPDIR
+registered_stop_p4d_atexit_handler=
start_p4d () {
+ # One of the test scripts stops and then re-starts p4d.
+ # Don't register and then run the same atexit handlers several times.
+ if test -z "$registered_stop_p4d_atexit_handler"
+ then
+ test_atexit 'stop_p4d_and_watchdog'
+ registered_stop_p4d_atexit_handler=AlreadyDone
+ fi
+
mkdir -p "$db" "$cli" "$git" &&
rm -f "$pidfile" &&
(
@@ -92,6 +87,7 @@ start_p4d () {
echo $! >"$pidfile"
}
) &&
+ p4d_pid=$(cat "$pidfile")
# This gives p4d a long time to start up, as it can be
# quite slow depending on the machine. Set this environment
@@ -99,18 +95,18 @@ start_p4d () {
# an automated test setup. If the p4d process dies, that
# will be caught with the "kill -0" check below.
i=${P4D_START_PATIENCE:-300}
- pid=$(cat "$pidfile")
- timeout=$(($(time_in_seconds) + $P4D_TIMEOUT))
+ nr_tries_left=$P4D_TIMEOUT
while true
do
- if test $(time_in_seconds) -gt $timeout
+ if test $nr_tries_left -eq 0
then
- kill -9 $pid
+ kill -9 $p4d_pid
exit 1
fi
sleep 1
- done &
+ nr_tries_left=$(($nr_tries_left - 1))
+ done 2>/dev/null 4>&2 &
watchdog_pid=$!
ready=
@@ -123,7 +119,7 @@ start_p4d () {
break
fi
# fail if p4d died
- kill -0 $pid 2>/dev/null || break
+ kill -0 $p4d_pid 2>/dev/null || break
echo waiting for p4d to start
sleep 1
i=$(( $i - 1 ))
@@ -163,29 +159,18 @@ p4_add_job () {
}
retry_until_success () {
- timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
- until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
- do
- sleep 1
- done
-}
-
-retry_until_fail () {
- timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT))
- until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout
+ nr_tries_left=$RETRY_TIMEOUT
+ until "$@" 2>/dev/null || test $nr_tries_left -eq 0
do
sleep 1
+ nr_tries_left=$(($nr_tries_left - 1))
done
}
-kill_p4d () {
- pid=$(cat "$pidfile")
- retry_until_fail kill $pid
- retry_until_fail kill -9 $pid
- # complain if it would not die
- test_must_fail kill $pid >/dev/null 2>&1 &&
- rm -rf "$db" "$cli" "$pidfile" &&
- retry_until_fail kill -9 $watchdog_pid
+stop_and_cleanup_p4d () {
+ kill -9 $p4d_pid $watchdog_pid
+ wait $p4d_pid
+ rm -rf "$db" "$cli" "$pidfile"
}
cleanup_git () {
diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh
index f3b478c307..c1271d6863 100644
--- a/t/lib-git-svn.sh
+++ b/t/lib-git-svn.sh
@@ -76,11 +76,6 @@ maybe_start_httpd () {
LIB_HTTPD_SVN="$loc"
start_httpd
;;
- *)
- stop_httpd () {
- : noop
- }
- ;;
esac
}
diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh
index 0dfb48c2f6..b3cc62bd36 100644
--- a/t/lib-httpd.sh
+++ b/t/lib-httpd.sh
@@ -14,7 +14,6 @@
#
# test_expect_success ...
#
-# stop_httpd
# test_done
#
# Can be configured using the following variables.
@@ -176,7 +175,7 @@ prepare_httpd() {
start_httpd() {
prepare_httpd >&3 2>&4
- trap 'code=$?; stop_httpd; (exit $code); die' EXIT
+ test_atexit stop_httpd
"$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
-f "$TEST_PATH/apache.conf" $HTTPD_PARA \
@@ -184,15 +183,12 @@ start_httpd() {
>&3 2>&4
if test $? -ne 0
then
- trap 'die' EXIT
cat "$HTTPD_ROOT_PATH"/error.log >&4 2>/dev/null
test_skip_or_die $GIT_TEST_HTTPD "web server setup failed"
fi
}
stop_httpd() {
- trap 'die' EXIT
-
"$LIB_HTTPD_PATH" -d "$HTTPD_ROOT_PATH" \
-f "$TEST_PATH/apache.conf" $HTTPD_PARA -k stop
}
diff --git a/t/lib-submodule-update.sh b/t/lib-submodule-update.sh
index 5b56b23166..1dd17fc03e 100755
--- a/t/lib-submodule-update.sh
+++ b/t/lib-submodule-update.sh
@@ -139,7 +139,7 @@ create_lib_submodule_repo () {
git revert HEAD &&
git checkout -b invalid_sub1 add_sub1 &&
- git update-index --cacheinfo 160000 0123456789012345678901234567890123456789 sub1 &&
+ git update-index --cacheinfo 160000 $(test_oid numeric) sub1 &&
git commit -m "Invalid sub1 commit" &&
git checkout -b valid_sub1 &&
git revert HEAD &&
@@ -196,6 +196,7 @@ test_git_directory_exists() {
# the submodule repo if it doesn't exist and configures the most problematic
# settings for diff.ignoreSubmodules.
prolog () {
+ test_oid_init &&
(test -d submodule_update_repo || create_lib_submodule_repo) &&
test_config_global diff.ignoreSubmodules all &&
test_config diff.ignoreSubmodules all
diff --git a/t/perf/p0001-rev-list.sh b/t/perf/p0001-rev-list.sh
index ebf172401b..3042a85666 100755
--- a/t/perf/p0001-rev-list.sh
+++ b/t/perf/p0001-rev-list.sh
@@ -14,6 +14,24 @@ test_perf 'rev-list --all --objects' '
git rev-list --all --objects >/dev/null
'
+test_perf 'rev-list --parents' '
+ git rev-list --parents HEAD >/dev/null
+'
+
+test_expect_success 'create dummy file' '
+ echo unlikely-to-already-be-there >dummy &&
+ git add dummy &&
+ git commit -m dummy
+'
+
+test_perf 'rev-list -- dummy' '
+ git rev-list HEAD -- dummy
+'
+
+test_perf 'rev-list --parents -- dummy' '
+ git rev-list --parents HEAD -- dummy
+'
+
test_expect_success 'create new unreferenced commit' '
commit=$(git commit-tree HEAD^{tree} -p HEAD) &&
test_export commit
diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh
index b6566003dd..c03054c538 100755
--- a/t/t0000-basic.sh
+++ b/t/t0000-basic.sh
@@ -825,6 +825,24 @@ test_expect_success 'tests clean up even on failures' "
EOF
"
+test_expect_success 'test_atexit is run' "
+ test_must_fail run_sub_test_lib_test \
+ atexit-cleanup 'Run atexit commands' -i <<-\\EOF &&
+ test_expect_success 'tests clean up even after a failure' '
+ > ../../clean-atexit &&
+ test_atexit rm ../../clean-atexit &&
+ > ../../also-clean-atexit &&
+ test_atexit rm ../../also-clean-atexit &&
+ > ../../dont-clean-atexit &&
+ (exit 1)
+ '
+ test_done
+ EOF
+ test_path_is_file dont-clean-atexit &&
+ test_path_is_missing clean-atexit &&
+ test_path_is_missing also-clean-atexit
+"
+
test_expect_success 'test_oid setup' '
test_oid_init
'
diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh
index b8f366c442..800b3ea5f5 100755
--- a/t/t0040-parse-options.sh
+++ b/t/t0040-parse-options.sh
@@ -203,20 +203,24 @@ file: (not set)
EOF
test_expect_success 'unambiguously abbreviated option' '
+ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
test-tool parse-options --int 2 --boolean --no-bo >output 2>output.err &&
test_must_be_empty output.err &&
test_cmp expect output
'
test_expect_success 'unambiguously abbreviated option with "="' '
+ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
test-tool parse-options --expect="integer: 2" --int=2
'
test_expect_success 'ambiguously abbreviated option' '
- test_expect_code 129 test-tool parse-options --strin 123
+ test_expect_code 129 env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+ test-tool parse-options --strin 123
'
test_expect_success 'non ambiguous option (after two options it abbreviates)' '
+ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
test-tool parse-options --expect="string: 123" --st 123
'
@@ -325,6 +329,7 @@ file: (not set)
EOF
test_expect_success 'negation of OPT_NONEG flags is not ambiguous' '
+ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
test-tool parse-options --no-ambig >output 2>output.err &&
test_must_be_empty output.err &&
test_cmp expect output
@@ -370,4 +375,11 @@ test_expect_success '--no-verbose resets multiple verbose to 0' '
test-tool parse-options --expect="verbose: 0" -v -v -v --no-verbose
'
+test_expect_success 'GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS works' '
+ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=false \
+ test-tool parse-options --ye &&
+ test_must_fail env GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true \
+ test-tool parse-options --ye
+'
+
test_done
diff --git a/t/t0301-credential-cache.sh b/t/t0301-credential-cache.sh
index fd92533acf..ebd5fa5249 100755
--- a/t/t0301-credential-cache.sh
+++ b/t/t0301-credential-cache.sh
@@ -10,7 +10,7 @@ test -z "$NO_UNIX_SOCKETS" || {
}
# don't leave a stale daemon running
-trap 'code=$?; git credential-cache exit; (exit $code); die' EXIT
+test_atexit 'git credential-cache exit'
# test that the daemon works with no special setup
helper_test cache
@@ -108,9 +108,4 @@ test_expect_success SYMLINKS 'use user socket if user directory is a symlink to
helper_test_timeout cache --timeout=1
-# we can't rely on our "trap" above working after test_done,
-# as test_done will delete the trash directory containing
-# our socket, leaving us with no way to access the daemon.
-git credential-cache exit
-
test_done
diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh
index bce02788e6..5bd892f2f7 100755
--- a/t/t0410-partial-clone.sh
+++ b/t/t0410-partial-clone.sh
@@ -518,6 +518,4 @@ test_expect_success 'fetching of missing objects from an HTTP server' '
git verify-pack --verbose "$IDX" | grep "$HASH"
'
-stop_httpd
-
test_done
diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh
index 635918505d..579a86b7f8 100755
--- a/t/t1305-config-include.sh
+++ b/t/t1305-config-include.sh
@@ -229,6 +229,19 @@ test_expect_success 'conditional include, early config reading' '
)
'
+test_expect_success 'conditional include with /**/' '
+ REPO=foo/bar/repo &&
+ git init $REPO &&
+ cat >>$REPO/.git/config <<-\EOF &&
+ [includeIf "gitdir:**/foo/**/bar/**"]
+ path=bar7
+ EOF
+ echo "[test]seven=7" >$REPO/.git/bar7 &&
+ echo 7 >expect &&
+ git -C $REPO config test.seven >actual &&
+ test_cmp expect actual
+'
+
test_expect_success SYMLINKS 'conditional include, set up symlinked $HOME' '
mkdir real-home &&
ln -s real-home home &&
diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh
index ae8a448e34..79f731db37 100755
--- a/t/t1410-reflog.sh
+++ b/t/t1410-reflog.sh
@@ -232,25 +232,34 @@ test_expect_success '--expire=never' '
'
test_expect_success 'gc.reflogexpire=never' '
+ test_config gc.reflogexpire never &&
+ test_config gc.reflogexpireunreachable never &&
+
+ git reflog expire --verbose --all >output &&
+ test_line_count = 9 output &&
- git config gc.reflogexpire never &&
- git config gc.reflogexpireunreachable never &&
- git reflog expire --verbose --all &&
git reflog refs/heads/master >output &&
test_line_count = 4 output
'
test_expect_success 'gc.reflogexpire=false' '
+ test_config gc.reflogexpire false &&
+ test_config gc.reflogexpireunreachable false &&
- git config gc.reflogexpire false &&
- git config gc.reflogexpireunreachable false &&
git reflog expire --verbose --all &&
git reflog refs/heads/master >output &&
- test_line_count = 4 output &&
+ test_line_count = 4 output
+
+'
- git config --unset gc.reflogexpire &&
- git config --unset gc.reflogexpireunreachable
+test_expect_success 'git reflog expire unknown reference' '
+ test_config gc.reflogexpire never &&
+ test_config gc.reflogexpireunreachable never &&
+ test_must_fail git reflog expire master@{123} 2>stderr &&
+ test_i18ngrep "points nowhere" stderr &&
+ test_must_fail git reflog expire does-not-exist 2>stderr &&
+ test_i18ngrep "points nowhere" stderr
'
test_expect_success 'checkout should not delete log for packed ref' '
diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh
index afd4756134..0aefadacb0 100755
--- a/t/t3000-ls-files-others.sh
+++ b/t/t3000-ls-files-others.sh
@@ -3,7 +3,7 @@
# Copyright (c) 2005 Junio C Hamano
#
-test_description='git ls-files test (--others should pick up symlinks).
+test_description='basic tests for ls-files --others
This test runs git ls-files --others with the following on the
filesystem.
diff --git a/t/t3009-ls-files-others-nonsubmodule.sh b/t/t3009-ls-files-others-nonsubmodule.sh
new file mode 100755
index 0000000000..963f3462b7
--- /dev/null
+++ b/t/t3009-ls-files-others-nonsubmodule.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+test_description='test git ls-files --others with non-submodule repositories
+
+This test runs git ls-files --others with the following working tree:
+
+ nonrepo-no-files/
+ plain directory with no files
+ nonrepo-untracked-file/
+ plain directory with an untracked file
+ repo-no-commit-no-files/
+ git repository without a commit or a file
+ repo-no-commit-untracked-file/
+ git repository without a commit but with an untracked file
+ repo-with-commit-no-files/
+ git repository with a commit and no untracked files
+ repo-with-commit-untracked-file/
+ git repository with a commit and an untracked file
+'
+
+. ./test-lib.sh
+
+test_expect_success 'setup: directories' '
+ mkdir nonrepo-no-files/ &&
+ mkdir nonrepo-untracked-file &&
+ : >nonrepo-untracked-file/untracked &&
+ git init repo-no-commit-no-files &&
+ git init repo-no-commit-untracked-file &&
+ : >repo-no-commit-untracked-file/untracked &&
+ git init repo-with-commit-no-files &&
+ git -C repo-with-commit-no-files commit --allow-empty -mmsg &&
+ git init repo-with-commit-untracked-file &&
+ test_commit -C repo-with-commit-untracked-file msg &&
+ : >repo-with-commit-untracked-file/untracked
+'
+
+test_expect_success 'ls-files --others handles untracked git repositories' '
+ git ls-files -o >output &&
+ cat >expect <<-EOF &&
+ nonrepo-untracked-file/untracked
+ output
+ repo-no-commit-no-files/
+ repo-no-commit-untracked-file/
+ repo-with-commit-no-files/
+ repo-with-commit-untracked-file/
+ EOF
+ test_cmp expect output
+'
+
+test_done
diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh
index 84bbf88cf9..704bbc6541 100755
--- a/t/t3301-notes.sh
+++ b/t/t3301-notes.sh
@@ -1120,9 +1120,10 @@ test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' '
test_config notes.rewriteMode overwrite &&
test_config notes.rewriteRef refs/notes/other &&
echo $(git rev-parse HEAD^) $(git rev-parse HEAD) |
- GIT_NOTES_REWRITE_REF= git notes copy --for-rewrite=foo &&
+ GIT_NOTES_REWRITE_REF=refs/notes/commits \
+ git notes copy --for-rewrite=foo &&
git log -1 >actual &&
- test_cmp expect actual
+ grep "replacement note 3" actual
'
test_expect_success 'git notes copy diagnoses too many or too few parameters' '
diff --git a/t/t3401-rebase-and-am-rename.sh b/t/t3401-rebase-and-am-rename.sh
index e0b5111993..a0b9438b22 100755
--- a/t/t3401-rebase-and-am-rename.sh
+++ b/t/t3401-rebase-and-am-rename.sh
@@ -42,7 +42,7 @@ test_expect_success 'rebase --interactive: directory rename detected' '
git checkout B^0 &&
set_fake_editor &&
- FAKE_LINES="1" git rebase --interactive A &&
+ FAKE_LINES="1" git -c merge.directoryRenames=true rebase --interactive A &&
git ls-files -s >out &&
test_line_count = 5 out &&
@@ -58,7 +58,7 @@ test_expect_failure 'rebase (am): directory rename detected' '
git checkout B^0 &&
- git rebase A &&
+ git -c merge.directoryRenames=true rebase A &&
git ls-files -s >out &&
test_line_count = 5 out &&
@@ -74,7 +74,7 @@ test_expect_success 'rebase --merge: directory rename detected' '
git checkout B^0 &&
- git rebase --merge A &&
+ git -c merge.directoryRenames=true rebase --merge A &&
git ls-files -s >out &&
test_line_count = 5 out &&
@@ -92,7 +92,7 @@ test_expect_failure 'am: directory rename detected' '
git format-patch -1 B &&
- git am --3way 0001*.patch &&
+ git -c merge.directoryRenames=true am --3way 0001*.patch &&
git ls-files -s >out &&
test_line_count = 5 out &&
diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh
index 13f5688135..22d218698e 100755
--- a/t/t3415-rebase-autosquash.sh
+++ b/t/t3415-rebase-autosquash.sh
@@ -277,7 +277,7 @@ test_expect_success 'autosquash with empty custom instructionFormat' '
(
set_cat_todo_editor &&
test_must_fail git -c rebase.instructionFormat= \
- rebase --autosquash --force -i HEAD^ >actual &&
+ rebase --autosquash --force-rebase -i HEAD^ >actual &&
git log -1 --format="pick %h %s" >expect &&
test_cmp expect actual
)
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
index 4c69255ee6..42ba5b9f09 100755
--- a/t/t3430-rebase-merges.sh
+++ b/t/t3430-rebase-merges.sh
@@ -271,7 +271,7 @@ test_expect_success 'root commits' '
EOF
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
test_tick &&
- git rebase -i --force --root -r &&
+ git rebase -i --force-rebase --root -r &&
test "Parsnip" = "$(git show -s --format=%an HEAD^)" &&
test $(git rev-parse second-root^0) != $(git rev-parse HEAD^) &&
test $(git rev-parse second-root:second-root.t) = \
@@ -364,7 +364,7 @@ test_expect_success 'octopus merges' '
test_cmp_rev HEAD $before &&
test_tick &&
- git rebase -i --force -r HEAD^^ &&
+ git rebase -i --force-rebase -r HEAD^^ &&
test "Hank" = "$(git show -s --format=%an HEAD)" &&
test "$before" != $(git rev-parse HEAD) &&
test_cmp_graph HEAD^^.. <<-\EOF
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index a584b11c98..1a8818fbe0 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -25,6 +25,11 @@ test_expect_success setup '
test_commit base foo b &&
test_commit picked foo c &&
test_commit --signoff picked-signed foo d &&
+ git checkout -b topic initial &&
+ test_commit redundant-pick foo c redundant &&
+ git commit --allow-empty --allow-empty-message &&
+ git tag empty &&
+ git checkout master &&
git config advice.detachedhead false
'
@@ -491,4 +496,23 @@ test_expect_success 'cherry-pick preserves sparse-checkout' '
test_i18ngrep ! "Changes not staged for commit:" actual
'
+test_expect_success 'cherry-pick --continue remembers --keep-redundant-commits' '
+ test_when_finished "git cherry-pick --abort || :" &&
+ pristine_detach initial &&
+ test_must_fail git cherry-pick --keep-redundant-commits picked redundant &&
+ echo c >foo &&
+ git add foo &&
+ git cherry-pick --continue
+'
+
+test_expect_success 'cherry-pick --continue remembers --allow-empty and --allow-empty-message' '
+ test_when_finished "git cherry-pick --abort || :" &&
+ pristine_detach initial &&
+ test_must_fail git cherry-pick --allow-empty --allow-empty-message \
+ picked empty &&
+ echo c >foo &&
+ git add foo &&
+ git cherry-pick --continue
+'
+
test_done
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index be582a513b..c325167b90 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -296,6 +296,17 @@ test_expect_success '"git add ." in empty repo' '
)
'
+test_expect_success 'error on a repository with no commits' '
+ rm -fr empty &&
+ git init empty &&
+ test_must_fail git add empty >actual 2>&1 &&
+ cat >expect <<-EOF &&
+ error: '"'empty/'"' does not have a commit checked out
+ fatal: adding files failed
+ EOF
+ test_i18ncmp expect actual
+'
+
test_expect_success 'git add --dry-run of existing changed file' "
echo new >>track-this &&
git add --dry-run track-this >actual 2>&1 &&
@@ -396,6 +407,7 @@ test_expect_success 'no file status change if no pathspec is given in subdir' '
'
test_expect_success 'all statuses changed in folder if . is given' '
+ rm -fr empty &&
git add --chmod=+x . &&
test $(git ls-files --stage | grep ^100644 | wc -l) -eq 0 &&
git add --chmod=-x . &&
diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh
index 5f8272b6f9..ea30d5f6a0 100755
--- a/t/t3903-stash.sh
+++ b/t/t3903-stash.sh
@@ -8,22 +8,22 @@ test_description='Test git stash'
. ./test-lib.sh
test_expect_success 'stash some dirty working directory' '
- echo 1 > file &&
+ echo 1 >file &&
git add file &&
echo unrelated >other-file &&
git add other-file &&
test_tick &&
git commit -m initial &&
- echo 2 > file &&
+ echo 2 >file &&
git add file &&
- echo 3 > file &&
+ echo 3 >file &&
test_tick &&
git stash &&
git diff-files --quiet &&
git diff-index --cached --quiet HEAD
'
-cat > expect << EOF
+cat >expect <<EOF
diff --git a/file b/file
index 0cfbf08..00750ed 100644
--- a/file
@@ -35,7 +35,7 @@ EOF
test_expect_success 'parents of stash' '
test $(git rev-parse stash^) = $(git rev-parse HEAD) &&
- git diff stash^2..stash > output &&
+ git diff stash^2..stash >output &&
test_cmp expect output
'
@@ -74,7 +74,7 @@ test_expect_success 'apply stashed changes' '
test_expect_success 'apply stashed changes (including index)' '
git reset --hard HEAD^ &&
- echo 6 > other-file &&
+ echo 6 >other-file &&
git add other-file &&
test_tick &&
git commit -m other-file &&
@@ -99,12 +99,12 @@ test_expect_success 'stash drop complains of extra options' '
test_expect_success 'drop top stash' '
git reset --hard &&
- git stash list > stashlist1 &&
- echo 7 > file &&
+ git stash list >expected &&
+ echo 7 >file &&
git stash &&
git stash drop &&
- git stash list > stashlist2 &&
- test_cmp stashlist1 stashlist2 &&
+ git stash list >actual &&
+ test_cmp expected actual &&
git stash apply &&
test 3 = $(cat file) &&
test 1 = $(git show :file) &&
@@ -113,9 +113,9 @@ test_expect_success 'drop top stash' '
test_expect_success 'drop middle stash' '
git reset --hard &&
- echo 8 > file &&
+ echo 8 >file &&
git stash &&
- echo 9 > file &&
+ echo 9 >file &&
git stash &&
git stash drop stash@{1} &&
test 2 = $(git stash list | wc -l) &&
@@ -160,7 +160,7 @@ test_expect_success 'stash pop' '
test 0 = $(git stash list | wc -l)
'
-cat > expect << EOF
+cat >expect <<EOF
diff --git a/file2 b/file2
new file mode 100644
index 0000000..1fe912c
@@ -170,7 +170,7 @@ index 0000000..1fe912c
+bar2
EOF
-cat > expect1 << EOF
+cat >expect1 <<EOF
diff --git a/file b/file
index 257cc56..5716ca5 100644
--- a/file
@@ -180,7 +180,7 @@ index 257cc56..5716ca5 100644
+bar
EOF
-cat > expect2 << EOF
+cat >expect2 <<EOF
diff --git a/file b/file
index 7601807..5716ca5 100644
--- a/file
@@ -198,79 +198,79 @@ index 0000000..1fe912c
EOF
test_expect_success 'stash branch' '
- echo foo > file &&
+ echo foo >file &&
git commit file -m first &&
- echo bar > file &&
- echo bar2 > file2 &&
+ echo bar >file &&
+ echo bar2 >file2 &&
git add file2 &&
git stash &&
- echo baz > file &&
+ echo baz >file &&
git commit file -m second &&
git stash branch stashbranch &&
test refs/heads/stashbranch = $(git symbolic-ref HEAD) &&
test $(git rev-parse HEAD) = $(git rev-parse master^) &&
- git diff --cached > output &&
+ git diff --cached >output &&
test_cmp expect output &&
- git diff > output &&
+ git diff >output &&
test_cmp expect1 output &&
git add file &&
git commit -m alternate\ second &&
- git diff master..stashbranch > output &&
+ git diff master..stashbranch >output &&
test_cmp output expect2 &&
test 0 = $(git stash list | wc -l)
'
test_expect_success 'apply -q is quiet' '
- echo foo > file &&
+ echo foo >file &&
git stash &&
- git stash apply -q > output.out 2>&1 &&
+ git stash apply -q >output.out 2>&1 &&
test_must_be_empty output.out
'
test_expect_success 'save -q is quiet' '
- git stash save --quiet > output.out 2>&1 &&
+ git stash save --quiet >output.out 2>&1 &&
test_must_be_empty output.out
'
test_expect_success 'pop -q is quiet' '
- git stash pop -q > output.out 2>&1 &&
+ git stash pop -q >output.out 2>&1 &&
test_must_be_empty output.out
'
test_expect_success 'pop -q --index works and is quiet' '
- echo foo > file &&
+ echo foo >file &&
git add file &&
git stash save --quiet &&
- git stash pop -q --index > output.out 2>&1 &&
+ git stash pop -q --index >output.out 2>&1 &&
test foo = "$(git show :file)" &&
test_must_be_empty output.out
'
test_expect_success 'drop -q is quiet' '
git stash &&
- git stash drop -q > output.out 2>&1 &&
+ git stash drop -q >output.out 2>&1 &&
test_must_be_empty output.out
'
test_expect_success 'stash -k' '
- echo bar3 > file &&
- echo bar4 > file2 &&
+ echo bar3 >file &&
+ echo bar4 >file2 &&
git add file2 &&
git stash -k &&
test bar,bar4 = $(cat file),$(cat file2)
'
test_expect_success 'stash --no-keep-index' '
- echo bar33 > file &&
- echo bar44 > file2 &&
+ echo bar33 >file &&
+ echo bar44 >file2 &&
git add file2 &&
git stash --no-keep-index &&
test bar,bar2 = $(cat file),$(cat file2)
'
test_expect_success 'stash --invalid-option' '
- echo bar5 > file &&
- echo bar6 > file2 &&
+ echo bar5 >file &&
+ echo bar6 >file2 &&
git add file2 &&
test_must_fail git stash --invalid-option &&
test_must_fail git stash save --invalid-option &&
@@ -287,6 +287,14 @@ test_expect_success 'stash an added file' '
test new = "$(cat file3)"
'
+test_expect_success 'stash --intent-to-add file' '
+ git reset --hard &&
+ echo new >file4 &&
+ git add --intent-to-add file4 &&
+ test_when_finished "git rm -f file4" &&
+ test_must_fail git stash
+'
+
test_expect_success 'stash rm then recreate' '
git reset --hard &&
git rm file &&
@@ -444,6 +452,36 @@ test_expect_failure 'stash file to directory' '
test foo = "$(cat file/file)"
'
+test_expect_success 'giving too many ref arguments does not modify files' '
+ git stash clear &&
+ test_when_finished "git reset --hard HEAD" &&
+ echo foo >file2 &&
+ git stash &&
+ echo bar >file2 &&
+ git stash &&
+ test-tool chmtime =123456789 file2 &&
+ for type in apply pop "branch stash-branch"
+ do
+ test_must_fail git stash $type stash@{0} stash@{1} 2>err &&
+ test_i18ngrep "Too many revisions" err &&
+ test 123456789 = $(test-tool chmtime -g file2) || return 1
+ done
+'
+
+test_expect_success 'drop: too many arguments errors out (does nothing)' '
+ git stash list >expect &&
+ test_must_fail git stash drop stash@{0} stash@{1} 2>err &&
+ test_i18ngrep "Too many revisions" err &&
+ git stash list >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'show: too many arguments errors out (does nothing)' '
+ test_must_fail git stash show stash@{0} stash@{1} 2>err 1>out &&
+ test_i18ngrep "Too many revisions" err &&
+ test_must_be_empty out
+'
+
test_expect_success 'stash create - no changes' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
@@ -456,11 +494,12 @@ test_expect_success 'stash branch - no stashes on stack, stash-like argument' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
git reset --hard &&
- echo foo >> file &&
+ echo foo >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
git stash branch stash-branch ${STASH_ID} &&
- test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
+ test_when_finished "git reset --hard HEAD && git checkout master &&
+ git branch -D stash-branch" &&
test $(git ls-files --modified | wc -l) -eq 1
'
@@ -468,25 +507,31 @@ test_expect_success 'stash branch - stashes on stack, stash-like argument' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
git reset --hard &&
- echo foo >> file &&
+ echo foo >>file &&
git stash &&
test_when_finished "git stash drop" &&
- echo bar >> file &&
+ echo bar >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
git stash branch stash-branch ${STASH_ID} &&
- test_when_finished "git reset --hard HEAD && git checkout master && git branch -D stash-branch" &&
+ test_when_finished "git reset --hard HEAD && git checkout master &&
+ git branch -D stash-branch" &&
test $(git ls-files --modified | wc -l) -eq 1
'
+test_expect_success 'stash branch complains with no arguments' '
+ test_must_fail git stash branch 2>err &&
+ test_i18ngrep "No branch name specified" err
+'
+
test_expect_success 'stash show format defaults to --stat' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
git reset --hard &&
- echo foo >> file &&
+ echo foo >>file &&
git stash &&
test_when_finished "git stash drop" &&
- echo bar >> file &&
+ echo bar >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
@@ -501,10 +546,10 @@ test_expect_success 'stash show - stashes on stack, stash-like argument' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
git reset --hard &&
- echo foo >> file &&
+ echo foo >>file &&
git stash &&
test_when_finished "git stash drop" &&
- echo bar >> file &&
+ echo bar >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
echo "1 0 file" >expected &&
@@ -516,10 +561,10 @@ test_expect_success 'stash show -p - stashes on stack, stash-like argument' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
git reset --hard &&
- echo foo >> file &&
+ echo foo >>file &&
git stash &&
test_when_finished "git stash drop" &&
- echo bar >> file &&
+ echo bar >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
@@ -539,7 +584,7 @@ test_expect_success 'stash show - no stashes on stack, stash-like argument' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
git reset --hard &&
- echo foo >> file &&
+ echo foo >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
echo "1 0 file" >expected &&
@@ -551,7 +596,7 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
git stash clear &&
test_when_finished "git reset --hard HEAD" &&
git reset --hard &&
- echo foo >> file &&
+ echo foo >>file &&
STASH_ID=$(git stash create) &&
git reset --hard &&
cat >expected <<-EOF &&
@@ -567,13 +612,31 @@ test_expect_success 'stash show -p - no stashes on stack, stash-like argument' '
test_cmp expected actual
'
-test_expect_success 'stash drop - fail early if specified stash is not a stash reference' '
+test_expect_success 'stash show --patience shows diff' '
+ git reset --hard &&
+ echo foo >>file &&
+ STASH_ID=$(git stash create) &&
+ git reset --hard &&
+ cat >expected <<-EOF &&
+ diff --git a/file b/file
+ index 7601807..71b52c4 100644
+ --- a/file
+ +++ b/file
+ @@ -1 +1,2 @@
+ baz
+ +foo
+ EOF
+ git stash show --patience ${STASH_ID} >actual &&
+ test_cmp expected actual
+'
+
+test_expect_success 'drop: fail early if specified stash is not a stash ref' '
git stash clear &&
test_when_finished "git reset --hard HEAD && git stash clear" &&
git reset --hard &&
- echo foo > file &&
+ echo foo >file &&
git stash &&
- echo bar > file &&
+ echo bar >file &&
git stash &&
test_must_fail git stash drop $(git rev-parse stash@{0}) &&
git stash pop &&
@@ -581,13 +644,13 @@ test_expect_success 'stash drop - fail early if specified stash is not a stash r
git reset --hard HEAD
'
-test_expect_success 'stash pop - fail early if specified stash is not a stash reference' '
+test_expect_success 'pop: fail early if specified stash is not a stash ref' '
git stash clear &&
test_when_finished "git reset --hard HEAD && git stash clear" &&
git reset --hard &&
- echo foo > file &&
+ echo foo >file &&
git stash &&
- echo bar > file &&
+ echo bar >file &&
git stash &&
test_must_fail git stash pop $(git rev-parse stash@{0}) &&
git stash pop &&
@@ -597,8 +660,8 @@ test_expect_success 'stash pop - fail early if specified stash is not a stash re
test_expect_success 'ref with non-existent reflog' '
git stash clear &&
- echo bar5 > file &&
- echo bar6 > file2 &&
+ echo bar5 >file &&
+ echo bar6 >file2 &&
git add file2 &&
git stash &&
test_must_fail git rev-parse --quiet --verify does-not-exist &&
@@ -618,8 +681,8 @@ test_expect_success 'ref with non-existent reflog' '
test_expect_success 'invalid ref of the form stash@{n}, n >= N' '
git stash clear &&
test_must_fail git stash drop stash@{0} &&
- echo bar5 > file &&
- echo bar6 > file2 &&
+ echo bar5 >file &&
+ echo bar6 >file2 &&
git add file2 &&
git stash &&
test_must_fail git stash drop stash@{1} &&
@@ -645,7 +708,7 @@ test_expect_success 'invalid ref of the form "n", n >= N' '
git stash drop
'
-test_expect_success 'stash branch should not drop the stash if the branch exists' '
+test_expect_success 'branch: do not drop the stash if the branch exists' '
git stash clear &&
echo foo >file &&
git add file &&
@@ -656,7 +719,7 @@ test_expect_success 'stash branch should not drop the stash if the branch exists
git rev-parse stash@{0} --
'
-test_expect_success 'stash branch should not drop the stash if the apply fails' '
+test_expect_success 'branch: should not drop the stash if the apply fails' '
git stash clear &&
git reset HEAD~1 --hard &&
echo foo >file &&
@@ -670,7 +733,7 @@ test_expect_success 'stash branch should not drop the stash if the apply fails'
git rev-parse stash@{0} --
'
-test_expect_success 'stash apply shows status same as git status (relative to current directory)' '
+test_expect_success 'apply: show same status as git status (relative to ./)' '
git stash clear &&
echo 1 >subdir/subfile1 &&
echo 2 >subdir/subfile2 &&
@@ -689,7 +752,7 @@ test_expect_success 'stash apply shows status same as git status (relative to cu
test_i18ncmp expect actual
'
-cat > expect << EOF
+cat >expect <<EOF
diff --git a/HEAD b/HEAD
new file mode 100644
index 0000000..fe0cbee
@@ -702,14 +765,14 @@ EOF
test_expect_success 'stash where working directory contains "HEAD" file' '
git stash clear &&
git reset --hard &&
- echo file-not-a-ref > HEAD &&
+ echo file-not-a-ref >HEAD &&
git add HEAD &&
test_tick &&
git stash &&
git diff-files --quiet &&
git diff-index --cached --quiet HEAD &&
test "$(git rev-parse stash^)" = "$(git rev-parse HEAD)" &&
- git diff stash^..stash > output &&
+ git diff stash^..stash >output &&
test_cmp expect output
'
@@ -1011,7 +1074,7 @@ test_expect_success 'stash push -p with pathspec shows no changes only once' '
test_i18ncmp expect actual
'
-test_expect_success 'stash push with pathspec shows no changes when there are none' '
+test_expect_success 'push <pathspec>: show no changes when there are none' '
>foo &&
git add foo &&
git commit -m "tmp" &&
@@ -1021,12 +1084,35 @@ test_expect_success 'stash push with pathspec shows no changes when there are no
test_i18ncmp expect actual
'
-test_expect_success 'stash push with pathspec not in the repository errors out' '
+test_expect_success 'push: <pathspec> not in the repository errors out' '
>untracked &&
test_must_fail git stash push untracked &&
test_path_is_file untracked
'
+test_expect_success 'push: -q is quiet with changes' '
+ >foo &&
+ git add foo &&
+ git stash push -q >output 2>&1 &&
+ test_must_be_empty output
+'
+
+test_expect_success 'push: -q is quiet with no changes' '
+ git stash push -q >output 2>&1 &&
+ test_must_be_empty output
+'
+
+test_expect_success 'push: -q is quiet even if there is no initial commit' '
+ git init foo_dir &&
+ test_when_finished rm -rf foo_dir &&
+ (
+ cd foo_dir &&
+ >bar &&
+ test_must_fail git stash push -q >output 2>&1 &&
+ test_must_be_empty output
+ )
+'
+
test_expect_success 'untracked files are left in place when -u is not given' '
>file &&
git add file &&
@@ -1096,6 +1182,12 @@ test_expect_success 'stash -- <subdir> works with binary files' '
test_path_is_file subdir/untracked
'
+test_expect_success 'stash with user.name and user.email set works' '
+ test_config user.name "A U Thor" &&
+ test_config user.email "a.u@thor" &&
+ git stash
+'
+
test_expect_success 'stash works when user.name and user.email are not set' '
git reset &&
>1 &&
diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh
index cc1c8a7bb2..29ca76f2fb 100755
--- a/t/t3905-stash-include-untracked.sh
+++ b/t/t3905-stash-include-untracked.sh
@@ -283,4 +283,10 @@ test_expect_success 'stash -u -- <non-existant> shows no changes when there are
test_i18ncmp expect actual
'
+test_expect_success 'stash -u with globs' '
+ >untracked.txt &&
+ git stash -u -- ":(glob)**/*.txt" &&
+ test_path_is_missing untracked.txt
+'
+
test_done
diff --git a/t/t3907-stash-show-config.sh b/t/t3907-stash-show-config.sh
new file mode 100755
index 0000000000..10914bba7b
--- /dev/null
+++ b/t/t3907-stash-show-config.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+test_description='Test git stash show configuration.'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ test_commit file
+'
+
+# takes three parameters:
+# 1. the stash.showStat value (or "<unset>")
+# 2. the stash.showPatch value (or "<unset>")
+# 3. the diff options of the expected output (or nothing for no output)
+test_stat_and_patch () {
+ if test "<unset>" = "$1"
+ then
+ test_unconfig stash.showStat
+ else
+ test_config stash.showStat "$1"
+ fi &&
+
+ if test "<unset>" = "$2"
+ then
+ test_unconfig stash.showPatch
+ else
+ test_config stash.showPatch "$2"
+ fi &&
+
+ shift 2 &&
+ echo 2 >file.t &&
+ if test $# != 0
+ then
+ git diff "$@" >expect
+ fi &&
+ git stash &&
+ git stash show >actual &&
+
+ if test $# = 0
+ then
+ test_must_be_empty actual
+ else
+ test_cmp expect actual
+ fi
+}
+
+test_expect_success 'showStat unset showPatch unset' '
+ test_stat_and_patch "<unset>" "<unset>" --stat
+'
+
+test_expect_success 'showStat unset showPatch false' '
+ test_stat_and_patch "<unset>" false --stat
+'
+
+test_expect_success 'showStat unset showPatch true' '
+ test_stat_and_patch "<unset>" true --stat -p
+'
+
+test_expect_success 'showStat false showPatch unset' '
+ test_stat_and_patch false "<unset>"
+'
+
+test_expect_success 'showStat false showPatch false' '
+ test_stat_and_patch false false
+'
+
+test_expect_success 'showStat false showPatch true' '
+ test_stat_and_patch false true -p
+'
+
+test_expect_success 'showStat true showPatch unset' '
+ test_stat_and_patch true "<unset>" --stat
+'
+
+test_expect_success 'showStat true showPatch false' '
+ test_stat_and_patch true false --stat
+'
+
+test_expect_success 'showStat true showPatch true' '
+ test_stat_and_patch true true --stat -p
+'
+
+test_done
diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh
index 4331b3118a..0168946b63 100755
--- a/t/t4053-diff-no-index.sh
+++ b/t/t4053-diff-no-index.sh
@@ -50,8 +50,7 @@ test_expect_success 'git diff --no-index executed outside repo gives correct err
export GIT_CEILING_DIRECTORIES &&
cd non/git &&
test_must_fail git diff --no-index a 2>actual.err &&
- echo "usage: git diff --no-index <path> <path>" >expect.err &&
- test_cmp expect.err actual.err
+ test_i18ngrep "usage: git diff --no-index" actual.err
)
'
diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh
new file mode 100755
index 0000000000..90c8fb2901
--- /dev/null
+++ b/t/t4067-diff-partial-clone.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+test_description='behavior of diff when reading objects in a partial clone'
+
+. ./test-lib.sh
+
+test_expect_success 'git show batches blobs' '
+ test_when_finished "rm -rf server client trace" &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ echo b >server/b &&
+ git -C server add a b &&
+ git -C server commit -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ # Ensure that there is exactly 1 negotiation by checking that there is
+ # only 1 "done" line sent. ("done" marks the end of negotiation.)
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client show HEAD &&
+ grep "git> done" trace >done_lines &&
+ test_line_count = 1 done_lines
+'
+
+test_expect_success 'diff batches blobs' '
+ test_when_finished "rm -rf server client trace" &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ echo b >server/b &&
+ git -C server add a b &&
+ git -C server commit -m x &&
+ echo c >server/c &&
+ echo d >server/d &&
+ git -C server add c d &&
+ git -C server commit -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ # Ensure that there is exactly 1 negotiation by checking that there is
+ # only 1 "done" line sent. ("done" marks the end of negotiation.)
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD &&
+ grep "git> done" trace >done_lines &&
+ test_line_count = 1 done_lines
+'
+
+test_expect_success 'diff skips same-OID blobs' '
+ test_when_finished "rm -rf server client trace" &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ echo b >server/b &&
+ git -C server add a b &&
+ git -C server commit -m x &&
+ echo another-a >server/a &&
+ git -C server add a &&
+ git -C server commit -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ echo a | git hash-object --stdin >hash-old-a &&
+ echo another-a | git hash-object --stdin >hash-new-a &&
+ echo b | git hash-object --stdin >hash-b &&
+
+ # Ensure that only a and another-a are fetched.
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD &&
+ grep "want $(cat hash-old-a)" trace &&
+ grep "want $(cat hash-new-a)" trace &&
+ ! grep "want $(cat hash-b)" trace
+'
+
+test_expect_success 'diff with rename detection batches blobs' '
+ test_when_finished "rm -rf server client trace" &&
+
+ test_create_repo server &&
+ echo a >server/a &&
+ printf "b\nb\nb\nb\nb\n" >server/b &&
+ git -C server add a b &&
+ git -C server commit -m x &&
+ rm server/b &&
+ printf "b\nb\nb\nb\nbX\n" >server/c &&
+ git -C server add c &&
+ git -C server commit -a -m x &&
+
+ test_config -C server uploadpack.allowfilter 1 &&
+ test_config -C server uploadpack.allowanysha1inwant 1 &&
+ git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
+
+ # Ensure that there is exactly 1 negotiation by checking that there is
+ # only 1 "done" line sent. ("done" marks the end of negotiation.)
+ GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff -M HEAD^ HEAD >out &&
+ grep "similarity index" out &&
+ grep "git> done" trace >done_lines &&
+ test_line_count = 1 done_lines
+'
+
+test_done
diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh
index 24541ea137..4c0201c34b 100755
--- a/t/t5317-pack-objects-filter-objects.sh
+++ b/t/t5317-pack-objects-filter-objects.sh
@@ -25,7 +25,7 @@ test_expect_success 'verify blob count in normal packfile' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r1 pack-objects --rev --stdout >all.pack <<-EOF &&
+ git -C r1 pack-objects --revs --stdout >all.pack <<-EOF &&
HEAD
EOF
git -C r1 index-pack ../all.pack &&
@@ -39,7 +39,7 @@ test_expect_success 'verify blob count in normal packfile' '
'
test_expect_success 'verify blob:none packfile has no blobs' '
- git -C r1 pack-objects --rev --stdout --filter=blob:none >filter.pack <<-EOF &&
+ git -C r1 pack-objects --revs --stdout --filter=blob:none >filter.pack <<-EOF &&
HEAD
EOF
git -C r1 index-pack ../filter.pack &&
@@ -74,7 +74,7 @@ test_expect_success 'get an error for missing tree object' '
git -C r5 commit -m "foo" &&
del=$(git -C r5 rev-parse HEAD^{tree} | sed "s|..|&/|") &&
rm r5/.git/objects/$del &&
- test_must_fail git -C r5 pack-objects --rev --stdout 2>bad_tree <<-EOF &&
+ test_must_fail git -C r5 pack-objects --revs --stdout 2>bad_tree <<-EOF &&
HEAD
EOF
grep "bad tree object" bad_tree
@@ -88,7 +88,7 @@ test_expect_success 'setup for tests of tree:0' '
'
test_expect_success 'verify tree:0 packfile has no blobs or trees' '
- git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF &&
+ git -C r1 pack-objects --revs --stdout --filter=tree:0 >commitsonly.pack <<-EOF &&
HEAD
EOF
git -C r1 index-pack ../commitsonly.pack &&
@@ -98,7 +98,7 @@ test_expect_success 'verify tree:0 packfile has no blobs or trees' '
test_expect_success 'grab tree directly when using tree:0' '
# We should get the tree specified directly but not its blobs or subtrees.
- git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF &&
+ git -C r1 pack-objects --revs --stdout --filter=tree:0 >commitsonly.pack <<-EOF &&
HEAD:
EOF
git -C r1 index-pack ../commitsonly.pack &&
@@ -128,7 +128,7 @@ test_expect_success 'verify blob count in normal packfile' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r2 pack-objects --rev --stdout >all.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout >all.pack <<-EOF &&
HEAD
EOF
git -C r2 index-pack ../all.pack &&
@@ -142,7 +142,7 @@ test_expect_success 'verify blob count in normal packfile' '
'
test_expect_success 'verify blob:limit=500 omits all blobs' '
- git -C r2 pack-objects --rev --stdout --filter=blob:limit=500 >filter.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=500 >filter.pack <<-EOF &&
HEAD
EOF
git -C r2 index-pack ../filter.pack &&
@@ -157,7 +157,7 @@ test_expect_success 'verify blob:limit=500 omits all blobs' '
'
test_expect_success 'verify blob:limit=1000' '
- git -C r2 pack-objects --rev --stdout --filter=blob:limit=1000 >filter.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=1000 >filter.pack <<-EOF &&
HEAD
EOF
git -C r2 index-pack ../filter.pack &&
@@ -176,7 +176,7 @@ test_expect_success 'verify blob:limit=1001' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r2 pack-objects --rev --stdout --filter=blob:limit=1001 >filter.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=1001 >filter.pack <<-EOF &&
HEAD
EOF
git -C r2 index-pack ../filter.pack &&
@@ -194,7 +194,7 @@ test_expect_success 'verify blob:limit=10001' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r2 pack-objects --rev --stdout --filter=blob:limit=10001 >filter.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=10001 >filter.pack <<-EOF &&
HEAD
EOF
git -C r2 index-pack ../filter.pack &&
@@ -212,7 +212,7 @@ test_expect_success 'verify blob:limit=1k' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r2 pack-objects --rev --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
HEAD
EOF
git -C r2 index-pack ../filter.pack &&
@@ -230,7 +230,7 @@ test_expect_success 'verify explicitly specifying oversized blob in input' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r2 pack-objects --rev --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k >filter.pack <<-EOF &&
HEAD
$(git -C r2 rev-parse HEAD:large.10000)
EOF
@@ -249,7 +249,7 @@ test_expect_success 'verify blob:limit=1m' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r2 pack-objects --rev --stdout --filter=blob:limit=1m >filter.pack <<-EOF &&
+ git -C r2 pack-objects --revs --stdout --filter=blob:limit=1m >filter.pack <<-EOF &&
HEAD
EOF
git -C r2 index-pack ../filter.pack &&
@@ -302,7 +302,7 @@ test_expect_success 'verify blob count in normal packfile' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r3 pack-objects --rev --stdout >all.pack <<-EOF &&
+ git -C r3 pack-objects --revs --stdout >all.pack <<-EOF &&
HEAD
EOF
git -C r3 index-pack ../all.pack &&
@@ -320,7 +320,7 @@ test_expect_success 'verify sparse:path=pattern1' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r3 pack-objects --rev --stdout --filter=sparse:path=../pattern1 >filter.pack <<-EOF &&
+ git -C r3 pack-objects --revs --stdout --filter=sparse:path=../pattern1 >filter.pack <<-EOF &&
HEAD
EOF
git -C r3 index-pack ../filter.pack &&
@@ -352,7 +352,7 @@ test_expect_success 'verify sparse:path=pattern2' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r3 pack-objects --rev --stdout --filter=sparse:path=../pattern2 >filter.pack <<-EOF &&
+ git -C r3 pack-objects --revs --stdout --filter=sparse:path=../pattern2 >filter.pack <<-EOF &&
HEAD
EOF
git -C r3 index-pack ../filter.pack &&
@@ -404,7 +404,7 @@ test_expect_success 'verify blob count in normal packfile' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r4 pack-objects --rev --stdout >all.pack <<-EOF &&
+ git -C r4 pack-objects --revs --stdout >all.pack <<-EOF &&
HEAD
EOF
git -C r4 index-pack ../all.pack &&
@@ -423,7 +423,7 @@ test_expect_success 'verify sparse:oid=OID' '
sort >expected &&
oid=$(git -C r4 ls-files -s pattern | awk -f print_2.awk) &&
- git -C r4 pack-objects --rev --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF &&
+ git -C r4 pack-objects --revs --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF &&
HEAD
EOF
git -C r4 index-pack ../filter.pack &&
@@ -441,7 +441,7 @@ test_expect_success 'verify sparse:oid=oid-ish' '
awk -f print_2.awk ls_files_result |
sort >expected &&
- git -C r4 pack-objects --rev --stdout --filter=sparse:oid=master:pattern >filter.pack <<-EOF &&
+ git -C r4 pack-objects --revs --stdout --filter=sparse:oid=master:pattern >filter.pack <<-EOF &&
HEAD
EOF
git -C r4 index-pack ../filter.pack &&
@@ -470,19 +470,19 @@ test_expect_success 'setup r1 - delete loose blobs' '
'
test_expect_success 'verify pack-objects fails w/ missing objects' '
- test_must_fail git -C r1 pack-objects --rev --stdout >miss.pack <<-EOF
+ test_must_fail git -C r1 pack-objects --revs --stdout >miss.pack <<-EOF
HEAD
EOF
'
test_expect_success 'verify pack-objects fails w/ --missing=error' '
- test_must_fail git -C r1 pack-objects --rev --stdout --missing=error >miss.pack <<-EOF
+ test_must_fail git -C r1 pack-objects --revs --stdout --missing=error >miss.pack <<-EOF
HEAD
EOF
'
test_expect_success 'verify pack-objects w/ --missing=allow-any' '
- git -C r1 pack-objects --rev --stdout --missing=allow-any >miss.pack <<-EOF
+ git -C r1 pack-objects --revs --stdout --missing=allow-any >miss.pack <<-EOF
HEAD
EOF
'
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
index 069e4e28e4..840ad4d8ac 100755
--- a/t/t5318-commit-graph.sh
+++ b/t/t5318-commit-graph.sh
@@ -366,6 +366,26 @@ GRAPH_OCTOPUS_DATA_OFFSET=$(($GRAPH_COMMIT_DATA_OFFSET + \
GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4))
GRAPH_BYTE_FOOTER=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4 * $NUM_OCTOPUS_EDGES))
+corrupt_graph_setup() {
+ cd "$TRASH_DIRECTORY/full" &&
+ test_when_finished mv commit-graph-backup $objdir/info/commit-graph &&
+ cp $objdir/info/commit-graph commit-graph-backup
+}
+
+corrupt_graph_verify() {
+ grepstr=$1
+ test_must_fail git commit-graph verify 2>test_err &&
+ grep -v "^+" test_err >err &&
+ test_i18ngrep "$grepstr" err &&
+ if test "$2" != "no-copy"
+ then
+ cp $objdir/info/commit-graph commit-graph-pre-write-test
+ fi &&
+ git status --short &&
+ GIT_TEST_COMMIT_GRAPH_DIE_ON_LOAD=true git commit-graph write &&
+ git commit-graph verify
+}
+
# usage: corrupt_graph_and_verify <position> <data> <string> [<zero_pos>]
# Manipulates the commit-graph file at the position
# by inserting the data, optionally zeroing the file
@@ -376,19 +396,28 @@ corrupt_graph_and_verify() {
pos=$1
data="${2:-\0}"
grepstr=$3
- cd "$TRASH_DIRECTORY/full" &&
+ corrupt_graph_setup &&
orig_size=$(wc -c < $objdir/info/commit-graph) &&
zero_pos=${4:-${orig_size}} &&
- test_when_finished mv commit-graph-backup $objdir/info/commit-graph &&
- cp $objdir/info/commit-graph commit-graph-backup &&
printf "$data" | dd of="$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc &&
dd of="$objdir/info/commit-graph" bs=1 seek="$zero_pos" if=/dev/null &&
generate_zero_bytes $(($orig_size - $zero_pos)) >>"$objdir/info/commit-graph" &&
- test_must_fail git commit-graph verify 2>test_err &&
- grep -v "^+" test_err >err &&
- test_i18ngrep "$grepstr" err
+ corrupt_graph_verify "$grepstr"
+
}
+test_expect_success POSIXPERM,SANITY 'detect permission problem' '
+ corrupt_graph_setup &&
+ chmod 000 $objdir/info/commit-graph &&
+ corrupt_graph_verify "Could not open" "no-copy"
+'
+
+test_expect_success 'detect too small' '
+ corrupt_graph_setup &&
+ echo "a small graph" >$objdir/info/commit-graph &&
+ corrupt_graph_verify "too small"
+'
+
test_expect_success 'detect bad signature' '
corrupt_graph_and_verify 0 "\0" \
"graph signature"
@@ -499,6 +528,7 @@ test_expect_success 'git fsck (checks commit-graph)' '
git fsck &&
corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \
"incorrect checksum" &&
+ cp commit-graph-pre-write-test $objdir/info/commit-graph &&
test_must_fail git fsck
'
diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh
index 70926b5bc0..1ebf19ec3c 100755
--- a/t/t5319-multi-pack-index.sh
+++ b/t/t5319-multi-pack-index.sh
@@ -86,13 +86,14 @@ test_expect_success 'write midx with one v1 pack' '
'
midx_git_two_modes () {
+ git -c core.multiPackIndex=false $1 >expect &&
+ git -c core.multiPackIndex=true $1 >actual &&
if [ "$2" = "sorted" ]
then
- git -c core.multiPackIndex=false $1 | sort >expect &&
- git -c core.multiPackIndex=true $1 | sort >actual
- else
- git -c core.multiPackIndex=false $1 >expect &&
- git -c core.multiPackIndex=true $1 >actual
+ sort <expect >expect.sorted &&
+ mv expect.sorted expect &&
+ sort <actual >actual.sorted &&
+ mv actual.sorted actual
fi &&
test_cmp expect actual
}
@@ -103,8 +104,8 @@ compare_results_with_midx () {
midx_git_two_modes "rev-list --objects --all" &&
midx_git_two_modes "log --raw" &&
midx_git_two_modes "count-objects --verbose" &&
- midx_git_two_modes "cat-file --batch-all-objects --buffer --batch-check" &&
- midx_git_two_modes "cat-file --batch-all-objects --buffer --batch-check --unsorted" sorted
+ midx_git_two_modes "cat-file --batch-all-objects --batch-check" &&
+ midx_git_two_modes "cat-file --batch-all-objects --batch-check --unordered" sorted
'
}
@@ -116,6 +117,20 @@ test_expect_success 'write midx with one v2 pack' '
compare_results_with_midx "one v2 pack"
+test_expect_success 'corrupt idx not opened' '
+ idx=$(test-tool read-midx $objdir | grep "\.idx\$") &&
+ mv $objdir/pack/$idx backup-$idx &&
+ test_when_finished "mv backup-\$idx \$objdir/pack/\$idx" &&
+
+ # This is the minimum size for a sha-1 based .idx; this lets
+ # us pass perfunctory tests, but anything that actually opens and reads
+ # the idx file will complain.
+ test_copy_bytes 1064 <backup-$idx >$objdir/pack/$idx &&
+
+ git -c core.multiPackIndex=true rev-list --objects --all 2>err &&
+ test_must_be_empty err
+'
+
test_expect_success 'add more objects' '
for i in $(test_seq 6 10)
do
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index a4a5903cba..7344253bfb 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -131,7 +131,7 @@ test_expect_success 'git rebase -m --skip' '
test_expect_success 'git rebase with implicit use of interactive backend' '
git reset --hard D &&
clear_hook_input &&
- test_must_fail git rebase --keep --onto A B &&
+ test_must_fail git rebase --keep-empty --onto A B &&
echo C > foo &&
git add foo &&
git rebase --continue &&
@@ -146,7 +146,7 @@ test_expect_success 'git rebase with implicit use of interactive backend' '
test_expect_success 'git rebase --skip with implicit use of interactive backend' '
git reset --hard D &&
clear_hook_input &&
- test_must_fail git rebase --keep --onto A B &&
+ test_must_fail git rebase --keep-empty --onto A B &&
test_must_fail git rebase --skip &&
echo D > foo &&
git add foo &&
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 0ef4d6f20c..1c71c0ec77 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -920,7 +920,4 @@ test_expect_success 'fetch with --filter=blob:limit=0 and HTTP' '
fetch_filter_blob_limit_zero "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
'
-stop_httpd
-
-
test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index 3b7b30568c..e98d90dd9b 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -978,6 +978,4 @@ test_expect_success '--negotiation-tip limits "have" lines sent with HTTP protoc
check_negotiation_tip
'
-stop_httpd
-
test_done
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 4bfbb79654..c81ca360ac 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -1241,9 +1241,9 @@ do
cd shallow &&
# Some protocol versions (e.g. 2) support fetching
# unadvertised objects, so restrict this test to v0.
- test_must_fail ok=sigpipe env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
git fetch ../testrepo/.git $SHA1_3 &&
- test_must_fail ok=sigpipe env GIT_TEST_PROTOCOL_VERSION= \
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
git fetch ../testrepo/.git $SHA1_1 &&
git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true &&
git fetch ../testrepo/.git $SHA1_1 &&
@@ -1251,8 +1251,9 @@ do
test_must_fail git cat-file commit $SHA1_2 &&
git fetch ../testrepo/.git $SHA1_2 &&
git cat-file commit $SHA1_2 &&
- test_must_fail ok=sigpipe env GIT_TEST_PROTOCOL_VERSION= \
- git fetch ../testrepo/.git $SHA1_3
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ git fetch ../testrepo/.git $SHA1_3 2>err &&
+ test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err
)
'
done
@@ -1284,6 +1285,17 @@ test_expect_success 'fetch follows tags by default' '
test_cmp expect actual
'
+test_expect_success 'peeled advertisements are not considered ref tips' '
+ mk_empty testrepo &&
+ git -C testrepo commit --allow-empty -m one &&
+ git -C testrepo commit --allow-empty -m two &&
+ git -C testrepo tag -m foo mytag HEAD^ &&
+ oid=$(git -C testrepo rev-parse mytag^{commit}) &&
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION= \
+ git fetch testrepo $oid 2>err &&
+ test_i18ngrep "Server does not allow request for unadvertised object" err
+'
+
test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '
mk_test testrepo heads/master &&
rm -fr src dst &&
@@ -1382,7 +1394,7 @@ test_expect_success 'push does not follow tags by default' '
test_cmp expect actual
'
-test_expect_success 'push --follow-tag only pushes relevant tags' '
+test_expect_success 'push --follow-tags only pushes relevant tags' '
mk_test testrepo heads/master &&
rm -fr src dst &&
git init src &&
@@ -1396,7 +1408,7 @@ test_expect_success 'push --follow-tag only pushes relevant tags' '
git tag -m "future" future &&
git checkout master &&
git for-each-ref refs/heads/master refs/tags/tag >../expect &&
- git push --follow-tag ../dst master
+ git push --follow-tags ../dst master
) &&
(
cd dst &&
diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh
index 4f6e32b04c..a1d3031d40 100755
--- a/t/t5530-upload-pack-error.sh
+++ b/t/t5530-upload-pack-error.sh
@@ -57,13 +57,25 @@ test_expect_success 'upload-pack fails due to error in rev-list' '
grep "bad tree object" output.err
'
-test_expect_success 'upload-pack error message when bad ref requested' '
+test_expect_success 'upload-pack fails due to bad want (no object)' '
printf "0045want %s multi_ack_detailed\n00000009done\n0000" \
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" >input &&
test_must_fail git upload-pack . <input >output 2>output.err &&
- grep -q "not our ref" output.err &&
- ! grep -q multi_ack_detailed output.err
+ grep "not our ref" output.err &&
+ grep "ERR" output &&
+ ! grep multi_ack_detailed output.err
+'
+
+test_expect_success 'upload-pack fails due to bad want (not tip)' '
+
+ oid=$(echo an object we have | git hash-object -w --stdin) &&
+ printf "0045want %s multi_ack_detailed\n00000009done\n0000" \
+ "$oid" >input &&
+ test_must_fail git upload-pack . <input >output 2>output.err &&
+ grep "not our ref" output.err &&
+ grep "ERR" output &&
+ ! grep multi_ack_detailed output.err
'
test_expect_success 'upload-pack fails due to error in pack-objects enumeration' '
diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh
index e2c37fd978..4ad059e6be 100755
--- a/t/t5531-deep-submodule-push.sh
+++ b/t/t5531-deep-submodule-push.sh
@@ -363,7 +363,7 @@ test_expect_success 'push succeeds if submodule has no remote and is on the firs
) &&
git add b &&
git commit -m "added submodule" &&
- git push --recurse-submodule=check origin master
+ git push --recurse-submodules=check origin master
)
'
diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh
index 6caf628efa..66f0b64d39 100755
--- a/t/t5537-fetch-shallow.sh
+++ b/t/t5537-fetch-shallow.sh
@@ -255,6 +255,4 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f
git -C client fsck
'
-stop_httpd
-
test_done
diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh
index cdb687b93a..b4ad81f006 100755
--- a/t/t5539-fetch-http-shallow.sh
+++ b/t/t5539-fetch-http-shallow.sh
@@ -149,5 +149,4 @@ test_expect_success 'fetching deepen' '
)
'
-stop_httpd
test_done
diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh
index 88ff5a49e4..a094fd5e71 100755
--- a/t/t5540-http-push-webdav.sh
+++ b/t/t5540-http-push-webdav.sh
@@ -176,6 +176,4 @@ test_expect_failure 'push to password-protected repository (no user in URL)' '
test_cmp expect actual
'
-stop_httpd
-
test_done
diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh
index 0e3055ab98..8ef8763e06 100755
--- a/t/t5541-http-push-smart.sh
+++ b/t/t5541-http-push-smart.sh
@@ -383,5 +383,4 @@ test_expect_success 'colorize errors/hints' '
test_i18ngrep ! "^hint: " decoded
'
-stop_httpd
test_done
diff --git a/t/t5542-push-http-shallow.sh b/t/t5542-push-http-shallow.sh
index 5165833157..ddc1db722d 100755
--- a/t/t5542-push-http-shallow.sh
+++ b/t/t5542-push-http-shallow.sh
@@ -90,5 +90,4 @@ EOF
)
'
-stop_httpd
test_done
diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh
index b47a95871c..6d1d59c9b1 100755
--- a/t/t5545-push-options.sh
+++ b/t/t5545-push-options.sh
@@ -278,6 +278,4 @@ test_expect_success 'push options keep quoted characters intact (http)' '
test_cmp expect "$HTTPD_DOCUMENT_ROOT_PATH"/upstream.git/hooks/pre-receive.push_options
'
-stop_httpd
-
test_done
diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh
index 694b77c855..b811d89cfd 100755
--- a/t/t5550-http-fetch-dumb.sh
+++ b/t/t5550-http-fetch-dumb.sh
@@ -424,5 +424,4 @@ test_expect_success 'fetching via http alternates works' '
git -c http.followredirects=true clone "$HTTPD_URL/dumb/alt-child.git"
'
-stop_httpd
test_done
diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh
index c760514716..ac74626a7b 100755
--- a/t/t5551-http-fetch-smart.sh
+++ b/t/t5551-http-fetch-smart.sh
@@ -469,5 +469,4 @@ test_expect_success 'server-side error detected' '
grep "server-side error" actual
'
-stop_httpd
test_done
diff --git a/t/t5561-http-backend.sh b/t/t5561-http-backend.sh
index 1c49054595..6eb0294978 100755
--- a/t/t5561-http-backend.sh
+++ b/t/t5561-http-backend.sh
@@ -132,5 +132,4 @@ test_expect_success 'server request log matches test results' '
check_access_log exp
'
-stop_httpd
test_done
diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh
index 58ee787685..34487bbb8c 100755
--- a/t/t5570-git-daemon.sh
+++ b/t/t5570-git-daemon.sh
@@ -90,6 +90,7 @@ test_expect_success 'fetch notices corrupt pack' '
test_expect_success 'fetch notices corrupt idx' '
cp -R "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_pack.git "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
(cd "$GIT_DAEMON_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
+ rm -f objects/pack/multi-pack-index &&
p=$(ls objects/pack/pack-*.idx) &&
chmod u+w $p &&
printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
@@ -198,5 +199,4 @@ test_expect_success FAKENC 'hostname interpolation works after LF-stripping' '
test_cmp expect actual
'
-stop_git_daemon
test_done
diff --git a/t/t5581-http-curl-verbose.sh b/t/t5581-http-curl-verbose.sh
index cd9283eeec..5129b0724f 100755
--- a/t/t5581-http-curl-verbose.sh
+++ b/t/t5581-http-curl-verbose.sh
@@ -23,6 +23,4 @@ test_expect_success 'failure in git-upload-pack is shown' '
grep "< HTTP/1.1 500 Intentional Breakage" curl_log
'
-stop_httpd
-
test_done
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index a454b143ea..23854cab26 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -733,6 +733,4 @@ test_expect_success 'partial clone using HTTP' '
partial_clone "$HTTPD_DOCUMENT_ROOT_PATH/server" "$HTTPD_URL/smart/server"
'
-stop_httpd
-
test_done
diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh
index 9643acb161..9a8f9886b3 100755
--- a/t/t5616-partial-clone.sh
+++ b/t/t5616-partial-clone.sh
@@ -331,6 +331,4 @@ test_expect_success 'when partial cloning, tolerate server not sending target of
! test -e "$HTTPD_ROOT_PATH/one-time-sed"
'
-stop_httpd
-
test_done
diff --git a/t/t5700-protocol-v1.sh b/t/t5700-protocol-v1.sh
index d5ed196bfd..7c9511c593 100755
--- a/t/t5700-protocol-v1.sh
+++ b/t/t5700-protocol-v1.sh
@@ -292,6 +292,4 @@ test_expect_success 'push with http:// using protocol v1' '
grep "git< version 1" log
'
-stop_httpd
-
test_done
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index e112b6086c..a089659337 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -687,6 +687,4 @@ test_expect_success 'when server does not send "ready", expect FLUSH' '
test_i18ngrep "expected no other sections to be sent after no .ready." err
'
-stop_httpd
-
test_done
diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index f87b2f6df3..b6a995e857 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -257,8 +257,6 @@ test_expect_success 'server loses a ref - ref in want' '
test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err
'
-stop_httpd
-
REPO="$(pwd)/repo"
LOCAL_PRISTINE="$(pwd)/local_pristine"
diff --git a/t/t5812-proto-disable-http.sh b/t/t5812-proto-disable-http.sh
index 872788ac8c..af8772fada 100755
--- a/t/t5812-proto-disable-http.sh
+++ b/t/t5812-proto-disable-http.sh
@@ -34,5 +34,4 @@ test_expect_success 'http can be limited to from-user' '
clone "$HTTPD_URL/smart-redir-perm/repo.git" redir.git
'
-stop_httpd
test_done
diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh
index 62c564707b..50b7543483 100755
--- a/t/t6043-merge-rename-directories.sh
+++ b/t/t6043-merge-rename-directories.sh
@@ -75,7 +75,7 @@ test_expect_success '1a-check: Simple directory rename detection' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
git ls-files -s >out &&
test_line_count = 4 out &&
@@ -142,7 +142,7 @@ test_expect_success '1b-check: Merge a directory with another' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
@@ -201,7 +201,7 @@ test_expect_success '1c-check: Transitive renaming' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -270,7 +270,7 @@ test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) con
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
git ls-files -s >out &&
@@ -350,7 +350,7 @@ test_expect_success '1e-check: Renamed directory, with all files being renamed t
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -416,7 +416,7 @@ test_expect_success '1f-check: Split a directory into two other directories' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
@@ -497,7 +497,7 @@ test_expect_success '2a-check: Directory split into two on one side, with equal
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT.*directory rename split" out &&
git ls-files -s >out &&
@@ -559,7 +559,7 @@ test_expect_success '2b-check: Directory split into two on one side, with equal
git checkout A^0 &&
- git merge -s recursive B^0 >out &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -640,7 +640,7 @@ test_expect_success '3a-check: Avoid implicit rename if involved as source on ot
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -705,7 +705,7 @@ test_expect_success '3b-check: Avoid implicit rename if involved as source on cu
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out &&
test_i18ngrep ! CONFLICT.*rename/rename.*y/d out &&
@@ -826,7 +826,7 @@ test_expect_success '4a-check: Directory split, with original directory still pr
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 5 out &&
@@ -915,7 +915,7 @@ test_expect_success '5a-check: Merge directories, other side adds files to origi
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT.*implicit dir rename" out &&
git ls-files -s >out &&
@@ -989,7 +989,7 @@ test_expect_success '5b-check: Rename/delete in order to get add/add/add conflic
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (add/add).* y/d" out &&
git ls-files -s >out &&
@@ -1069,7 +1069,7 @@ test_expect_success '5c-check: Transitive rename would cause rename/rename/renam
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*z/d" out &&
test_i18ngrep "CONFLICT (add/add).* y/d" out &&
@@ -1153,7 +1153,7 @@ test_expect_success '5d-check: Directory/file/file conflict due to directory ren
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (file/directory).*y/d" out &&
git ls-files -s >out &&
@@ -1243,7 +1243,7 @@ test_expect_success '6a-check: Tricky rename/delete' '
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*z/c.*y/c" out &&
git ls-files -s >out &&
@@ -1308,7 +1308,7 @@ test_expect_success '6b-check: Same rename done on both sides' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -1370,7 +1370,7 @@ test_expect_success '6c-check: Rename only done on same side' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -1432,7 +1432,7 @@ test_expect_success '6d-check: We do not always want transitive renaming' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -1495,7 +1495,7 @@ test_expect_success '6e-check: Add/add from one side' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
@@ -1591,7 +1591,7 @@ test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename).*z/b.*y/b.*w/b" out &&
test_i18ngrep "CONFLICT (rename/rename).*z/c.*y/c.*x/c" out &&
@@ -1663,7 +1663,7 @@ test_expect_success '7b-check: rename/rename(2to1), but only due to transitive r
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
git ls-files -s >out &&
@@ -1740,7 +1740,7 @@ test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*y/d" out &&
git ls-files -s >out &&
@@ -1804,7 +1804,7 @@ test_expect_success '7d-check: transitive rename involved in rename/delete; how
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
git ls-files -s >out &&
@@ -1894,7 +1894,7 @@ test_expect_success '7e-check: transitive rename in rename/delete AND dirs in th
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
git ls-files -s >out &&
@@ -1985,7 +1985,7 @@ test_expect_success '8a-check: Dual-directory rename, one into the others way' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
@@ -2063,7 +2063,7 @@ test_expect_success '8b-check: Dual-directory rename, one into the others way, w
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
@@ -2135,7 +2135,7 @@ test_expect_success '8c-check: modify/delete or rename+modify/delete' '
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (modify/delete).* z/d" out &&
git ls-files -s >out &&
@@ -2212,7 +2212,7 @@ test_expect_success '8d-check: rename/delete...or not?' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -2287,7 +2287,7 @@ test_expect_success '8e-check: Both sides rename, one side adds to original dire
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep CONFLICT.*rename/rename.*z/c.*y/c.*w/c out &&
test_i18ngrep CONFLICT.*rename/rename.*z/b.*y/b.*w/b out &&
@@ -2374,7 +2374,7 @@ test_expect_success '9a-check: Inner renamed directory within outer renamed dire
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 7 out &&
@@ -2444,7 +2444,7 @@ test_expect_success '9b-check: Transitive rename with content merge' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -2534,7 +2534,7 @@ test_expect_success '9c-check: Doubly transitive rename?' '
git checkout A^0 &&
- git merge -s recursive B^0 >out &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "WARNING: Avoiding applying x -> z rename to x/f" out &&
git ls-files -s >out &&
@@ -2622,7 +2622,7 @@ test_expect_success '9d-check: N-way transitive rename?' '
git checkout A^0 &&
- git merge -s recursive B^0 >out &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "WARNING: Avoiding applying z -> y rename to z/t" out &&
test_i18ngrep "WARNING: Avoiding applying y -> x rename to y/a" out &&
test_i18ngrep "WARNING: Avoiding applying x -> w rename to x/b" out &&
@@ -2704,7 +2704,7 @@ test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' '
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
grep "CONFLICT (implicit dir rename): Cannot map more than one path to combined/yo" out >error_line &&
grep -q dir1/yo error_line &&
grep -q dir2/yo error_line &&
@@ -2782,7 +2782,7 @@ test_expect_success '9f-check: Renamed directory that only contained immediate s
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
@@ -2849,7 +2849,7 @@ test_expect_failure '9g-check: Renamed directory that only contained immediate s
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
@@ -2918,7 +2918,7 @@ test_expect_success '9h-check: Avoid dir rename on merely modified path' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
@@ -2993,7 +2993,7 @@ test_expect_success '10a-check: Overwrite untracked with normal rename/delete' '
echo very >z/c &&
echo important >z/d &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "The following untracked working tree files would be overwritten by merge" err &&
git ls-files -s >out &&
@@ -3061,7 +3061,7 @@ test_expect_success '10b-check: Overwrite untracked with dir rename + delete' '
echo important >y/d &&
echo contents >y/e &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/delete).*Version B\^0 of y/d left in tree at y/d~B\^0" out &&
test_i18ngrep "Error: Refusing to lose untracked file at y/e; writing to y/e~B\^0 instead" out &&
@@ -3137,7 +3137,7 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
git checkout A^0 &&
echo important >y/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~B\^0 instead" out &&
@@ -3174,7 +3174,7 @@ test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)
mkdir y &&
echo important >y/c &&
- test_must_fail git merge -s recursive A^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true 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 &&
@@ -3249,7 +3249,7 @@ test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
git checkout A^0 &&
echo important >y/wham &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose untracked file at y/wham" out &&
@@ -3327,7 +3327,7 @@ test_expect_failure '10e-check: Does git complain about untracked file that is n
mkdir z &&
echo random >z/c &&
- git merge -s recursive B^0 >out 2>err &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep ! "following untracked working tree files would be overwritten by merge" err &&
git ls-files -s >out &&
@@ -3407,7 +3407,7 @@ test_expect_success '11a-check: Avoid losing dirty contents with simple rename'
git checkout A^0 &&
echo stuff >>z/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
test_seq 1 10 >expected &&
@@ -3479,7 +3479,7 @@ test_expect_success '11b-check: Avoid losing dirty file involved in directory re
git checkout A^0 &&
echo stuff >>z/c &&
- git merge -s recursive B^0 >out 2>err &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
grep -q stuff z/c &&
@@ -3554,7 +3554,7 @@ test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conf
git checkout A^0 &&
echo stuff >>y/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "following files would be overwritten by merge" err &&
grep -q stuff y/c &&
@@ -3621,7 +3621,7 @@ test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conf
git checkout A^0 &&
echo stuff >>z/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
grep -q stuff z/c &&
@@ -3700,7 +3700,7 @@ test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rena
git checkout A^0 &&
echo mods >>y/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose dirty file at y/c" out &&
@@ -3782,7 +3782,7 @@ test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rena
git checkout A^0 &&
echo important >>y/wham &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose dirty file at y/wham" out &&
@@ -3870,7 +3870,7 @@ test_expect_success '12a-check: Moving one directory hierarchy into another' '
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
@@ -3910,7 +3910,7 @@ test_expect_success '12a-check: Moving one directory hierarchy into another' '
# To which, I can do no more than shrug my shoulders and say that
# even simple rules give weird results when given weird inputs.
-test_expect_success '12b-setup: Moving one directory hierarchy into another' '
+test_expect_success '12b-setup: Moving two directory hierarchies into each other' '
test_create_repo 12b &&
(
cd 12b &&
@@ -3940,13 +3940,13 @@ test_expect_success '12b-setup: Moving one directory hierarchy into another' '
)
'
-test_expect_success '12b-check: Moving one directory hierarchy into another' '
+test_expect_success '12b-check: Moving two directory hierarchies into each other' '
(
cd 12b &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
@@ -4016,7 +4016,7 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -u >out &&
test_line_count = 12 out &&
@@ -4051,4 +4051,356 @@ test_expect_success '12c-check: Moving one directory hierarchy into another w/ c
)
'
+###########################################################################
+# SECTION 13: Checking informational and conflict messages
+#
+# A year after directory rename detection became the default, it was
+# instead decided to report conflicts on the pathname on the basis that
+# some users may expect the new files added or moved into a directory to
+# be unrelated to all the other files in that directory, and thus that
+# directory rename detection is unexpected. Test that the messages printed
+# match our expectation.
+###########################################################################
+
+# Testcase 13a, Basic directory rename with newly added files
+# Commit O: z/{b,c}
+# Commit A: y/{b,c}
+# Commit B: z/{b,c,d,e/f}
+# Expected: y/{b,c,d,e/f}, with notices/conflicts for both y/d and y/e/f
+
+test_expect_success '13a-setup: messages for newly added files' '
+ test_create_repo 13a &&
+ (
+ cd 13a &&
+
+ mkdir z &&
+ echo b >z/b &&
+ echo c >z/c &&
+ git add z &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv z y &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ echo d >z/d &&
+ mkdir z/e &&
+ echo f >z/e/f &&
+ git add z/d z/e/f &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13a-check(conflict): messages for newly added files' '
+ (
+ cd 13a &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT..file.location.*z/e/f.added.in.B^0.*y/e/f out &&
+ test_i18ngrep CONFLICT..file.location.*z/d.added.in.B^0.*y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/[de]" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d &&
+ test_path_is_missing z/e/f &&
+ test_path_is_file y/e/f
+ )
+'
+
+test_expect_success '13a-check(info): messages for newly added files' '
+ (
+ cd 13a &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep Path.updated:.*z/e/f.added.in.B^0.*y/e/f out &&
+ test_i18ngrep Path.updated:.*z/d.added.in.B^0.*y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/[de]" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d &&
+ test_path_is_missing z/e/f &&
+ test_path_is_file y/e/f
+ )
+'
+
+# Testcase 13b, Transitive rename with conflicted content merge and default
+# "conflict" setting
+# (Related to testcase 1c, 9b)
+# Commit O: z/{b,c}, x/d_1
+# Commit A: y/{b,c}, x/d_2
+# Commit B: z/{b,c,d_3}
+# Expected: y/{b,c,d_merged}, with two conflict messages for y/d,
+# one about content, and one about file location
+
+test_expect_success '13b-setup: messages for transitive rename with conflicted content' '
+ test_create_repo 13b &&
+ (
+ cd 13b &&
+
+ mkdir x &&
+ mkdir z &&
+ test_seq 1 10 >x/d &&
+ echo b >z/b &&
+ echo c >z/c &&
+ git add x z &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv z y &&
+ echo 11 >>x/d &&
+ git add x/d &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ echo eleven >>x/d &&
+ git mv x/d z/d &&
+ git add z/d &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13b-check(conflict): messages for transitive rename with conflicted content' '
+ (
+ cd 13b &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT.*content.*Merge.conflict.in.y/d out &&
+ test_i18ngrep CONFLICT..file.location.*x/d.renamed.to.z/d.*moved.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+test_expect_success '13b-check(info): messages for transitive rename with conflicted content' '
+ (
+ cd 13b &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT.*content.*Merge.conflict.in.y/d out &&
+ test_i18ngrep Path.updated:.*x/d.renamed.to.z/d.in.B^0.*moving.it.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+# Testcase 13c, Rename/rename(1to1) due to directory rename
+# Commit O: z/{b,c}, x/{d,e}
+# Commit A: y/{b,c,d}, x/e
+# Commit B: z/{b,c,d}, x/e
+# Expected: y/{b,c,d}, with info or conflict messages for d (
+# A: renamed x/d -> z/d; B: renamed z/ -> y/ AND renamed x/d to y/d
+# One could argue A had partial knowledge of what was done with
+# d and B had full knowledge, but that's a slippery slope as
+# shown in testcase 13d.
+
+test_expect_success '13c-setup: messages for rename/rename(1to1) via transitive rename' '
+ test_create_repo 13c &&
+ (
+ cd 13c &&
+
+ mkdir x &&
+ mkdir z &&
+ test_seq 1 10 >x/d &&
+ echo e >x/e &&
+ echo b >z/b &&
+ echo c >z/c &&
+ git add x z &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv z y &&
+ git mv x/d y/ &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ git mv x/d z/d &&
+ git add z/d &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13c-check(conflict): messages for rename/rename(1to1) via transitive rename' '
+ (
+ cd 13c &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT..file.location.*x/d.renamed.to.z/d.*moved.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+test_expect_success '13c-check(info): messages for rename/rename(1to1) via transitive rename' '
+ (
+ cd 13c &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep Path.updated:.*x/d.renamed.to.z/d.in.B^0.*moving.it.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+# Testcase 13d, Rename/rename(1to1) due to directory rename on both sides
+# Commit O: a/{z,y}, b/x, c/w
+# Commit A: a/z, b/{y,x}, d/w
+# Commit B: a/z, d/x, c/{y,w}
+# Expected: a/z, d/{y,x,w} with no file location conflict for x
+# Easy cases:
+# * z is always in a; so it stays in a.
+# * x starts in b, only modified on one side to move into d/
+# * w starts in c, only modified on one side to move into d/
+# Hard case:
+# * A renames a/y to b/y, and B renames b/->d/ => a/y -> d/y
+# * B renames a/y to c/y, and A renames c/->d/ => a/y -> d/y
+# No conflict in where a/y ends up, so put it in d/y.
+
+test_expect_success '13d-setup: messages for rename/rename(1to1) via dual transitive rename' '
+ test_create_repo 13d &&
+ (
+ cd 13d &&
+
+ mkdir a &&
+ mkdir b &&
+ mkdir c &&
+ echo z >a/z &&
+ echo y >a/y &&
+ echo x >b/x &&
+ echo w >c/w &&
+ git add a b c &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv a/y b/ &&
+ git mv c/ d/ &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ git mv a/y c/ &&
+ git mv b/ d/ &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13d-check(conflict): messages for rename/rename(1to1) via dual transitive rename' '
+ (
+ cd 13d &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT..file.location.*a/y.renamed.to.b/y.*moved.to.d/y out &&
+ test_i18ngrep CONFLICT..file.location.*a/y.renamed.to.c/y.*moved.to.d/y out &&
+
+ git ls-files >paths &&
+ ! grep b/ paths &&
+ ! grep c/ paths &&
+ grep "d/y" paths &&
+
+ test_path_is_missing b/y &&
+ test_path_is_missing c/y &&
+ test_path_is_file d/y
+ )
+'
+
+test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual transitive rename' '
+ (
+ cd 13d &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep Path.updated.*a/y.renamed.to.b/y.*moving.it.to.d/y out &&
+ test_i18ngrep Path.updated.*a/y.renamed.to.c/y.*moving.it.to.d/y out &&
+
+ git ls-files >paths &&
+ ! grep b/ paths &&
+ ! grep c/ paths &&
+ grep "d/y" paths &&
+
+ test_path_is_missing b/y &&
+ test_path_is_missing c/y &&
+ test_path_is_file d/y
+ )
+'
+
test_done
diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh
index 38e24f787c..3a47623ed3 100755
--- a/t/t6046-merge-skip-unneeded-updates.sh
+++ b/t/t6046-merge-skip-unneeded-updates.sh
@@ -466,7 +466,7 @@ test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
git checkout A^0 &&
- GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+ GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
@@ -495,7 +495,7 @@ test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
git checkout B^0 &&
- GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
+ GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
@@ -560,7 +560,7 @@ test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
git checkout A^0 &&
- GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+ GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
@@ -589,7 +589,7 @@ test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
git checkout B^0 &&
- GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
+ GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
test_i18ngrep ! "Skipped bar/bq" out &&
test_must_be_empty err &&
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index 4684d06552..7411bf7fec 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -120,6 +120,25 @@ test_expect_success 'gc --quiet' '
test_must_be_empty stderr
'
+test_expect_success 'gc.reflogExpire{Unreachable,}=never skips "expire" via "gc"' '
+ test_config gc.reflogExpire never &&
+ test_config gc.reflogExpireUnreachable never &&
+
+ GIT_TRACE=$(pwd)/trace.out git gc &&
+
+ # Check that git-pack-refs is run as a sanity check (done via
+ # gc_before_repack()) but that git-expire is not.
+ grep -E "^trace: (built-in|exec|run_command): git pack-refs --" trace.out &&
+ ! grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out
+'
+
+test_expect_success 'one of gc.reflogExpire{Unreachable,}=never does not skip "expire" via "gc"' '
+ >trace.out &&
+ test_config gc.reflogExpire never &&
+ GIT_TRACE=$(pwd)/trace.out git gc &&
+ grep -E "^trace: (built-in|exec|run_command): git reflog expire --" trace.out
+'
+
run_and_wait_for_auto_gc () {
# We read stdout from gc for the side effect of waiting until the
# background gc process exits, closing its fd 9. Furthermore, the
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 0b01862c23..e285686662 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1700,6 +1700,17 @@ test_expect_success '--points-at finds annotated tags of tags' '
test_cmp expect actual
'
+test_expect_success 'recursive tagging should give advice' '
+ sed -e "s/|$//" <<-EOF >expect &&
+ hint: You have created a nested tag. The object referred to by your new is
+ hint: already a tag. If you meant to tag the object that it points to, use:
+ hint: |
+ hint: git tag -f nested annotated-v4.0^{}
+ EOF
+ git tag -m nested nested annotated-v4.0 2>actual &&
+ test_i18ncmp expect actual
+'
+
test_expect_success 'multiple --points-at are OR-ed together' '
cat >expect <<-\EOF &&
v2.0
diff --git a/t/t7113-post-index-change-hook.sh b/t/t7113-post-index-change-hook.sh
new file mode 100755
index 0000000000..f011ad7eec
--- /dev/null
+++ b/t/t7113-post-index-change-hook.sh
@@ -0,0 +1,144 @@
+#!/bin/sh
+
+test_description='post index change hook'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ mkdir -p dir1 &&
+ touch dir1/file1.txt &&
+ echo testing >dir1/file2.txt &&
+ git add . &&
+ git commit -m "initial"
+'
+
+test_expect_success 'test status, add, commit, others trigger hook without flags set' '
+ mkdir -p .git/hooks &&
+ write_script .git/hooks/post-index-change <<-\EOF &&
+ if test "$1" -eq 1; then
+ echo "Invalid combination of flags passed to hook; updated_workdir is set." >testfailure
+ exit 1
+ fi
+ if test "$2" -eq 1; then
+ echo "Invalid combination of flags passed to hook; updated_skipworktree is set." >testfailure
+ exit 1
+ fi
+ if test -f ".git/index.lock"; then
+ echo ".git/index.lock exists" >testfailure
+ exit 3
+ fi
+ if ! test -f ".git/index"; then
+ echo ".git/index does not exist" >testfailure
+ exit 3
+ fi
+ echo "success" >testsuccess
+ EOF
+ mkdir -p dir2 &&
+ touch dir2/file1.txt &&
+ touch dir2/file2.txt &&
+ : force index to be dirty &&
+ test-tool chmtime +60 dir1/file1.txt &&
+ git status &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ git add . &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ git commit -m "second" &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ git checkout -- dir1/file1.txt &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ git update-index &&
+ test_path_is_missing testsuccess &&
+ test_path_is_missing testfailure &&
+ git reset --soft &&
+ test_path_is_missing testsuccess &&
+ test_path_is_missing testfailure
+'
+
+test_expect_success 'test checkout and reset trigger the hook' '
+ write_script .git/hooks/post-index-change <<-\EOF &&
+ if test "$1" -eq 1 && test "$2" -eq 1; then
+ echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
+ exit 1
+ fi
+ if test "$1" -eq 0 && test "$2" -eq 0; then
+ echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
+ exit 2
+ fi
+ if test "$1" -eq 1; then
+ if test -f ".git/index.lock"; then
+ echo "updated_workdir set but .git/index.lock exists" >testfailure
+ exit 3
+ fi
+ if ! test -f ".git/index"; then
+ echo "updated_workdir set but .git/index does not exist" >testfailure
+ exit 3
+ fi
+ else
+ echo "update_workdir should be set for checkout" >testfailure
+ exit 4
+ fi
+ echo "success" >testsuccess
+ EOF
+ : force index to be dirty &&
+ test-tool chmtime +60 dir1/file1.txt &&
+ git checkout master &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ test-tool chmtime +60 dir1/file1.txt &&
+ git checkout HEAD &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ test-tool chmtime +60 dir1/file1.txt &&
+ git reset --hard &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ git checkout -B test &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure
+'
+
+test_expect_success 'test reset --mixed and update-index triggers the hook' '
+ write_script .git/hooks/post-index-change <<-\EOF &&
+ if test "$1" -eq 1 && test "$2" -eq 1; then
+ echo "Invalid combination of flags passed to hook; updated_workdir and updated_skipworktree are both set." >testfailure
+ exit 1
+ fi
+ if test "$1" -eq 0 && test "$2" -eq 0; then
+ echo "Invalid combination of flags passed to hook; neither updated_workdir or updated_skipworktree are set." >testfailure
+ exit 2
+ fi
+ if test "$2" -eq 1; then
+ if test -f ".git/index.lock"; then
+ echo "updated_skipworktree set but .git/index.lock exists" >testfailure
+ exit 3
+ fi
+ if ! test -f ".git/index"; then
+ echo "updated_skipworktree set but .git/index does not exist" >testfailure
+ exit 3
+ fi
+ else
+ echo "updated_skipworktree should be set for reset --mixed and update-index" >testfailure
+ exit 4
+ fi
+ echo "success" >testsuccess
+ EOF
+ : force index to be dirty &&
+ test-tool chmtime +60 dir1/file1.txt &&
+ git reset --mixed --quiet HEAD~1 &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ git hash-object -w --stdin <dir1/file2.txt >expect &&
+ git update-index --cacheinfo 100644 "$(cat expect)" dir1/file1.txt &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure &&
+ git update-index --skip-worktree dir1/file2.txt &&
+ git update-index --remove dir1/file2.txt &&
+ test_path_is_file testsuccess && rm -f testsuccess &&
+ test_path_is_missing testfailure
+'
+
+test_done
diff --git a/t/t7201-co.sh b/t/t7201-co.sh
index 72b9b375ba..5990299fc9 100755
--- a/t/t7201-co.sh
+++ b/t/t7201-co.sh
@@ -223,13 +223,8 @@ test_expect_success 'switch to another branch while carrying a deletion' '
test_must_fail git checkout simple 2>errs &&
test_i18ngrep overwritten errs &&
- git checkout --merge simple 2>errs &&
- test_i18ngrep ! overwritten errs &&
- git ls-files -u &&
- test_must_fail git cat-file -t :0:two &&
- test "$(git cat-file -t :1:two)" = blob &&
- test "$(git cat-file -t :2:two)" = blob &&
- test_must_fail git cat-file -t :3:two
+ test_must_fail git read-tree --quiet -m -u HEAD simple 2>errs &&
+ test_must_be_empty errs
'
test_expect_success 'checkout to detach HEAD (with advice declined)' '
diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh
index aba2d4d6ee..a208cb26e1 100755
--- a/t/t7400-submodule-basic.sh
+++ b/t/t7400-submodule-basic.sh
@@ -46,6 +46,15 @@ test_expect_success 'submodule update aborts on missing gitmodules url' '
test_must_fail git submodule init
'
+test_expect_success 'add aborts on repository with no commits' '
+ cat >expect <<-\EOF &&
+ '"'repo-no-commits'"' does not have a commit checked out
+ EOF
+ git init repo-no-commits &&
+ test_must_fail git submodule add ../a ./repo-no-commits 2>actual &&
+ test_i18ncmp expect actual
+'
+
test_expect_success 'setup - repository in init subdirectory' '
mkdir init &&
(
@@ -809,7 +818,7 @@ test_expect_success '../bar/a/b/c works with relative local path - ../foo/bar.gi
cp pristine-.git-config .git/config &&
cp pristine-.gitmodules .gitmodules &&
mkdir -p a/b/c &&
- (cd a/b/c && git init) &&
+ (cd a/b/c && git init && test_commit msg) &&
git config remote.origin.url ../foo/bar.git &&
git submodule add ../bar/a/b/c ./a/b/c &&
git submodule init &&
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 77729ac4aa..706ae762e0 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -411,4 +411,14 @@ test_expect_success 'multi-argument command passed to foreach is not shell-evalu
test_cmp expected actual
'
+test_expect_success 'option-like arguments passed to foreach commands are not lost' '
+ (
+ cd super &&
+ git submodule foreach "echo be --quiet" > ../expected &&
+ git submodule foreach echo be --quiet > ../actual
+ ) &&
+ grep -sq -e "--quiet" expected &&
+ test_cmp expected actual
+'
+
test_done
diff --git a/t/t7411-submodule-config.sh b/t/t7411-submodule-config.sh
index 89690b7adb..fcc0fb82d8 100755
--- a/t/t7411-submodule-config.sh
+++ b/t/t7411-submodule-config.sh
@@ -142,6 +142,15 @@ test_expect_success 'reading submodules config from the working tree with "submo
)
'
+test_expect_success 'unsetting submodules config from the working tree with "submodule--helper config --unset"' '
+ (cd super &&
+ git submodule--helper config --unset submodule.submodule.url &&
+ git submodule--helper config submodule.submodule.url >actual &&
+ test_must_be_empty actual
+ )
+'
+
+
test_expect_success 'writing submodules config with "submodule--helper config"' '
(cd super &&
echo "new_url" >expect &&
diff --git a/t/t7419-submodule-set-branch.sh b/t/t7419-submodule-set-branch.sh
new file mode 100755
index 0000000000..c4b370ea85
--- /dev/null
+++ b/t/t7419-submodule-set-branch.sh
@@ -0,0 +1,93 @@
+#!/bin/sh
+#
+# Copyright (c) 2019 Denton Liu
+#
+
+test_description='Test submodules set-branch subcommand
+
+This test verifies that the set-branch subcommand of git-submodule is working
+as expected.
+'
+
+TEST_NO_CREATE_REPO=1
+. ./test-lib.sh
+
+test_expect_success 'submodule config cache setup' '
+ mkdir submodule &&
+ (cd submodule &&
+ git init &&
+ echo a >a &&
+ git add . &&
+ git commit -ma &&
+ git checkout -b topic &&
+ echo b >a &&
+ git add . &&
+ git commit -mb
+ ) &&
+ mkdir super &&
+ (cd super &&
+ git init &&
+ git submodule add ../submodule &&
+ git commit -m "add submodule"
+ )
+'
+
+test_expect_success 'ensure submodule branch is unset' '
+ (cd super &&
+ test_must_fail grep branch .gitmodules
+ )
+'
+
+test_expect_success 'test submodule set-branch --branch' '
+ (cd super &&
+ git submodule set-branch --branch topic submodule &&
+ grep "branch = topic" .gitmodules &&
+ git submodule update --remote &&
+ cat <<-\EOF >expect &&
+ b
+ EOF
+ git -C submodule show -s --pretty=%s >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'test submodule set-branch --default' '
+ (cd super &&
+ git submodule set-branch --default submodule &&
+ test_must_fail grep branch .gitmodules &&
+ git submodule update --remote &&
+ cat <<-\EOF >expect &&
+ a
+ EOF
+ git -C submodule show -s --pretty=%s >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'test submodule set-branch -b' '
+ (cd super &&
+ git submodule set-branch -b topic submodule &&
+ grep "branch = topic" .gitmodules &&
+ git submodule update --remote &&
+ cat <<-\EOF >expect &&
+ b
+ EOF
+ git -C submodule show -s --pretty=%s >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_expect_success 'test submodule set-branch -d' '
+ (cd super &&
+ git submodule set-branch -d submodule &&
+ test_must_fail grep branch .gitmodules &&
+ git submodule update --remote &&
+ cat <<-\EOF >expect &&
+ a
+ EOF
+ git -C submodule show -s --pretty=%s >actual &&
+ test_cmp expect actual
+ )
+'
+
+test_done
diff --git a/t/t7525-status-rename.sh b/t/t7525-status-rename.sh
index ef8b1b3078..a62736dce0 100755
--- a/t/t7525-status-rename.sh
+++ b/t/t7525-status-rename.sh
@@ -84,7 +84,7 @@ test_expect_success 'status score=100%' '
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual &&
- git status --find-rename=100% >actual &&
+ git status --find-renames=100% >actual &&
test_i18ngrep "deleted:" actual &&
test_i18ngrep "new file:" actual
'
@@ -93,11 +93,11 @@ test_expect_success 'status score=01%' '
git status -M=01% >actual &&
test_i18ngrep "renamed:" actual &&
- git status --find-rename=01% >actual &&
+ git status --find-renames=01% >actual &&
test_i18ngrep "renamed:" actual
'
-test_expect_success 'copies not overridden by find-rename' '
+test_expect_success 'copies not overridden by find-renames' '
cp renamed copy &&
git add copy &&
@@ -105,7 +105,7 @@ test_expect_success 'copies not overridden by find-rename' '
test_i18ngrep "copied:" actual &&
test_i18ngrep "renamed:" actual &&
- git -c status.renames=copies status --find-rename=01% >actual &&
+ git -c status.renames=copies status --find-renames=01% >actual &&
test_i18ngrep "copied:" actual &&
test_i18ngrep "renamed:" actual
'
diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh
index bb9a7f4ff9..480dd0633f 100755
--- a/t/t7800-difftool.sh
+++ b/t/t7800-difftool.sh
@@ -705,4 +705,14 @@ test_expect_success SYMLINKS 'difftool --dir-diff handles modified symlinks' '
test_cmp expect actual
'
+test_expect_success 'outside worktree' '
+ echo 1 >1 &&
+ echo 2 >2 &&
+ test_expect_code 1 nongit git \
+ -c diff.tool=echo -c difftool.echo.cmd="echo \$LOCAL \$REMOTE" \
+ difftool --no-prompt --no-index ../1 ../2 >actual &&
+ echo "../1 ../2" >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 43aa4161cf..2e1bb61b41 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -119,33 +119,33 @@ do
test_cmp expected actual
'
- test_expect_success "grep -w $L (with --column, --invert)" '
+ test_expect_success "grep -w $L (with --column, --invert-match)" '
{
echo ${HC}file:1:foo mmap bar
echo ${HC}file:1:foo_mmap bar
echo ${HC}file:1:foo_mmap bar mmap
echo ${HC}file:1:foo mmap bar_mmap
} >expected &&
- git grep --column --invert -w -e baz $H -- file >actual &&
+ git grep --column --invert-match -w -e baz $H -- file >actual &&
test_cmp expected actual
'
- test_expect_success "grep $L (with --column, --invert, extended OR)" '
+ test_expect_success "grep $L (with --column, --invert-match, extended OR)" '
{
echo ${HC}hello_world:6:HeLLo_world
} >expected &&
- git grep --column --invert -e ll --or --not -e _ $H -- hello_world \
+ git grep --column --invert-match -e ll --or --not -e _ $H -- hello_world \
>actual &&
test_cmp expected actual
'
- test_expect_success "grep $L (with --column, --invert, extended AND)" '
+ test_expect_success "grep $L (with --column, --invert-match, extended AND)" '
{
echo ${HC}hello_world:3:Hello world
echo ${HC}hello_world:3:Hello_world
echo ${HC}hello_world:6:HeLLo_world
} >expected &&
- git grep --column --invert --not -e _ --and --not -e ll $H -- hello_world \
+ git grep --column --invert-match --not -e _ --and --not -e ll $H -- hello_world \
>actual &&
test_cmp expected actual
'
@@ -1010,7 +1010,7 @@ test_expect_success 'outside of git repository' '
echo ".gitignore:.*o*" &&
cat ../expect.full
} >../expect.with.ignored &&
- git grep --no-index --no-exclude o >../actual.full &&
+ git grep --no-index --no-exclude-standard o >../actual.full &&
test_cmp ../expect.with.ignored ../actual.full
)
'
@@ -1051,7 +1051,7 @@ test_expect_success 'outside of git repository with fallbackToNoIndex' '
echo ".gitignore:.*o*" &&
cat ../expect.full
} >../expect.with.ignored &&
- git -c grep.fallbackToNoIndex grep --no-exclude o >../actual.full &&
+ git -c grep.fallbackToNoIndex grep --no-exclude-standard o >../actual.full &&
test_cmp ../expect.with.ignored ../actual.full
)
'
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index ee1efcc59d..1e3ac3c384 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -481,6 +481,20 @@ test_expect_success $PREREQ 'long lines with auto encoding are quoted-printable'
grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
'
+test_expect_success $PREREQ 'carriage returns with auto encoding are quoted-printable' '
+ clean_fake_sendmail &&
+ cp $patches cr.patch &&
+ printf "this is a line\r\n" >>cr.patch &&
+ git send-email \
+ --from="Example <nobody@example.com>" \
+ --to=nobody@example.com \
+ --smtp-server="$(pwd)/fake.sendmail" \
+ --transfer-encoding=auto \
+ --no-validate \
+ cr.patch &&
+ grep "Content-Transfer-Encoding: quoted-printable" msgtxt1
+'
+
for enc in auto quoted-printable base64
do
test_expect_success $PREREQ "--validate passes with encoding $enc" '
diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh
index 64bb495834..9b44a44bc1 100755
--- a/t/t9115-git-svn-dcommit-funky-renames.sh
+++ b/t/t9115-git-svn-dcommit-funky-renames.sh
@@ -120,6 +120,4 @@ test_expect_success !MINGW,!UTF8_NFD_TO_NFC 'svn.pathnameencoding=cp932 rename o
git svn dcommit
'
-stop_httpd
-
test_done
diff --git a/t/t9118-git-svn-funky-branch-names.sh b/t/t9118-git-svn-funky-branch-names.sh
index 41a026637f..a159ff96b7 100755
--- a/t/t9118-git-svn-funky-branch-names.sh
+++ b/t/t9118-git-svn-funky-branch-names.sh
@@ -87,6 +87,4 @@ test_expect_success 'test dcommit to trailing_dotlock branch' '
)
'
-stop_httpd
-
test_done
diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh
index b28a1741e3..40b714df31 100755
--- a/t/t9120-git-svn-clone-with-percent-escapes.sh
+++ b/t/t9120-git-svn-clone-with-percent-escapes.sh
@@ -74,6 +74,4 @@ test_expect_success 'test clone -s with unescaped space' '
)
'
-stop_httpd
-
test_done
diff --git a/t/t9142-git-svn-shallow-clone.sh b/t/t9142-git-svn-shallow-clone.sh
index 9ee23be640..a30730502d 100755
--- a/t/t9142-git-svn-shallow-clone.sh
+++ b/t/t9142-git-svn-shallow-clone.sh
@@ -26,6 +26,4 @@ test_expect_success 'clone trunk with "-r HEAD"' '
( cd g && git rev-parse --symbolic --verify HEAD )
'
-stop_httpd
-
test_done
diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh
index 59a13b6a77..3668263c40 100755
--- a/t/t9300-fast-import.sh
+++ b/t/t9300-fast-import.sh
@@ -3262,4 +3262,41 @@ test_expect_success PIPE 'V: checkpoint updates tags after tag' '
background_import_still_running
'
+###
+### series W (get-mark and empty orphan commits)
+###
+
+cat >>W-input <<-W_INPUT_END
+ commit refs/heads/W-branch
+ mark :1
+ author Full Name <user@company.tld> 1000000000 +0100
+ committer Full Name <user@company.tld> 1000000000 +0100
+ data 27
+ Intentionally empty commit
+ LFsget-mark :1
+ W_INPUT_END
+
+test_expect_success !MINGW 'W: get-mark & empty orphan commit with no newlines' '
+ sed -e s/LFs// W-input | tr L "\n" | git fast-import
+'
+
+test_expect_success !MINGW 'W: get-mark & empty orphan commit with one newline' '
+ sed -e s/LFs/L/ W-input | tr L "\n" | git fast-import
+'
+
+test_expect_success !MINGW 'W: get-mark & empty orphan commit with ugly second newline' '
+ # Technically, this should fail as it has too many linefeeds
+ # according to the grammar in fast-import.txt. But, for whatever
+ # reason, it works. Since using the correct number of newlines
+ # does not work with older (pre-2.22) versions of git, allow apps
+ # that used this second-newline workaround to keep working by
+ # checking it with this test...
+ sed -e s/LFs/LL/ W-input | tr L "\n" | git fast-import
+'
+
+test_expect_success !MINGW 'W: get-mark & empty orphan commit with erroneous third newline' '
+ # ...but do NOT allow more empty lines than that (see previous test).
+ sed -e s/LFs/LLL/ W-input | tr L "\n" | test_must_fail git fast-import
+'
+
test_done
diff --git a/t/t9800-git-p4-basic.sh b/t/t9800-git-p4-basic.sh
index 729cd25770..5856563068 100755
--- a/t/t9800-git-p4-basic.sh
+++ b/t/t9800-git-p4-basic.sh
@@ -326,8 +326,4 @@ test_expect_success 'submit from worktree' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9801-git-p4-branch.sh b/t/t9801-git-p4-branch.sh
index 6a86d6996b..38d6b9043b 100755
--- a/t/t9801-git-p4-branch.sh
+++ b/t/t9801-git-p4-branch.sh
@@ -151,7 +151,7 @@ test_expect_success 'import depot, branch detection, branchList branch definitio
'
test_expect_success 'restart p4d' '
- kill_p4d &&
+ stop_and_cleanup_p4d &&
start_p4d
'
@@ -505,7 +505,7 @@ test_expect_success 'use-client-spec detect-branches skips files in branches' '
'
test_expect_success 'restart p4d' '
- kill_p4d &&
+ stop_and_cleanup_p4d &&
start_p4d
'
@@ -610,8 +610,4 @@ test_expect_success 'Update a file in git side and submit to P4 using client vie
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh
index 9978352d78..94edebe272 100755
--- a/t/t9802-git-p4-filetype.sh
+++ b/t/t9802-git-p4-filetype.sh
@@ -333,8 +333,4 @@ test_expect_success SYMLINKS 'empty symlink target' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9803-git-p4-shell-metachars.sh b/t/t9803-git-p4-shell-metachars.sh
index d5c3675100..2913277013 100755
--- a/t/t9803-git-p4-shell-metachars.sh
+++ b/t/t9803-git-p4-shell-metachars.sh
@@ -105,8 +105,4 @@ test_expect_success 'branch with shell char' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9804-git-p4-label.sh b/t/t9804-git-p4-label.sh
index e30f80e617..3236457106 100755
--- a/t/t9804-git-p4-label.sh
+++ b/t/t9804-git-p4-label.sh
@@ -108,8 +108,4 @@ test_expect_failure 'two labels on the same changelist' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9805-git-p4-skip-submit-edit.sh b/t/t9805-git-p4-skip-submit-edit.sh
index 5fbf904dc8..90ef647db7 100755
--- a/t/t9805-git-p4-skip-submit-edit.sh
+++ b/t/t9805-git-p4-skip-submit-edit.sh
@@ -98,8 +98,4 @@ test_expect_success 'no config, edited' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9806-git-p4-options.sh b/t/t9806-git-p4-options.sh
index 3f5291b857..4e794a01bf 100755
--- a/t/t9806-git-p4-options.sh
+++ b/t/t9806-git-p4-options.sh
@@ -300,9 +300,4 @@ test_expect_success 'use --git-dir option and GIT_DIR' '
test_path_is_file "$git"/cli_file2.t
'
-
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh
index 850d979119..eaaae414a1 100755
--- a/t/t9807-git-p4-submit.sh
+++ b/t/t9807-git-p4-submit.sh
@@ -593,8 +593,4 @@ test_expect_success 'update a shelve involving moved and copied files' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9808-git-p4-chdir.sh b/t/t9808-git-p4-chdir.sh
index 11d2b5102c..58a9b3b71e 100755
--- a/t/t9808-git-p4-chdir.sh
+++ b/t/t9808-git-p4-chdir.sh
@@ -83,8 +83,4 @@ test_expect_success SYMLINKS 'p4 client root symlink should stay symbolic' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh
index 897b3c3034..3cff1fce1b 100755
--- a/t/t9809-git-p4-client-view.sh
+++ b/t/t9809-git-p4-client-view.sh
@@ -836,8 +836,4 @@ test_expect_success 'quotes on both sides' '
git_verify "cdir 1/file11" "cdir 1/file12"
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9810-git-p4-rcs.sh b/t/t9810-git-p4-rcs.sh
index cc53debe19..57b533dc6f 100755
--- a/t/t9810-git-p4-rcs.sh
+++ b/t/t9810-git-p4-rcs.sh
@@ -360,8 +360,4 @@ test_expect_failure 'Add keywords in git which do not match the default p4 value
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9811-git-p4-label-import.sh b/t/t9811-git-p4-label-import.sh
index 602b0a5d5c..c1446f26ab 100755
--- a/t/t9811-git-p4-label-import.sh
+++ b/t/t9811-git-p4-label-import.sh
@@ -191,7 +191,7 @@ test_expect_success 'tag that cannot be exported' '
(
cd "$cli" &&
p4 sync ... &&
- !(p4 labels | grep GIT_TAG_ON_A_BRANCH)
+ ! p4 labels | grep GIT_TAG_ON_A_BRANCH
)
'
@@ -259,9 +259,4 @@ test_expect_success 'importing labels with missing revisions' '
)
'
-
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9812-git-p4-wildcards.sh b/t/t9812-git-p4-wildcards.sh
index 0206771fbb..254a7c2446 100755
--- a/t/t9812-git-p4-wildcards.sh
+++ b/t/t9812-git-p4-wildcards.sh
@@ -211,8 +211,4 @@ test_expect_success 'wildcard files requiring keyword scrub' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9813-git-p4-preserve-users.sh b/t/t9813-git-p4-preserve-users.sh
index 783c6ad165..fd018c87a8 100755
--- a/t/t9813-git-p4-preserve-users.sh
+++ b/t/t9813-git-p4-preserve-users.sh
@@ -138,8 +138,4 @@ test_expect_success 'not preserving user with mixed authorship' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9814-git-p4-rename.sh b/t/t9814-git-p4-rename.sh
index 60baa06e27..468767cbf4 100755
--- a/t/t9814-git-p4-rename.sh
+++ b/t/t9814-git-p4-rename.sh
@@ -242,8 +242,4 @@ test_expect_success P4D_HAVE_CONFIGURABLE_RUN_MOVE_ALLOW \
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9815-git-p4-submit-fail.sh b/t/t9815-git-p4-submit-fail.sh
index eaf03a6563..9779dc0d11 100755
--- a/t/t9815-git-p4-submit-fail.sh
+++ b/t/t9815-git-p4-submit-fail.sh
@@ -422,8 +422,4 @@ test_expect_success 'cleanup chmod after submit cancel' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9816-git-p4-locked.sh b/t/t9816-git-p4-locked.sh
index d048bd33fa..932841003c 100755
--- a/t/t9816-git-p4-locked.sh
+++ b/t/t9816-git-p4-locked.sh
@@ -138,8 +138,4 @@ test_expect_failure 'move with lock taken' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9817-git-p4-exclude.sh b/t/t9817-git-p4-exclude.sh
index aac568eadf..96d25f0c02 100755
--- a/t/t9817-git-p4-exclude.sh
+++ b/t/t9817-git-p4-exclude.sh
@@ -64,8 +64,4 @@ test_expect_success 'clone, then sync with exclude' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9818-git-p4-block.sh b/t/t9818-git-p4-block.sh
index ce7cb22ad3..0db7ab9918 100755
--- a/t/t9818-git-p4-block.sh
+++ b/t/t9818-git-p4-block.sh
@@ -146,8 +146,4 @@ test_expect_success 'Clone repo with self-sizing block size' '
test_line_count \> 10 log
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9819-git-p4-case-folding.sh b/t/t9819-git-p4-case-folding.sh
index d808c008c1..600ce1e0b0 100755
--- a/t/t9819-git-p4-case-folding.sh
+++ b/t/t9819-git-p4-case-folding.sh
@@ -53,8 +53,4 @@ test_expect_failure 'Clone UC repo with lc name' '
test_must_fail git p4 clone //depot/uc/...
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9820-git-p4-editor-handling.sh b/t/t9820-git-p4-editor-handling.sh
index 3c22f74bd4..fa1bba1dd9 100755
--- a/t/t9820-git-p4-editor-handling.sh
+++ b/t/t9820-git-p4-editor-handling.sh
@@ -31,8 +31,4 @@ test_expect_success 'EDITOR with options' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9821-git-p4-path-variations.sh b/t/t9821-git-p4-path-variations.sh
index 81e46acfa8..ef80f1690b 100755
--- a/t/t9821-git-p4-path-variations.sh
+++ b/t/t9821-git-p4-path-variations.sh
@@ -193,8 +193,4 @@ test_expect_success 'Add a new file and clone path with new file (ignorecase)' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9822-git-p4-path-encoding.sh b/t/t9822-git-p4-path-encoding.sh
index c78477c19b..572d395498 100755
--- a/t/t9822-git-p4-path-encoding.sh
+++ b/t/t9822-git-p4-path-encoding.sh
@@ -7,6 +7,13 @@ test_description='Clone repositories with non ASCII paths'
UTF8_ESCAPED="a-\303\244_o-\303\266_u-\303\274.txt"
ISO8859_ESCAPED="a-\344_o-\366_u-\374.txt"
+ISO8859="$(printf "$ISO8859_ESCAPED")" &&
+echo content123 >"$ISO8859" &&
+rm "$ISO8859" || {
+ skip_all="fs does not accept ISO-8859-1 filenames"
+ test_done
+}
+
test_expect_success 'start p4d' '
start_p4d
'
@@ -67,8 +74,4 @@ test_expect_success 'Delete iso8859-1 encoded paths and clone' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9823-git-p4-mock-lfs.sh b/t/t9823-git-p4-mock-lfs.sh
index 1f2dc369bf..88b76dc4d6 100755
--- a/t/t9823-git-p4-mock-lfs.sh
+++ b/t/t9823-git-p4-mock-lfs.sh
@@ -185,8 +185,4 @@ test_expect_success 'Run git p4 submit in repo configured with large file system
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9824-git-p4-git-lfs.sh b/t/t9824-git-p4-git-lfs.sh
index ed80ca858c..a28dbbdd56 100755
--- a/t/t9824-git-p4-git-lfs.sh
+++ b/t/t9824-git-p4-git-lfs.sh
@@ -287,8 +287,4 @@ test_expect_success 'Add big files to repo and store files in LFS based on compr
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9825-git-p4-handle-utf16-without-bom.sh b/t/t9825-git-p4-handle-utf16-without-bom.sh
index 1551845dc1..f049ff8229 100755
--- a/t/t9825-git-p4-handle-utf16-without-bom.sh
+++ b/t/t9825-git-p4-handle-utf16-without-bom.sh
@@ -43,8 +43,4 @@ test_expect_failure 'clone depot with invalid UTF-16 file in non-verbose mode' '
git p4 clone --dest="$git" //depot
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9826-git-p4-keep-empty-commits.sh b/t/t9826-git-p4-keep-empty-commits.sh
index fa8b9daf1f..fd64afe064 100755
--- a/t/t9826-git-p4-keep-empty-commits.sh
+++ b/t/t9826-git-p4-keep-empty-commits.sh
@@ -127,8 +127,4 @@ test_expect_success 'Clone repo subdir with all history' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9827-git-p4-change-filetype.sh b/t/t9827-git-p4-change-filetype.sh
index 7433998f47..d3670bd7a2 100755
--- a/t/t9827-git-p4-change-filetype.sh
+++ b/t/t9827-git-p4-change-filetype.sh
@@ -59,8 +59,4 @@ test_expect_success SYMLINKS 'change symbolic link to file' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9828-git-p4-map-user.sh b/t/t9828-git-p4-map-user.sh
index e20395c89f..ca6c2942bd 100755
--- a/t/t9828-git-p4-map-user.sh
+++ b/t/t9828-git-p4-map-user.sh
@@ -54,8 +54,4 @@ test_expect_success 'Clone repo root path with all history' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9829-git-p4-jobs.sh b/t/t9829-git-p4-jobs.sh
index 971aeeea1f..88cfb1fcd3 100755
--- a/t/t9829-git-p4-jobs.sh
+++ b/t/t9829-git-p4-jobs.sh
@@ -92,8 +92,4 @@ test_expect_success 'check log message of changelist with more jobs' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9830-git-p4-symlink-dir.sh b/t/t9830-git-p4-symlink-dir.sh
index 2ad1b0810d..3fb6960c18 100755
--- a/t/t9830-git-p4-symlink-dir.sh
+++ b/t/t9830-git-p4-symlink-dir.sh
@@ -36,8 +36,4 @@ test_expect_success 'symlinked directory' '
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9831-git-p4-triggers.sh b/t/t9831-git-p4-triggers.sh
index be44c9751a..d743ca33ee 100755
--- a/t/t9831-git-p4-triggers.sh
+++ b/t/t9831-git-p4-triggers.sh
@@ -96,8 +96,4 @@ test_expect_success 'submit description with extra info lines from verbose p4 ch
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
test_done
diff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh
index 41c09f11f4..1286a5b824 100755
--- a/t/t9832-unshelve.sh
+++ b/t/t9832-unshelve.sh
@@ -174,8 +174,5 @@ test_expect_success 'unshelve specifying the origin' '
test_path_is_file file_to_shelve
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
test_done
diff --git a/t/t9833-errors.sh b/t/t9833-errors.sh
index 47b312e1c9..e22369ccdf 100755
--- a/t/t9833-errors.sh
+++ b/t/t9833-errors.sh
@@ -45,9 +45,4 @@ test_expect_success 'ticket logged out' '
)
'
-test_expect_success 'kill p4d' '
- kill_p4d
-'
-
-
test_done
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index 681c41ba32..788ea1f18b 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -943,6 +943,34 @@ test_when_finished () {
} && (exit \"\$eval_ret\"); eval_ret=\$?; $test_cleanup"
}
+# This function can be used to schedule some commands to be run
+# unconditionally at the end of the test script, e.g. to stop a daemon:
+#
+# test_expect_success 'test git daemon' '
+# git daemon &
+# daemon_pid=$! &&
+# test_atexit 'kill $daemon_pid' &&
+# hello world
+# '
+#
+# The commands will be executed before the trash directory is removed,
+# i.e. the atexit commands will still be able to access any pidfiles or
+# socket files.
+#
+# Note that these commands will be run even when a test script run
+# with '--immediate' fails. Be careful with your atexit commands to
+# minimize any changes to the failed state.
+
+test_atexit () {
+ # We cannot detect when we are in a subshell in general, but by
+ # 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_atexit does nothing in a subshell"
+ test_atexit_cleanup="{ $*
+ } && (exit \"\$eval_ret\"); eval_ret=\$?; $test_atexit_cleanup"
+}
+
# Most tests can use the created repository, but some may need to create more.
# Usage: test_create_repo <directory>
test_create_repo () {
diff --git a/t/test-lib.sh b/t/test-lib.sh
index 562c57e685..908ddb9c46 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -57,6 +57,13 @@ fi
. "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS
export PERL_PATH SHELL_PATH
+# Disallow the use of abbreviated options in the test suite by default
+if test -z "${GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS}"
+then
+ GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS=true
+ export GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS
+fi
+
################################################################
# It appears that people try to run tests without building...
"${GIT_TEST_INSTALLED:-$GIT_BUILD_DIR}/git$X" >/dev/null
@@ -379,6 +386,7 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
my @env = keys %ENV;
my $ok = join("|", qw(
TRACE
+ TR2_
DEBUG
TEST
.*_TEST
@@ -627,6 +635,10 @@ test_external_has_tap=0
die () {
code=$?
+ # This is responsible for running the atexit commands even when a
+ # test script run with '--immediate' fails, or when the user hits
+ # ctrl-C, i.e. when 'test_done' is not invoked at all.
+ test_atexit_handler || code=$?
if test -n "$GIT_EXIT_OK"
then
exit $code
@@ -638,7 +650,10 @@ die () {
GIT_EXIT_OK=
trap 'die' EXIT
-trap 'exit $?' INT TERM HUP
+# Disable '-x' tracing, because with some shells, notably dash, it
+# prevents running the cleanup commands when a test script run with
+# '--verbose-log -x' is interrupted.
+trap '{ code=$?; set +x; } 2>/dev/null; exit $code' INT TERM HUP
# The user-facing functions are loaded from a separate file so that
# test_perf subshells can have them too
@@ -1049,9 +1064,28 @@ write_junit_xml_testcase () {
junit_have_testcase=t
}
+test_atexit_cleanup=:
+test_atexit_handler () {
+ # In a succeeding test script 'test_atexit_handler' is invoked
+ # twice: first from 'test_done', then from 'die' in the trap on
+ # EXIT.
+ # This condition and resetting 'test_atexit_cleanup' below makes
+ # sure that the registered cleanup commands are run only once.
+ test : != "$test_atexit_cleanup" || return 0
+
+ setup_malloc_check
+ test_eval_ "$test_atexit_cleanup"
+ test_atexit_cleanup=:
+ teardown_malloc_check
+}
+
test_done () {
GIT_EXIT_OK=t
+ # Run the atexit commands _before_ the trash directory is
+ # removed, so the commands can access pidfiles and socket files.
+ test_atexit_handler
+
if test -n "$write_junit_xml" && test -n "$junit_xml_path"
then
test -n "$junit_have_testcase" || {
@@ -1405,6 +1439,7 @@ 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
+ export GIT_TEST_GETTEXT_POISON
unset GIT_TEST_GETTEXT_POISON_ORIG
fi