diff options
Diffstat (limited to 't')
128 files changed, 2238 insertions, 523 deletions
@@ -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 |