summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/README20
-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
-rw-r--r--t/helper/test-serve-v2.c31
-rw-r--r--t/helper/test-tool.c20
-rw-r--r--t/helper/test-tool.h1
-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/perf/p5302-pack-index.sh31
-rwxr-xr-xt/perf/p5310-pack-bitmaps.sh3
-rwxr-xr-xt/perf/p5311-pack-bitmaps-fetch.sh1
-rwxr-xr-xt/perf/p5600-partial-clone.sh26
-rwxr-xr-xt/t0000-basic.sh18
-rwxr-xr-xt/t0210-trace2-normal.sh64
-rwxr-xr-xt/t0211-trace2-perf.sh43
-rwxr-xr-xt/t0212-trace2-event.sh42
-rwxr-xr-xt/t0301-credential-cache.sh7
-rwxr-xr-xt/t0410-partial-clone.sh2
-rwxr-xr-xt/t1007-hash-object.sh4
-rwxr-xr-xt/t1410-reflog.sh25
-rwxr-xr-xt/t1450-fsck.sh4
-rwxr-xr-xt/t3000-ls-files-others.sh2
-rwxr-xr-xt/t3009-ls-files-others-nonsubmodule.sh50
-rwxr-xr-xt/t3200-branch.sh24
-rwxr-xr-xt/t3301-notes.sh5
-rwxr-xr-xt/t3401-rebase-and-am-rename.sh8
-rwxr-xr-xt/t3507-cherry-pick-conflict.sh152
-rwxr-xr-xt/t3511-cherry-pick-x.sh20
-rwxr-xr-xt/t3700-add.sh12
-rwxr-xr-xt/t4053-diff-no-index.sh3
-rwxr-xr-xt/t4067-diff-partial-clone.sh103
-rwxr-xr-xt/t5304-prune.sh8
-rwxr-xr-xt/t5310-pack-bitmaps.sh5
-rwxr-xr-xt/t5318-commit-graph.sh42
-rwxr-xr-xt/t5319-multi-pack-index.sh29
-rwxr-xr-xt/t5500-fetch-pack.sh3
-rwxr-xr-xt/t5510-fetch.sh2
-rwxr-xr-xt/t5516-fetch-push.sh20
-rwxr-xr-xt/t5521-pull-options.sh8
-rwxr-xr-xt/t5530-upload-pack-error.sh18
-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.sh6
-rwxr-xr-xt/t5616-partial-clone.sh2
-rwxr-xr-xt/t5700-protocol-v1.sh2
-rwxr-xr-xt/t5701-git-serve.sh32
-rwxr-xr-xt/t5702-protocol-v2.sh48
-rwxr-xr-xt/t5703-upload-pack-ref-in-want.sh18
-rwxr-xr-xt/t5801-remote-helpers.sh2
-rwxr-xr-xt/t5801/git-remote-testgit147
-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/t6050-replace.sh31
-rwxr-xr-xt/t6102-rev-list-unexpected-objects.sh127
-rwxr-xr-xt/t6300-for-each-ref.sh13
-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/t7502-commit-porcelain.sh93
-rwxr-xr-xt/t7600-merge.sh73
-rwxr-xr-xt/t7604-merge-custom-message.sh75
-rwxr-xr-xt/t7700-repack.sh19
-rwxr-xr-xt/t7800-difftool.sh10
-rwxr-xr-xt/t7814-grep-recurse-submodules.sh6
-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.sh34
-rw-r--r--t/test-lib.sh30
128 files changed, 2238 insertions, 523 deletions
diff --git a/t/README b/t/README
index af1243eb49..6404f33e19 100644
--- a/t/README
+++ b/t/README
@@ -871,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/helper/test-serve-v2.c b/t/helper/test-serve-v2.c
new file mode 100644
index 0000000000..aee35e5aef
--- /dev/null
+++ b/t/helper/test-serve-v2.c
@@ -0,0 +1,31 @@
+#include "test-tool.h"
+#include "cache.h"
+#include "parse-options.h"
+#include "serve.h"
+
+static char const * const serve_usage[] = {
+ N_("test-tool serve-v2 [<options>]"),
+ NULL
+};
+
+int cmd__serve_v2(int argc, const char **argv)
+{
+ struct serve_options opts = SERVE_OPTIONS_INIT;
+
+ struct option options[] = {
+ OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc,
+ N_("quit after a single request/response exchange")),
+ OPT_BOOL(0, "advertise-capabilities", &opts.advertise_capabilities,
+ N_("exit immediately after advertising capabilities")),
+ OPT_END()
+ };
+ const char *prefix = setup_git_directory();
+
+ /* ignore all unknown cmdline switches for now */
+ argc = parse_options(argc, argv, prefix, options, serve_usage,
+ PARSE_OPT_KEEP_DASHDASH |
+ PARSE_OPT_KEEP_UNKNOWN);
+ serve(&opts);
+
+ return 0;
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 53c06932c4..087a8c0cc9 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -1,6 +1,12 @@
#include "git-compat-util.h"
#include "test-tool.h"
#include "trace2.h"
+#include "parse-options.h"
+
+static const char * const test_tool_usage[] = {
+ "test-tool [-C <directory>] <command [<arguments>...]]",
+ NULL
+};
struct test_cmd {
const char *name;
@@ -43,6 +49,7 @@ static struct test_cmd cmds[] = {
{ "revision-walking", cmd__revision_walking },
{ "run-command", cmd__run_command },
{ "scrap-cache-tree", cmd__scrap_cache_tree },
+ { "serve-v2", cmd__serve_v2 },
{ "sha1", cmd__sha1 },
{ "sha1-array", cmd__sha1_array },
{ "sha256", cmd__sha256 },
@@ -75,11 +82,24 @@ static NORETURN void die_usage(void)
int cmd_main(int argc, const char **argv)
{
int i;
+ const char *working_directory = NULL;
+ struct option options[] = {
+ OPT_STRING('C', NULL, &working_directory, "directory",
+ "change the working directory"),
+ OPT_END()
+ };
BUG_exit_code = 99;
+ argc = parse_options(argc, argv, NULL, options, test_tool_usage,
+ PARSE_OPT_STOP_AT_NON_OPTION |
+ PARSE_OPT_KEEP_ARGV0);
+
if (argc < 2)
die_usage();
+ if (working_directory && chdir(working_directory) < 0)
+ die("Could not cd to '%s'", working_directory);
+
for (i = 0; i < ARRAY_SIZE(cmds); i++) {
if (!strcmp(cmds[i].name, argv[1])) {
argv++;
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index ffab4d19d7..7e703f3038 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -39,6 +39,7 @@ int cmd__repository(int argc, const char **argv);
int cmd__revision_walking(int argc, const char **argv);
int cmd__run_command(int argc, const char **argv);
int cmd__scrap_cache_tree(int argc, const char **argv);
+int cmd__serve_v2(int argc, const char **argv);
int cmd__sha1(int argc, const char **argv);
int cmd__sha1_array(int argc, const char **argv);
int cmd__sha256(int argc, const char **argv);
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/perf/p5302-pack-index.sh b/t/perf/p5302-pack-index.sh
index 99bdb16c85..a9b3e112d9 100755
--- a/t/perf/p5302-pack-index.sh
+++ b/t/perf/p5302-pack-index.sh
@@ -13,35 +13,40 @@ test_expect_success 'repack' '
export PACK
'
-test_expect_success 'create target repositories' '
- for repo in t1 t2 t3 t4 t5 t6
- do
- git init --bare $repo
- done
-'
-
test_perf 'index-pack 0 threads' '
- GIT_DIR=t1 git index-pack --threads=1 --stdin < $PACK
+ rm -rf repo.git &&
+ git init --bare repo.git &&
+ GIT_DIR=repo.git git index-pack --threads=1 --stdin < $PACK
'
test_perf 'index-pack 1 thread ' '
- GIT_DIR=t2 GIT_FORCE_THREADS=1 git index-pack --threads=1 --stdin < $PACK
+ rm -rf repo.git &&
+ git init --bare repo.git &&
+ GIT_DIR=repo.git GIT_FORCE_THREADS=1 git index-pack --threads=1 --stdin < $PACK
'
test_perf 'index-pack 2 threads' '
- GIT_DIR=t3 git index-pack --threads=2 --stdin < $PACK
+ rm -rf repo.git &&
+ git init --bare repo.git &&
+ GIT_DIR=repo.git git index-pack --threads=2 --stdin < $PACK
'
test_perf 'index-pack 4 threads' '
- GIT_DIR=t4 git index-pack --threads=4 --stdin < $PACK
+ rm -rf repo.git &&
+ git init --bare repo.git &&
+ GIT_DIR=repo.git git index-pack --threads=4 --stdin < $PACK
'
test_perf 'index-pack 8 threads' '
- GIT_DIR=t5 git index-pack --threads=8 --stdin < $PACK
+ rm -rf repo.git &&
+ git init --bare repo.git &&
+ GIT_DIR=repo.git git index-pack --threads=8 --stdin < $PACK
'
test_perf 'index-pack default number of threads' '
- GIT_DIR=t6 git index-pack --stdin < $PACK
+ rm -rf repo.git &&
+ git init --bare repo.git &&
+ GIT_DIR=repo.git git index-pack --stdin < $PACK
'
test_done
diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh
index bb91dbb173..6a3a42531b 100755
--- a/t/perf/p5310-pack-bitmaps.sh
+++ b/t/perf/p5310-pack-bitmaps.sh
@@ -12,8 +12,7 @@ test_perf_large_repo
# We intentionally use the deprecated pack.writebitmaps
# config so that we can test against older versions of git.
test_expect_success 'setup bitmap config' '
- git config pack.writebitmaps true &&
- git config pack.writebitmaphashcache true
+ git config pack.writebitmaps true
'
test_perf 'repack to disk' '
diff --git a/t/perf/p5311-pack-bitmaps-fetch.sh b/t/perf/p5311-pack-bitmaps-fetch.sh
index b04575951f..47c3fd7581 100755
--- a/t/perf/p5311-pack-bitmaps-fetch.sh
+++ b/t/perf/p5311-pack-bitmaps-fetch.sh
@@ -7,7 +7,6 @@ test_perf_default_repo
test_expect_success 'create bitmapped server repo' '
git config pack.writebitmaps true &&
- git config pack.writebitmaphashcache true &&
git repack -ad
'
diff --git a/t/perf/p5600-partial-clone.sh b/t/perf/p5600-partial-clone.sh
new file mode 100755
index 0000000000..3e04bd2ae1
--- /dev/null
+++ b/t/perf/p5600-partial-clone.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+test_description='performance of partial clones'
+. ./perf-lib.sh
+
+test_perf_default_repo
+
+test_expect_success 'enable server-side config' '
+ git config uploadpack.allowFilter true &&
+ git config uploadpack.allowAnySHA1InWant true
+'
+
+test_perf 'clone without blobs' '
+ rm -rf bare.git &&
+ git clone --no-local --bare --filter=blob:none . bare.git
+'
+
+test_perf 'checkout of result' '
+ rm -rf worktree &&
+ mkdir -p worktree/.git &&
+ tar -C bare.git -cf - . | tar -C worktree/.git -xf - &&
+ git -C worktree config core.bare false &&
+ git -C worktree checkout -f
+'
+
+test_done
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/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh
index 03a0aedb1d..71194a3623 100755
--- a/t/t0210-trace2-normal.sh
+++ b/t/t0210-trace2-normal.sh
@@ -3,6 +3,11 @@
test_description='test trace2 facility (normal target)'
. ./test-lib.sh
+# Turn off any inherited trace2 settings for this test.
+sane_unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
+sane_unset GIT_TR2_BRIEF
+sane_unset GIT_TR2_CONFIG_PARAMS
+
# Add t/helper directory to PATH so that we can use a relative
# path to run nested instances of test-tool.exe (see 004child).
# This helps with HEREDOC comparisons later.
@@ -15,11 +20,6 @@ PATH="$TTDIR:$PATH" && export PATH
# Warning: So you may see extra lines in artifact files when
# Warning: interactively debugging.
-# Turn off any inherited trace2 settings for this test.
-unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
-unset GIT_TR2_BRIEF
-unset GIT_TR2_CONFIG_PARAMS
-
V=$(git version | sed -e 's/^git version //') && export V
# There are multiple trace2 targets: normal, perf, and event.
@@ -80,6 +80,21 @@ test_expect_success 'normal stream, return code 1' '
test_cmp expect actual
'
+test_expect_success 'automatic filename' '
+ test_when_finished "rm -r traces actual expect" &&
+ mkdir traces &&
+ GIT_TR2="$(pwd)/traces" test-tool trace2 001return 0 &&
+ perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <"$(ls traces/*)" >actual &&
+ cat >expect <<-EOF &&
+ version $V
+ start _EXE_ trace2 001return 0
+ cmd_name trace2 (trace2)
+ exit elapsed:_TIME_ code:0
+ atexit elapsed:_TIME_ code:0
+ EOF
+ test_cmp expect actual
+'
+
# Verb 002exit
#
# Explicit exit(code) from within cmd_<verb> propagates <code>.
@@ -132,4 +147,43 @@ test_expect_success 'normal stream, error event' '
test_cmp expect actual
'
+sane_unset GIT_TR2_BRIEF
+
+# Now test without environment variables and get all Trace2 settings
+# from the global config.
+
+test_expect_success 'using global config, normal stream, return code 0' '
+ test_when_finished "rm trace.normal actual expect" &&
+ test_config_global trace2.normalBrief 1 &&
+ test_config_global trace2.normalTarget "$(pwd)/trace.normal" &&
+ test-tool trace2 001return 0 &&
+ perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual &&
+ cat >expect <<-EOF &&
+ version $V
+ start _EXE_ trace2 001return 0
+ cmd_name trace2 (trace2)
+ exit elapsed:_TIME_ code:0
+ atexit elapsed:_TIME_ code:0
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'using global config with include' '
+ test_when_finished "rm trace.normal actual expect real.gitconfig" &&
+ test_config_global trace2.normalBrief 1 &&
+ test_config_global trace2.normalTarget "$(pwd)/trace.normal" &&
+ mv "$(pwd)/.gitconfig" "$(pwd)/real.gitconfig" &&
+ test_config_global include.path "$(pwd)/real.gitconfig" &&
+ test-tool trace2 001return 0 &&
+ perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual &&
+ cat >expect <<-EOF &&
+ version $V
+ start _EXE_ trace2 001return 0
+ cmd_name trace2 (trace2)
+ exit elapsed:_TIME_ code:0
+ atexit elapsed:_TIME_ code:0
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh
index 953e2f7847..b501e867af 100755
--- a/t/t0211-trace2-perf.sh
+++ b/t/t0211-trace2-perf.sh
@@ -3,6 +3,11 @@
test_description='test trace2 facility (perf target)'
. ./test-lib.sh
+# Turn off any inherited trace2 settings for this test.
+sane_unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
+sane_unset GIT_TR2_PERF_BRIEF
+sane_unset GIT_TR2_CONFIG_PARAMS
+
# Add t/helper directory to PATH so that we can use a relative
# path to run nested instances of test-tool.exe (see 004child).
# This helps with HEREDOC comparisons later.
@@ -15,11 +20,6 @@ PATH="$TTDIR:$PATH" && export PATH
# Warning: So you may see extra lines in artifact files when
# Warning: interactively debugging.
-# Turn off any inherited trace2 settings for this test.
-unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
-unset GIT_TR2_PERF_BRIEF
-unset GIT_TR2_CONFIG_PARAMS
-
V=$(git version | sed -e 's/^git version //') && export V
# There are multiple trace2 targets: normal, perf, and event.
@@ -50,7 +50,7 @@ test_expect_success 'perf stream, return code 0' '
perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
cat >expect <<-EOF &&
d0|main|version|||||$V
- d0|main|start|||||_EXE_ trace2 001return 0
+ d0|main|start||_T_ABS_|||_EXE_ trace2 001return 0
d0|main|cmd_name|||||trace2 (trace2)
d0|main|exit||_T_ABS_|||code:0
d0|main|atexit||_T_ABS_|||code:0
@@ -64,7 +64,7 @@ test_expect_success 'perf stream, return code 1' '
perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
cat >expect <<-EOF &&
d0|main|version|||||$V
- d0|main|start|||||_EXE_ trace2 001return 1
+ d0|main|start||_T_ABS_|||_EXE_ trace2 001return 1
d0|main|cmd_name|||||trace2 (trace2)
d0|main|exit||_T_ABS_|||code:1
d0|main|atexit||_T_ABS_|||code:1
@@ -82,7 +82,7 @@ test_expect_success 'perf stream, error event' '
perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
cat >expect <<-EOF &&
d0|main|version|||||$V
- d0|main|start|||||_EXE_ trace2 003error '\''hello world'\'' '\''this is a test'\''
+ d0|main|start||_T_ABS_|||_EXE_ trace2 003error '\''hello world'\'' '\''this is a test'\''
d0|main|cmd_name|||||trace2 (trace2)
d0|main|error|||||hello world
d0|main|error|||||this is a test
@@ -128,15 +128,15 @@ test_expect_success 'perf stream, child processes' '
perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
cat >expect <<-EOF &&
d0|main|version|||||$V
- d0|main|start|||||_EXE_ trace2 004child test-tool trace2 004child test-tool trace2 001return 0
+ d0|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 004child test-tool trace2 001return 0
d0|main|cmd_name|||||trace2 (trace2)
d0|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 004child test-tool trace2 001return 0
d1|main|version|||||$V
- d1|main|start|||||_EXE_ trace2 004child test-tool trace2 001return 0
+ d1|main|start||_T_ABS_|||_EXE_ trace2 004child test-tool trace2 001return 0
d1|main|cmd_name|||||trace2 (trace2/trace2)
d1|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 001return 0
d2|main|version|||||$V
- d2|main|start|||||_EXE_ trace2 001return 0
+ d2|main|start||_T_ABS_|||_EXE_ trace2 001return 0
d2|main|cmd_name|||||trace2 (trace2/trace2/trace2)
d2|main|exit||_T_ABS_|||code:0
d2|main|atexit||_T_ABS_|||code:0
@@ -150,4 +150,25 @@ test_expect_success 'perf stream, child processes' '
test_cmp expect actual
'
+sane_unset GIT_TR2_PERF_BRIEF
+
+# Now test without environment variables and get all Trace2 settings
+# from the global config.
+
+test_expect_success 'using global config, perf stream, return code 0' '
+ test_when_finished "rm trace.perf actual expect" &&
+ test_config_global trace2.perfBrief 1 &&
+ test_config_global trace2.perfTarget "$(pwd)/trace.perf" &&
+ test-tool trace2 001return 0 &&
+ perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual &&
+ cat >expect <<-EOF &&
+ d0|main|version|||||$V
+ d0|main|start||_T_ABS_|||_EXE_ trace2 001return 0
+ d0|main|cmd_name|||||trace2 (trace2)
+ d0|main|exit||_T_ABS_|||code:0
+ d0|main|atexit||_T_ABS_|||code:0
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh
index 028b6c5671..59adae8123 100755
--- a/t/t0212-trace2-event.sh
+++ b/t/t0212-trace2-event.sh
@@ -3,6 +3,11 @@
test_description='test trace2 facility'
. ./test-lib.sh
+# Turn off any inherited trace2 settings for this test.
+sane_unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
+sane_unset GIT_TR2_BARE
+sane_unset GIT_TR2_CONFIG_PARAMS
+
perl -MJSON::PP -e 0 >/dev/null 2>&1 && test_set_prereq JSON_PP
# Add t/helper directory to PATH so that we can use a relative
@@ -17,11 +22,6 @@ PATH="$TTDIR:$PATH" && export PATH
# Warning: So you may see extra lines in artifact files when
# Warning: interactively debugging.
-# Turn off any inherited trace2 settings for this test.
-unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT
-unset GIT_TR2_BARE
-unset GIT_TR2_CONFIG_PARAMS
-
V=$(git version | sed -e 's/^git version //') && export V
# There are multiple trace2 targets: normal, perf, and event.
@@ -233,4 +233,36 @@ test_expect_success JSON_PP 'basic trace2_data' '
test_cmp expect actual
'
+# Now test without environment variables and get all Trace2 settings
+# from the global config.
+
+test_expect_success JSON_PP 'using global config, event stream, error event' '
+ test_when_finished "rm trace.event actual expect" &&
+ test_config_global trace2.eventTarget "$(pwd)/trace.event" &&
+ test-tool trace2 003error "hello world" "this is a test" &&
+ perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual &&
+ sed -e "s/^|//" >expect <<-EOF &&
+ |VAR1 = {
+ | "_SID0_":{
+ | "argv":[
+ | "_EXE_",
+ | "trace2",
+ | "003error",
+ | "hello world",
+ | "this is a test"
+ | ],
+ | "errors":[
+ | "%s",
+ | "%s"
+ | ],
+ | "exit_code":0,
+ | "hierarchy":"trace2",
+ | "name":"trace2",
+ | "version":"$V"
+ | }
+ |};
+ EOF
+ test_cmp expect actual
+'
+
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/t1007-hash-object.sh b/t/t1007-hash-object.sh
index a37753047e..7099d33508 100755
--- a/t/t1007-hash-object.sh
+++ b/t/t1007-hash-object.sh
@@ -199,10 +199,6 @@ test_expect_success 'too-short tree' '
test_i18ngrep "too-short tree object" err
'
-hex2oct() {
- perl -ne 'printf "\\%03o", hex for /../g'
-}
-
test_expect_success 'malformed mode in tree' '
hex_sha1=$(echo foo | git hash-object --stdin -w) &&
bin_sha1=$(echo $hex_sha1 | hex2oct) &&
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/t1450-fsck.sh b/t/t1450-fsck.sh
index 49f08d5b9c..0f268a3664 100755
--- a/t/t1450-fsck.sh
+++ b/t/t1450-fsck.sh
@@ -256,10 +256,6 @@ test_expect_success 'unparseable tree object' '
test_i18ngrep ! "fatal: empty filename in tree entry" out
'
-hex2oct() {
- perl -ne 'printf "\\%03o", hex for /../g'
-}
-
test_expect_success 'tree entry with type mismatch' '
test_when_finished "remove_object \$blob" &&
test_when_finished "remove_object \$tree" &&
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/t3200-branch.sh b/t/t3200-branch.sh
index 478b82cf9b..e9ad50b66d 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -264,6 +264,30 @@ test_expect_success 'git branch --list -d t should fail' '
test_must_fail git rev-parse refs/heads/t
'
+test_expect_success 'deleting checked-out branch from repo that is a submodule' '
+ test_when_finished "rm -rf repo1 repo2" &&
+
+ git init repo1 &&
+ git init repo1/sub &&
+ test_commit -C repo1/sub x &&
+ git -C repo1 submodule add ./sub &&
+ git -C repo1 commit -m "adding sub" &&
+
+ git clone --recurse-submodules repo1 repo2 &&
+ git -C repo2/sub checkout -b work &&
+ test_must_fail git -C repo2/sub branch -D work
+'
+
+test_expect_success 'bare main worktree has HEAD at branch deleted by secondary worktree' '
+ test_when_finished "rm -rf nonbare base secondary" &&
+
+ git init nonbare &&
+ test_commit -C nonbare x &&
+ git clone --bare nonbare bare &&
+ git -C bare worktree add --detach ../secondary master &&
+ git -C secondary branch -D master
+'
+
test_expect_success 'git branch --list -v with --abbrev' '
test_when_finished "git branch -D t" &&
git branch t &&
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/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 0db166152a..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
'
@@ -88,7 +93,7 @@ test_expect_success 'cherry-pick --no-commit does not set CHERRY_PICK_HEAD' '
test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
pristine_detach initial &&
- echo foo > foo &&
+ echo foo >foo &&
test_must_fail git cherry-pick base &&
test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
'
@@ -96,7 +101,7 @@ test_expect_success 'cherry-pick w/dirty tree does not set CHERRY_PICK_HEAD' '
test_expect_success \
'cherry-pick --strategy=resolve w/dirty tree does not set CHERRY_PICK_HEAD' '
pristine_detach initial &&
- echo foo > foo &&
+ echo foo >foo &&
test_must_fail git cherry-pick --strategy=resolve base &&
test_must_fail git rev-parse --verify CHERRY_PICK_HEAD
'
@@ -175,23 +180,63 @@ test_expect_success 'failed cherry-pick registers participants in index' '
git ls-files --stage foo &&
git checkout picked -- foo &&
git ls-files --stage foo
- } > stages &&
+ } >stages &&
sed "
1 s/ 0 / 1 /
2 s/ 0 / 2 /
3 s/ 0 / 3 /
- " < stages > expected &&
+ " stages >expected &&
git read-tree -u --reset HEAD &&
test_must_fail git cherry-pick picked &&
- git ls-files --stage --unmerged > actual &&
+ git ls-files --stage --unmerged >actual &&
test_cmp expected actual
'
+test_expect_success \
+ 'cherry-pick conflict, ensure commit.cleanup = scissors places scissors line properly' '
+ pristine_detach initial &&
+ git config commit.cleanup scissors &&
+ cat <<-EOF >expected &&
+ picked
+
+ # ------------------------ >8 ------------------------
+ # Do not modify or remove the line above.
+ # Everything below it will be ignored.
+ #
+ # Conflicts:
+ # foo
+ EOF
+
+ test_must_fail git cherry-pick picked &&
+
+ test_i18ncmp expected .git/MERGE_MSG
+'
+
+test_expect_success \
+ 'cherry-pick conflict, ensure cleanup=scissors places scissors line properly' '
+ pristine_detach initial &&
+ git config --unset commit.cleanup &&
+ cat <<-EOF >expected &&
+ picked
+
+ # ------------------------ >8 ------------------------
+ # Do not modify or remove the line above.
+ # Everything below it will be ignored.
+ #
+ # Conflicts:
+ # foo
+ EOF
+
+ test_must_fail git cherry-pick --cleanup=scissors picked &&
+
+ test_i18ncmp expected .git/MERGE_MSG
+'
+
test_expect_success 'failed cherry-pick describes conflict in work tree' '
pristine_detach initial &&
- cat <<-EOF > expected &&
+ cat <<-EOF >expected &&
<<<<<<< HEAD
a
=======
@@ -201,14 +246,14 @@ test_expect_success 'failed cherry-pick describes conflict in work tree' '
test_must_fail git cherry-pick picked &&
- sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
test_cmp expected actual
'
test_expect_success 'diff3 -m style' '
pristine_detach initial &&
git config merge.conflictstyle diff3 &&
- cat <<-EOF > expected &&
+ cat <<-EOF >expected &&
<<<<<<< HEAD
a
||||||| parent of objid picked
@@ -220,14 +265,14 @@ test_expect_success 'diff3 -m style' '
test_must_fail git cherry-pick picked &&
- sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
test_cmp expected actual
'
test_expect_success 'revert also handles conflicts sanely' '
git config --unset merge.conflictstyle &&
pristine_detach initial &&
- cat <<-EOF > expected &&
+ cat <<-EOF >expected &&
<<<<<<< HEAD
a
=======
@@ -241,24 +286,24 @@ test_expect_success 'revert also handles conflicts sanely' '
git ls-files --stage foo &&
git checkout base -- foo &&
git ls-files --stage foo
- } > stages &&
+ } >stages &&
sed "
1 s/ 0 / 1 /
2 s/ 0 / 2 /
3 s/ 0 / 3 /
- " < stages > expected-stages &&
+ " stages >expected-stages &&
git read-tree -u --reset HEAD &&
head=$(git rev-parse HEAD) &&
test_must_fail git revert picked &&
newhead=$(git rev-parse HEAD) &&
- git ls-files --stage --unmerged > actual-stages &&
+ git ls-files --stage --unmerged >actual-stages &&
test "$head" = "$newhead" &&
test_must_fail git update-index --refresh -q &&
test_must_fail git diff-index --exit-code HEAD &&
test_cmp expected-stages actual-stages &&
- sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
test_cmp expected actual
'
@@ -284,7 +329,7 @@ test_expect_success 'revert --no-commit sets REVERT_HEAD' '
test_expect_success 'revert w/dirty tree does not set REVERT_HEAD' '
pristine_detach base &&
- echo foo > foo &&
+ echo foo >foo &&
test_must_fail git revert base &&
test_must_fail git rev-parse --verify CHERRY_PICK_HEAD &&
test_must_fail git rev-parse --verify REVERT_HEAD
@@ -319,7 +364,7 @@ test_expect_success 'failed commit does not clear REVERT_HEAD' '
test_expect_success 'revert conflict, diff3 -m style' '
pristine_detach initial &&
git config merge.conflictstyle diff3 &&
- cat <<-EOF > expected &&
+ cat <<-EOF >expected &&
<<<<<<< HEAD
a
||||||| objid picked
@@ -331,10 +376,56 @@ test_expect_success 'revert conflict, diff3 -m style' '
test_must_fail git revert picked &&
- sed "s/[a-f0-9]*\.\.\./objid/" foo > actual &&
+ sed "s/[a-f0-9]*\.\.\./objid/" foo >actual &&
test_cmp expected actual
'
+test_expect_success \
+ 'revert conflict, ensure commit.cleanup = scissors places scissors line properly' '
+ pristine_detach initial &&
+ git config commit.cleanup scissors &&
+ cat >expected <<-EOF &&
+ Revert "picked"
+
+ This reverts commit OBJID.
+
+ # ------------------------ >8 ------------------------
+ # Do not modify or remove the line above.
+ # Everything below it will be ignored.
+ #
+ # Conflicts:
+ # foo
+ EOF
+
+ test_must_fail git revert picked &&
+
+ sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
+ test_i18ncmp expected actual
+'
+
+test_expect_success \
+ 'revert conflict, ensure cleanup=scissors places scissors line properly' '
+ pristine_detach initial &&
+ git config --unset commit.cleanup &&
+ cat >expected <<-EOF &&
+ Revert "picked"
+
+ This reverts commit OBJID.
+
+ # ------------------------ >8 ------------------------
+ # Do not modify or remove the line above.
+ # Everything below it will be ignored.
+ #
+ # Conflicts:
+ # foo
+ EOF
+
+ test_must_fail git revert --cleanup=scissors picked &&
+
+ sed "s/$OID_REGEX/OBJID/" .git/MERGE_MSG >actual &&
+ test_i18ncmp expected actual
+'
+
test_expect_success 'failed cherry-pick does not forget -s' '
pristine_detach initial &&
test_must_fail git cherry-pick -s picked &&
@@ -345,7 +436,7 @@ test_expect_success 'commit after failed cherry-pick does not add duplicated -s'
pristine_detach initial &&
test_must_fail git cherry-pick -s picked-signed &&
git commit -a -s &&
- test $(git show -s |grep -c "Signed-off-by") = 1
+ test $(git show -s >tmp && grep -c "Signed-off-by" tmp && rm tmp) = 1
'
test_expect_success 'commit after failed cherry-pick adds -s at the right place' '
@@ -359,7 +450,7 @@ test_expect_success 'commit after failed cherry-pick adds -s at the right place'
Signed-off-by: C O Mitter <committer@example.com>
# Conflicts:
EOF
- grep -e "^# Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
+ grep -e "^# Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
test_cmp expect actual &&
cat <<-\EOF >expected &&
@@ -378,7 +469,7 @@ test_expect_success 'commit --amend -s places the sign-off at the right place' '
# emulate old-style conflicts block
mv .git/MERGE_MSG .git/MERGE_MSG+ &&
- sed -e "/^# Conflicts:/,\$s/^# *//" <.git/MERGE_MSG+ >.git/MERGE_MSG &&
+ sed -e "/^# Conflicts:/,\$s/^# *//" .git/MERGE_MSG+ >.git/MERGE_MSG &&
git commit -a &&
git commit --amend -s &&
@@ -388,7 +479,7 @@ test_expect_success 'commit --amend -s places the sign-off at the right place' '
Signed-off-by: C O Mitter <committer@example.com>
Conflicts:
EOF
- grep -e "^Conflicts:" -e '^Signed-off-by' <.git/COMMIT_EDITMSG >actual &&
+ grep -e "^Conflicts:" -e '^Signed-off-by' .git/COMMIT_EDITMSG >actual &&
test_cmp expect actual
'
@@ -405,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/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh
index 9888bf34b9..84a587daf3 100755
--- a/t/t3511-cherry-pick-x.sh
+++ b/t/t3511-cherry-pick-x.sh
@@ -298,4 +298,24 @@ test_expect_success 'cherry-pick preserves commit message' '
test_cmp expect actual
'
+test_expect_success 'cherry-pick -x cleans commit message' '
+ pristine_detach initial &&
+ git cherry-pick -x mesg-unclean &&
+ git log -1 --pretty=format:%B >actual &&
+ printf "%s\n(cherry picked from commit %s)\n" \
+ "$mesg_unclean" $(git rev-parse mesg-unclean) |
+ git stripspace >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cherry-pick -x respects commit.cleanup' '
+ pristine_detach initial &&
+ git -c commit.cleanup=strip cherry-pick -x mesg-unclean &&
+ git log -1 --pretty=format:%B >actual &&
+ printf "%s\n(cherry picked from commit %s)\n" \
+ "$mesg_unclean" $(git rev-parse mesg-unclean) |
+ git stripspace -s >expect &&
+ test_cmp expect actual
+'
+
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/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/t5304-prune.sh b/t/t5304-prune.sh
index 1eeb828a15..df60f18fb8 100755
--- a/t/t5304-prune.sh
+++ b/t/t5304-prune.sh
@@ -341,4 +341,12 @@ test_expect_success 'prune: handle expire option correctly' '
git prune --no-expire
'
+test_expect_success 'trivial prune with bitmaps enabled' '
+ git repack -adb &&
+ blob=$(echo bitmap-unreachable-blob | git hash-object -w --stdin) &&
+ git prune --expire=now &&
+ git cat-file -e HEAD &&
+ test_must_fail git cat-file -e $blob
+'
+
test_done
diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh
index 82d7f7f6a5..a26c8ba9a2 100755
--- a/t/t5310-pack-bitmaps.sh
+++ b/t/t5310-pack-bitmaps.sh
@@ -34,8 +34,7 @@ test_expect_success 'setup repo with moderate-sized history' '
bitmaptip=$(git rev-parse master) &&
blob=$(echo tagged-blob | git hash-object -w --stdin) &&
git tag tagged-blob $blob &&
- git config repack.writebitmaps true &&
- git config pack.writebitmaphashcache true
+ git config repack.writebitmaps true
'
test_expect_success 'full repack creates bitmaps' '
@@ -269,7 +268,7 @@ test_expect_success JGIT 'we can read jgit bitmaps' '
git clone --bare . compat-jgit.git &&
(
cd compat-jgit.git &&
- rm -f .git/objects/pack/*.bitmap &&
+ rm -f objects/pack/*.bitmap &&
jgit gc &&
git rev-list --test-bitmap HEAD
)
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/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 49bf4280e8..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 &&
diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
index c19d8dbc9d..ccde8ba491 100755
--- a/t/t5521-pull-options.sh
+++ b/t/t5521-pull-options.sh
@@ -77,6 +77,14 @@ test_expect_success 'git pull -q -v' '
test_must_be_empty out &&
test -s err)
'
+test_expect_success 'git pull --cleanup errors early on invalid argument' '
+ mkdir clonedcleanup &&
+ (cd clonedcleanup && git init &&
+ test_must_fail git pull --cleanup invalid "../parent" >out 2>err &&
+ test_must_be_empty out &&
+ test -s err)
+'
+
test_expect_success 'git pull --force' '
mkdir clonedoldstyle &&
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/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..de9d99cf88 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -611,10 +611,6 @@ test_expect_success 'GIT_TRACE_PACKFILE produces a usable pack' '
git -C replay.git index-pack -v --stdin <tmp.pack
'
-hex2oct () {
- perl -ne 'printf "\\%03o", hex for /../g'
-}
-
test_expect_success 'clone on case-insensitive fs' '
git init icasefs &&
(
@@ -733,6 +729,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/t5701-git-serve.sh b/t/t5701-git-serve.sh
index fe45bf828d..ffb9613885 100755
--- a/t/t5701-git-serve.sh
+++ b/t/t5701-git-serve.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='test git-serve and server commands'
+test_description='test protocol v2 server commands'
. ./test-lib.sh
@@ -14,7 +14,8 @@ test_expect_success 'test capability advertisement' '
0000
EOF
- GIT_TEST_SIDEBAND_ALL=0 git serve --advertise-capabilities >out &&
+ GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
+ --advertise-capabilities >out &&
test-tool pkt-line unpack <out >actual &&
test_cmp expect actual
'
@@ -24,11 +25,11 @@ test_expect_success 'stateless-rpc flag does not list capabilities' '
test-tool pkt-line pack >in <<-EOF &&
0000
EOF
- git serve --stateless-rpc >out <in &&
+ test-tool serve-v2 --stateless-rpc >out <in &&
test_must_be_empty out &&
# EOF
- git serve --stateless-rpc >out &&
+ test-tool serve-v2 --stateless-rpc >out &&
test_must_be_empty out
'
@@ -37,7 +38,7 @@ test_expect_success 'request invalid capability' '
foobar
0000
EOF
- test_must_fail git serve --stateless-rpc 2>err <in &&
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
test_i18ngrep "unknown capability" err
'
@@ -46,7 +47,7 @@ test_expect_success 'request with no command' '
agent=git/test
0000
EOF
- test_must_fail git serve --stateless-rpc 2>err <in &&
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
test_i18ngrep "no command requested" err
'
@@ -56,7 +57,7 @@ test_expect_success 'request invalid command' '
agent=git/test
0000
EOF
- test_must_fail git serve --stateless-rpc 2>err <in &&
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>err <in &&
test_i18ngrep "invalid command" err
'
@@ -87,7 +88,7 @@ test_expect_success 'basics of ls-refs' '
0000
EOF
- git serve --stateless-rpc <in >out &&
+ test-tool serve-v2 --stateless-rpc <in >out &&
test-tool pkt-line unpack <out >actual &&
test_cmp expect actual
'
@@ -107,7 +108,7 @@ test_expect_success 'basic ref-prefixes' '
0000
EOF
- git serve --stateless-rpc <in >out &&
+ test-tool serve-v2 --stateless-rpc <in >out &&
test-tool pkt-line unpack <out >actual &&
test_cmp expect actual
'
@@ -127,7 +128,7 @@ test_expect_success 'refs/heads prefix' '
0000
EOF
- git serve --stateless-rpc <in >out &&
+ test-tool serve-v2 --stateless-rpc <in >out &&
test-tool pkt-line unpack <out >actual &&
test_cmp expect actual
'
@@ -148,7 +149,7 @@ test_expect_success 'peel parameter' '
0000
EOF
- git serve --stateless-rpc <in >out &&
+ test-tool serve-v2 --stateless-rpc <in >out &&
test-tool pkt-line unpack <out >actual &&
test_cmp expect actual
'
@@ -169,7 +170,7 @@ test_expect_success 'symrefs parameter' '
0000
EOF
- git serve --stateless-rpc <in >out &&
+ test-tool serve-v2 --stateless-rpc <in >out &&
test-tool pkt-line unpack <out >actual &&
test_cmp expect actual
'
@@ -189,7 +190,7 @@ test_expect_success 'sending server-options' '
0000
EOF
- git serve --stateless-rpc <in >out &&
+ test-tool serve-v2 --stateless-rpc <in >out &&
test-tool pkt-line unpack <out >actual &&
test_cmp expect actual
'
@@ -204,7 +205,10 @@ test_expect_success 'unexpected lines are not allowed in fetch request' '
0000
EOF
- test_must_fail git -C server serve --stateless-rpc <in >/dev/null 2>err &&
+ (
+ cd server &&
+ test_must_fail test-tool serve-v2 --stateless-rpc
+ ) <in >/dev/null 2>err &&
grep "unexpected line: .this-is-not-a-command." err
'
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
index e112b6086c..5b33f625dd 100755
--- a/t/t5702-protocol-v2.sh
+++ b/t/t5702-protocol-v2.sh
@@ -182,6 +182,13 @@ test_expect_success 'server-options are sent when using ls-remote' '
grep "server-option=world" log
'
+test_expect_success 'warn if using server-option with ls-remote with legacy protocol' '
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
+ ls-remote -o hello -o world "file://$(pwd)/file_parent" master 2>err &&
+
+ test_i18ngrep "see protocol.version in" err &&
+ test_i18ngrep "server options require protocol version 2 or later" err
+'
test_expect_success 'clone with file:// using protocol v2' '
test_when_finished "rm -f log" &&
@@ -251,6 +258,40 @@ test_expect_success 'server-options are sent when fetching' '
grep "server-option=world" log
'
+test_expect_success 'warn if using server-option with fetch with legacy protocol' '
+ test_when_finished "rm -rf temp_child" &&
+
+ git init temp_child &&
+
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C temp_child -c protocol.version=0 \
+ fetch -o hello -o world "file://$(pwd)/file_parent" master 2>err &&
+
+ test_i18ngrep "see protocol.version in" err &&
+ test_i18ngrep "server options require protocol version 2 or later" err
+'
+
+test_expect_success 'server-options are sent when cloning' '
+ test_when_finished "rm -rf log myclone" &&
+
+ GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+ clone --server-option=hello --server-option=world \
+ "file://$(pwd)/file_parent" myclone &&
+
+ grep "server-option=hello" log &&
+ grep "server-option=world" log
+'
+
+test_expect_success 'warn if using server-option with clone with legacy protocol' '
+ test_when_finished "rm -rf myclone" &&
+
+ test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -c protocol.version=0 \
+ clone --server-option=hello --server-option=world \
+ "file://$(pwd)/file_parent" myclone 2>err &&
+
+ test_i18ngrep "see protocol.version in" err &&
+ test_i18ngrep "server options require protocol version 2 or later" err
+'
+
test_expect_success 'upload-pack respects config using protocol v2' '
git init server &&
write_script server/.git/hook <<-\EOF &&
@@ -359,12 +400,13 @@ test_expect_success 'even with handcrafted request, filter does not work if not
0000
EOF
- test_must_fail git -C server serve --stateless-rpc <in >/dev/null 2>err &&
+ test_must_fail test-tool -C server serve-v2 --stateless-rpc \
+ <in >/dev/null 2>err &&
grep "unexpected line: .filter blob:none." err &&
# Exercise to ensure that if advertised, filter works
git -C server config uploadpack.allowfilter 1 &&
- git -C server serve --stateless-rpc <in >/dev/null
+ test-tool -C server serve-v2 --stateless-rpc <in >/dev/null
'
test_expect_success 'default refspec is used to filter ref when fetchcing' '
@@ -687,6 +729,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..0951d1bbdc 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -48,15 +48,15 @@ test_expect_success 'setup repository' '
'
test_expect_success 'config controls ref-in-want advertisement' '
- git serve --advertise-capabilities >out &&
+ test-tool serve-v2 --advertise-capabilities >out &&
! grep -a ref-in-want out &&
git config uploadpack.allowRefInWant false &&
- git serve --advertise-capabilities >out &&
+ test-tool serve-v2 --advertise-capabilities >out &&
! grep -a ref-in-want out &&
git config uploadpack.allowRefInWant true &&
- git serve --advertise-capabilities >out &&
+ test-tool serve-v2 --advertise-capabilities >out &&
grep -a ref-in-want out
'
@@ -70,7 +70,7 @@ test_expect_success 'invalid want-ref line' '
0000
EOF
- test_must_fail git serve --stateless-rpc 2>out <in &&
+ test_must_fail test-tool serve-v2 --stateless-rpc 2>out <in &&
grep "unknown ref" out
'
@@ -90,7 +90,7 @@ test_expect_success 'basic want-ref' '
0000
EOF
- git serve --stateless-rpc >out <in &&
+ test-tool serve-v2 --stateless-rpc >out <in &&
check_output
'
@@ -112,7 +112,7 @@ test_expect_success 'multiple want-ref lines' '
0000
EOF
- git serve --stateless-rpc >out <in &&
+ test-tool serve-v2 --stateless-rpc >out <in &&
check_output
'
@@ -133,7 +133,7 @@ test_expect_success 'mix want and want-ref' '
0000
EOF
- git serve --stateless-rpc >out <in &&
+ test-tool serve-v2 --stateless-rpc >out <in &&
check_output
'
@@ -153,7 +153,7 @@ test_expect_success 'want-ref with ref we already have commit for' '
0000
EOF
- git serve --stateless-rpc >out <in &&
+ test-tool serve-v2 --stateless-rpc >out <in &&
check_output
'
@@ -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/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh
index aaaa722cca..d04f8007e0 100755
--- a/t/t5801-remote-helpers.sh
+++ b/t/t5801-remote-helpers.sh
@@ -8,6 +8,8 @@ test_description='Test remote-helper import and export commands'
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-gpg.sh
+PATH="$TEST_DIRECTORY/t5801:$PATH"
+
compare_refs() {
git --git-dir="$1/.git" rev-parse --verify $2 >expect &&
git --git-dir="$3/.git" rev-parse --verify $4 >actual &&
diff --git a/t/t5801/git-remote-testgit b/t/t5801/git-remote-testgit
new file mode 100755
index 0000000000..752c763eb6
--- /dev/null
+++ b/t/t5801/git-remote-testgit
@@ -0,0 +1,147 @@
+#!/bin/sh
+# Copyright (c) 2012 Felipe Contreras
+
+# The first argument can be a url when the fetch/push command was a url
+# instead of a configured remote. In this case, use a generic alias.
+if test "$1" = "testgit::$2"; then
+ alias=_
+else
+ alias=$1
+fi
+url=$2
+
+dir="$GIT_DIR/testgit/$alias"
+prefix="refs/testgit/$alias"
+
+default_refspec="refs/heads/*:${prefix}/heads/*"
+
+refspec="${GIT_REMOTE_TESTGIT_REFSPEC-$default_refspec}"
+
+test -z "$refspec" && prefix="refs"
+
+GIT_DIR="$url/.git"
+export GIT_DIR
+
+force=
+
+mkdir -p "$dir"
+
+if test -z "$GIT_REMOTE_TESTGIT_NO_MARKS"
+then
+ gitmarks="$dir/git.marks"
+ testgitmarks="$dir/testgit.marks"
+ test -e "$gitmarks" || >"$gitmarks"
+ test -e "$testgitmarks" || >"$testgitmarks"
+fi
+
+while read line
+do
+ case $line in
+ capabilities)
+ echo 'import'
+ echo 'export'
+ test -n "$refspec" && echo "refspec $refspec"
+ if test -n "$gitmarks"
+ then
+ echo "*import-marks $gitmarks"
+ echo "*export-marks $gitmarks"
+ fi
+ test -n "$GIT_REMOTE_TESTGIT_SIGNED_TAGS" && echo "signed-tags"
+ test -n "$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE" && echo "no-private-update"
+ echo 'option'
+ echo
+ ;;
+ list)
+ git for-each-ref --format='? %(refname)' 'refs/heads/'
+ head=$(git symbolic-ref HEAD)
+ echo "@$head HEAD"
+ echo
+ ;;
+ import*)
+ # read all import lines
+ while true
+ do
+ ref="${line#* }"
+ refs="$refs $ref"
+ read line
+ test "${line%% *}" != "import" && break
+ done
+
+ if test -n "$gitmarks"
+ then
+ echo "feature import-marks=$gitmarks"
+ echo "feature export-marks=$gitmarks"
+ fi
+
+ if test -n "$GIT_REMOTE_TESTGIT_FAILURE"
+ then
+ echo "feature done"
+ exit 1
+ fi
+
+ echo "feature done"
+ git fast-export \
+ ${testgitmarks:+"--import-marks=$testgitmarks"} \
+ ${testgitmarks:+"--export-marks=$testgitmarks"} \
+ $refs |
+ sed -e "s#refs/heads/#${prefix}/heads/#g"
+ echo "done"
+ ;;
+ export)
+ if test -n "$GIT_REMOTE_TESTGIT_FAILURE"
+ then
+ # consume input so fast-export doesn't get SIGPIPE;
+ # git would also notice that case, but we want
+ # to make sure we are exercising the later
+ # error checks
+ while read line; do
+ test "done" = "$line" && break
+ done
+ exit 1
+ fi
+
+ before=$(git for-each-ref --format=' %(refname) %(objectname) ')
+
+ git fast-import \
+ ${force:+--force} \
+ ${testgitmarks:+"--import-marks=$testgitmarks"} \
+ ${testgitmarks:+"--export-marks=$testgitmarks"} \
+ --quiet
+
+ # figure out which refs were updated
+ git for-each-ref --format='%(refname) %(objectname)' |
+ while read ref a
+ do
+ case "$before" in
+ *" $ref $a "*)
+ continue ;; # unchanged
+ esac
+ if test -z "$GIT_REMOTE_TESTGIT_PUSH_ERROR"
+ then
+ echo "ok $ref"
+ else
+ echo "error $ref $GIT_REMOTE_TESTGIT_PUSH_ERROR"
+ fi
+ done
+
+ echo
+ ;;
+ option\ *)
+ read cmd opt val <<-EOF
+ $line
+ EOF
+ case $opt in
+ force)
+ test $val = "true" && force="true" || force=
+ echo "ok"
+ ;;
+ *)
+ echo "unsupported"
+ ;;
+ esac
+ ;;
+ '')
+ exit
+ ;;
+ esac
+done
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/t6050-replace.sh b/t/t6050-replace.sh
index d638119750..e7e64e085d 100755
--- a/t/t6050-replace.sh
+++ b/t/t6050-replace.sh
@@ -40,7 +40,8 @@ commit_peeling_shows_parents ()
test "$_found" = "$_parent" || return 1
_parent_number=$(( $_parent_number + 1 ))
done &&
- test_must_fail git rev-parse --verify $_commit^$_parent_number
+ test_must_fail git rev-parse --verify $_commit^$_parent_number 2>err &&
+ test_i18ngrep "Needed a single revision" err
}
commit_has_parents ()
@@ -393,9 +394,11 @@ test_expect_success 'replace ref cleanup' '
'
test_expect_success '--graft with and without already replaced object' '
- test $(git log --oneline | wc -l) = 7 &&
+ git log --oneline >log &&
+ test_line_count = 7 log &&
git replace --graft $HASH5 &&
- test $(git log --oneline | wc -l) = 3 &&
+ git log --oneline >log &&
+ test_line_count = 3 log &&
commit_has_parents $HASH5 &&
test_must_fail git replace --graft $HASH5 $HASH4 $HASH3 &&
git replace --force -g $HASH5 $HASH4 $HASH3 &&
@@ -403,6 +406,28 @@ test_expect_success '--graft with and without already replaced object' '
git replace -d $HASH5
'
+test_expect_success '--graft using a tag as the new parent' '
+ git tag new_parent $HASH5 &&
+ git replace --graft $HASH7 new_parent &&
+ commit_has_parents $HASH7 $HASH5 &&
+ git replace -d $HASH7 &&
+ git tag -a -m "annotated new parent tag" annotated_new_parent $HASH5 &&
+ git replace --graft $HASH7 annotated_new_parent &&
+ commit_has_parents $HASH7 $HASH5 &&
+ git replace -d $HASH7
+'
+
+test_expect_success '--graft using a tag as the replaced object' '
+ git tag replaced_object $HASH7 &&
+ git replace --graft replaced_object $HASH5 &&
+ commit_has_parents $HASH7 $HASH5 &&
+ git replace -d $HASH7 &&
+ git tag -a -m "annotated replaced object tag" annotated_replaced_object $HASH7 &&
+ git replace --graft annotated_replaced_object $HASH5 &&
+ commit_has_parents $HASH7 $HASH5 &&
+ git replace -d $HASH7
+'
+
test_expect_success GPG 'set up a signed commit' '
echo "line 17" >>hello &&
echo "line 18" >>hello &&
diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh
new file mode 100755
index 0000000000..28611c978e
--- /dev/null
+++ b/t/t6102-rev-list-unexpected-objects.sh
@@ -0,0 +1,127 @@
+#!/bin/sh
+
+test_description='git rev-list should handle unexpected object types'
+
+. ./test-lib.sh
+
+test_expect_success 'setup well-formed objects' '
+ blob="$(printf "foo" | git hash-object -w --stdin)" &&
+ tree="$(printf "100644 blob $blob\tfoo" | git mktree)" &&
+ commit="$(git commit-tree $tree -m "first commit")" &&
+ git cat-file commit $commit >good-commit
+'
+
+test_expect_success 'setup unexpected non-blob entry' '
+ printf "100644 foo\0$(echo $tree | hex2oct)" >broken-tree &&
+ broken_tree="$(git hash-object -w --literally -t tree broken-tree)"
+'
+
+test_expect_failure 'traverse unexpected non-blob entry (lone)' '
+ test_must_fail git rev-list --objects $broken_tree
+'
+
+test_expect_success 'traverse unexpected non-blob entry (seen)' '
+ test_must_fail git rev-list --objects $tree $broken_tree >output 2>&1 &&
+ test_i18ngrep "is not a blob" output
+'
+
+test_expect_success 'setup unexpected non-tree entry' '
+ printf "40000 foo\0$(echo $blob | hex2oct)" >broken-tree &&
+ broken_tree="$(git hash-object -w --literally -t tree broken-tree)"
+'
+
+test_expect_success 'traverse unexpected non-tree entry (lone)' '
+ test_must_fail git rev-list --objects $broken_tree
+'
+
+test_expect_success 'traverse unexpected non-tree entry (seen)' '
+ test_must_fail git rev-list --objects $blob $broken_tree >output 2>&1 &&
+ test_i18ngrep "is not a tree" output
+'
+
+test_expect_success 'setup unexpected non-commit parent' '
+ sed "/^author/ { h; s/.*/parent $blob/; G; }" <good-commit \
+ >broken-commit &&
+ broken_commit="$(git hash-object -w --literally -t commit \
+ broken-commit)"
+'
+
+test_expect_success 'traverse unexpected non-commit parent (lone)' '
+ test_must_fail git rev-list --objects $broken_commit >output 2>&1 &&
+ test_i18ngrep "not a commit" output
+'
+
+test_expect_success 'traverse unexpected non-commit parent (seen)' '
+ test_must_fail git rev-list --objects $commit $broken_commit \
+ >output 2>&1 &&
+ test_i18ngrep "not a commit" output
+'
+
+test_expect_success 'setup unexpected non-tree root' '
+ sed -e "s/$tree/$blob/" <good-commit >broken-commit &&
+ broken_commit="$(git hash-object -w --literally -t commit \
+ broken-commit)"
+'
+
+test_expect_success 'traverse unexpected non-tree root (lone)' '
+ test_must_fail git rev-list --objects $broken_commit
+'
+
+test_expect_success 'traverse unexpected non-tree root (seen)' '
+ test_must_fail git rev-list --objects $blob $broken_commit \
+ >output 2>&1 &&
+ test_i18ngrep "not a tree" output
+'
+
+test_expect_success 'setup unexpected non-commit tag' '
+ git tag -a -m "tagged commit" tag $commit &&
+ git cat-file tag tag >good-tag &&
+ test_when_finished "git tag -d tag" &&
+ sed -e "s/$commit/$blob/" <good-tag >broken-tag &&
+ tag=$(git hash-object -w --literally -t tag broken-tag)
+'
+
+test_expect_success 'traverse unexpected non-commit tag (lone)' '
+ test_must_fail git rev-list --objects $tag
+'
+
+test_expect_success 'traverse unexpected non-commit tag (seen)' '
+ test_must_fail git rev-list --objects $blob $tag >output 2>&1 &&
+ test_i18ngrep "not a commit" output
+'
+
+test_expect_success 'setup unexpected non-tree tag' '
+ git tag -a -m "tagged tree" tag $tree &&
+ git cat-file tag tag >good-tag &&
+ test_when_finished "git tag -d tag" &&
+ sed -e "s/$tree/$blob/" <good-tag >broken-tag &&
+ tag=$(git hash-object -w --literally -t tag broken-tag)
+'
+
+test_expect_success 'traverse unexpected non-tree tag (lone)' '
+ test_must_fail git rev-list --objects $tag
+'
+
+test_expect_success 'traverse unexpected non-tree tag (seen)' '
+ test_must_fail git rev-list --objects $blob $tag >output 2>&1 &&
+ test_i18ngrep "not a tree" output
+'
+
+test_expect_success 'setup unexpected non-blob tag' '
+ git tag -a -m "tagged blob" tag $blob &&
+ git cat-file tag tag >good-tag &&
+ test_when_finished "git tag -d tag" &&
+ sed -e "s/$blob/$commit/" <good-tag >broken-tag &&
+ tag=$(git hash-object -w --literally -t tag broken-tag)
+'
+
+test_expect_failure 'traverse unexpected non-blob tag (lone)' '
+ test_must_fail git rev-list --objects $tag
+'
+
+test_expect_success 'traverse unexpected non-blob tag (seen)' '
+ test_must_fail git rev-list --objects $commit $tag >output 2>&1 &&
+ test_i18ngrep "not a blob" output
+'
+
+test_done
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 0ffd630713..d9235217fc 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -392,8 +392,15 @@ test_atom head upstream:track '[ahead 1]'
test_atom head upstream:trackshort '>'
test_atom head upstream:track,nobracket 'ahead 1'
test_atom head upstream:nobracket,track 'ahead 1'
-test_atom head push:track '[ahead 1]'
-test_atom head push:trackshort '>'
+
+test_expect_success 'setup for push:track[short]' '
+ test_commit third &&
+ git update-ref refs/remotes/myfork/master master &&
+ git reset master~1
+'
+
+test_atom head push:track '[behind 1]'
+test_atom head push:trackshort '<'
test_expect_success 'Check that :track[short] cannot be used with other atoms' '
test_must_fail git for-each-ref --format="%(refname:track)" 2>/dev/null &&
@@ -420,8 +427,10 @@ test_expect_success 'Check for invalid refname format' '
test_expect_success 'set up color tests' '
cat >expected.color <<-EOF &&
$(git rev-parse --short refs/heads/master) <GREEN>master<RESET>
+ $(git rev-parse --short refs/remotes/myfork/master) <GREEN>myfork/master<RESET>
$(git rev-parse --short refs/remotes/origin/master) <GREEN>origin/master<RESET>
$(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET>
+ $(git rev-parse --short refs/tags/third) <GREEN>third<RESET>
$(git rev-parse --short refs/tags/two) <GREEN>two<RESET>
EOF
sed "s/<[^>]*>//g" <expected.color >expected.bare &&
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/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh
index ca4a740da0..5733d9cd34 100755
--- a/t/t7502-commit-porcelain.sh
+++ b/t/t7502-commit-porcelain.sh
@@ -16,7 +16,8 @@ commit_msg_is () {
# Arguments: [<prefix] [<commit message>] [<commit options>]
check_summary_oneline() {
test_tick &&
- git commit ${3+"$3"} -m "$2" | head -1 > act &&
+ git commit ${3+"$3"} -m "$2" >raw &&
+ head -n 1 raw >act &&
# branch name
SUMMARY_PREFIX="$(git name-rev --name-only HEAD)" &&
@@ -68,7 +69,7 @@ test_expect_success 'output summary format for merges' '
git checkout recursive-a &&
test_must_fail git merge recursive-b &&
# resolve the conflict
- echo commit-a > file1 &&
+ echo commit-a >file1 &&
git add file1 &&
check_summary_oneline "" "Merge"
'
@@ -142,9 +143,11 @@ test_expect_success 'sign off' '
>positive &&
git add positive &&
git commit -s -m "thank you" &&
- actual=$(git cat-file commit HEAD | sed -ne "s/Signed-off-by: //p") &&
- expected=$(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/") &&
- test "z$actual" = "z$expected"
+ git cat-file commit HEAD >commit.msg &&
+ sed -ne "s/Signed-off-by: //p" commit.msg >actual &&
+ git var GIT_COMMITTER_IDENT >ident &&
+ sed -e "s/>.*/>/" ident >expected &&
+ test_cmp expected actual
'
@@ -153,8 +156,8 @@ test_expect_success 'multiple -m' '
>negative &&
git add negative &&
git commit -m "one" -m "two" -m "three" &&
- actual=$(git cat-file commit HEAD | sed -e "1,/^\$/d") &&
- expected=$(echo one; echo; echo two; echo; echo three) &&
+ actual=$(git cat-file commit HEAD >tmp && sed -e "1,/^\$/d" tmp && rm tmp) &&
+ expected=$(test_write_lines "one" "" "two" "" "three") &&
test "z$actual" = "z$expected"
'
@@ -163,7 +166,8 @@ test_expect_success 'verbose' '
echo minus >negative &&
git add negative &&
- git status -v | sed -ne "/^diff --git /p" >actual &&
+ git status -v >raw &&
+ sed -ne "/^diff --git /p" raw >actual &&
echo "diff --git a/negative b/negative" >expect &&
test_cmp expect actual
@@ -189,7 +193,8 @@ test_expect_success 'cleanup commit messages (verbatim option,-t)' '
echo >>negative &&
git commit --cleanup=verbatim --no-status -t expect -a &&
- git cat-file -p HEAD |sed -e "1,/^\$/d" >actual &&
+ git cat-file -p HEAD >raw &&
+ sed -e "1,/^\$/d" raw >actual &&
test_cmp expect actual
'
@@ -198,7 +203,8 @@ test_expect_success 'cleanup commit messages (verbatim option,-F)' '
echo >>negative &&
git commit --cleanup=verbatim -F expect -a &&
- git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ git cat-file -p HEAD >raw &&
+ sed -e "1,/^\$/d" raw >actual &&
test_cmp expect actual
'
@@ -207,7 +213,8 @@ test_expect_success 'cleanup commit messages (verbatim option,-m)' '
echo >>negative &&
git commit --cleanup=verbatim -m "$mesg_with_comment_and_newlines" -a &&
- git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ git cat-file -p HEAD >raw &&
+ sed -e "1,/^\$/d" raw >actual &&
test_cmp expect actual
'
@@ -215,10 +222,11 @@ test_expect_success 'cleanup commit messages (verbatim option,-m)' '
test_expect_success 'cleanup commit messages (whitespace option,-F)' '
echo >>negative &&
- { echo;echo "# text";echo; } >text &&
+ test_write_lines "" "# text" "" >text &&
echo "# text" >expect &&
git commit --cleanup=whitespace -F text -a &&
- git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ git cat-file -p HEAD >raw &&
+ sed -e "1,/^\$/d" raw >actual &&
test_cmp expect actual
'
@@ -226,48 +234,51 @@ test_expect_success 'cleanup commit messages (whitespace option,-F)' '
test_expect_success 'cleanup commit messages (scissors option,-F,-e)' '
echo >>negative &&
- cat >text <<EOF &&
+ cat >text <<-\EOF &&
-# to be kept
+ # to be kept
- # ------------------------ >8 ------------------------
-# to be kept, too
-# ------------------------ >8 ------------------------
-to be removed
-# ------------------------ >8 ------------------------
-to be removed, too
-EOF
+ # ------------------------ >8 ------------------------
+ # to be kept, too
+ # ------------------------ >8 ------------------------
+ to be removed
+ # ------------------------ >8 ------------------------
+ to be removed, too
+ EOF
- cat >expect <<EOF &&
-# to be kept
+ cat >expect <<-\EOF &&
+ # to be kept
- # ------------------------ >8 ------------------------
-# to be kept, too
-EOF
+ # ------------------------ >8 ------------------------
+ # to be kept, too
+ EOF
git commit --cleanup=scissors -e -F text -a &&
- git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ git cat-file -p HEAD >raw &&
+ sed -e "1,/^\$/d" raw >actual &&
test_cmp expect actual
'
test_expect_success 'cleanup commit messages (scissors option,-F,-e, scissors on first line)' '
echo >>negative &&
- cat >text <<EOF &&
-# ------------------------ >8 ------------------------
-to be removed
-EOF
+ cat >text <<-\EOF &&
+ # ------------------------ >8 ------------------------
+ to be removed
+ EOF
git commit --cleanup=scissors -e -F text -a --allow-empty-message &&
- git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ git cat-file -p HEAD >raw &&
+ sed -e "1,/^\$/d" raw >actual &&
test_must_be_empty actual
'
test_expect_success 'cleanup commit messages (strip option,-F)' '
echo >>negative &&
- { echo;echo "# text";echo sample;echo; } >text &&
+ test_write_lines "" "# text" "sample" "" >text &&
echo sample >expect &&
git commit --cleanup=strip -F text -a &&
- git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ git cat-file -p HEAD >raw &&
+ sed -e "1,/^\$/d" raw >actual &&
test_cmp expect actual
'
@@ -275,7 +286,7 @@ test_expect_success 'cleanup commit messages (strip option,-F)' '
test_expect_success 'cleanup commit messages (strip option,-F,-e)' '
echo >>negative &&
- { echo;echo sample;echo; } >text &&
+ test_write_lines "" "sample" "" >text &&
git commit -e -F text -a &&
head -n 4 .git/COMMIT_EDITMSG >actual
'
@@ -387,7 +398,7 @@ test_expect_success AUTOIDENT 'message shows committer when it is automatic' '
'
write_script .git/FAKE_EDITOR <<EOF
-echo editor started > "$(pwd)/.git/result"
+echo editor started >"$(pwd)/.git/result"
exit 0
EOF
@@ -455,7 +466,7 @@ EOF
test_expect_success EXECKEEPSPID 'a SIGTERM should break locks' '
echo >>negative &&
! "$SHELL_PATH" -c '\''
- echo kill -TERM $$ >> .git/FAKE_EDITOR
+ echo kill -TERM $$ >>.git/FAKE_EDITOR
GIT_EDITOR=.git/FAKE_EDITOR
export GIT_EDITOR
exec git commit -a'\'' &&
@@ -471,7 +482,8 @@ test_expect_success 'Hand committing of a redundant merge removes dups' '
test_must_fail git merge second master &&
git checkout master g &&
EDITOR=: git commit -a &&
- git cat-file commit HEAD | sed -n -e "s/^parent //p" -e "/^$/q" >actual &&
+ git cat-file commit HEAD >raw &&
+ sed -n -e "s/^parent //p" -e "/^$/q" raw >actual &&
test_cmp expect actual
'
@@ -480,7 +492,8 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo
git reset --hard &&
git commit -s -m "hello: kitty" --allow-empty &&
- git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
+ git cat-file commit HEAD >raw &&
+ sed -e "1,/^$/d" raw >actual &&
test_line_count = 3 actual
'
diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh
index 106148254d..7f9c68cbe7 100755
--- a/t/t7600-merge.sh
+++ b/t/t7600-merge.sh
@@ -233,20 +233,65 @@ test_expect_success 'merge --squash c3 with c7' '
cat result.9z >file &&
git commit --no-edit -a &&
- {
- cat <<-EOF
- Squashed commit of the following:
+ cat >expect <<-EOF &&
+ Squashed commit of the following:
- $(git show -s c7)
+ $(git show -s c7)
- # Conflicts:
- # file
- EOF
- } >expect &&
- git cat-file commit HEAD | sed -e '1,/^$/d' >actual &&
+ # Conflicts:
+ # file
+ EOF
+ git cat-file commit HEAD >raw &&
+ sed -e '1,/^$/d' raw >actual &&
test_cmp expect actual
'
+test_expect_success 'merge c3 with c7 with commit.cleanup = scissors' '
+ git config commit.cleanup scissors &&
+ git reset --hard c3 &&
+ test_must_fail git merge c7 &&
+ cat result.9z >file &&
+ git commit --no-edit -a &&
+
+ cat >expect <<-\EOF &&
+ Merge tag '"'"'c7'"'"'
+
+ # ------------------------ >8 ------------------------
+ # Do not modify or remove the line above.
+ # Everything below it will be ignored.
+ #
+ # Conflicts:
+ # file
+ EOF
+ git cat-file commit HEAD >raw &&
+ sed -e '1,/^$/d' raw >actual &&
+ test_i18ncmp expect actual
+'
+
+test_expect_success 'merge c3 with c7 with --squash commit.cleanup = scissors' '
+ git config commit.cleanup scissors &&
+ git reset --hard c3 &&
+ test_must_fail git merge --squash c7 &&
+ cat result.9z >file &&
+ git commit --no-edit -a &&
+
+ cat >expect <<-EOF &&
+ Squashed commit of the following:
+
+ $(git show -s c7)
+
+ # ------------------------ >8 ------------------------
+ # Do not modify or remove the line above.
+ # Everything below it will be ignored.
+ #
+ # Conflicts:
+ # file
+ EOF
+ git cat-file commit HEAD >raw &&
+ sed -e '1,/^$/d' raw >actual &&
+ test_i18ncmp expect actual
+'
+
test_debug 'git log --graph --decorate --oneline --all'
test_expect_success 'merge c1 with c2 and c3' '
@@ -680,10 +725,10 @@ cat >editor <<\EOF
(
echo "Merge work done on the side branch c1"
echo
- cat <"$1"
+ cat "$1"
) >"$1.tmp" && mv "$1.tmp" "$1"
# strip comments and blank lines from end of message
-sed -e '/^#/d' < "$1" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' > expected
+sed -e '/^#/d' "$1" | sed -e :a -e '/^\n*$/{$d;N;ba' -e '}' >expected
EOF
chmod 755 editor
@@ -768,14 +813,14 @@ test_expect_success 'set up mod-256 conflict scenario' '
git commit -m base &&
# one side changes the first line of each to "master"
- sed s/-1/-master/ <file >tmp &&
+ sed s/-1/-master/ file >tmp &&
mv tmp file &&
git commit -am master &&
# and the other to "side"; merging the two will
# yield 256 separate conflicts
git checkout -b side HEAD^ &&
- sed s/-1/-side/ <file >tmp &&
+ sed s/-1/-side/ file >tmp &&
mv tmp file &&
git commit -am side
'
@@ -814,7 +859,7 @@ EOF
test_expect_success EXECKEEPSPID 'killed merge can be completed with --continue' '
git reset --hard c0 &&
! "$SHELL_PATH" -c '\''
- echo kill -TERM $$ >> .git/FAKE_EDITOR
+ echo kill -TERM $$ >>.git/FAKE_EDITOR
GIT_EDITOR=.git/FAKE_EDITOR
export GIT_EDITOR
exec git merge --no-ff --edit c1'\'' &&
diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh
index 89619cf446..cd4f9607dc 100755
--- a/t/t7604-merge-custom-message.sh
+++ b/t/t7604-merge-custom-message.sh
@@ -16,16 +16,16 @@ create_merge_msgs() {
}
test_expect_success 'setup' '
- echo c0 > c0.c &&
+ echo c0 >c0.c &&
git add c0.c &&
git commit -m c0 &&
git tag c0 &&
- echo c1 > c1.c &&
+ echo c1 >c1.c &&
git add c1.c &&
git commit -m c1 &&
git tag c1 &&
git reset --hard c0 &&
- echo c2 > c2.c &&
+ echo c2 >c2.c &&
git add c2.c &&
git commit -m c2 &&
git tag c2 &&
@@ -36,15 +36,80 @@ test_expect_success 'setup' '
test_expect_success 'merge c2 with a custom message' '
git reset --hard c1 &&
git merge -m "$(cat exp.subject)" c2 &&
- git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
+ git cat-file commit HEAD >raw &&
+ sed -e "1,/^$/d" raw >actual &&
test_cmp exp.subject actual
'
test_expect_success 'merge --log appends to custom message' '
git reset --hard c1 &&
git merge --log -m "$(cat exp.subject)" c2 &&
- git cat-file commit HEAD | sed -e "1,/^$/d" >actual &&
+ git cat-file commit HEAD >raw &&
+ sed -e "1,/^$/d" raw >actual &&
test_cmp exp.log actual
'
+mesg_with_comment_and_newlines='
+# text
+
+'
+
+test_expect_success 'prepare file with comment line and trailing newlines' '
+ printf "%s" "$mesg_with_comment_and_newlines" >expect
+'
+
+test_expect_success 'cleanup commit messages (verbatim option)' '
+ git reset --hard c1 &&
+ git merge --cleanup=verbatim -F expect c2 &&
+ git cat-file commit HEAD >raw &&
+ sed -e "1,/^$/d" raw >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cleanup commit messages (whitespace option)' '
+ git reset --hard c1 &&
+ test_write_lines "" "# text" "" >text &&
+ echo "# text" >expect &&
+ git merge --cleanup=whitespace -F text c2 &&
+ git cat-file commit HEAD >raw &&
+ sed -e "1,/^$/d" raw >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cleanup merge messages (scissors option)' '
+ git reset --hard c1 &&
+ cat >text <<-\EOF &&
+
+ # to be kept
+
+ # ------------------------ >8 ------------------------
+ # to be kept, too
+ # ------------------------ >8 ------------------------
+ to be removed
+ # ------------------------ >8 ------------------------
+ to be removed, too
+ EOF
+
+ cat >expect <<-\EOF &&
+ # to be kept
+
+ # ------------------------ >8 ------------------------
+ # to be kept, too
+ EOF
+ git merge --cleanup=scissors -e -F text c2 &&
+ git cat-file commit HEAD >raw &&
+ sed -e "1,/^$/d" raw >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cleanup commit messages (strip option)' '
+ git reset --hard c1 &&
+ test_write_lines "" "# text" "sample" "" >text &&
+ echo sample >expect &&
+ git merge --cleanup=strip -F text c2 &&
+ git cat-file commit HEAD >raw &&
+ sed -e "1,/^$/d" raw >actual &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh
index 6162e2a8e6..86d05160a3 100755
--- a/t/t7700-repack.sh
+++ b/t/t7700-repack.sh
@@ -221,5 +221,22 @@ test_expect_success 'repack --keep-pack' '
)
'
-test_done
+test_expect_success 'bitmaps are created by default in bare repos' '
+ git clone --bare .git bare.git &&
+ git -C bare.git repack -ad &&
+ bitmap=$(ls bare.git/objects/pack/*.bitmap) &&
+ test_path_is_file "$bitmap"
+'
+
+test_expect_success 'incremental repack does not complain' '
+ git -C bare.git repack -q 2>repack.err &&
+ test_must_be_empty repack.err
+'
+test_expect_success 'bitmaps can be disabled on bare repos' '
+ git -c repack.writeBitmaps=false -C bare.git repack -ad &&
+ bitmap=$(ls bare.git/objects/pack/*.bitmap 2>/dev/null || :) &&
+ test -z "$bitmap"
+'
+
+test_done
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/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
index fa475d52fa..134a694516 100755
--- a/t/t7814-grep-recurse-submodules.sh
+++ b/t/t7814-grep-recurse-submodules.sh
@@ -380,11 +380,7 @@ test_expect_success 'grep --recurse-submodules should pass the pattern type alon
fi
'
-# Recursing down into nested submodules which do not have .gitmodules in their
-# working tree does not work yet. This is because config_from_gitmodules()
-# uses get_oid() and the latter is still not able to get objects from an
-# arbitrary repository (the nested submodule, in this case).
-test_expect_failure 'grep --recurse-submodules with submodules without .gitmodules in the working tree' '
+test_expect_success 'grep --recurse-submodules with submodules without .gitmodules in the working tree' '
test_when_finished "git -C submodule checkout .gitmodules" &&
rm submodule/.gitmodules &&
git grep --recurse-submodules -e "(.|.)[\d]" >actual &&
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..8270de74be 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 () {
@@ -1211,6 +1239,12 @@ depacketize () {
'
}
+# Converts base-16 data into base-8. The output is given as a sequence of
+# escaped octals, suitable for consumption by 'printf'.
+hex2oct () {
+ perl -ne 'printf "\\%03o", hex for /../g'
+}
+
# Set the hash algorithm in use to $1. Only useful when testing the testsuite.
test_set_hash () {
test_hash_algo="$1"
diff --git a/t/test-lib.sh b/t/test-lib.sh
index c14ebe68d3..908ddb9c46 100644
--- a/t/test-lib.sh
+++ b/t/test-lib.sh
@@ -386,6 +386,7 @@ unset VISUAL EMAIL LANGUAGE COLUMNS $("$PERL_PATH" -e '
my @env = keys %ENV;
my $ok = join("|", qw(
TRACE
+ TR2_
DEBUG
TEST
.*_TEST
@@ -634,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
@@ -645,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
@@ -1056,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" || {
@@ -1412,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