diff options
Diffstat (limited to 't')
280 files changed, 9085 insertions, 2086 deletions
@@ -352,8 +352,8 @@ details. GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole test suite. Accept any boolean values that are accepted by git-config. -GIT_TEST_PROTOCOL_VERSION=<n>, when set, overrides the -'protocol.version' setting to n if it is less than n. +GIT_TEST_PROTOCOL_VERSION=<n>, when set, makes 'protocol.version' +default to n. GIT_TEST_FULL_IN_PACK_ARRAY=<boolean> exercises the uncommon pack-objects code path where there are more than 1024 packs even if @@ -397,6 +397,10 @@ GIT_TEST_STASH_USE_BUILTIN=<boolean>, when false, disables the built-in version of git-stash. See 'stash.useBuiltin' in git-config(1). +GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when true, enables the +built-in version of git add -i. See 'add.interactive.useBuiltin' in +git-config(1). + GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading of the index for the whole test suite by bypassing the default number of cache entries and thread minimums. Setting this to 1 will make the @@ -978,6 +982,15 @@ library for your script to use. output to the downstream---unlike the real version, it generates only up to 99 lines. + - test_bool_env <env-variable-name> <default-value> + + Given the name of an environment variable with a bool value, + normalize its value to a 0 (true) or 1 (false or empty string) + return code. Return with code corresponding to the given default + value if the variable is unset. + Abort the test script if either the value of the variable or the + default are not valid bool values. + Prerequisites ------------- diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl index 38bfeebd88..fd3303552b 100755 --- a/t/check-non-portable-shell.pl +++ b/t/check-non-portable-shell.pl @@ -46,7 +46,7 @@ while (<>) { /(?:\$\(seq|^\s*seq\b)/ and err 'seq is not portable (use test_seq)'; /\bgrep\b.*--file\b/ and err 'grep --file FILE is not portable (use grep -f FILE)'; /\bexport\s+[A-Za-z0-9_]*=/ and err '"export FOO=bar" is not portable (use FOO=bar && export FOO)'; - /^\s*([A-Z0-9_]+=(\w+|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and + /^\s*([A-Z0-9_]+=(\w*|(["']).*?\3)\s+)+(\w+)/ and exists($func{$4}) and err '"FOO=bar shell_func" assignment extends beyond "shell_func"'; $line = ''; # this resets our $. for each file diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh index 006d2a8152..1f32ca66ea 100644 --- a/t/gitweb-lib.sh +++ b/t/gitweb-lib.sh @@ -58,10 +58,11 @@ gitweb_run () { GATEWAY_INTERFACE='CGI/1.1' HTTP_ACCEPT='*/*' REQUEST_METHOD='GET' - QUERY_STRING=""$1"" - PATH_INFO=""$2"" + QUERY_STRING=$1 + PATH_INFO=$2 + REQUEST_URI=/gitweb.cgi$PATH_INFO export GATEWAY_INTERFACE HTTP_ACCEPT REQUEST_METHOD \ - QUERY_STRING PATH_INFO + QUERY_STRING PATH_INFO REQUEST_URI GITWEB_CONFIG=$(pwd)/gitweb_config.perl export GITWEB_CONFIG diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 214003d5b2..234c722b48 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -37,21 +37,6 @@ * */ -static const char *scope_name(enum config_scope scope) -{ - switch (scope) { - case CONFIG_SCOPE_SYSTEM: - return "system"; - case CONFIG_SCOPE_GLOBAL: - return "global"; - case CONFIG_SCOPE_REPO: - return "repo"; - case CONFIG_SCOPE_CMDLINE: - return "cmdline"; - default: - return "unknown"; - } -} static int iterate_cb(const char *var, const char *value, void *data) { static int nr; @@ -63,7 +48,8 @@ static int iterate_cb(const char *var, const char *value, void *data) printf("value=%s\n", value ? value : "(null)"); printf("origin=%s\n", current_config_origin_type()); printf("name=%s\n", current_config_name()); - printf("scope=%s\n", scope_name(current_config_scope())); + printf("lno=%d\n", current_config_line()); + printf("scope=%s\n", config_scope_name(current_config_scope())); return 0; } diff --git a/t/helper/test-drop-caches.c b/t/helper/test-drop-caches.c index f65e301f9d..7b4278462b 100644 --- a/t/helper/test-drop-caches.c +++ b/t/helper/test-drop-caches.c @@ -8,18 +8,21 @@ static int cmd_sync(void) { char Buffer[MAX_PATH]; DWORD dwRet; - char szVolumeAccessPath[] = "\\\\.\\X:"; + char szVolumeAccessPath[] = "\\\\.\\XXXX:"; HANDLE hVolWrite; - int success = 0; + int success = 0, dos_drive_prefix; dwRet = GetCurrentDirectory(MAX_PATH, Buffer); if ((0 == dwRet) || (dwRet > MAX_PATH)) return error("Error getting current directory"); - if (!has_dos_drive_prefix(Buffer)) + dos_drive_prefix = has_dos_drive_prefix(Buffer); + if (!dos_drive_prefix) return error("'%s': invalid drive letter", Buffer); - szVolumeAccessPath[4] = Buffer[0]; + memcpy(szVolumeAccessPath, Buffer, dos_drive_prefix); + szVolumeAccessPath[dos_drive_prefix] = '\0'; + hVolWrite = CreateFile(szVolumeAccessPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (INVALID_HANDLE_VALUE == hVolWrite) diff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c index 2786f47088..975f0ac890 100644 --- a/t/helper/test-dump-fsmonitor.c +++ b/t/helper/test-dump-fsmonitor.c @@ -13,7 +13,7 @@ int cmd__dump_fsmonitor(int ac, const char **av) printf("no fsmonitor\n"); return 0; } - printf("fsmonitor last update %"PRIuMAX"\n", (uintmax_t)istate->fsmonitor_last_update); + printf("fsmonitor last update %s\n", istate->fsmonitor_last_update); for (i = 0; i < istate->cache_nr; i++) printf((istate->cache[i]->ce_flags & CE_FSMONITOR_VALID) ? "+" : "-"); diff --git a/t/helper/test-parse-pathspec-file.c b/t/helper/test-parse-pathspec-file.c new file mode 100644 index 0000000000..02f4ccfd2a --- /dev/null +++ b/t/helper/test-parse-pathspec-file.c @@ -0,0 +1,33 @@ +#include "test-tool.h" +#include "parse-options.h" +#include "pathspec.h" +#include "gettext.h" + +int cmd__parse_pathspec_file(int argc, const char **argv) +{ + struct pathspec pathspec; + const char *pathspec_from_file = 0; + int pathspec_file_nul = 0, i; + + static const char *const usage[] = { + "test-tool parse-pathspec-file --pathspec-from-file [--pathspec-file-nul]", + NULL + }; + + struct option options[] = { + OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), + OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul), + OPT_END() + }; + + parse_options(argc, argv, 0, options, usage, 0); + + parse_pathspec_file(&pathspec, 0, 0, 0, pathspec_from_file, + pathspec_file_nul); + + for (i = 0; i < pathspec.nr; i++) + printf("%s\n", pathspec.items[i].original); + + clear_pathspec(&pathspec); + return 0; +} diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index 5d543ad21f..409034cf4e 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -185,6 +185,99 @@ static int cmp_by_st_size(const void *a, const void *b) return x > y ? -1 : (x < y ? +1 : 0); } +/* + * A very simple, reproducible pseudo-random generator. Copied from + * `test-genrandom.c`. + */ +static uint64_t my_random_value = 1234; + +static uint64_t my_random(void) +{ + my_random_value = my_random_value * 1103515245 + 12345; + return my_random_value; +} + +/* + * A fast approximation of the square root, without requiring math.h. + * + * It uses Newton's method to approximate the solution of 0 = x^2 - value. + */ +static double my_sqrt(double value) +{ + const double epsilon = 1e-6; + double x = value; + + if (value == 0) + return 0; + + for (;;) { + double delta = (value / x - x) / 2; + if (delta < epsilon && delta > -epsilon) + return x + delta; + x += delta; + } +} + +static int protect_ntfs_hfs_benchmark(int argc, const char **argv) +{ + size_t i, j, nr, min_len = 3, max_len = 20; + char **names; + int repetitions = 15, file_mode = 0100644; + uint64_t begin, end; + double m[3][2], v[3][2]; + uint64_t cumul; + double cumul2; + + if (argc > 1 && !strcmp(argv[1], "--with-symlink-mode")) { + file_mode = 0120000; + argc--; + argv++; + } + + nr = argc > 1 ? strtoul(argv[1], NULL, 0) : 1000000; + ALLOC_ARRAY(names, nr); + + if (argc > 2) { + min_len = strtoul(argv[2], NULL, 0); + if (argc > 3) + max_len = strtoul(argv[3], NULL, 0); + if (min_len > max_len) + die("min_len > max_len"); + } + + for (i = 0; i < nr; i++) { + size_t len = min_len + (my_random() % (max_len + 1 - min_len)); + + names[i] = xmallocz(len); + while (len > 0) + names[i][--len] = (char)(' ' + (my_random() % ('\x7f' - ' '))); + } + + for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++) + for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) { + cumul = 0; + cumul2 = 0; + for (i = 0; i < repetitions; i++) { + begin = getnanotime(); + for (j = 0; j < nr; j++) + verify_path(names[j], file_mode); + end = getnanotime(); + printf("protect_ntfs = %d, protect_hfs = %d: %lfms\n", protect_ntfs, protect_hfs, (end-begin) / (double)1e6); + cumul += end - begin; + cumul2 += (end - begin) * (end - begin); + } + m[protect_ntfs][protect_hfs] = cumul / (double)repetitions; + v[protect_ntfs][protect_hfs] = my_sqrt(cumul2 / (double)repetitions - m[protect_ntfs][protect_hfs] * m[protect_ntfs][protect_hfs]); + printf("mean: %lfms, stddev: %lfms\n", m[protect_ntfs][protect_hfs] / (double)1e6, v[protect_ntfs][protect_hfs] / (double)1e6); + } + + for (protect_ntfs = 0; protect_ntfs < 2; protect_ntfs++) + for (protect_hfs = 0; protect_hfs < 2; protect_hfs++) + printf("ntfs=%d/hfs=%d: %lf%% slower\n", protect_ntfs, protect_hfs, (m[protect_ntfs][protect_hfs] - m[0][0]) * 100 / m[0][0]); + + return 0; +} + int cmd__path_utils(int argc, const char **argv) { if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) { @@ -355,6 +448,26 @@ int cmd__path_utils(int argc, const char **argv) return !!res; } + if (argc > 1 && !strcmp(argv[1], "protect_ntfs_hfs")) + return !!protect_ntfs_hfs_benchmark(argc - 1, argv + 1); + + if (argc > 1 && !strcmp(argv[1], "is_valid_path")) { + int res = 0, expect = 1, i; + + for (i = 2; i < argc; i++) + if (!strcmp("--not", argv[i])) + expect = 0; + else if (expect != is_valid_path(argv[i])) + res = error("'%s' is%s a valid path", + argv[i], expect ? " not" : ""); + else + fprintf(stderr, + "'%s' is%s a valid path\n", + argv[i], expect ? "" : " not"); + + return !!res; + } + fprintf(stderr, "%s: unknown function name: %s\n", argv[0], argv[1] ? argv[1] : "(there was none)"); return 1; diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c new file mode 100644 index 0000000000..f8a461767c --- /dev/null +++ b/t/helper/test-read-graph.c @@ -0,0 +1,53 @@ +#include "test-tool.h" +#include "cache.h" +#include "commit-graph.h" +#include "repository.h" +#include "object-store.h" + +int cmd__read_graph(int argc, const char **argv) +{ + struct commit_graph *graph = NULL; + char *graph_name; + int open_ok; + int fd; + struct stat st; + struct object_directory *odb; + + setup_git_directory(); + odb = the_repository->objects->odb; + + graph_name = get_commit_graph_filename(odb); + + open_ok = open_commit_graph(graph_name, &fd, &st); + if (!open_ok) + die_errno(_("Could not open commit-graph '%s'"), graph_name); + + graph = load_commit_graph_one_fd_st(fd, &st, odb); + if (!graph) + return 1; + + FREE_AND_NULL(graph_name); + + printf("header: %08x %d %d %d %d\n", + ntohl(*(uint32_t*)graph->data), + *(unsigned char*)(graph->data + 4), + *(unsigned char*)(graph->data + 5), + *(unsigned char*)(graph->data + 6), + *(unsigned char*)(graph->data + 7)); + printf("num_commits: %u\n", graph->num_commits); + printf("chunks:"); + + if (graph->chunk_oid_fanout) + printf(" oid_fanout"); + if (graph->chunk_oid_lookup) + printf(" oid_lookup"); + if (graph->chunk_commit_data) + printf(" commit_metadata"); + if (graph->chunk_extra_edges) + printf(" extra_edges"); + printf("\n"); + + UNLEAK(graph); + + return 0; +} diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index ead6dc611a..1646aa25d8 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -18,8 +18,8 @@ #include "string-list.h" #include "thread-utils.h" #include "wildmatch.h" -#include <string.h> -#include <errno.h> +#include "gettext.h" +#include "parse-options.h" static int number_callbacks; static int parallel_next(struct child_process *cp, @@ -200,6 +200,174 @@ static int testsuite(int argc, const char **argv) return !!ret; } +static uint64_t my_random_next = 1234; + +static uint64_t my_random(void) +{ + uint64_t res = my_random_next; + my_random_next = my_random_next * 1103515245 + 12345; + return res; +} + +static int quote_stress_test(int argc, const char **argv) +{ + /* + * We are running a quote-stress test. + * spawn a subprocess that runs quote-stress with a + * special option that echoes back the arguments that + * were passed in. + */ + char special[] = ".?*\\^_\"'`{}()[]<>@~&+:;$%"; // \t\r\n\a"; + int i, j, k, trials = 100, skip = 0, msys2 = 0; + struct strbuf out = STRBUF_INIT; + struct argv_array args = ARGV_ARRAY_INIT; + struct option options[] = { + OPT_INTEGER('n', "trials", &trials, "Number of trials"), + OPT_INTEGER('s', "skip", &skip, "Skip <n> trials"), + OPT_BOOL('m', "msys2", &msys2, "Test quoting for MSYS2's sh"), + OPT_END() + }; + const char * const usage[] = { + "test-tool run-command quote-stress-test <options>", + NULL + }; + + argc = parse_options(argc, argv, NULL, options, usage, 0); + + setenv("MSYS_NO_PATHCONV", "1", 0); + + for (i = 0; i < trials; i++) { + struct child_process cp = CHILD_PROCESS_INIT; + size_t arg_count, arg_offset; + int ret = 0; + + argv_array_clear(&args); + if (msys2) + argv_array_pushl(&args, "sh", "-c", + "printf %s\\\\0 \"$@\"", "skip", NULL); + else + argv_array_pushl(&args, "test-tool", "run-command", + "quote-echo", NULL); + arg_offset = args.argc; + + if (argc > 0) { + trials = 1; + arg_count = argc; + for (j = 0; j < arg_count; j++) + argv_array_push(&args, argv[j]); + } else { + arg_count = 1 + (my_random() % 5); + for (j = 0; j < arg_count; j++) { + char buf[20]; + size_t min_len = 1; + size_t arg_len = min_len + + (my_random() % (ARRAY_SIZE(buf) - min_len)); + + for (k = 0; k < arg_len; k++) + buf[k] = special[my_random() % + ARRAY_SIZE(special)]; + buf[arg_len] = '\0'; + + argv_array_push(&args, buf); + } + } + + if (i < skip) + continue; + + cp.argv = args.argv; + strbuf_reset(&out); + if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0) + return error("Failed to spawn child process"); + + for (j = 0, k = 0; j < arg_count; j++) { + const char *arg = args.argv[j + arg_offset]; + + if (strcmp(arg, out.buf + k)) + ret = error("incorrectly quoted arg: '%s', " + "echoed back as '%s'", + arg, out.buf + k); + k += strlen(out.buf + k) + 1; + } + + if (k != out.len) + ret = error("got %d bytes, but consumed only %d", + (int)out.len, (int)k); + + if (ret) { + fprintf(stderr, "Trial #%d failed. Arguments:\n", i); + for (j = 0; j < arg_count; j++) + fprintf(stderr, "arg #%d: '%s'\n", + (int)j, args.argv[j + arg_offset]); + + strbuf_release(&out); + argv_array_clear(&args); + + return ret; + } + + if (i && (i % 100) == 0) + fprintf(stderr, "Trials completed: %d\n", (int)i); + } + + strbuf_release(&out); + argv_array_clear(&args); + + return 0; +} + +static int quote_echo(int argc, const char **argv) +{ + while (argc > 1) { + fwrite(argv[1], strlen(argv[1]), 1, stdout); + fputc('\0', stdout); + argv++; + argc--; + } + + return 0; +} + +static int inherit_handle(const char *argv0) +{ + struct child_process cp = CHILD_PROCESS_INIT; + char path[PATH_MAX]; + int tmp; + + /* First, open an inheritable handle */ + xsnprintf(path, sizeof(path), "out-XXXXXX"); + tmp = xmkstemp(path); + + argv_array_pushl(&cp.args, + "test-tool", argv0, "inherited-handle-child", NULL); + cp.in = -1; + cp.no_stdout = cp.no_stderr = 1; + if (start_command(&cp) < 0) + die("Could not start child process"); + + /* Then close it, and try to delete it. */ + close(tmp); + if (unlink(path)) + die("Could not delete '%s'", path); + + if (close(cp.in) < 0 || finish_command(&cp) < 0) + die("Child did not finish"); + + return 0; +} + +static int inherit_handle_child(void) +{ + struct strbuf buf = STRBUF_INIT; + + if (strbuf_read(&buf, 0, 0) < 0) + die("Could not read stdin"); + printf("Received %s\n", buf.buf); + strbuf_release(&buf); + + return 0; +} + int cmd__run_command(int argc, const char **argv) { struct child_process proc = CHILD_PROCESS_INIT; @@ -207,6 +375,16 @@ int cmd__run_command(int argc, const char **argv) if (argc > 1 && !strcmp(argv[1], "testsuite")) exit(testsuite(argc - 1, argv + 1)); + if (!strcmp(argv[1], "inherited-handle")) + exit(inherit_handle(argv[0])); + if (!strcmp(argv[1], "inherited-handle-child")) + exit(inherit_handle_child()); + + if (argc >= 2 && !strcmp(argv[1], "quote-stress-test")) + return !!quote_stress_test(argc - 1, argv + 1); + + if (argc >= 2 && !strcmp(argv[1], "quote-echo")) + return !!quote_echo(argc - 1, argv + 1); if (argc < 3) return 1; diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 19ee26d931..c9a232d238 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -39,12 +39,14 @@ static struct test_cmd cmds[] = { { "oidmap", cmd__oidmap }, { "online-cpus", cmd__online_cpus }, { "parse-options", cmd__parse_options }, + { "parse-pathspec-file", cmd__parse_pathspec_file }, { "path-utils", cmd__path_utils }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, + { "read-graph", cmd__read_graph }, { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, { "regex", cmd__regex }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index c2aa56ef50..c8549fd87f 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -29,12 +29,14 @@ int cmd__mktemp(int argc, const char **argv); int cmd__oidmap(int argc, const char **argv); int cmd__online_cpus(int argc, const char **argv); int cmd__parse_options(int argc, const char **argv); +int cmd__parse_pathspec_file(int argc, const char** argv); int cmd__path_utils(int argc, const char **argv); int cmd__pkt_line(int argc, const char **argv); int cmd__prio_queue(int argc, const char **argv); int cmd__progress(int argc, const char **argv); int cmd__reach(int argc, const char **argv); int cmd__read_cache(int argc, const char **argv); +int cmd__read_graph(int argc, const char **argv); int cmd__read_midx(int argc, const char **argv); int cmd__ref_store(int argc, const char **argv); int cmd__regex(int argc, const char **argv); diff --git a/t/lib-bash.sh b/t/lib-bash.sh index 2be955fafb..b0b6060929 100644 --- a/t/lib-bash.sh +++ b/t/lib-bash.sh @@ -2,10 +2,12 @@ # to run under Bash; primarily intended for tests of the completion # script. -if test -n "$BASH" && test -z "$POSIXLY_CORRECT"; then +if test -n "$BASH" && test -z "$POSIXLY_CORRECT" +then # we are in full-on bash mode true -elif type bash >/dev/null 2>&1; then +elif type bash >/dev/null 2>&1 +then # execute in full-on bash mode unset POSIXLY_CORRECT exec bash "$0" "$@" diff --git a/t/lib-git-daemon.sh b/t/lib-git-daemon.sh index fb8f887080..e62569222b 100644 --- a/t/lib-git-daemon.sh +++ b/t/lib-git-daemon.sh @@ -15,7 +15,7 @@ # # test_done -if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON +if ! test_bool_env GIT_TEST_GIT_DAEMON true then skip_all="git-daemon testing disabled (unset GIT_TEST_GIT_DAEMON to enable)" test_done diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh index 547b9f88e1..5aff2abe8b 100644 --- a/t/lib-git-p4.sh +++ b/t/lib-git-p4.sh @@ -175,7 +175,7 @@ stop_and_cleanup_p4d () { cleanup_git () { retry_until_success rm -r "$git" - test_must_fail test -d "$git" && + test_path_is_missing "$git" && retry_until_success mkdir "$git" } diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index bc0b9c71f8..7d248e6588 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -69,7 +69,7 @@ svn_cmd () { maybe_start_httpd () { loc=${1-svn} - if git env--helper --type=bool --default=false --exit-code GIT_TEST_SVN_HTTPD + if test_bool_env GIT_TEST_SVN_HTTPD false then . "$TEST_DIRECTORY"/lib-httpd.sh LIB_HTTPD_SVN="$loc" @@ -104,7 +104,7 @@ EOF } require_svnserve () { - if ! git env--helper --type=bool --default=false --exit-code GIT_TEST_SVNSERVE + if ! test_bool_env GIT_TEST_SVNSERVE false then skip_all='skipping svnserve test. (set $GIT_TEST_SVNSERVE to enable)' test_done diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index 0d985758c6..656997b4d6 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -41,7 +41,7 @@ then test_done fi -if ! git env--helper --type=bool --default=true --exit-code GIT_TEST_HTTPD +if ! test_bool_env GIT_TEST_HTTPD true then skip_all="Network testing disabled (unset GIT_TEST_HTTPD to enable)" test_done diff --git a/t/lib-httpd/apply-one-time-sed.sh b/t/lib-httpd/apply-one-time-sed.sh index fcef728925..bf7689d020 100644 --- a/t/lib-httpd/apply-one-time-sed.sh +++ b/t/lib-httpd/apply-one-time-sed.sh @@ -7,11 +7,13 @@ # # This can be used to simulate the effects of the repository changing in # between HTTP request-response pairs. -if [ -e one-time-sed ]; then +if test -f one-time-sed +then "$GIT_EXEC_PATH/git-http-backend" >out - sed "$(cat one-time-sed)" <out >out_modified + sed "$(cat one-time-sed)" out >out_modified - if diff out out_modified >/dev/null; then + if cmp -s out out_modified + then cat out else cat out_modified diff --git a/t/lib-pack.sh b/t/lib-pack.sh index c4d907a450..f3463170b3 100644 --- a/t/lib-pack.sh +++ b/t/lib-pack.sh @@ -35,9 +35,11 @@ pack_header () { # have hardcoded some well-known objects. See the case statements below for the # complete list. pack_obj () { + test_oid_init + case "$1" in # empty blob - e69de29bb2d1d6434b8b29ae775ad8c2e48c5391) + $EMPTY_BLOB) case "$2" in '') printf '\060\170\234\003\0\0\0\0\1' @@ -47,7 +49,7 @@ pack_obj () { ;; # blob containing "\7\76" - e68fe8129b546b101aee9510c5328e7f21ca1d18) + $(test_oid packlib_7_76)) case "$2" in '') printf '\062\170\234\143\267\3\0\0\116\0\106' @@ -59,11 +61,18 @@ pack_obj () { printf '\234\143\142\142\142\267\003\0\0\151\0\114' return ;; + 37c8e2c15bb22b912e59b43fd51a4f7e9465ed0b5084c5a1411d991cbe630683) + printf '\165\67\310\342\301\133\262\53\221\56\131' && + printf '\264\77\325\32\117\176\224\145\355\13\120' && + printf '\204\305\241\101\35\231\34\276\143\6\203\170' && + printf '\234\143\142\142\142\267\003\0\0\151\0\114' + return + ;; esac ;; # blob containing "\7\0" - 01d7713666f4de822776c7622c10f1b07de280dc) + $(test_oid packlib_7_0)) case "$2" in '') printf '\062\170\234\143\147\0\0\0\20\0\10' @@ -75,6 +84,13 @@ pack_obj () { printf '\143\142\142\142\147\0\0\0\53\0\16' return ;; + 5d8e6fc40f2dab00e6983a48523fe57e621f46434cb58dbd4422fba03380d886) + printf '\165\135\216\157\304\17\55\253\0\346\230\72' && + printf '\110\122\77\345\176\142\37\106\103\114\265' && + printf '\215\275\104\42\373\240\63\200\330\206\170\234' && + printf '\143\142\142\142\147\0\0\0\53\0\16' + return + ;; esac ;; esac @@ -86,7 +102,7 @@ pack_obj () { then echo "$1" | git pack-objects --stdout >pack_obj.tmp && size=$(wc -c <pack_obj.tmp) && - dd if=pack_obj.tmp bs=1 count=$((size - 20 - 12)) skip=12 && + dd if=pack_obj.tmp bs=1 count=$((size - $(test_oid rawsz) - 12)) skip=12 && rm -f pack_obj.tmp return fi @@ -97,7 +113,8 @@ pack_obj () { # Compute and append pack trailer to "$1" pack_trailer () { - test-tool sha1 -b <"$1" >trailer.tmp && + test_oid_init && + test-tool $(test_oid algo) -b <"$1" >trailer.tmp && cat trailer.tmp >>"$1" && rm -f trailer.tmp } @@ -108,3 +125,11 @@ pack_trailer () { clear_packs () { rm -f .git/objects/pack/* } + +test_oid_cache <<-EOF +packlib_7_0 sha1:01d7713666f4de822776c7622c10f1b07de280dc +packlib_7_0 sha256:37c8e2c15bb22b912e59b43fd51a4f7e9465ed0b5084c5a1411d991cbe630683 + +packlib_7_76 sha1:e68fe8129b546b101aee9510c5328e7f21ca1d18 +packlib_7_76 sha256:5d8e6fc40f2dab00e6983a48523fe57e621f46434cb58dbd4422fba03380d886 +EOF diff --git a/t/perf/aggregate.perl b/t/perf/aggregate.perl index 66554d2161..14e4cda287 100755 --- a/t/perf/aggregate.perl +++ b/t/perf/aggregate.perl @@ -4,7 +4,6 @@ use lib '../../perl/build/lib'; use strict; use warnings; use Getopt::Long; -use Git; use Cwd qw(realpath); sub get_times { @@ -85,6 +84,11 @@ sub format_size { return $out; } +sub sane_backticks { + open(my $fh, '-|', @_); + return <$fh>; +} + my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests, $codespeed, $sortby, $subsection, $reponame); @@ -102,7 +106,8 @@ while (scalar @ARGV) { my $prefix = ''; last if -f $arg or $arg eq "--"; if (! -d $arg) { - my $rev = Git::command_oneline(qw(rev-parse --verify), $arg); + my $rev = sane_backticks(qw(git rev-parse --verify), $arg); + chomp $rev; $dir = "build/".$rev; } elsif ($arg eq '.') { $dir = '.'; @@ -219,13 +224,7 @@ sub print_default_results { for my $i (0..$#dirs) { my $d = $dirs[$i]; my $base = "$resultsdir/$prefixes{$d}$t"; - $times{$prefixes{$d}.$t} = []; - foreach my $type (qw(times size)) { - if (-e "$base.$type") { - $times{$prefixes{$d}.$t} = [get_times("$base.$type")]; - last; - } - } + $times{$prefixes{$d}.$t} = [get_times("$base.result")]; my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}}; my $w = length format_times($r,$u,$s,$firstr); $colwidth[$i] = $w if $w > $colwidth[$i]; @@ -267,7 +266,7 @@ sub print_sorted_results { my ($prevr, $prevu, $prevs, $prevrev); for my $i (0..$#dirs) { my $d = $dirs[$i]; - my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times"); + my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.result"); if ($i > 0 and defined $r and defined $prevr and $prevr > 0) { my $percent = 100.0 * ($r - $prevr) / $prevr; push @evolutions, { "percent" => $percent, @@ -327,7 +326,7 @@ sub print_codespeed_results { my $commitid = $prefixes{$d}; $commitid =~ s/^build_//; $commitid =~ s/\.$//; - my ($result_value, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times"); + my ($result_value, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.result"); my %vals = ( "commitid" => $commitid, diff --git a/t/perf/bisect_regression b/t/perf/bisect_regression index a94d9955d0..ce47e1662a 100755 --- a/t/perf/bisect_regression +++ b/t/perf/bisect_regression @@ -51,7 +51,7 @@ oldtime=$(echo "$oldtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/') newtime=$(echo "$newtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/') test $(echo "$newtime" "$oldtime" | awk '{ print ($1 > $2) }') = 1 || - die "New time '$newtime' shoud be greater than old time '$oldtime'" + die "New time '$newtime' should be greater than old time '$oldtime'" tmpdir=$(mktemp -d -t bisect_regression_XXXXXX) || die "Failed to create temp directory" echo "$oldtime" >"$tmpdir/oldtime" || die "Failed to write to '$tmpdir/oldtime'" diff --git a/t/perf/p5303-many-packs.sh b/t/perf/p5303-many-packs.sh index 3779851941..7ee791669a 100755 --- a/t/perf/p5303-many-packs.sh +++ b/t/perf/p5303-many-packs.sh @@ -77,6 +77,7 @@ do # actual pack generation, without smudging the on-disk setup # between trials. test_perf "repack ($nr_packs)" ' + GIT_TEST_FULL_IN_PACK_ARRAY=1 \ git pack-objects --keep-true-parents \ --honor-pack-keep --non-empty --all \ --reflog --indexed-objects --delta-base-offset \ @@ -84,4 +85,22 @@ do ' done +# Measure pack loading with 10,000 packs. +test_expect_success 'generate lots of packs' ' + for i in $(test_seq 10000); do + echo "blob" + echo "data <<EOF" + echo "blob $i" + echo "EOF" + echo "checkpoint" + done | + git -c fastimport.unpackLimit=0 fast-import +' + +# The purpose of this test is to evaluate load time for a large number +# of packs while doing as little other work as possible. +test_perf "load 10,000 packs" ' + git rev-parse --verify "HEAD^{commit}" +' + test_done diff --git a/t/perf/p5310-pack-bitmaps.sh b/t/perf/p5310-pack-bitmaps.sh index 6a3a42531b..7743f4f4c9 100755 --- a/t/perf/p5310-pack-bitmaps.sh +++ b/t/perf/p5310-pack-bitmaps.sh @@ -39,6 +39,28 @@ test_perf 'pack to file (bitmap)' ' git pack-objects --use-bitmap-index --all pack1b </dev/null >/dev/null ' +test_perf 'rev-list (commits)' ' + git rev-list --all --use-bitmap-index >/dev/null +' + +test_perf 'rev-list (objects)' ' + git rev-list --all --use-bitmap-index --objects >/dev/null +' + +test_perf 'rev-list count with blob:none' ' + git rev-list --use-bitmap-index --count --objects --all \ + --filter=blob:none >/dev/null +' + +test_perf 'rev-list count with blob:limit=1k' ' + git rev-list --use-bitmap-index --count --objects --all \ + --filter=blob:limit=1k >/dev/null +' + +test_perf 'simulated partial clone' ' + git pack-objects --stdout --all --filter=blob:none </dev/null >/dev/null +' + test_expect_success 'create partial bitmap state' ' # pick a commit to represent the repo tip in the past cutoff=$(git rev-list HEAD~100 -1) && diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index b58a43ea43..13e389367a 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -214,7 +214,7 @@ test_perf_ () { else test_ok_ "$1" fi - "$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".times + "$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".result } test_perf () { @@ -223,7 +223,7 @@ test_perf () { test_size_ () { say >&3 "running: $2" - if test_eval_ "$2" 3>"$base".size; then + if test_eval_ "$2" 3>"$base".result; then test_ok_ "$1" else test_failure_ "$@" diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 4d3f7ba295..3e440c078d 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -20,9 +20,9 @@ modification *should* take notice and update the test vectors here. . ./test-lib.sh -try_local_x () { - local x="local" && - echo "$x" +try_local_xy () { + local x="local" y="alsolocal" && + echo "$x $y" } # Check whether the shell supports the "local" keyword. "local" is not @@ -35,11 +35,12 @@ try_local_x () { # relying on "local". test_expect_success 'verify that the running shell supports "local"' ' x="notlocal" && - echo "local" >expected1 && - try_local_x >actual1 && + y="alsonotlocal" && + echo "local alsolocal" >expected1 && + try_local_xy >actual1 && test_cmp expected1 actual1 && - echo "notlocal" >expected2 && - echo "$x" >actual2 && + echo "notlocal alsonotlocal" >expected2 && + echo "$x $y" >actual2 && test_cmp expected2 actual2 ' @@ -126,7 +127,7 @@ check_sub_test_lib_test () { check_sub_test_lib_test_err () { name="$1" # stdin is the expected output from the test - # expected error output is in descriptior 3 + # expected error output is in descriptor 3 ( cd "$name" && sed -e 's/^> //' -e 's/Z$//' >expect.out && @@ -154,7 +155,7 @@ test_expect_success 'pretend we have a fully passing test suite' " " test_expect_success 'pretend we have a partially passing test suite' " - test_must_fail run_sub_test_lib_test \ + run_sub_test_lib_test_err \ partial-pass '2/3 tests passing' <<-\\EOF && test_expect_success 'passing test #1' 'true' test_expect_success 'failing test #2' 'false' @@ -218,7 +219,7 @@ test_expect_success 'pretend we have fixed one of two known breakages (run in su " test_expect_success 'pretend we have a pass, fail, and known breakage' " - test_must_fail run_sub_test_lib_test \ + run_sub_test_lib_test_err \ mixed-results1 'mixed results #1' <<-\\EOF && test_expect_success 'passing test' 'true' test_expect_success 'failing test' 'false' @@ -237,7 +238,7 @@ test_expect_success 'pretend we have a pass, fail, and known breakage' " " test_expect_success 'pretend we have a mix of all possible results' " - test_must_fail run_sub_test_lib_test \ + run_sub_test_lib_test_err \ mixed-results2 'mixed results #2' <<-\\EOF && test_expect_success 'passing test' 'true' test_expect_success 'passing test' 'true' @@ -273,7 +274,7 @@ test_expect_success 'pretend we have a mix of all possible results' " " test_expect_success C_LOCALE_OUTPUT 'test --verbose' ' - test_must_fail run_sub_test_lib_test \ + run_sub_test_lib_test_err \ t1234-verbose "test verbose" --verbose <<-\EOF && test_expect_success "passing test" true test_expect_success "test with output" "echo foo" @@ -300,7 +301,7 @@ test_expect_success C_LOCALE_OUTPUT 'test --verbose' ' ' test_expect_success 'test --verbose-only' ' - test_must_fail run_sub_test_lib_test \ + run_sub_test_lib_test_err \ t2345-verbose-only-2 "test verbose-only=2" \ --verbose-only=2 <<-\EOF && test_expect_success "passing test" true @@ -833,7 +834,7 @@ then fi test_expect_success 'tests clean up even on failures' " - test_must_fail run_sub_test_lib_test \ + run_sub_test_lib_test_err \ failing-cleanup 'Failing tests with cleanup commands' <<-\\EOF && test_expect_success 'tests clean up even after a failure' ' touch clean-after-failure && @@ -862,7 +863,7 @@ test_expect_success 'tests clean up even on failures' " " test_expect_success 'test_atexit is run' " - test_must_fail run_sub_test_lib_test \ + run_sub_test_lib_test_err \ atexit-cleanup 'Run atexit commands' -i <<-\\EOF && test_expect_success 'tests clean up even after a failure' ' > ../../clean-atexit && @@ -916,6 +917,40 @@ test_expect_success 'test_oid can look up data for SHA-256' ' test "$hexsz" -eq 64 ' +test_expect_success 'test_bool_env' ' + ( + sane_unset envvar && + + test_bool_env envvar true && + ! test_bool_env envvar false && + + envvar= && + export envvar && + ! test_bool_env envvar true && + ! test_bool_env envvar false && + + envvar=true && + test_bool_env envvar true && + test_bool_env envvar false && + + envvar=false && + ! test_bool_env envvar true && + ! test_bool_env envvar false && + + envvar=invalid && + # When encountering an invalid bool value, test_bool_env + # prints its error message to the original stderr of the + # test script, hence the redirection of fd 7, and aborts + # with "exit 1", hence the subshell. + ! ( test_bool_env envvar true ) 7>err && + grep "error: test_bool_env requires bool values" err && + + envvar=true && + ! ( test_bool_env envvar invalid ) 7>err && + grep "error: test_bool_env requires bool values" err + ) +' + ################################################################ # Basics of the basics diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 71e63d8b50..b660593c20 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -5,19 +5,16 @@ test_description=gitattributes . ./test-lib.sh attr_check () { - path="$1" expect="$2" + path="$1" expect="$2" git_opts="$3" && - git $3 check-attr test -- "$path" >actual 2>err && - echo "$path: test: $2" >expect && + git $git_opts check-attr test -- "$path" >actual 2>err && + echo "$path: test: $expect" >expect && test_cmp expect actual && - test_line_count = 0 err + test_must_be_empty err } attr_check_quote () { - - path="$1" - quoted_path="$2" - expect="$3" + path="$1" quoted_path="$2" expect="$3" && git check-attr test -- "$path" >actual && echo "\"$quoted_path\": test: $expect" >expect && @@ -27,7 +24,7 @@ attr_check_quote () { test_expect_success 'open-quoted pathname' ' echo "\"a test=a" >.gitattributes && - test_must_fail attr_check a a + attr_check a unspecified ' @@ -112,20 +109,20 @@ test_expect_success 'attribute test' ' test_expect_success 'attribute matching is case sensitive when core.ignorecase=0' ' - test_must_fail attr_check F f "-c core.ignorecase=0" && - test_must_fail attr_check a/F f "-c core.ignorecase=0" && - test_must_fail attr_check a/c/F f "-c core.ignorecase=0" && - test_must_fail attr_check a/G a/g "-c core.ignorecase=0" && - test_must_fail attr_check a/B/g a/b/g "-c core.ignorecase=0" && - test_must_fail attr_check a/b/G a/b/g "-c core.ignorecase=0" && - test_must_fail attr_check a/b/H a/b/h "-c core.ignorecase=0" && - test_must_fail attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=0" && - test_must_fail attr_check oNoFf unset "-c core.ignorecase=0" && - test_must_fail attr_check oFfOn set "-c core.ignorecase=0" && + attr_check F unspecified "-c core.ignorecase=0" && + attr_check a/F unspecified "-c core.ignorecase=0" && + attr_check a/c/F unspecified "-c core.ignorecase=0" && + attr_check a/G unspecified "-c core.ignorecase=0" && + attr_check a/B/g a/g "-c core.ignorecase=0" && + attr_check a/b/G unspecified "-c core.ignorecase=0" && + attr_check a/b/H unspecified "-c core.ignorecase=0" && + attr_check a/b/D/g a/g "-c core.ignorecase=0" && + attr_check oNoFf unspecified "-c core.ignorecase=0" && + attr_check oFfOn unspecified "-c core.ignorecase=0" && attr_check NO unspecified "-c core.ignorecase=0" && - test_must_fail attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=0" && + attr_check a/b/D/NO unspecified "-c core.ignorecase=0" && attr_check a/b/d/YES a/b/d/* "-c core.ignorecase=0" && - test_must_fail attr_check a/E/f "A/e/F" "-c core.ignorecase=0" + attr_check a/E/f f "-c core.ignorecase=0" ' @@ -149,8 +146,8 @@ test_expect_success 'attribute matching is case insensitive when core.ignorecase ' test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' ' - test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" && - test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" && + attr_check a/B/D/g a/g "-c core.ignorecase=0" && + attr_check A/B/D/NO unspecified "-c core.ignorecase=0" && attr_check A/b/h a/b/h "-c core.ignorecase=1" && attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" && attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1" @@ -244,7 +241,7 @@ EOF git check-attr foo -- "a/b/f" >>actual 2>>err && git check-attr foo -- "a/b/c/f" >>actual 2>>err && test_cmp expect actual && - test_line_count = 0 err + test_must_be_empty err ' test_expect_success '"**" with no slashes test' ' @@ -265,7 +262,7 @@ EOF git check-attr foo -- "a/b/f" >>actual 2>>err && git check-attr foo -- "a/b/c/f" >>actual 2>>err && test_cmp expect actual && - test_line_count = 0 err + test_must_be_empty err ' test_expect_success 'using --git-dir and --work-tree' ' diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 1744cee5e9..370a389e5c 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -424,9 +424,24 @@ test_expect_success 'local ignore inside a sub-directory with --verbose' ' ) ' -test_expect_success_multi 'nested include' \ - 'a/b/.gitignore:8:!on* a/b/one' ' - test_check_ignore "a/b/one" +test_expect_success 'nested include of negated pattern' ' + expect "" && + test_check_ignore "a/b/one" 1 +' + +test_expect_success 'nested include of negated pattern with -q' ' + expect "" && + test_check_ignore "-q a/b/one" 1 +' + +test_expect_success 'nested include of negated pattern with -v' ' + expect "a/b/.gitignore:8:!on* a/b/one" && + test_check_ignore "-v a/b/one" 0 +' + +test_expect_success 'nested include of negated pattern with -v -n' ' + expect "a/b/.gitignore:8:!on* a/b/one" && + test_check_ignore "-v -n a/b/one" 0 ' ############################################################################ @@ -460,7 +475,6 @@ test_expect_success 'cd to ignored sub-directory' ' expect_from_stdin <<-\EOF && foo twoooo - ../one seven ../../one EOF @@ -543,7 +557,6 @@ test_expect_success 'global ignore' ' globalthree a/globalthree a/per-repo - globaltwo EOF test_check_ignore "globalone per-repo globalthree a/globalthree a/per-repo not-ignored globaltwo" ' @@ -586,17 +599,7 @@ EOF cat <<-\EOF >expected-default one a/one - a/b/on - a/b/one - a/b/one one - a/b/one two - "a/b/one\"three" - a/b/two a/b/twooo - globaltwo - a/globaltwo - a/b/globaltwo - b/globaltwo EOF cat <<-EOF >expected-verbose .gitignore:1:one one @@ -696,8 +699,12 @@ cat <<-EOF >expected-all $global_excludes:2:!globaltwo ../b/globaltwo :: c/not-ignored EOF +cat <<-EOF >expected-default +../one +one +b/twooo +EOF grep -v '^:: ' expected-all >expected-verbose -sed -e 's/.* //' expected-verbose >expected-default broken_c_unquote stdin >stdin0 diff --git a/t/t0014-alias.sh b/t/t0014-alias.sh index 2694c81afd..8d3d9144c0 100755 --- a/t/t0014-alias.sh +++ b/t/t0014-alias.sh @@ -38,8 +38,8 @@ test_expect_success 'looping aliases - internal execution' ' #' test_expect_success 'run-command formats empty args properly' ' - GIT_TRACE=1 git frotz a "" b " " c 2>&1 | - sed -ne "/run_command:/s/.*trace: run_command: //p" >actual && + test_must_fail env GIT_TRACE=1 git frotz a "" b " " c 2>actual.raw && + sed -ne "/run_command:/s/.*trace: run_command: //p" actual.raw >actual && echo "git-frotz a '\'''\'' b '\'' '\'' c" >expect && test_cmp expect actual ' diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index 854da0ae16..b63ba62e5d 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -159,8 +159,8 @@ test_expect_success 'checkout with autocrlf=input' ' rm -f tmp one dir/two three && git config core.autocrlf input && git read-tree --reset -u HEAD && - test_must_fail has_cr one && - test_must_fail has_cr dir/two && + ! has_cr one && + ! has_cr dir/two && git update-index -- one dir/two && test "$one" = $(git hash-object --stdin <one) && test "$two" = $(git hash-object --stdin <dir/two) && @@ -237,9 +237,9 @@ test_expect_success '.gitattributes says two is binary' ' git config core.autocrlf true && git read-tree --reset -u HEAD && - test_must_fail has_cr dir/two && + ! has_cr dir/two && verbose has_cr one && - test_must_fail has_cr three + ! has_cr three ' test_expect_success '.gitattributes says two is input' ' @@ -248,7 +248,7 @@ test_expect_success '.gitattributes says two is input' ' echo "two crlf=input" >.gitattributes && git read-tree --reset -u HEAD && - test_must_fail has_cr dir/two + ! has_cr dir/two ' test_expect_success '.gitattributes says two and three are text' ' @@ -270,7 +270,7 @@ test_expect_success 'in-tree .gitattributes (1)' ' rm -rf tmp one dir .gitattributes patch.file three && git read-tree --reset -u HEAD && - test_must_fail has_cr one && + ! has_cr one && verbose has_cr three ' @@ -280,7 +280,7 @@ test_expect_success 'in-tree .gitattributes (2)' ' git read-tree --reset HEAD && git checkout-index -f -q -u -a && - test_must_fail has_cr one && + ! has_cr one && verbose has_cr three ' @@ -291,7 +291,7 @@ test_expect_success 'in-tree .gitattributes (3)' ' git checkout-index -u .gitattributes && git checkout-index -u one dir/two three && - test_must_fail has_cr one && + ! has_cr one && verbose has_cr three ' @@ -302,7 +302,7 @@ test_expect_success 'in-tree .gitattributes (4)' ' git checkout-index -u one dir/two three && git checkout-index -u .gitattributes && - test_must_fail has_cr one && + ! has_cr one && verbose has_cr three ' diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index c954c709ad..6c6d77b51a 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -35,7 +35,7 @@ filter_git () { # Compare two files and ensure that `clean` and `smudge` respectively are # called at least once if specified in the `expect` file. The actual # invocation count is not relevant because their number can vary. -# c.f. http://public-inbox.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/ +# c.f. http://lore.kernel.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/ test_cmp_count () { expect=$1 actual=$2 @@ -50,7 +50,7 @@ test_cmp_count () { # Compare two files but exclude all `clean` invocations because Git can # call `clean` zero or more times. -# c.f. http://public-inbox.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/ +# c.f. http://lore.kernel.org/git/xmqqshv18i8i.fsf@gitster.mtv.corp.google.com/ test_cmp_exclude_clean () { expect=$1 actual=$2 diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh index 959b6da449..9fcd56fab3 100755 --- a/t/t0027-auto-crlf.sh +++ b/t/t0027-auto-crlf.sh @@ -215,7 +215,7 @@ stats_ascii () { } -# contruct the attr/ returned by git ls-files --eol +# construct the attr/ returned by git ls-files --eol # Take none (=empty), one or two args # convert.c: eol=XX overrides text=auto attr_ascii () { diff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh index 7aa0945d8d..bfc4fb9af5 100755 --- a/t/t0028-working-tree-encoding.sh +++ b/t/t0028-working-tree-encoding.sh @@ -17,7 +17,7 @@ test_lazy_prereq NO_UTF32_BOM ' write_utf16 () { if test_have_prereq NO_UTF16_BOM then - printf '\xfe\xff' + printf '\376\377' fi && iconv -f UTF-8 -t UTF-16 } @@ -25,7 +25,7 @@ write_utf16 () { write_utf32 () { if test_have_prereq NO_UTF32_BOM then - printf '\x00\x00\xfe\xff' + printf '\0\0\376\377' fi && iconv -f UTF-8 -t UTF-32 } diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 705a136ed9..9d7c7fdaa2 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -242,7 +242,7 @@ test_expect_success 'Alias options do not contribute to abbreviation' ' ' cat >typo.err <<\EOF -error: did you mean `--boolean` (with two dashes ?) +error: did you mean `--boolean` (with two dashes)? EOF test_expect_success 'detect possible typos' ' @@ -252,7 +252,7 @@ test_expect_success 'detect possible typos' ' ' cat >typo.err <<\EOF -error: did you mean `--ambiguous` (with two dashes ?) +error: did you mean `--ambiguous` (with two dashes)? EOF test_expect_success 'detect possible typos' ' diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 501e1a288d..2ea2d00c39 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -165,6 +165,15 @@ test_expect_success 'absolute path rejects the empty string' ' test_must_fail test-tool path-utils absolute_path "" ' +test_expect_success MINGW '<drive-letter>:\\abc is an absolute path' ' + for letter in : \" C Z 1 ä + do + path=$letter:\\abc && + absolute="$(test-tool path-utils absolute_path "$path")" && + test "$path" = "$absolute" || return 1 + done +' + test_expect_success 'real path rejects the empty string' ' test_must_fail test-tool path-utils real_path "" ' @@ -285,8 +294,10 @@ test_git_path GIT_OBJECT_DIRECTORY=foo objects/foo foo/foo test_git_path GIT_OBJECT_DIRECTORY=foo objects2 .git/objects2 test_expect_success 'setup common repository' 'git --git-dir=bar init' test_git_path GIT_COMMON_DIR=bar index .git/index +test_git_path GIT_COMMON_DIR=bar index.lock .git/index.lock test_git_path GIT_COMMON_DIR=bar HEAD .git/HEAD test_git_path GIT_COMMON_DIR=bar logs/HEAD .git/logs/HEAD +test_git_path GIT_COMMON_DIR=bar logs/HEAD.lock .git/logs/HEAD.lock test_git_path GIT_COMMON_DIR=bar logs/refs/bisect/foo .git/logs/refs/bisect/foo test_git_path GIT_COMMON_DIR=bar logs/refs bar/logs/refs test_git_path GIT_COMMON_DIR=bar logs/refs/ bar/logs/refs/ @@ -425,6 +436,9 @@ test_expect_success 'match .gitmodules' ' ~1000000 \ ~9999999 \ \ + .gitmodules:\$DATA \ + "gitmod~4 . :\$DATA" \ + \ --not \ ".gitmodules x" \ ".gitmodules .x" \ @@ -449,7 +463,34 @@ test_expect_success 'match .gitmodules' ' \ GI7EB~1 \ GI7EB~01 \ - GI7EB~1X + GI7EB~1X \ + \ + .gitmodules,:\$DATA +' + +test_expect_success MINGW 'is_valid_path() on Windows' ' + test-tool path-utils is_valid_path \ + win32 \ + "win32 x" \ + ../hello.txt \ + C:\\git \ + comm \ + conout.c \ + lptN \ + \ + --not \ + "win32 " \ + "win32 /x " \ + "win32." \ + "win32 . ." \ + .../hello.txt \ + colon:test \ + "AUX.c" \ + "abc/conOut\$ .xyz/test" \ + lpt8 \ + "lpt*" \ + Nul \ + "PRN./abc" ' test_done diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 17c9c0f3bb..7d599675e3 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -12,6 +12,10 @@ cat >hello-script <<-EOF cat hello-script EOF +test_expect_success MINGW 'subprocess inherits only std handles' ' + test-tool run-command inherited-handle +' + test_expect_success 'start_command reports ENOENT (slash)' ' test-tool run-command start-command-ENOENT ./does-not-exist 2>err && test_i18ngrep "\./does-not-exist" err diff --git a/t/t0067-parse_pathspec_file.sh b/t/t0067-parse_pathspec_file.sh new file mode 100755 index 0000000000..7bab49f361 --- /dev/null +++ b/t/t0067-parse_pathspec_file.sh @@ -0,0 +1,108 @@ +#!/bin/sh + +test_description='Test parse_pathspec_file()' + +. ./test-lib.sh + +test_expect_success 'one item from stdin' ' + cat >expect <<-\EOF && + fileA.t + EOF + + echo fileA.t | + test-tool parse-pathspec-file --pathspec-from-file=- >actual && + + test_cmp expect actual +' + +test_expect_success 'one item from file' ' + cat >expect <<-\EOF && + fileA.t + EOF + + echo fileA.t >list && + test-tool parse-pathspec-file --pathspec-from-file=list >actual && + + test_cmp expect actual +' + +test_expect_success 'NUL delimiters' ' + cat >expect <<-\EOF && + fileA.t + fileB.t + EOF + + printf "fileA.t\0fileB.t\0" | + test-tool parse-pathspec-file --pathspec-from-file=- --pathspec-file-nul >actual && + + test_cmp expect actual +' + +test_expect_success 'LF delimiters' ' + cat >expect <<-\EOF && + fileA.t + fileB.t + EOF + + printf "fileA.t\nfileB.t\n" | + test-tool parse-pathspec-file --pathspec-from-file=- >actual && + + test_cmp expect actual +' + +test_expect_success 'no trailing delimiter' ' + cat >expect <<-\EOF && + fileA.t + fileB.t + EOF + + printf "fileA.t\nfileB.t" | + test-tool parse-pathspec-file --pathspec-from-file=- >actual && + + test_cmp expect actual +' + +test_expect_success 'CRLF delimiters' ' + cat >expect <<-\EOF && + fileA.t + fileB.t + EOF + + printf "fileA.t\r\nfileB.t\r\n" | + test-tool parse-pathspec-file --pathspec-from-file=- >actual && + + test_cmp expect actual +' + +test_expect_success 'quotes' ' + cat >expect <<-\EOF && + fileA.t + EOF + + cat >list <<-\EOF && + "file\101.t" + EOF + + test-tool parse-pathspec-file --pathspec-from-file=list >actual && + + test_cmp expect actual +' + +test_expect_success '--pathspec-file-nul takes quotes literally' ' + # Note: there is an extra newline because --pathspec-file-nul takes + # input \n literally, too + cat >expect <<-\EOF && + "file\101.t" + + EOF + + cat >list <<-\EOF && + "file\101.t" + EOF + + test-tool parse-pathspec-file --pathspec-from-file=list --pathspec-file-nul >actual && + + test_cmp expect actual +' + +test_done diff --git a/t/t0090-cache-tree.sh b/t/t0090-cache-tree.sh index ce9a4a5f32..5a633690bf 100755 --- a/t/t0090-cache-tree.sh +++ b/t/t0090-cache-tree.sh @@ -21,9 +21,10 @@ generate_expected_cache_tree_rec () { parent="$2" && # ls-files might have foo/bar, foo/bar/baz, and foo/bar/quux # We want to count only foo because it's the only direct child - subtrees=$(git ls-files|grep /|cut -d / -f 1|uniq) && + git ls-files >files && + subtrees=$(grep / files|cut -d / -f 1|uniq) && subtree_count=$(echo "$subtrees"|awk -v c=0 '$1 != "" {++c} END {print c}') && - entries=$(git ls-files|wc -l) && + entries=$(wc -l <files) && printf "SHA $dir (%d entries, %d subtrees)\n" "$entries" "$subtree_count" && for subtree in $subtrees do diff --git a/t/t0500-progress-display.sh b/t/t0500-progress-display.sh index 24ccbd8d3b..d2d088d9a0 100755 --- a/t/t0500-progress-display.sh +++ b/t/t0500-progress-display.sh @@ -76,7 +76,7 @@ EOF ' test_expect_success 'progress display breaks long lines #2' ' - # Note: we dont need that many spaces after the title to cover up + # Note: we do not need that many spaces after the title to cover up # the last line before breaking the progress line. sed -e "s/Z$//" >expect <<\EOF && Working hard.......2.........3.........4.........5.........6: 0% (1/100000)<CR> @@ -104,7 +104,7 @@ EOF ' test_expect_success 'progress display breaks long lines #3 - even the first is too long' ' - # Note: we dont actually need any spaces at the end of the title + # Note: we do not actually need any spaces at the end of the title # line, because there is no previous progress line to cover up. sed -e "s/Z$//" >expect <<\EOF && Working hard.......2.........3.........4.........5.........6: Z diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index ba71b159ba..eb44bafb59 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -215,7 +215,6 @@ test_expect_success 'read-tree adds to worktree, dirty case' ' ' test_expect_success 'index removal and worktree narrowing at the same time' ' - >empty && echo init.t >.git/info/sparse-checkout && echo sub/added >>.git/info/sparse-checkout && git checkout -f top && @@ -223,7 +222,7 @@ test_expect_success 'index removal and worktree narrowing at the same time' ' git checkout removed && git ls-files sub/added >result && test ! -f sub/added && - test_cmp empty result + test_must_be_empty result ' test_expect_success 'read-tree --reset removes outside worktree' ' diff --git a/t/t1014-read-tree-confusing.sh b/t/t1014-read-tree-confusing.sh index 2f5a25d503..da3376b3bb 100755 --- a/t/t1014-read-tree-confusing.sh +++ b/t/t1014-read-tree-confusing.sh @@ -49,6 +49,7 @@ git~1 .git.SPACE .git.{space} .\\\\.GIT\\\\foobar backslashes .git\\\\foobar backslashes2 +.git...:alternate-stream EOF test_expect_success 'utf-8 paths allowed with core.protectHFS off' ' diff --git a/t/t1050-large.sh b/t/t1050-large.sh index dcb4dbba67..d3b2adb28b 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -194,15 +194,15 @@ test_expect_success 'pack-objects with large loose object' ' test_cmp huge actual ' -test_expect_success 'tar achiving' ' +test_expect_success 'tar archiving' ' git archive --format=tar HEAD >/dev/null ' -test_expect_success 'zip achiving, store only' ' +test_expect_success 'zip archiving, store only' ' git archive --format=zip -0 HEAD >/dev/null ' -test_expect_success 'zip achiving, deflate' ' +test_expect_success 'zip archiving, deflate' ' git archive --format=zip HEAD >/dev/null ' diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh new file mode 100755 index 0000000000..7d982096fb --- /dev/null +++ b/t/t1091-sparse-checkout-builtin.sh @@ -0,0 +1,441 @@ +#!/bin/sh + +test_description='sparse checkout builtin tests' + +. ./test-lib.sh + +list_files() { + # Do not replace this with 'ls "$1"', as "ls" with BSD-lineage + # enables "-A" by default for root and ends up including ".git" and + # such in its output. (Note, though, that running the test suite as + # root is generally not recommended.) + (cd "$1" && printf '%s\n' *) +} + +check_files() { + list_files "$1" >actual && + shift && + printf "%s\n" $@ >expect && + test_cmp expect actual +} + +test_expect_success 'setup' ' + git init repo && + ( + cd repo && + echo "initial" >a && + mkdir folder1 folder2 deep && + mkdir deep/deeper1 deep/deeper2 && + mkdir deep/deeper1/deepest && + cp a folder1 && + cp a folder2 && + cp a deep && + cp a deep/deeper1 && + cp a deep/deeper2 && + cp a deep/deeper1/deepest && + git add . && + git commit -m "initial commit" + ) +' + +test_expect_success 'git sparse-checkout list (empty)' ' + git -C repo sparse-checkout list >list 2>err && + test_must_be_empty list && + test_i18ngrep "this worktree is not sparse (sparse-checkout file may not exist)" err +' + +test_expect_success 'git sparse-checkout list (populated)' ' + test_when_finished rm -f repo/.git/info/sparse-checkout && + cat >repo/.git/info/sparse-checkout <<-\EOF && + /folder1/* + /deep/ + **/a + !*bin* + EOF + cp repo/.git/info/sparse-checkout expect && + git -C repo sparse-checkout list >list && + test_cmp expect list +' + +test_expect_success 'git sparse-checkout init' ' + git -C repo sparse-checkout init && + cat >expect <<-\EOF && + /* + !/*/ + EOF + test_cmp expect repo/.git/info/sparse-checkout && + test_cmp_config -C repo true core.sparsecheckout && + check_files repo a +' + +test_expect_success 'git sparse-checkout list after init' ' + git -C repo sparse-checkout list >actual && + cat >expect <<-\EOF && + /* + !/*/ + EOF + test_cmp expect actual +' + +test_expect_success 'init with existing sparse-checkout' ' + echo "*folder*" >> repo/.git/info/sparse-checkout && + git -C repo sparse-checkout init && + cat >expect <<-\EOF && + /* + !/*/ + *folder* + EOF + test_cmp expect repo/.git/info/sparse-checkout && + check_files repo a folder1 folder2 +' + +test_expect_success 'clone --sparse' ' + git clone --sparse "file://$(pwd)/repo" clone && + git -C clone sparse-checkout list >actual && + cat >expect <<-\EOF && + /* + !/*/ + EOF + test_cmp expect actual && + check_files clone a +' + +test_expect_success 'set enables config' ' + git init empty-config && + ( + cd empty-config && + test_commit test file && + test_path_is_missing .git/config.worktree && + test_must_fail git sparse-checkout set nothing && + test_path_is_file .git/config.worktree && + test_must_fail git config core.sparseCheckout && + git sparse-checkout set "/*" && + test_cmp_config true core.sparseCheckout + ) +' + +test_expect_success 'set sparse-checkout using builtin' ' + git -C repo sparse-checkout set "/*" "!/*/" "*folder*" && + cat >expect <<-\EOF && + /* + !/*/ + *folder* + EOF + git -C repo sparse-checkout list >actual && + test_cmp expect actual && + test_cmp expect repo/.git/info/sparse-checkout && + check_files repo a folder1 folder2 +' + +test_expect_success 'set sparse-checkout using --stdin' ' + cat >expect <<-\EOF && + /* + !/*/ + /folder1/ + /folder2/ + EOF + git -C repo sparse-checkout set --stdin <expect && + git -C repo sparse-checkout list >actual && + test_cmp expect actual && + test_cmp expect repo/.git/info/sparse-checkout && + check_files repo "a folder1 folder2" +' + +test_expect_success 'cone mode: match patterns' ' + git -C repo config --worktree core.sparseCheckoutCone true && + rm -rf repo/a repo/folder1 repo/folder2 && + git -C repo read-tree -mu HEAD 2>err && + test_i18ngrep ! "disabling cone patterns" err && + git -C repo reset --hard && + check_files repo a folder1 folder2 +' + +test_expect_success 'cone mode: warn on bad pattern' ' + test_when_finished mv sparse-checkout repo/.git/info/ && + cp repo/.git/info/sparse-checkout . && + echo "!/deep/deeper/*" >>repo/.git/info/sparse-checkout && + git -C repo read-tree -mu HEAD 2>err && + test_i18ngrep "unrecognized negative pattern" err +' + +test_expect_success 'sparse-checkout disable' ' + test_when_finished rm -rf repo/.git/info/sparse-checkout && + git -C repo sparse-checkout disable && + test_path_is_file repo/.git/info/sparse-checkout && + git -C repo config --list >config && + test_must_fail git config core.sparseCheckout && + check_files repo a deep folder1 folder2 +' + +test_expect_success 'cone mode: init and set' ' + git -C repo sparse-checkout init --cone && + git -C repo config --list >config && + test_i18ngrep "core.sparsecheckoutcone=true" config && + list_files repo >dir && + echo a >expect && + test_cmp expect dir && + git -C repo sparse-checkout set deep/deeper1/deepest/ 2>err && + test_must_be_empty err && + check_files repo a deep && + check_files repo/deep a deeper1 && + check_files repo/deep/deeper1 a deepest && + cat >expect <<-\EOF && + /* + !/*/ + /deep/ + !/deep/*/ + /deep/deeper1/ + !/deep/deeper1/*/ + /deep/deeper1/deepest/ + EOF + test_cmp expect repo/.git/info/sparse-checkout && + git -C repo sparse-checkout set --stdin 2>err <<-\EOF && + folder1 + folder2 + EOF + test_must_be_empty err && + check_files repo a folder1 folder2 +' + +test_expect_success 'cone mode: list' ' + cat >expect <<-\EOF && + folder1 + folder2 + EOF + git -C repo sparse-checkout set --stdin <expect && + git -C repo sparse-checkout list >actual 2>err && + test_must_be_empty err && + test_cmp expect actual +' + +test_expect_success 'cone mode: set with nested folders' ' + git -C repo sparse-checkout set deep deep/deeper1/deepest 2>err && + test_line_count = 0 err && + cat >expect <<-\EOF && + /* + !/*/ + /deep/ + EOF + test_cmp repo/.git/info/sparse-checkout expect +' + +test_expect_success 'revert to old sparse-checkout on bad update' ' + test_when_finished git -C repo reset --hard && + echo update >repo/deep/deeper2/a && + cp repo/.git/info/sparse-checkout expect && + test_must_fail git -C repo sparse-checkout set deep/deeper1 2>err && + test_i18ngrep "cannot set sparse-checkout patterns" err && + test_cmp repo/.git/info/sparse-checkout expect && + check_files repo/deep a deeper1 deeper2 +' + +test_expect_success 'revert to old sparse-checkout on empty update' ' + git init empty-test && + ( + echo >file && + git add file && + git commit -m "test" && + test_must_fail git sparse-checkout set nothing 2>err && + test_i18ngrep "Sparse checkout leaves no entry on working directory" err && + test_i18ngrep ! ".git/index.lock" err && + git sparse-checkout set file + ) +' + +test_expect_success 'fail when lock is taken' ' + test_when_finished rm -rf repo/.git/info/sparse-checkout.lock && + touch repo/.git/info/sparse-checkout.lock && + test_must_fail git -C repo sparse-checkout set deep 2>err && + test_i18ngrep "File exists" err +' + +test_expect_success '.gitignore should not warn about cone mode' ' + git -C repo config --worktree core.sparseCheckoutCone true && + echo "**/bin/*" >repo/.gitignore && + git -C repo reset --hard 2>err && + test_i18ngrep ! "disabling cone patterns" err +' + +test_expect_success 'sparse-checkout (init|set|disable) fails with dirty status' ' + git clone repo dirty && + echo dirty >dirty/folder1/a && + test_must_fail git -C dirty sparse-checkout init && + test_must_fail git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* && + test_must_fail git -C dirty sparse-checkout disable && + git -C dirty reset --hard && + git -C dirty sparse-checkout init && + git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* && + git -C dirty sparse-checkout disable +' + +test_expect_success 'cone mode: set with core.ignoreCase=true' ' + git -C repo sparse-checkout init --cone && + git -C repo -c core.ignoreCase=true sparse-checkout set folder1 && + cat >expect <<-\EOF && + /* + !/*/ + /folder1/ + EOF + test_cmp expect repo/.git/info/sparse-checkout && + check_files repo a folder1 +' + +test_expect_success 'interaction with submodules' ' + git clone repo super && + ( + cd super && + mkdir modules && + git submodule add ../repo modules/child && + git add . && + git commit -m "add submodule" && + git sparse-checkout init --cone && + git sparse-checkout set folder1 + ) && + check_files super a folder1 modules && + check_files super/modules/child a deep folder1 folder2 +' + +test_expect_success 'different sparse-checkouts with worktrees' ' + git -C repo worktree add --detach ../worktree && + check_files worktree "a deep folder1 folder2" && + git -C worktree sparse-checkout init --cone && + git -C repo sparse-checkout set folder1 && + git -C worktree sparse-checkout set deep/deeper1 && + check_files repo a folder1 && + check_files worktree a deep +' + +test_expect_success 'set using filename keeps file on-disk' ' + git -C repo sparse-checkout set a deep && + cat >expect <<-\EOF && + /* + !/*/ + /a/ + /deep/ + EOF + test_cmp expect repo/.git/info/sparse-checkout && + check_files repo a deep +' + +check_read_tree_errors () { + REPO=$1 + FILES=$2 + ERRORS=$3 + git -C $REPO -c core.sparseCheckoutCone=false read-tree -mu HEAD 2>err && + test_must_be_empty err && + check_files $REPO "$FILES" && + git -C $REPO read-tree -mu HEAD 2>err && + if test -z "$ERRORS" + then + test_must_be_empty err + else + test_i18ngrep "$ERRORS" err + fi && + check_files $REPO $FILES +} + +test_expect_success 'pattern-checks: /A/**' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /folder1/** + EOF + check_read_tree_errors repo "a folder1" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: /A/**/B/' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /deep/**/deepest + EOF + check_read_tree_errors repo "a deep" "disabling cone pattern matching" && + check_files repo/deep "deeper1" && + check_files repo/deep/deeper1 "deepest" +' + +test_expect_success 'pattern-checks: too short' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /a + EOF + check_read_tree_errors repo "a" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: trailing "*"' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + /a* + EOF + check_read_tree_errors repo "a" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: starting "*"' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /* + !/*/ + *eep/ + EOF + check_read_tree_errors repo "a deep" "disabling cone pattern matching" +' + +test_expect_success 'pattern-checks: contained glob characters' ' + for c in "[a]" "\\" "?" "*" + do + cat >repo/.git/info/sparse-checkout <<-EOF && + /* + !/*/ + something$c-else/ + EOF + check_read_tree_errors repo "a" "disabling cone pattern matching" + done +' + +test_expect_success BSLASHPSPEC 'pattern-checks: escaped characters' ' + git clone repo escaped && + TREEOID=$(git -C escaped rev-parse HEAD:folder1) && + NEWTREE=$(git -C escaped mktree <<-EOF + $(git -C escaped ls-tree HEAD) + 040000 tree $TREEOID zbad\\dir + 040000 tree $TREEOID zdoes*exist + 040000 tree $TREEOID zglob[!a]? + EOF + ) && + COMMIT=$(git -C escaped commit-tree $NEWTREE -p HEAD) && + git -C escaped reset --hard $COMMIT && + check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? && + git -C escaped sparse-checkout init --cone && + git -C escaped sparse-checkout set zbad\\dir/bogus "zdoes*not*exist" "zdoes*exist" "zglob[!a]?" && + cat >expect <<-\EOF && + /* + !/*/ + /zbad\\dir/ + !/zbad\\dir/*/ + /zbad\\dir/bogus/ + /zdoes\*exist/ + /zdoes\*not\*exist/ + /zglob\[!a]\?/ + EOF + test_cmp expect escaped/.git/info/sparse-checkout && + check_read_tree_errors escaped "a zbad\\dir zdoes*exist zglob[!a]?" && + git -C escaped ls-tree -d --name-only HEAD >list-expect && + git -C escaped sparse-checkout set --stdin <list-expect && + cat >expect <<-\EOF && + /* + !/*/ + /deep/ + /folder1/ + /folder2/ + /zbad\\dir/ + /zdoes\*exist/ + /zglob\[!a]\?/ + EOF + test_cmp expect escaped/.git/info/sparse-checkout && + check_files escaped "a deep folder1 folder2 zbad\\dir zdoes*exist" zglob[!a]? && + git -C escaped sparse-checkout list >list-actual && + test_cmp list-expect list-actual +' + +test_done diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 983a0a1583..5464c46c18 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1191,47 +1191,47 @@ test_expect_success 'old-fashioned settings are case insensitive' ' test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" && cat >testConfig_actual <<-EOF && - [V.A] - r = value1 + [V.A] + r = value1 EOF q_to_tab >testConfig_expect <<-EOF && - [V.A] - Qr = value2 + [V.A] + Qr = value2 EOF git config -f testConfig_actual "v.a.r" value2 && test_cmp testConfig_expect testConfig_actual && cat >testConfig_actual <<-EOF && - [V.A] - r = value1 + [V.A] + r = value1 EOF q_to_tab >testConfig_expect <<-EOF && - [V.A] - QR = value2 + [V.A] + QR = value2 EOF git config -f testConfig_actual "V.a.R" value2 && test_cmp testConfig_expect testConfig_actual && cat >testConfig_actual <<-EOF && - [V.A] - r = value1 + [V.A] + r = value1 EOF q_to_tab >testConfig_expect <<-EOF && - [V.A] - r = value1 - Qr = value2 + [V.A] + r = value1 + Qr = value2 EOF git config -f testConfig_actual "V.A.r" value2 && test_cmp testConfig_expect testConfig_actual && cat >testConfig_actual <<-EOF && - [V.A] - r = value1 + [V.A] + r = value1 EOF q_to_tab >testConfig_expect <<-EOF && - [V.A] - r = value1 - Qr = value2 + [V.A] + r = value1 + Qr = value2 EOF git config -f testConfig_actual "v.A.r" value2 && test_cmp testConfig_expect testConfig_actual @@ -1241,26 +1241,26 @@ test_expect_success 'setting different case sensitive subsections ' ' test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" && cat >testConfig_actual <<-EOF && - [V "A"] - R = v1 - [K "E"] - Y = v1 - [a "b"] - c = v1 - [d "e"] - f = v1 + [V "A"] + R = v1 + [K "E"] + Y = v1 + [a "b"] + c = v1 + [d "e"] + f = v1 EOF q_to_tab >testConfig_expect <<-EOF && - [V "A"] - Qr = v2 - [K "E"] - Qy = v2 - [a "b"] - Qc = v2 - [d "e"] - f = v1 - [d "E"] - Qf = v2 + [V "A"] + Qr = v2 + [K "E"] + Qy = v2 + [a "b"] + Qc = v2 + [d "e"] + f = v1 + [d "E"] + Qf = v2 EOF # exact match git config -f testConfig_actual a.b.c v2 && @@ -1622,40 +1622,40 @@ test_expect_success 'set up --show-origin tests' ' INCLUDE_DIR="$HOME/include" && mkdir -p "$INCLUDE_DIR" && cat >"$INCLUDE_DIR"/absolute.include <<-\EOF && - [user] - absolute = include + [user] + absolute = include EOF cat >"$INCLUDE_DIR"/relative.include <<-\EOF && - [user] - relative = include + [user] + relative = include EOF cat >"$HOME"/.gitconfig <<-EOF && - [user] - global = true - override = global - [include] - path = "$INCLUDE_DIR/absolute.include" + [user] + global = true + override = global + [include] + path = "$INCLUDE_DIR/absolute.include" EOF cat >.git/config <<-\EOF - [user] - local = true - override = local - [include] - path = ../include/relative.include + [user] + local = true + override = local + [include] + path = ../include/relative.include EOF ' test_expect_success '--show-origin with --list' ' cat >expect <<-EOF && - file:$HOME/.gitconfig user.global=true - file:$HOME/.gitconfig user.override=global - file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include - file:$INCLUDE_DIR/absolute.include user.absolute=include - file:.git/config user.local=true - file:.git/config user.override=local - file:.git/config include.path=../include/relative.include - file:.git/../include/relative.include user.relative=include - command line: user.cmdline=true + file:$HOME/.gitconfig user.global=true + file:$HOME/.gitconfig user.override=global + file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include + file:$INCLUDE_DIR/absolute.include user.absolute=include + file:.git/config user.local=true + file:.git/config user.override=local + file:.git/config include.path=../include/relative.include + file:.git/../include/relative.include user.relative=include + command line: user.cmdline=true EOF git -c user.cmdline=true config --list --show-origin >output && test_cmp expect output @@ -1663,16 +1663,16 @@ test_expect_success '--show-origin with --list' ' test_expect_success '--show-origin with --list --null' ' cat >expect <<-EOF && - file:$HOME/.gitconfigQuser.global - trueQfile:$HOME/.gitconfigQuser.override - globalQfile:$HOME/.gitconfigQinclude.path - $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute - includeQfile:.git/configQuser.local - trueQfile:.git/configQuser.override - localQfile:.git/configQinclude.path - ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative - includeQcommand line:Quser.cmdline - trueQ + file:$HOME/.gitconfigQuser.global + trueQfile:$HOME/.gitconfigQuser.override + globalQfile:$HOME/.gitconfigQinclude.path + $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute + includeQfile:.git/configQuser.local + trueQfile:.git/configQuser.override + localQfile:.git/configQinclude.path + ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative + includeQcommand line:Quser.cmdline + trueQ EOF git -c user.cmdline=true config --null --list --show-origin >output.raw && nul_to_q <output.raw >output && @@ -1684,9 +1684,9 @@ test_expect_success '--show-origin with --list --null' ' test_expect_success '--show-origin with single file' ' cat >expect <<-\EOF && - file:.git/config user.local=true - file:.git/config user.override=local - file:.git/config include.path=../include/relative.include + file:.git/config user.local=true + file:.git/config user.override=local + file:.git/config include.path=../include/relative.include EOF git config --local --list --show-origin >output && test_cmp expect output @@ -1694,8 +1694,8 @@ test_expect_success '--show-origin with single file' ' test_expect_success '--show-origin with --get-regexp' ' cat >expect <<-EOF && - file:$HOME/.gitconfig user.global true - file:.git/config user.local true + file:$HOME/.gitconfig user.global true + file:.git/config user.local true EOF git config --show-origin --get-regexp "user\.[g|l].*" >output && test_cmp expect output @@ -1703,31 +1703,36 @@ test_expect_success '--show-origin with --get-regexp' ' test_expect_success '--show-origin getting a single key' ' cat >expect <<-\EOF && - file:.git/config local + file:.git/config local EOF git config --show-origin user.override >output && test_cmp expect output ' test_expect_success 'set up custom config file' ' - CUSTOM_CONFIG_FILE="file\" (dq) and spaces.conf" && + CUSTOM_CONFIG_FILE="custom.conf" && cat >"$CUSTOM_CONFIG_FILE" <<-\EOF - [user] - custom = true + [user] + custom = true EOF ' +test_expect_success !MINGW 'set up custom config file with special name characters' ' + WEIRDLY_NAMED_FILE="file\" (dq) and spaces.conf" && + cp "$CUSTOM_CONFIG_FILE" "$WEIRDLY_NAMED_FILE" +' + test_expect_success !MINGW '--show-origin escape special file name characters' ' cat >expect <<-\EOF && - file:"file\" (dq) and spaces.conf" user.custom=true + file:"file\" (dq) and spaces.conf" user.custom=true EOF - git config --file "$CUSTOM_CONFIG_FILE" --show-origin --list >output && + git config --file "$WEIRDLY_NAMED_FILE" --show-origin --list >output && test_cmp expect output ' test_expect_success '--show-origin stdin' ' cat >expect <<-\EOF && - standard input: user.custom=true + standard input: user.custom=true EOF git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output && test_cmp expect output @@ -1735,11 +1740,11 @@ test_expect_success '--show-origin stdin' ' test_expect_success '--show-origin stdin with file include' ' cat >"$INCLUDE_DIR"/stdin.include <<-EOF && - [user] - stdin = include + [user] + stdin = include EOF cat >expect <<-EOF && - file:$INCLUDE_DIR/stdin.include include + file:$INCLUDE_DIR/stdin.include include EOF echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" | git config --show-origin --includes --file - user.stdin >output && @@ -1747,18 +1752,18 @@ test_expect_success '--show-origin stdin with file include' ' test_cmp expect output ' -test_expect_success !MINGW '--show-origin blob' ' +test_expect_success '--show-origin blob' ' blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") && cat >expect <<-EOF && - blob:$blob user.custom=true + blob:$blob user.custom=true EOF git config --blob=$blob --show-origin --list >output && test_cmp expect output ' -test_expect_success !MINGW '--show-origin blob ref' ' +test_expect_success '--show-origin blob ref' ' cat >expect <<-\EOF && - blob:"master:file\" (dq) and spaces.conf" user.custom=true + blob:master:custom.conf user.custom=true EOF git add "$CUSTOM_CONFIG_FILE" && git commit -m "new config file" && @@ -1766,6 +1771,65 @@ test_expect_success !MINGW '--show-origin blob ref' ' test_cmp expect output ' +test_expect_success '--show-scope with --list' ' + cat >expect <<-EOF && + global user.global=true + global user.override=global + global include.path=$INCLUDE_DIR/absolute.include + global user.absolute=include + local user.local=true + local user.override=local + local include.path=../include/relative.include + local user.relative=include + command user.cmdline=true + EOF + git -c user.cmdline=true config --list --show-scope >output && + test_cmp expect output +' + +test_expect_success !MINGW '--show-scope with --blob' ' + blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") && + cat >expect <<-EOF && + command user.custom=true + EOF + git config --blob=$blob --show-scope --list >output && + test_cmp expect output +' + +test_expect_success '--show-scope with --local' ' + cat >expect <<-\EOF && + local user.local=true + local user.override=local + local include.path=../include/relative.include + EOF + git config --local --list --show-scope >output && + test_cmp expect output +' + +test_expect_success '--show-scope getting a single value' ' + cat >expect <<-\EOF && + local true + EOF + git config --show-scope --get user.local >output && + test_cmp expect output +' + +test_expect_success '--show-scope with --show-origin' ' + cat >expect <<-EOF && + global file:$HOME/.gitconfig user.global=true + global file:$HOME/.gitconfig user.override=global + global file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include + global file:$INCLUDE_DIR/absolute.include user.absolute=include + local file:.git/config user.local=true + local file:.git/config user.override=local + local file:.git/config include.path=../include/relative.include + local file:.git/../include/relative.include user.relative=include + command command line: user.cmdline=true + EOF + git -c user.cmdline=true config --list --show-origin --show-scope >output && + test_cmp expect output +' + test_expect_success '--local requires a repo' ' # we expect 128 to ensure that we do not simply # fail to find anything and return code "1" diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh index 21e139a313..dd87b43be1 100755 --- a/t/t1306-xdg-files.sh +++ b/t/t1306-xdg-files.sh @@ -153,7 +153,7 @@ test_expect_success 'Checking attributes in both XDG and local attributes files' test_expect_success 'Checking attributes in a non-XDG global attributes file' ' - test_might_fail rm .gitattributes && + rm -f .gitattributes && echo "f attr_f=test" >"$HOME"/my_gitattributes && git config core.attributesfile "$HOME"/my_gitattributes && echo "f: attr_f: test" >expected && @@ -165,7 +165,7 @@ test_expect_success 'Checking attributes in a non-XDG global attributes file' ' test_expect_success 'write: xdg file exists and ~/.gitconfig doesn'\''t' ' mkdir -p "$HOME"/.config/git && >"$HOME"/.config/git/config && - test_might_fail rm "$HOME"/.gitconfig && + rm -f "$HOME"/.gitconfig && git config --global user.name "write_config" && echo "[user]" >expected && echo " name = write_config" >>expected && @@ -183,8 +183,8 @@ test_expect_success 'write: xdg file exists and ~/.gitconfig exists' ' test_expect_success 'write: ~/.config/git/ exists and config file doesn'\''t' ' - test_might_fail rm "$HOME"/.gitconfig && - test_might_fail rm "$HOME"/.config/git/config && + rm -f "$HOME"/.gitconfig && + rm -f "$HOME"/.config/git/config && git config --global user.name "write_gitconfig" && echo "[user]" >expected && echo " name = write_gitconfig" >>expected && diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh index 37dc689d8c..002e6d3388 100755 --- a/t/t1307-config-blob.sh +++ b/t/t1307-config-blob.sh @@ -74,7 +74,7 @@ test_expect_success 'can parse blob ending with CR' ' ' test_expect_success 'config --blob outside of a repository is an error' ' - test_must_fail nongit git config --blob=foo --list + nongit test_must_fail git config --blob=foo --list ' test_done diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh index 7b4e1a63eb..3a527e3a84 100755 --- a/t/t1308-config-set.sh +++ b/t/t1308-config-set.sh @@ -238,8 +238,8 @@ test_expect_success 'error on modifying repo config without repo' ' cmdline_config="'foo.bar=from-cmdline'" test_expect_success 'iteration shows correct origins' ' - echo "[foo]bar = from-repo" >.git/config && - echo "[foo]bar = from-home" >.gitconfig && + printf "[ignore]\n\tthis = please\n[foo]bar = from-repo\n" >.git/config && + printf "[foo]\n\tbar = from-home\n" >.gitconfig && if test_have_prereq MINGW then # Use Windows path (i.e. *not* $HOME) @@ -253,19 +253,29 @@ test_expect_success 'iteration shows correct origins' ' value=from-home origin=file name=$HOME_GITCONFIG + lno=2 scope=global + key=ignore.this + value=please + origin=file + name=.git/config + lno=2 + scope=local + key=foo.bar value=from-repo origin=file name=.git/config - scope=repo + lno=3 + scope=local key=foo.bar value=from-cmdline origin=command line name= - scope=cmdline + lno=-1 + scope=command EOF GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual && test_cmp expect actual diff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh index 3a0de0ddaa..ebb8e1aecb 100755 --- a/t/t1309-early-config.sh +++ b/t/t1309-early-config.sh @@ -29,7 +29,7 @@ test_expect_success 'ceiling' ' cd sub && test-tool config read_early_config early.config ) >output && - test -z "$(cat output)" + test_must_be_empty output ' test_expect_success 'ceiling #2' ' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 1fbd940408..a6224ef65f 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -344,14 +344,16 @@ test_expect_success "verifying $m's log (logged by config)" ' test_cmp expect .git/logs/$m ' -git update-ref $m $D -cat >.git/logs/$m <<EOF -$Z $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500 -$C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500 -$A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500 -$F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500 -$Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500 -EOF +test_expect_success 'set up for querying the reflog' ' + git update-ref $m $D && + cat >.git/logs/$m <<-EOF + $Z $C $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150320 -0500 + $C $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150350 -0500 + $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 -0500 + $F $Z $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150680 -0500 + $Z $E $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 -0500 + EOF +' ed="Thu, 26 May 2005 18:32:00 -0500" gd="Thu, 26 May 2005 18:33:00 -0500" @@ -359,55 +361,67 @@ ld="Thu, 26 May 2005 18:43:00 -0500" test_expect_success 'Query "master@{May 25 2005}" (before history)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{May 25 2005}" >o 2>e && - test $C = $(cat o) && - test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)" + echo "$C" >expect && + test_cmp expect o && + echo "warning: log for '\''master'\'' only goes back to $ed" >expect && + test_i18ncmp expect e ' test_expect_success 'Query master@{2005-05-25} (before history)' ' test_when_finished "rm -f o e" && git rev-parse --verify master@{2005-05-25} >o 2>e && - test $C = $(cat o) && - test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)" + echo "$C" >expect && + test_cmp expect o && + echo "warning: log for '\''master'\'' only goes back to $ed" >expect && + test_i18ncmp expect e ' test_expect_success 'Query "master@{May 26 2005 23:31:59}" (1 second before history)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{May 26 2005 23:31:59}" >o 2>e && - test $C = $(cat o) && - test "warning: Log for '\''master'\'' only goes back to $ed." = "$(cat e)" + echo "$C" >expect && + test_cmp expect o && + echo "warning: log for '\''master'\'' only goes back to $ed" >expect && + test_i18ncmp expect e ' test_expect_success 'Query "master@{May 26 2005 23:32:00}" (exactly history start)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{May 26 2005 23:32:00}" >o 2>e && - test $C = $(cat o) && - test "" = "$(cat e)" + echo "$C" >expect && + test_cmp expect o && + test_must_be_empty e ' test_expect_success 'Query "master@{May 26 2005 23:32:30}" (first non-creation change)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{May 26 2005 23:32:30}" >o 2>e && - test $A = $(cat o) && - test "" = "$(cat e)" + echo "$A" >expect && + test_cmp expect o && + test_must_be_empty e ' test_expect_success 'Query "master@{2005-05-26 23:33:01}" (middle of history with gap)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{2005-05-26 23:33:01}" >o 2>e && - test $B = $(cat o) && + echo "$B" >expect && + test_cmp expect o && test_i18ngrep -F "warning: log for ref $m has gap after $gd" e ' test_expect_success 'Query "master@{2005-05-26 23:38:00}" (middle of history)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{2005-05-26 23:38:00}" >o 2>e && - test $Z = $(cat o) && - test "" = "$(cat e)" + echo "$Z" >expect && + test_cmp expect o && + test_must_be_empty e ' test_expect_success 'Query "master@{2005-05-26 23:43:00}" (exact end of history)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{2005-05-26 23:43:00}" >o 2>e && - test $E = $(cat o) && - test "" = "$(cat e)" + echo "$E" >expect && + test_cmp expect o && + test_must_be_empty e ' test_expect_success 'Query "master@{2005-05-28}" (past end of history)' ' test_when_finished "rm -f o e" && git rev-parse --verify "master@{2005-05-28}" >o 2>e && - test $D = $(cat o) && + echo "$D" >expect && + test_cmp expect o && test_i18ngrep -F "warning: log for ref $m unexpectedly ended on $ld" e ' diff --git a/t/t1409-avoid-packing-refs.sh b/t/t1409-avoid-packing-refs.sh index e5cb8a252d..be12fb6350 100755 --- a/t/t1409-avoid-packing-refs.sh +++ b/t/t1409-avoid-packing-refs.sh @@ -8,7 +8,7 @@ test_description='avoid rewriting packed-refs unnecessarily' # shouldn't upset readers, and it should be omitted if the file is # ever rewritten. mark_packed_refs () { - sed -e "s/^\(#.*\)/\1 t1409 /" <.git/packed-refs >.git/packed-refs.new && + sed -e "s/^\(#.*\)/\1 t1409 /" .git/packed-refs >.git/packed-refs.new && mv .git/packed-refs.new .git/packed-refs } @@ -27,15 +27,15 @@ test_expect_success 'setup' ' ' test_expect_success 'do not create packed-refs file gratuitously' ' - test_must_fail test -f .git/packed-refs && + test_path_is_missing .git/packed-refs && git update-ref refs/heads/foo $A && - test_must_fail test -f .git/packed-refs && + test_path_is_missing .git/packed-refs && git update-ref refs/heads/foo $B && - test_must_fail test -f .git/packed-refs && + test_path_is_missing .git/packed-refs && git update-ref refs/heads/foo $C $B && - test_must_fail test -f .git/packed-refs && + test_path_is_missing .git/packed-refs && git update-ref -d refs/heads/foo && - test_must_fail test -f .git/packed-refs + test_path_is_missing .git/packed-refs ' test_expect_success 'check that marking the packed-refs file works' ' @@ -46,7 +46,7 @@ test_expect_success 'check that marking the packed-refs file works' ' git for-each-ref >actual && test_cmp expected actual && git pack-refs --all && - test_must_fail check_packed_refs_marked && + ! check_packed_refs_marked && git for-each-ref >actual2 && test_cmp expected actual2 ' @@ -80,7 +80,7 @@ test_expect_success 'touch packed-refs on delete of packed' ' git pack-refs --all && mark_packed_refs && git update-ref -d refs/heads/packed-delete && - test_must_fail check_packed_refs_marked + ! check_packed_refs_marked ' test_expect_success 'leave packed-refs untouched on update of loose' ' diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 82950c0282..76d9b744a6 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -195,7 +195,7 @@ test_expect_success 'delete' ' git reflog delete master@{1} && git reflog show master > output && - test $(($master_entry_count - 1)) = $(wc -l < output) && + test_line_count = $(($master_entry_count - 1)) output && test $HEAD_entry_count = $(git reflog | wc -l) && ! grep ox < output && @@ -209,7 +209,7 @@ test_expect_success 'delete' ' git reflog delete master@{07.04.2005.15:15:00.-0700} && git reflog show master > output && - test $(($master_entry_count - 1)) = $(wc -l < output) && + test_line_count = $(($master_entry_count - 1)) output && ! grep dragon < output ' diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 50d28e6fdb..02478bc4ec 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -441,6 +441,7 @@ while read name path pretty; do ( git init $name-$type && cd $name-$type && + git config core.protectNTFS false && echo content >file && git add file && git commit -m base && @@ -616,7 +617,7 @@ test_expect_success 'fsck --name-objects' ' remove_object $(git rev-parse julius:caesar.t) && test_must_fail git fsck --name-objects >out && tree=$(git rev-parse --verify julius:) && - test_i18ngrep -E "$tree \((refs/heads/master|HEAD)@\{[0-9]*\}:" out + test_i18ngrep "$tree (refs/tags/julius:" out ) ' diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 0177fd815c..603019b541 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -146,6 +146,16 @@ test_expect_success 'rev-parse --show-object-format in repo' ' grep "unknown mode for --show-object-format: squeamish-ossifrage" err ' +test_expect_success '--show-toplevel from subdir of working tree' ' + pwd >expect && + git -C sub/dir rev-parse --show-toplevel >actual && + test_cmp expect actual +' + +test_expect_success '--show-toplevel from inside .git' ' + test_must_fail git -C .git rev-parse --show-toplevel +' + test_expect_success 'showing the superproject correctly' ' git rev-parse --show-superproject-working-tree >out && test_must_be_empty out && diff --git a/t/t1501-work-tree.sh b/t/t1501-work-tree.sh index 3498d3d55e..b75558040f 100755 --- a/t/t1501-work-tree.sh +++ b/t/t1501-work-tree.sh @@ -350,7 +350,7 @@ test_expect_success 'Multi-worktree setup' ' mkdir work && mkdir -p repo.git/repos/foo && cp repo.git/HEAD repo.git/index repo.git/repos/foo && - test_might_fail cp repo.git/sharedindex.* repo.git/repos/foo && + { cp repo.git/sharedindex.* repo.git/repos/foo || :; } && sane_unset GIT_DIR GIT_CONFIG GIT_WORK_TREE ' diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index 624d0a588f..52edcbdcc3 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -9,10 +9,10 @@ exec </dev/null test_did_you_mean () { cat >expected <<-EOF && - fatal: Path '$2$3' $4, but not ${5:-$SQ$3$SQ}. - Did you mean '$1:$2$3'${2:+ aka $SQ$1:./$3$SQ}? + fatal: path '$2$3' $4, but not ${5:-$SQ$3$SQ} + hint: Did you mean '$1:$2$3'${2:+ aka $SQ$1:./$3$SQ}? EOF - test_cmp expected error + test_i18ncmp expected error } HASH_file= @@ -103,66 +103,66 @@ test_expect_success 'correct relative file objects (6)' ' test_expect_success 'incorrect revision id' ' test_must_fail git rev-parse foobar:file.txt 2>error && - grep "Invalid object name '"'"'foobar'"'"'." error && - test_must_fail git rev-parse foobar 2> error && + test_i18ngrep "invalid object name .foobar." error && + test_must_fail git rev-parse foobar 2>error && test_i18ngrep "unknown revision or path not in the working tree." error ' test_expect_success 'incorrect file in sha1:path' ' - test_must_fail git rev-parse HEAD:nothing.txt 2> error && - grep "fatal: Path '"'"'nothing.txt'"'"' does not exist in '"'"'HEAD'"'"'" error && - test_must_fail git rev-parse HEAD:index-only.txt 2> error && - grep "fatal: Path '"'"'index-only.txt'"'"' exists on disk, but not in '"'"'HEAD'"'"'." error && + test_must_fail git rev-parse HEAD:nothing.txt 2>error && + test_i18ngrep "path .nothing.txt. does not exist in .HEAD." error && + test_must_fail git rev-parse HEAD:index-only.txt 2>error && + test_i18ngrep "path .index-only.txt. exists on disk, but not in .HEAD." error && (cd subdir && - test_must_fail git rev-parse HEAD:file2.txt 2> error && + test_must_fail git rev-parse HEAD:file2.txt 2>error && test_did_you_mean HEAD subdir/ file2.txt exists ) ' test_expect_success 'incorrect file in :path and :N:path' ' - test_must_fail git rev-parse :nothing.txt 2> error && - grep "fatal: Path '"'"'nothing.txt'"'"' does not exist (neither on disk nor in the index)." error && - test_must_fail git rev-parse :1:nothing.txt 2> error && - grep "Path '"'"'nothing.txt'"'"' does not exist (neither on disk nor in the index)." error && - test_must_fail git rev-parse :1:file.txt 2> error && + test_must_fail git rev-parse :nothing.txt 2>error && + test_i18ngrep "path .nothing.txt. does not exist (neither on disk nor in the index)" error && + test_must_fail git rev-parse :1:nothing.txt 2>error && + test_i18ngrep "path .nothing.txt. does not exist (neither on disk nor in the index)" error && + test_must_fail git rev-parse :1:file.txt 2>error && test_did_you_mean ":0" "" file.txt "is in the index" "at stage 1" && (cd subdir && - test_must_fail git rev-parse :1:file.txt 2> error && + test_must_fail git rev-parse :1:file.txt 2>error && test_did_you_mean ":0" "" file.txt "is in the index" "at stage 1" && - test_must_fail git rev-parse :file2.txt 2> error && + test_must_fail git rev-parse :file2.txt 2>error && test_did_you_mean ":0" subdir/ file2.txt "is in the index" && - test_must_fail git rev-parse :2:file2.txt 2> error && + test_must_fail git rev-parse :2:file2.txt 2>error && test_did_you_mean :0 subdir/ file2.txt "is in the index") && - test_must_fail git rev-parse :disk-only.txt 2> error && - grep "fatal: Path '"'"'disk-only.txt'"'"' exists on disk, but not in the index." error + test_must_fail git rev-parse :disk-only.txt 2>error && + test_i18ngrep "path .disk-only.txt. exists on disk, but not in the index" error ' test_expect_success 'invalid @{n} reference' ' test_must_fail git rev-parse master@{99999} >output 2>error && - test -z "$(cat output)" && - grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error && + test_must_be_empty output && + test_i18ngrep "log for [^ ]* only has [0-9][0-9]* entries" error && test_must_fail git rev-parse --verify master@{99999} >output 2>error && - test -z "$(cat output)" && - grep "fatal: Log for [^ ]* only has [0-9][0-9]* entries." error + test_must_be_empty output && + test_i18ngrep "log for [^ ]* only has [0-9][0-9]* entries" error ' test_expect_success 'relative path not found' ' ( cd subdir && test_must_fail git rev-parse HEAD:./nonexistent.txt 2>error && - grep subdir/nonexistent.txt error + test_i18ngrep subdir/nonexistent.txt error ) ' test_expect_success 'relative path outside worktree' ' test_must_fail git rev-parse HEAD:../file.txt >output 2>error && - test -z "$(cat output)" && + test_must_be_empty output && test_i18ngrep "outside repository" error ' test_expect_success 'relative path when cwd is outside worktree' ' test_must_fail git --git-dir=.git --work-tree=subdir rev-parse HEAD:./file.txt >output 2>error && - test -z "$(cat output)" && - grep "relative path syntax can.t be used outside working tree." error + test_must_be_empty output && + test_i18ngrep "relative path syntax can.t be used outside working tree" error ' test_expect_success '<commit>:file correctly diagnosed after a pathname' ' @@ -222,4 +222,18 @@ test_expect_success 'reject Nth ancestor if N is too high' ' test_must_fail git rev-parse HEAD~100000000000000000000000000000000 ' +test_expect_success 'pathspecs with wildcards are not ambiguous' ' + echo "*.c" >expect && + git rev-parse "*.c" >actual && + test_cmp expect actual +' + +test_expect_success 'backslash does not trigger wildcard rule' ' + test_must_fail git rev-parse "foo\\bar" +' + +test_expect_success 'escaped char does not trigger wildcard rule' ' + test_must_fail git rev-parse "foo\\*bar" +' + test_done diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index 8b4cf8a6e3..dfc0d96d8a 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -28,14 +28,9 @@ test_expect_success 'setup' ' ) ' -full_name () { - (cd clone && - git rev-parse --symbolic-full-name "$@") -} - commit_subject () { (cd clone && - git show -s --pretty=format:%s "$@") + git show -s --pretty=tformat:%s "$@") } error_message () { @@ -44,63 +39,78 @@ error_message () { } test_expect_success '@{upstream} resolves to correct full name' ' - test refs/remotes/origin/master = "$(full_name @{upstream})" && - test refs/remotes/origin/master = "$(full_name @{UPSTREAM})" && - test refs/remotes/origin/master = "$(full_name @{UpSTReam})" + echo refs/remotes/origin/master >expect && + git -C clone rev-parse --symbolic-full-name @{upstream} >actual && + test_cmp expect actual && + git -C clone rev-parse --symbolic-full-name @{UPSTREAM} >actual && + test_cmp expect actual && + git -C clone rev-parse --symbolic-full-name @{UpSTReam} >actual && + test_cmp expect actual ' test_expect_success '@{u} resolves to correct full name' ' - test refs/remotes/origin/master = "$(full_name @{u})" && - test refs/remotes/origin/master = "$(full_name @{U})" + echo refs/remotes/origin/master >expect && + git -C clone rev-parse --symbolic-full-name @{u} >actual && + test_cmp expect actual && + git -C clone rev-parse --symbolic-full-name @{U} >actual && + test_cmp expect actual ' test_expect_success 'my-side@{upstream} resolves to correct full name' ' - test refs/remotes/origin/side = "$(full_name my-side@{u})" + echo refs/remotes/origin/side >expect && + git -C clone rev-parse --symbolic-full-name my-side@{u} >actual && + test_cmp expect actual ' test_expect_success 'upstream of branch with @ in middle' ' - full_name fun@ny@{u} >actual && + git -C clone rev-parse --symbolic-full-name fun@ny@{u} >actual && echo refs/remotes/origin/side >expect && test_cmp expect actual && - full_name fun@ny@{U} >actual && + git -C clone rev-parse --symbolic-full-name fun@ny@{U} >actual && test_cmp expect actual ' test_expect_success 'upstream of branch with @ at start' ' - full_name @funny@{u} >actual && + git -C clone rev-parse --symbolic-full-name @funny@{u} >actual && echo refs/remotes/origin/side >expect && test_cmp expect actual ' test_expect_success 'upstream of branch with @ at end' ' - full_name funny@@{u} >actual && + git -C clone rev-parse --symbolic-full-name funny@@{u} >actual && echo refs/remotes/origin/side >expect && test_cmp expect actual ' test_expect_success 'refs/heads/my-side@{upstream} does not resolve to my-side{upstream}' ' - test_must_fail full_name refs/heads/my-side@{upstream} + test_must_fail git -C clone rev-parse --symbolic-full-name refs/heads/my-side@{upstream} ' test_expect_success 'my-side@{u} resolves to correct commit' ' git checkout side && test_commit 5 && (cd clone && git fetch) && - test 2 = "$(commit_subject my-side)" && - test 5 = "$(commit_subject my-side@{u})" + echo 2 >expect && + commit_subject my-side >actual && + test_cmp expect actual && + echo 5 >expect && + commit_subject my-side@{u} >actual ' test_expect_success 'not-tracking@{u} fails' ' - test_must_fail full_name non-tracking@{u} && + test_must_fail git -C clone rev-parse --symbolic-full-name non-tracking@{u} && (cd clone && git checkout --no-track -b non-tracking) && - test_must_fail full_name non-tracking@{u} + test_must_fail git -C clone rev-parse --symbolic-full-name non-tracking@{u} ' test_expect_success '<branch>@{u}@{1} resolves correctly' ' test_commit 6 && (cd clone && git fetch) && - test 5 = $(commit_subject my-side@{u}@{1}) && - test 5 = $(commit_subject my-side@{U}@{1}) + echo 5 >expect && + commit_subject my-side@{u}@{1} >actual && + test_cmp expect actual && + commit_subject my-side@{U}@{1} >actual && + test_cmp expect actual ' test_expect_success '@{u} without specifying branch fails on a detached HEAD' ' @@ -149,7 +159,9 @@ test_expect_success 'checkout other@{u}' ' ' test_expect_success 'branch@{u} works when tracking a local branch' ' - test refs/heads/master = "$(full_name local-master@{u})" + echo refs/heads/master >expect && + git -C clone rev-parse --symbolic-full-name local-master@{u} >actual && + test_cmp expect actual ' test_expect_success 'branch@{u} error message when no upstream' ' @@ -203,35 +215,37 @@ test_expect_success 'pull works when tracking a local branch' ' # makes sense if the previous one succeeded test_expect_success '@{u} works when tracking a local branch' ' - test refs/heads/master = "$(full_name @{u})" + echo refs/heads/master >expect && + git -C clone rev-parse --symbolic-full-name @{u} >actual && + test_cmp expect actual ' -commit=$(git rev-parse HEAD) -cat >expect <<EOF -commit $commit -Reflog: master@{0} (C O Mitter <committer@example.com>) -Reflog message: branch: Created from HEAD -Author: A U Thor <author@example.com> -Date: Thu Apr 7 15:15:13 2005 -0700 - - 3 -EOF test_expect_success 'log -g other@{u}' ' + commit=$(git rev-parse HEAD) && + cat >expect <<-EOF && + commit $commit + Reflog: master@{0} (C O Mitter <committer@example.com>) + Reflog message: branch: Created from HEAD + Author: A U Thor <author@example.com> + Date: Thu Apr 7 15:15:13 2005 -0700 + + 3 + EOF git log -1 -g other@{u} >actual && test_cmp expect actual ' -cat >expect <<EOF -commit $commit -Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>) -Reflog message: branch: Created from HEAD -Author: A U Thor <author@example.com> -Date: Thu Apr 7 15:15:13 2005 -0700 - - 3 -EOF - test_expect_success 'log -g other@{u}@{now}' ' + commit=$(git rev-parse HEAD) && + cat >expect <<-EOF && + commit $commit + Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>) + Reflog message: branch: Created from HEAD + Author: A U Thor <author@example.com> + Date: Thu Apr 7 15:15:13 2005 -0700 + + 3 + EOF git log -1 -g other@{u}@{now} >actual && test_cmp expect actual ' diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh index c19fb500cb..18fa6cf40d 100755 --- a/t/t1512-rev-parse-disambiguation.sh +++ b/t/t1512-rev-parse-disambiguation.sh @@ -282,7 +282,7 @@ test_expect_success 'rev-parse --disambiguate' ' # commits created by commit-tree in earlier tests share a # different prefix. git rev-parse --disambiguate=000000000 >actual && - test $(wc -l <actual) = 16 && + test_line_count = 16 actual && test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000 ' @@ -339,7 +339,7 @@ test_expect_success C_LOCALE_OUTPUT 'ambiguity hints' ' test_expect_success C_LOCALE_OUTPUT 'ambiguity hints respect type' ' test_must_fail git rev-parse 000000000^{commit} 2>stderr && grep ^hint: stderr >hints && - # 5 commits, 1 tag (which is a commitish), plus intro line + # 5 commits, 1 tag (which is a committish), plus intro line test_line_count = 7 hints ' diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index 822381dd9d..bbca7ef8da 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -1,50 +1,76 @@ #!/bin/sh -test_description='checkout ' +test_description='checkout' . ./test-lib.sh -# Arguments: <branch> <sha> [<checkout options>] +# Arguments: [!] <branch> <oid> [<checkout options>] # # Runs "git checkout" to switch to <branch>, testing that # # 1) we are on the specified branch, <branch>; -# 2) HEAD is <sha>; if <sha> is not specified, the old HEAD is used. +# 2) HEAD is <oid>; if <oid> is not specified, the old HEAD is used. # # If <checkout options> is not specified, "git checkout" is run with -b. -do_checkout() { +# +# If the first argument is `!`, "git checkout" is expected to fail when +# it is run. +do_checkout () { + should_fail= && + if test "x$1" = "x!" + then + should_fail=yes && + shift + fi && exp_branch=$1 && exp_ref="refs/heads/$exp_branch" && - # if <sha> is not specified, use HEAD. - exp_sha=${2:-$(git rev-parse --verify HEAD)} && + # if <oid> is not specified, use HEAD. + exp_oid=${2:-$(git rev-parse --verify HEAD)} && # default options for git checkout: -b - if [ -z "$3" ]; then + if test -z "$3" + then opts="-b" else opts="$3" fi - git checkout $opts $exp_branch $exp_sha && + if test -n "$should_fail" + then + test_must_fail git checkout $opts $exp_branch $exp_oid + else + git checkout $opts $exp_branch $exp_oid && + echo "$exp_ref" >ref.expect && + git rev-parse --symbolic-full-name HEAD >ref.actual && + test_cmp ref.expect ref.actual && + echo "$exp_oid" >oid.expect && + git rev-parse --verify HEAD >oid.actual && + test_cmp oid.expect oid.actual + fi +} - test $exp_ref = $(git rev-parse --symbolic-full-name HEAD) && - test $exp_sha = $(git rev-parse --verify HEAD) +test_dirty_unmergeable () { + test_expect_code 1 git diff --exit-code } -test_dirty_unmergeable() { - ! git diff --exit-code >/dev/null +test_dirty_unmergeable_discards_changes () { + git diff --exit-code } -setup_dirty_unmergeable() { +setup_dirty_unmergeable () { echo >>file1 change2 } -test_dirty_mergeable() { - ! git diff --cached --exit-code >/dev/null +test_dirty_mergeable () { + test_expect_code 1 git diff --cached --exit-code +} + +test_dirty_mergeable_discards_changes () { + git diff --cached --exit-code } -setup_dirty_mergeable() { +setup_dirty_mergeable () { echo >file2 file2 && git add file2 } @@ -82,7 +108,7 @@ test_expect_success 'checkout -b to a new branch, set to an explicit ref' ' test_expect_success 'checkout -b to a new branch with unmergeable changes fails' ' setup_dirty_unmergeable && - test_must_fail do_checkout branch2 $HEAD1 && + do_checkout ! branch2 $HEAD1 && test_dirty_unmergeable ' @@ -93,7 +119,7 @@ test_expect_success 'checkout -f -b to a new branch with unmergeable changes dis # still dirty and on branch1 do_checkout branch2 $HEAD1 "-f -b" && - test_must_fail test_dirty_unmergeable + test_dirty_unmergeable_discards_changes ' test_expect_success 'checkout -b to a new branch preserves mergeable changes' ' @@ -111,12 +137,12 @@ test_expect_success 'checkout -f -b to a new branch with mergeable changes disca test_when_finished git reset --hard HEAD && setup_dirty_mergeable && do_checkout branch2 $HEAD1 "-f -b" && - test_must_fail test_dirty_mergeable + test_dirty_mergeable_discards_changes ' test_expect_success 'checkout -b to an existing branch fails' ' test_when_finished git reset --hard HEAD && - test_must_fail do_checkout branch2 $HEAD2 + do_checkout ! branch2 $HEAD2 ' test_expect_success 'checkout -b to @{-1} fails with the right branch name' ' @@ -140,7 +166,8 @@ test_expect_success 'checkout -B to a merge base' ' ' test_expect_success 'checkout -B to an existing branch from detached HEAD resets branch to HEAD' ' - git checkout $(git rev-parse --verify HEAD) && + head=$(git rev-parse --verify HEAD) && + git checkout "$head" && do_checkout branch2 "" -B ' @@ -155,14 +182,14 @@ test_expect_success 'checkout -B to an existing branch with unmergeable changes git checkout branch1 && setup_dirty_unmergeable && - test_must_fail do_checkout branch2 $HEAD1 -B && + do_checkout ! branch2 $HEAD1 -B && test_dirty_unmergeable ' test_expect_success 'checkout -f -B to an existing branch with unmergeable changes discards changes' ' # still dirty and on branch1 do_checkout branch2 $HEAD1 "-f -B" && - test_must_fail test_dirty_unmergeable + test_dirty_unmergeable_discards_changes ' test_expect_success 'checkout -B to an existing branch preserves mergeable changes' ' @@ -179,7 +206,7 @@ test_expect_success 'checkout -f -B to an existing branch with mergeable changes setup_dirty_mergeable && do_checkout branch2 $HEAD1 "-f -B" && - test_must_fail test_dirty_mergeable + test_dirty_mergeable_discards_changes ' test_expect_success 'checkout -b <describe>' ' diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh index fa0718c730..accfa9aa4b 100755 --- a/t/t2024-checkout-dwim.sh +++ b/t/t2024-checkout-dwim.sh @@ -37,7 +37,9 @@ test_expect_success 'setup' ' git checkout -b foo && test_commit a_foo && git checkout -b bar && - test_commit a_bar + test_commit a_bar && + git checkout -b ambiguous_branch_and_file && + test_commit a_ambiguous_branch_and_file ) && git init repo_b && ( @@ -46,7 +48,9 @@ test_expect_success 'setup' ' git checkout -b foo && test_commit b_foo && git checkout -b baz && - test_commit b_baz + test_commit b_baz && + git checkout -b ambiguous_branch_and_file && + test_commit b_ambiguous_branch_and_file ) && git remote add repo_a repo_a && git remote add repo_b repo_b && @@ -75,6 +79,26 @@ test_expect_success 'checkout of branch from multiple remotes fails #1' ' test_branch master ' +test_expect_success 'when arg matches multiple remotes, do not fallback to interpreting as pathspec' ' + # create a file with name matching remote branch name + git checkout -b t_ambiguous_branch_and_file && + >ambiguous_branch_and_file && + git add ambiguous_branch_and_file && + git commit -m "ambiguous_branch_and_file" && + + # modify file to verify that it will not be touched by checkout + test_when_finished "git checkout -- ambiguous_branch_and_file" && + echo "file contents" >ambiguous_branch_and_file && + cp ambiguous_branch_and_file expect && + + test_must_fail git checkout ambiguous_branch_and_file 2>err && + + test_i18ngrep "matched multiple (2) remote tracking branches" err && + + # file must not be altered + test_cmp expect ambiguous_branch_and_file +' + test_expect_success 'checkout of branch from multiple remotes fails with advice' ' git checkout -B master && test_might_fail git branch -D foo && diff --git a/t/t2026-checkout-pathspec-file.sh b/t/t2026-checkout-pathspec-file.sh new file mode 100755 index 0000000000..43d31d7948 --- /dev/null +++ b/t/t2026-checkout-pathspec-file.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +test_description='checkout --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + test_commit file0 && + + echo 1 >fileA.t && + echo 1 >fileB.t && + echo 1 >fileC.t && + echo 1 >fileD.t && + git add fileA.t fileB.t fileC.t fileD.t && + git commit -m "files 1" && + + echo 2 >fileA.t && + echo 2 >fileB.t && + echo 2 >fileC.t && + echo 2 >fileD.t && + git add fileA.t fileB.t fileC.t fileD.t && + git commit -m "files 2" && + + git tag checkpoint +' + +restore_checkpoint () { + git reset --hard checkpoint +} + +verify_expect () { + git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual && + test_cmp expect actual +} + +test_expect_success '--pathspec-from-file from stdin' ' + restore_checkpoint && + + echo fileA.t | git checkout --pathspec-from-file=- HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + EOF + verify_expect +' + +test_expect_success '--pathspec-from-file from file' ' + restore_checkpoint && + + echo fileA.t >list && + git checkout --pathspec-from-file=list HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + EOF + verify_expect +' + +test_expect_success 'NUL delimiters' ' + restore_checkpoint && + + printf "fileA.t\0fileB.t\0" | git checkout --pathspec-from-file=- --pathspec-file-nul HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'LF delimiters' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t\n" | git checkout --pathspec-from-file=- HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'no trailing delimiter' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t" | git checkout --pathspec-from-file=- HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'CRLF delimiters' ' + restore_checkpoint && + + printf "fileA.t\r\nfileB.t\r\n" | git checkout --pathspec-from-file=- HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'quotes' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + git checkout --pathspec-from-file=list HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + EOF + verify_expect +' + +test_expect_success 'quotes not compatible with --pathspec-file-nul' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + test_must_fail git checkout --pathspec-from-file=list --pathspec-file-nul HEAD^1 +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + printf "fileB.t\nfileC.t\n" | git checkout --pathspec-from-file=- HEAD^1 && + + cat >expect <<-\EOF && + M fileB.t + M fileC.t + EOF + verify_expect +' + +test_expect_success 'error conditions' ' + restore_checkpoint && + echo fileA.t >list && + + test_must_fail git checkout --pathspec-from-file=list --detach 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --detach" err && + + test_must_fail git checkout --pathspec-from-file=list --patch 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err && + + test_must_fail git checkout --pathspec-from-file=list -- fileA.t 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err && + + test_must_fail git checkout --pathspec-file-nul 2>err && + test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err +' + +test_done diff --git a/t/t2070-restore.sh b/t/t2070-restore.sh index 21c3f84459..076d0df7fc 100755 --- a/t/t2070-restore.sh +++ b/t/t2070-restore.sh @@ -106,4 +106,21 @@ test_expect_success 'restore --staged adds deleted intent-to-add file back to in git diff --cached --exit-code ' +test_expect_success 'restore --staged invalidates cache tree for deletions' ' + test_when_finished git reset --hard && + >new1 && + >new2 && + git add new1 new2 && + + # It is important to commit and then reset here, so that the index + # contains a valid cache-tree for the "both" tree. + git commit -m both && + git reset --soft HEAD^ && + + git restore --staged new1 && + git commit -m "just new2" && + git rev-parse HEAD:new2 && + test_must_fail git rev-parse HEAD:new1 +' + test_done diff --git a/t/t2072-restore-pathspec-file.sh b/t/t2072-restore-pathspec-file.sh new file mode 100755 index 0000000000..0d47946e8a --- /dev/null +++ b/t/t2072-restore-pathspec-file.sh @@ -0,0 +1,164 @@ +#!/bin/sh + +test_description='restore --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + test_commit file0 && + + echo 1 >fileA.t && + echo 1 >fileB.t && + echo 1 >fileC.t && + echo 1 >fileD.t && + git add fileA.t fileB.t fileC.t fileD.t && + git commit -m "files 1" && + + echo 2 >fileA.t && + echo 2 >fileB.t && + echo 2 >fileC.t && + echo 2 >fileD.t && + git add fileA.t fileB.t fileC.t fileD.t && + git commit -m "files 2" && + + git tag checkpoint +' + +restore_checkpoint () { + git reset --hard checkpoint +} + +verify_expect () { + git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual && + test_cmp expect actual +} + +test_expect_success '--pathspec-from-file from stdin' ' + restore_checkpoint && + + echo fileA.t | git restore --pathspec-from-file=- --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + EOF + verify_expect +' + +test_expect_success '--pathspec-from-file from file' ' + restore_checkpoint && + + echo fileA.t >list && + git restore --pathspec-from-file=list --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + EOF + verify_expect +' + +test_expect_success 'NUL delimiters' ' + restore_checkpoint && + + printf "fileA.t\0fileB.t\0" | git restore --pathspec-from-file=- --pathspec-file-nul --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'LF delimiters' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t\n" | git restore --pathspec-from-file=- --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'no trailing delimiter' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t" | git restore --pathspec-from-file=- --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'CRLF delimiters' ' + restore_checkpoint && + + printf "fileA.t\r\nfileB.t\r\n" | git restore --pathspec-from-file=- --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + M fileB.t + EOF + verify_expect +' + +test_expect_success 'quotes' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + git restore --pathspec-from-file=list --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileA.t + EOF + verify_expect +' + +test_expect_success 'quotes not compatible with --pathspec-file-nul' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + test_must_fail git restore --pathspec-from-file=list --pathspec-file-nul --source=HEAD^1 +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + printf "fileB.t\nfileC.t\n" | git restore --pathspec-from-file=- --source=HEAD^1 && + + cat >expect <<-\EOF && + M fileB.t + M fileC.t + EOF + verify_expect +' + +test_expect_success 'error conditions' ' + restore_checkpoint && + echo fileA.t >list && + >empty_list && + + test_must_fail git restore --pathspec-from-file=list --patch --source=HEAD^1 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err && + + test_must_fail git restore --pathspec-from-file=list --source=HEAD^1 -- fileA.t 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err && + + test_must_fail git restore --pathspec-file-nul --source=HEAD^1 2>err && + test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err && + + test_must_fail git restore --pathspec-from-file=empty_list --source=HEAD^1 2>err && + test_i18ngrep -e "you must specify path(s) to restore" err +' + +test_done diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh index e819ba741e..b5ece19460 100755 --- a/t/t2400-worktree-add.sh +++ b/t/t2400-worktree-add.sh @@ -438,7 +438,7 @@ test_expect_success 'git worktree add does not match remote' ' cd foo && test_must_fail git config "branch.foo.remote" && test_must_fail git config "branch.foo.merge" && - ! test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo + test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo ) ' @@ -483,7 +483,7 @@ test_expect_success 'git worktree --no-guess-remote option overrides config' ' cd foo && test_must_fail git config "branch.foo.remote" && test_must_fail git config "branch.foo.merge" && - ! test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo + test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo ) ' @@ -587,4 +587,28 @@ test_expect_success '"add" should not fail because of another bad worktree' ' ) ' +test_expect_success '"add" with uninitialized submodule, with submodule.recurse unset' ' + test_create_repo submodule && + test_commit -C submodule first && + test_create_repo project && + git -C project submodule add ../submodule && + git -C project add submodule && + test_tick && + git -C project commit -m add_sub && + git clone project project-clone && + git -C project-clone worktree add ../project-2 +' +test_expect_success '"add" with uninitialized submodule, with submodule.recurse set' ' + git -C project-clone -c submodule.recurse worktree add ../project-3 +' + +test_expect_success '"add" with initialized submodule, with submodule.recurse unset' ' + git -C project-clone submodule update --init && + git -C project-clone worktree add ../project-4 +' + +test_expect_success '"add" with initialized submodule, with submodule.recurse set' ' + git -C project-clone -c submodule.recurse worktree add ../project-5 +' + test_done diff --git a/t/t2405-worktree-submodule.sh b/t/t2405-worktree-submodule.sh new file mode 100755 index 0000000000..e1b2bfd87e --- /dev/null +++ b/t/t2405-worktree-submodule.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +test_description='Combination of submodules and multiple worktrees' + +. ./test-lib.sh + +base_path=$(pwd -P) + +test_expect_success 'setup: create origin repos' ' + git init origin/sub && + test_commit -C origin/sub file1 && + git init origin/main && + test_commit -C origin/main first && + git -C origin/main submodule add ../sub && + git -C origin/main commit -m "add sub" && + test_commit -C origin/sub "file1 updated" file1 file1updated file1updated && + git -C origin/main/sub pull && + git -C origin/main add sub && + git -C origin/main commit -m "sub updated" +' + +test_expect_success 'setup: clone superproject to create main worktree' ' + git clone --recursive "$base_path/origin/main" main +' + +rev1_hash_main=$(git --git-dir=origin/main/.git show --pretty=format:%h -q "HEAD~1") +rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1") + +test_expect_success 'add superproject worktree' ' + git -C main worktree add "$base_path/worktree" "$rev1_hash_main" +' + +test_expect_failure 'submodule is checked out just after worktree add' ' + git -C worktree diff --submodule master"^!" >out && + grep "file1 updated" out +' + +test_expect_success 'add superproject worktree and initialize submodules' ' + git -C main worktree add "$base_path/worktree-submodule-update" "$rev1_hash_main" && + git -C worktree-submodule-update submodule update +' + +test_expect_success 'submodule is checked out just after submodule update in linked worktree' ' + git -C worktree-submodule-update diff --submodule master"^!" >out && + grep "file1 updated" out +' + +test_expect_success 'add superproject worktree and manually add submodule worktree' ' + git -C main worktree add "$base_path/linked_submodule" "$rev1_hash_main" && + git -C main/sub worktree add "$base_path/linked_submodule/sub" "$rev1_hash_sub" +' + +test_expect_success 'submodule is checked out after manually adding submodule worktree' ' + git -C linked_submodule diff --submodule master"^!" >out && + grep "file1 updated" out +' + +test_expect_success 'checkout --recurse-submodules uses $GIT_DIR for submodules in a linked worktree' ' + git -C main worktree add "$base_path/checkout-recurse" --detach && + git -C checkout-recurse submodule update --init && + echo "gitdir: ../../main/.git/worktrees/checkout-recurse/modules/sub" >expect-gitfile && + cat checkout-recurse/sub/.git >actual-gitfile && + test_cmp expect-gitfile actual-gitfile && + git -C main/sub rev-parse HEAD >expect-head-main && + git -C checkout-recurse checkout --recurse-submodules HEAD~1 && + cat checkout-recurse/sub/.git >actual-gitfile && + git -C main/sub rev-parse HEAD >actual-head-main && + test_cmp expect-gitfile actual-gitfile && + test_cmp expect-head-main actual-head-main +' + +test_expect_success 'core.worktree is removed in $GIT_DIR/modules/<name>/config, not in $GIT_COMMON_DIR/modules/<name>/config' ' + echo "../../../sub" >expect-main && + git -C main/sub config --get core.worktree >actual-main && + test_cmp expect-main actual-main && + echo "../../../../../../checkout-recurse/sub" >expect-linked && + git -C checkout-recurse/sub config --get core.worktree >actual-linked && + test_cmp expect-linked actual-linked && + git -C checkout-recurse checkout --recurse-submodules first && + test_expect_code 1 git -C main/.git/worktrees/checkout-recurse/modules/sub config --get core.worktree >linked-config && + test_must_be_empty linked-config && + git -C main/sub config --get core.worktree >actual-main && + test_cmp expect-main actual-main +' + +test_expect_success 'unsetting core.worktree does not prevent running commands directly against the submodule repository' ' + git -C main/.git/worktrees/checkout-recurse/modules/sub log +' + +test_done diff --git a/t/t3008-ls-files-lazy-init-name-hash.sh b/t/t3008-ls-files-lazy-init-name-hash.sh index 64f047332b..85f3704958 100755 --- a/t/t3008-ls-files-lazy-init-name-hash.sh +++ b/t/t3008-ls-files-lazy-init-name-hash.sh @@ -4,7 +4,7 @@ test_description='Test the lazy init name hash with various folder structures' . ./test-lib.sh -if test 1 -eq $($GIT_BUILD_DIR/t/helper/test-tool online-cpus) +if test 1 -eq $(test-tool online-cpus) then skip_all='skipping lazy-init tests, single cpu' test_done diff --git a/t/t3011-common-prefixes-and-directory-traversal.sh b/t/t3011-common-prefixes-and-directory-traversal.sh new file mode 100755 index 0000000000..3da5b2b6e7 --- /dev/null +++ b/t/t3011-common-prefixes-and-directory-traversal.sh @@ -0,0 +1,209 @@ +#!/bin/sh + +test_description='directory traversal handling, especially with common prefixes' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit hello && + + >empty && + mkdir untracked_dir && + >untracked_dir/empty && + git init untracked_repo && + >untracked_repo/empty && + + cat <<-EOF >.gitignore && + ignored + an_ignored_dir/ + EOF + mkdir an_ignored_dir && + mkdir an_untracked_dir && + >an_ignored_dir/ignored && + >an_ignored_dir/untracked && + >an_untracked_dir/ignored && + >an_untracked_dir/untracked +' + +test_expect_success 'git ls-files -o shows the right entries' ' + cat <<-EOF >expect && + .gitignore + actual + an_ignored_dir/ignored + an_ignored_dir/untracked + an_untracked_dir/ignored + an_untracked_dir/untracked + empty + expect + untracked_dir/empty + untracked_repo/ + EOF + git ls-files -o >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o --exclude-standard shows the right entries' ' + cat <<-EOF >expect && + .gitignore + actual + an_untracked_dir/untracked + empty + expect + untracked_dir/empty + untracked_repo/ + EOF + git ls-files -o --exclude-standard >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o untracked_dir recurses' ' + echo untracked_dir/empty >expect && + git ls-files -o untracked_dir >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o untracked_dir/ recurses' ' + echo untracked_dir/empty >expect && + git ls-files -o untracked_dir/ >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o --directory untracked_dir does not recurse' ' + echo untracked_dir/ >expect && + git ls-files -o --directory untracked_dir >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o --directory untracked_dir/ does not recurse' ' + echo untracked_dir/ >expect && + git ls-files -o --directory untracked_dir/ >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o untracked_repo does not recurse' ' + echo untracked_repo/ >expect && + git ls-files -o untracked_repo >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o untracked_repo/ does not recurse' ' + echo untracked_repo/ >expect && + git ls-files -o untracked_repo/ >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o untracked_dir untracked_repo recurses into untracked_dir only' ' + cat <<-EOF >expect && + untracked_dir/empty + untracked_repo/ + EOF + git ls-files -o untracked_dir untracked_repo >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o untracked_dir/ untracked_repo/ recurses into untracked_dir only' ' + cat <<-EOF >expect && + untracked_dir/empty + untracked_repo/ + EOF + git ls-files -o untracked_dir/ untracked_repo/ >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o --directory untracked_dir untracked_repo does not recurse' ' + cat <<-EOF >expect && + untracked_dir/ + untracked_repo/ + EOF + git ls-files -o --directory untracked_dir untracked_repo >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o --directory untracked_dir/ untracked_repo/ does not recurse' ' + cat <<-EOF >expect && + untracked_dir/ + untracked_repo/ + EOF + git ls-files -o --directory untracked_dir/ untracked_repo/ >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o .git shows nothing' ' + git ls-files -o .git >actual && + test_must_be_empty actual +' + +test_expect_success 'git ls-files -o .git/ shows nothing' ' + git ls-files -o .git/ >actual && + test_must_be_empty actual +' + +test_expect_success FUNNYNAMES 'git ls-files -o untracked_* recurses appropriately' ' + mkdir "untracked_*" && + >"untracked_*/empty" && + + cat <<-EOF >expect && + untracked_*/empty + untracked_dir/empty + untracked_repo/ + EOF + git ls-files -o "untracked_*" >actual && + test_cmp expect actual +' + +# It turns out fill_directory returns the right paths, but ls-files' post-call +# filtering in show_dir_entry() via calling dir_path_match() which ends up +# in git_fnmatch() has logic for PATHSPEC_ONESTAR that assumes the pathspec +# must match the full path; it doesn't check it for matching a leading +# directory. +test_expect_failure FUNNYNAMES 'git ls-files -o untracked_*/ recurses appropriately' ' + cat <<-EOF >expect && + untracked_*/empty + untracked_dir/empty + untracked_repo/ + EOF + git ls-files -o "untracked_*/" >actual && + test_cmp expect actual +' + +test_expect_success FUNNYNAMES 'git ls-files -o --directory untracked_* does not recurse' ' + cat <<-EOF >expect && + untracked_*/ + untracked_dir/ + untracked_repo/ + EOF + git ls-files -o --directory "untracked_*" >actual && + test_cmp expect actual +' + +test_expect_success FUNNYNAMES 'git ls-files -o --directory untracked_*/ does not recurse' ' + cat <<-EOF >expect && + untracked_*/ + untracked_dir/ + untracked_repo/ + EOF + git ls-files -o --directory "untracked_*/" >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files -o consistent between one or two dirs' ' + git ls-files -o --exclude-standard an_ignored_dir/ an_untracked_dir/ >tmp && + ! grep ^an_ignored_dir/ tmp >expect && + git ls-files -o --exclude-standard an_ignored_dir/ >actual && + test_cmp expect actual +' + +# ls-files doesn't have a way to request showing both untracked and ignored +# files at the same time, so use `git status --ignored` +test_expect_success 'git status --ignored shows same files under dir with or without pathspec' ' + cat <<-EOF >expect && + ?? an_untracked_dir/ + !! an_untracked_dir/ignored + EOF + git status --porcelain --ignored >output && + grep an_untracked_dir output >expect && + git status --porcelain --ignored an_untracked_dir/ >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh index 2170758e38..d48d211a95 100755 --- a/t/t3030-merge-recursive.sh +++ b/t/t3030-merge-recursive.sh @@ -604,7 +604,7 @@ test_expect_success 'merge removes empty directories' ' git commit -mremoved-d/e && git checkout master && git merge -s recursive rm && - test_must_fail test -d d + test_path_is_missing d ' test_expect_success 'merge-recursive simple w/submodule' ' diff --git a/t/t3060-ls-files-with-tree.sh b/t/t3060-ls-files-with-tree.sh index 44f378ce41..52ed665fcd 100755 --- a/t/t3060-ls-files-with-tree.sh +++ b/t/t3060-ls-files-with-tree.sh @@ -47,7 +47,7 @@ test_expect_success setup ' git add . ' -test_expect_success 'git -ls-files --with-tree should succeed from subdir' ' +test_expect_success 'git ls-files --with-tree should succeed from subdir' ' # We have to run from a sub-directory to trigger prune_path # Then we finally get to run our --with-tree test ( @@ -57,7 +57,7 @@ test_expect_success 'git -ls-files --with-tree should succeed from subdir' ' ' test_expect_success \ - 'git -ls-files --with-tree should add entries from named tree.' \ + 'git ls-files --with-tree should add entries from named tree.' \ 'test_cmp expected output' test_done diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index 0579cd9969..bd808f87ed 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -8,8 +8,8 @@ test_description='range-diff tests' # harm than good. We need some real history. test_expect_success 'setup' ' - git fast-import < "$TEST_DIRECTORY"/t3206/history.export && - test_oid_cache <<-EOF + git fast-import <"$TEST_DIRECTORY"/t3206/history.export && + test_oid_cache <<-\EOF # topic t1 sha1:4de457d t2 sha1:fccce22 @@ -102,6 +102,14 @@ test_expect_success 'setup' ' n3 sha256:3b0a644 n4 sha256:e461653 + # mode change + o1 sha1:4d39cb3 + o2 sha1:26c107f + o3 sha1:4c1e0f5 + o1 sha256:d0dd598 + o2 sha256:c4a279e + o3 sha256:78459d7 + # added and removed s1 sha1:096b1ba s2 sha1:d92e698 @@ -121,88 +129,88 @@ test_expect_success 'setup' ' test_expect_success 'simple A..B A..C (unmodified)' ' git range-diff --no-color master..topic master..unmodified \ >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/ 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/ 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/ 4: $(test_oid t4) = 4: $(test_oid u4) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'simple B...C (unmodified)' ' git range-diff --no-color topic...unmodified >actual && - # same "expected" as above - test_cmp expected actual + # same "expect" as above + test_cmp expect actual ' test_expect_success 'simple A B C (unmodified)' ' git range-diff --no-color master topic unmodified >actual && - # same "expected" as above - test_cmp expected actual + # same "expect" as above + test_cmp expect actual ' test_expect_success 'trivial reordering' ' git range-diff --no-color master topic reordered >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid r1) s/5/A/ 3: $(test_oid t3) = 2: $(test_oid r2) s/11/B/ 4: $(test_oid t4) = 3: $(test_oid r3) s/12/B/ 2: $(test_oid t2) = 4: $(test_oid r4) s/4/A/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'removed a commit' ' git range-diff --no-color master topic removed >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid d1) s/5/A/ 2: $(test_oid t2) < -: $(test_oid __) s/4/A/ 3: $(test_oid t3) = 2: $(test_oid d2) s/11/B/ 4: $(test_oid t4) = 3: $(test_oid d3) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'added a commit' ' git range-diff --no-color master topic added >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid a1) s/5/A/ 2: $(test_oid t2) = 2: $(test_oid a2) s/4/A/ -: $(test_oid __) > 3: $(test_oid a3) s/6/A/ 3: $(test_oid t3) = 4: $(test_oid a4) s/11/B/ 4: $(test_oid t4) = 5: $(test_oid a5) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'new base, A B C' ' git range-diff --no-color master topic rebased >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid b1) s/5/A/ 2: $(test_oid t2) = 2: $(test_oid b2) s/4/A/ 3: $(test_oid t3) = 3: $(test_oid b3) s/11/B/ 4: $(test_oid t4) = 4: $(test_oid b4) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'new base, B...C' ' # this syntax includes the commits from master! git range-diff --no-color topic...rebased >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && -: $(test_oid __) > 1: $(test_oid b5) unrelated 1: $(test_oid t1) = 2: $(test_oid b1) s/5/A/ 2: $(test_oid t2) = 3: $(test_oid b2) s/4/A/ 3: $(test_oid t3) = 4: $(test_oid b3) s/11/B/ 4: $(test_oid t4) = 5: $(test_oid b4) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'changed commit' ' git range-diff --no-color topic...changed >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/ @@ -226,23 +234,23 @@ test_expect_success 'changed commit' ' +B 13 EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'changed commit with --no-patch diff option' ' git range-diff --no-color --no-patch topic...changed >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/ 4: $(test_oid t4) ! 4: $(test_oid c4) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'changed commit with --stat diff option' ' git range-diff --no-color --stat topic...changed >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ a => b | 0 1 file changed, 0 insertions(+), 0 deletions(-) @@ -256,12 +264,12 @@ test_expect_success 'changed commit with --stat diff option' ' a => b | 0 1 file changed, 0 insertions(+), 0 deletions(-) EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'changed commit with sm config' ' git range-diff --no-color --submodule=log topic...changed >actual && - cat >expected <<-EOF && + cat >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid c1) s/5/A/ 2: $(test_oid t2) = 2: $(test_oid c2) s/4/A/ 3: $(test_oid t3) ! 3: $(test_oid c3) s/11/B/ @@ -285,12 +293,12 @@ test_expect_success 'changed commit with sm config' ' +B 13 EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'renamed file' ' git range-diff --no-color --submodule=log topic...renamed-file >actual && - sed s/Z/\ /g >expected <<-EOF && + sed s/Z/\ /g >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid n1) s/5/A/ 2: $(test_oid t2) ! 2: $(test_oid n2) s/4/A/ @@ Metadata @@ -330,13 +338,13 @@ test_expect_success 'renamed file' ' Z 10 Z B EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'file with mode only change' ' git range-diff --no-color --submodule=log topic...mode-only-change >actual && - sed s/Z/\ /g >expected <<-EOF && - 1: fccce22 ! 1: 4d39cb3 s/4/A/ + sed s/Z/\ /g >expect <<-EOF && + 1: $(test_oid t2) ! 1: $(test_oid o1) s/4/A/ @@ Metadata ZAuthor: Thomas Rast <trast@inf.ethz.ch> Z @@ -352,7 +360,7 @@ test_expect_success 'file with mode only change' ' Z 7 + + ## other-file (new) ## - 2: 147e64e ! 2: 26c107f s/11/B/ + 2: $(test_oid t3) ! 2: $(test_oid o2) s/11/B/ @@ Metadata ZAuthor: Thomas Rast <trast@inf.ethz.ch> Z @@ -368,14 +376,14 @@ test_expect_success 'file with mode only change' ' Z 14 + + ## other-file (mode change 100644 => 100755) ## - 3: a63e992 = 3: 4c1e0f5 s/12/B/ + 3: $(test_oid t4) = 3: $(test_oid o3) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'file added and later removed' ' git range-diff --no-color --submodule=log topic...added-removed >actual && - sed s/Z/\ /g >expected <<-EOF && + sed s/Z/\ /g >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid s1) s/5/A/ 2: $(test_oid t2) ! 2: $(test_oid s2) s/4/A/ @@ Metadata @@ -411,7 +419,7 @@ test_expect_success 'file added and later removed' ' + ## new-file (deleted) ## 4: $(test_oid t4) = 4: $(test_oid s4) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'no commits on one side' ' @@ -421,7 +429,7 @@ test_expect_success 'no commits on one side' ' test_expect_success 'changed message' ' git range-diff --no-color topic...changed-message >actual && - sed s/Z/\ /g >expected <<-EOF && + sed s/Z/\ /g >expect <<-EOF && 1: $(test_oid t1) = 1: $(test_oid m1) s/5/A/ 2: $(test_oid t2) ! 2: $(test_oid m2) s/4/A/ @@ Metadata @@ -436,7 +444,7 @@ test_expect_success 'changed message' ' 3: $(test_oid t3) = 3: $(test_oid m3) s/11/B/ 4: $(test_oid t4) = 4: $(test_oid m4) s/12/B/ EOF - test_cmp expected actual + test_cmp expect actual ' test_expect_success 'dual-coloring' ' @@ -505,4 +513,202 @@ test_expect_success 'range-diff overrides diff.noprefix internally' ' git -c diff.noprefix=true range-diff HEAD^... ' +test_expect_success 'range-diff compares notes by default' ' + git notes add -m "topic note" topic && + git notes add -m "unmodified note" unmodified && + test_when_finished git notes remove topic unmodified && + git range-diff --no-color master..topic master..unmodified \ + >actual && + sed s/Z/\ /g >expect <<-EOF && + 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/ + 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/ + 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/ + 4: $(test_oid t4) ! 4: $(test_oid u4) s/12/B/ + @@ Commit message + Z + Z + Z ## Notes ## + - topic note + + unmodified note + Z + Z ## file ## + Z@@ file: A + EOF + test_cmp expect actual +' + +test_expect_success 'range-diff with --no-notes' ' + git notes add -m "topic note" topic && + git notes add -m "unmodified note" unmodified && + test_when_finished git notes remove topic unmodified && + git range-diff --no-color --no-notes master..topic master..unmodified \ + >actual && + cat >expect <<-EOF && + 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/ + 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/ + 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/ + 4: $(test_oid t4) = 4: $(test_oid u4) s/12/B/ + EOF + test_cmp expect actual +' + +test_expect_success 'range-diff with multiple --notes' ' + git notes --ref=note1 add -m "topic note1" topic && + git notes --ref=note1 add -m "unmodified note1" unmodified && + test_when_finished git notes --ref=note1 remove topic unmodified && + git notes --ref=note2 add -m "topic note2" topic && + git notes --ref=note2 add -m "unmodified note2" unmodified && + test_when_finished git notes --ref=note2 remove topic unmodified && + git range-diff --no-color --notes=note1 --notes=note2 master..topic master..unmodified \ + >actual && + sed s/Z/\ /g >expect <<-EOF && + 1: $(test_oid t1) = 1: $(test_oid u1) s/5/A/ + 2: $(test_oid t2) = 2: $(test_oid u2) s/4/A/ + 3: $(test_oid t3) = 3: $(test_oid u3) s/11/B/ + 4: $(test_oid t4) ! 4: $(test_oid u4) s/12/B/ + @@ Commit message + Z + Z + Z ## Notes (note1) ## + - topic note1 + + unmodified note1 + Z + Z + Z ## Notes (note2) ## + - topic note2 + + unmodified note2 + Z + Z ## file ## + Z@@ file: A + EOF + test_cmp expect actual +' + +test_expect_success 'format-patch --range-diff does not compare notes by default' ' + git notes add -m "topic note" topic && + git notes add -m "unmodified note" unmodified && + test_when_finished git notes remove topic unmodified && + git format-patch --cover-letter --range-diff=$prev \ + master..unmodified >actual && + test_when_finished "rm 000?-*" && + test_line_count = 5 actual && + test_i18ngrep "^Range-diff:$" 0000-* && + grep "= 1: .* s/5/A" 0000-* && + grep "= 2: .* s/4/A" 0000-* && + grep "= 3: .* s/11/B" 0000-* && + grep "= 4: .* s/12/B" 0000-* && + ! grep "Notes" 0000-* && + ! grep "note" 0000-* +' + +test_expect_success 'format-patch --range-diff with --no-notes' ' + git notes add -m "topic note" topic && + git notes add -m "unmodified note" unmodified && + test_when_finished git notes remove topic unmodified && + git format-patch --no-notes --cover-letter --range-diff=$prev \ + master..unmodified >actual && + test_when_finished "rm 000?-*" && + test_line_count = 5 actual && + test_i18ngrep "^Range-diff:$" 0000-* && + grep "= 1: .* s/5/A" 0000-* && + grep "= 2: .* s/4/A" 0000-* && + grep "= 3: .* s/11/B" 0000-* && + grep "= 4: .* s/12/B" 0000-* && + ! grep "Notes" 0000-* && + ! grep "note" 0000-* +' + +test_expect_success 'format-patch --range-diff with --notes' ' + git notes add -m "topic note" topic && + git notes add -m "unmodified note" unmodified && + test_when_finished git notes remove topic unmodified && + git format-patch --notes --cover-letter --range-diff=$prev \ + master..unmodified >actual && + test_when_finished "rm 000?-*" && + test_line_count = 5 actual && + test_i18ngrep "^Range-diff:$" 0000-* && + grep "= 1: .* s/5/A" 0000-* && + grep "= 2: .* s/4/A" 0000-* && + grep "= 3: .* s/11/B" 0000-* && + grep "! 4: .* s/12/B" 0000-* && + sed s/Z/\ /g >expect <<-EOF && + @@ Commit message + Z + Z + Z ## Notes ## + - topic note + + unmodified note + Z + Z ## file ## + Z@@ file: A + EOF + sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual && + test_cmp expect actual +' + +test_expect_success 'format-patch --range-diff with format.notes config' ' + git notes add -m "topic note" topic && + git notes add -m "unmodified note" unmodified && + test_when_finished git notes remove topic unmodified && + test_config format.notes true && + git format-patch --cover-letter --range-diff=$prev \ + master..unmodified >actual && + test_when_finished "rm 000?-*" && + test_line_count = 5 actual && + test_i18ngrep "^Range-diff:$" 0000-* && + grep "= 1: .* s/5/A" 0000-* && + grep "= 2: .* s/4/A" 0000-* && + grep "= 3: .* s/11/B" 0000-* && + grep "! 4: .* s/12/B" 0000-* && + sed s/Z/\ /g >expect <<-EOF && + @@ Commit message + Z + Z + Z ## Notes ## + - topic note + + unmodified note + Z + Z ## file ## + Z@@ file: A + EOF + sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual && + test_cmp expect actual +' + +test_expect_success 'format-patch --range-diff with multiple notes' ' + git notes --ref=note1 add -m "topic note1" topic && + git notes --ref=note1 add -m "unmodified note1" unmodified && + test_when_finished git notes --ref=note1 remove topic unmodified && + git notes --ref=note2 add -m "topic note2" topic && + git notes --ref=note2 add -m "unmodified note2" unmodified && + test_when_finished git notes --ref=note2 remove topic unmodified && + git format-patch --notes=note1 --notes=note2 --cover-letter --range-diff=$prev \ + master..unmodified >actual && + test_when_finished "rm 000?-*" && + test_line_count = 5 actual && + test_i18ngrep "^Range-diff:$" 0000-* && + grep "= 1: .* s/5/A" 0000-* && + grep "= 2: .* s/4/A" 0000-* && + grep "= 3: .* s/11/B" 0000-* && + grep "! 4: .* s/12/B" 0000-* && + sed s/Z/\ /g >expect <<-EOF && + @@ Commit message + Z + Z + Z ## Notes (note1) ## + - topic note1 + + unmodified note1 + Z + Z + Z ## Notes (note2) ## + - topic note2 + + unmodified note2 + Z + Z ## file ## + Z@@ file: A + EOF + sed "/@@ Commit message/,/@@ file: A/!d" 0000-* >actual && + test_cmp expect actual +' + test_done diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 9ea5fa4fd2..f41b2afb99 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -240,7 +240,7 @@ test_expect_success 'retry acquiring packed-refs.lock' ' test_expect_success SYMLINKS 'pack symlinked packed-refs' ' # First make sure that symlinking works when reading: - git update-ref refs/heads/loosy refs/heads/master && + git update-ref refs/heads/lossy refs/heads/master && git for-each-ref >all-refs-before && mv .git/packed-refs .git/my-deviant-packed-refs && ln -s my-deviant-packed-refs .git/packed-refs && diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index d66a5f6faa..8f43303007 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -54,7 +54,9 @@ test_expect_success 'create notes' ' test_path_is_missing .git/NOTES_EDITMSG && git ls-tree -r refs/notes/commits >actual && test_line_count = 1 actual && - test "b4" = "$(git notes show)" && + echo b4 >expect && + git notes show >actual && + test_cmp expect actual && git show HEAD^ && test_must_fail git notes show HEAD^ ' @@ -79,14 +81,21 @@ test_expect_success 'edit existing notes' ' test_path_is_missing .git/NOTES_EDITMSG && git ls-tree -r refs/notes/commits >actual && test_line_count = 1 actual && - test "b3" = "$(git notes show)" && + echo b3 >expect && + git notes show >actual && + test_cmp expect actual && git show HEAD^ && test_must_fail git notes show HEAD^ ' test_expect_success 'show notes from treeish' ' - test "b3" = "$(git notes --ref commits^{tree} show)" && - test "b4" = "$(git notes --ref commits@{1} show)" + echo b3 >expect && + git notes --ref commits^{tree} show >actual && + test_cmp expect actual && + + echo b4 >expect && + git notes --ref commits@{1} show >actual && + test_cmp expect actual ' test_expect_success 'cannot edit notes from non-ref' ' @@ -99,7 +108,9 @@ test_expect_success 'cannot "git notes add -m" where notes already exists' ' test_path_is_missing .git/NOTES_EDITMSG && git ls-tree -r refs/notes/commits >actual && test_line_count = 1 actual && - test "b3" = "$(git notes show)" && + echo b3 >expect && + git notes show >actual && + test_cmp expect actual && git show HEAD^ && test_must_fail git notes show HEAD^ ' @@ -109,7 +120,9 @@ test_expect_success 'can overwrite existing note with "git notes add -f -m"' ' test_path_is_missing .git/NOTES_EDITMSG && git ls-tree -r refs/notes/commits >actual && test_line_count = 1 actual && - test "b1" = "$(git notes show)" && + echo b1 >expect && + git notes show >actual && + test_cmp expect actual && git show HEAD^ && test_must_fail git notes show HEAD^ ' @@ -119,7 +132,9 @@ test_expect_success 'add w/no options on existing note morphs into edit' ' test_path_is_missing .git/NOTES_EDITMSG && git ls-tree -r refs/notes/commits >actual && test_line_count = 1 actual && - test "b2" = "$(git notes show)" && + echo b2 >expect && + git notes show >actual && + test_cmp expect actual && git show HEAD^ && test_must_fail git notes show HEAD^ ' @@ -129,7 +144,9 @@ test_expect_success 'can overwrite existing note with "git notes add -f"' ' test_path_is_missing .git/NOTES_EDITMSG && git ls-tree -r refs/notes/commits >actual && test_line_count = 1 actual && - test "b1" = "$(git notes show)" && + echo b1 >expect && + git notes show >actual && + test_cmp expect actual && git show HEAD^ && test_must_fail git notes show HEAD^ ' @@ -146,7 +163,8 @@ test_expect_success 'show notes' ' Notes: ${indent}b1 EOF - ! (git cat-file commit HEAD | grep b1) && + git cat-file commit HEAD >commits && + ! grep b1 commits && git log -1 >actual && test_cmp expect actual ' @@ -472,9 +490,11 @@ test_expect_success 'removing with --stdin --ignore-missing' ' test_expect_success 'list notes with "git notes list"' ' commit_2=$(git rev-parse 2nd) && commit_3=$(git rev-parse 3rd) && + note_2=$(git rev-parse refs/notes/commits:$commit_2) && + note_3=$(git rev-parse refs/notes/commits:$commit_3) && sort -t" " -k2 >expect <<-EOF && - $(git rev-parse refs/notes/commits:$commit_2) $commit_2 - $(git rev-parse refs/notes/commits:$commit_3) $commit_3 + $note_2 $commit_2 + $note_3 $commit_3 EOF git notes list >actual && test_cmp expect actual @@ -486,9 +506,7 @@ test_expect_success 'list notes with "git notes"' ' ' test_expect_success 'list specific note with "git notes list <object>"' ' - cat >expect <<-EOF && - $(git rev-parse refs/notes/commits:$commit_3) - EOF + git rev-parse refs/notes/commits:$commit_3 >expect && git notes list HEAD^^ >actual && test_cmp expect actual ' @@ -512,10 +530,11 @@ test_expect_success 'append to existing note with "git notes append"' ' test_expect_success '"git notes list" does not expand to "git notes list HEAD"' ' commit_5=$(git rev-parse 5th) && + note_5=$(git rev-parse refs/notes/commits:$commit_5) && sort -t" " -k2 >expect_list <<-EOF && - $(git rev-parse refs/notes/commits:$commit_2) $commit_2 - $(git rev-parse refs/notes/commits:$commit_3) $commit_3 - $(git rev-parse refs/notes/commits:$commit_5) $commit_5 + $note_2 $commit_2 + $note_3 $commit_3 + $note_5 $commit_5 EOF git notes list >actual && test_cmp expect_list actual @@ -721,7 +740,8 @@ test_expect_success 'Allow notes on non-commits (trees, blobs, tags)' ' git notes show HEAD: >actual && test_cmp expect actual && echo "Note on a blob" >expect && - filename=$(git ls-tree --name-only HEAD | head -n1) && + git ls-tree --name-only HEAD >files && + filename=$(head -n1 files) && git notes add -m "Note on a blob" HEAD:$filename && git notes show HEAD:$filename >actual && test_cmp expect actual && @@ -745,10 +765,13 @@ test_expect_success 'create note from other note with "git notes add -C"' ' Notes: ${indent}order test EOF - git notes add -C $(git notes list HEAD^) && + note=$(git notes list HEAD^) && + git notes add -C $note && git log -1 >actual && test_cmp expect actual && - test "$(git notes list HEAD)" = "$(git notes list HEAD^)" + git notes list HEAD^ >expect && + git notes list HEAD >actual && + test_cmp expect actual ' test_expect_success 'create note from non-existing note with "git notes add -C" fails' ' @@ -777,11 +800,12 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i Notes: ${indent}This is a blob object EOF - blob=$(echo "This is a blob object" | git hash-object -w --stdin) && - git notes add -C $blob && + echo "This is a blob object" | git hash-object -w --stdin >blob && + git notes add -C $(cat blob) && git log -1 >actual && test_cmp expect actual && - test "$(git notes list HEAD)" = "$blob" + git notes list HEAD >actual && + test_cmp blob actual ' test_expect_success 'create note from other note with "git notes add -c"' ' @@ -797,7 +821,8 @@ test_expect_success 'create note from other note with "git notes add -c"' ' Notes: ${indent}yet another note EOF - MSG="yet another note" git notes add -c $(git notes list HEAD^^) && + note=$(git notes list HEAD^^) && + MSG="yet another note" git notes add -c $note && git log -1 >actual && test_cmp expect actual ' @@ -822,7 +847,8 @@ test_expect_success 'append to note from other note with "git notes append -C"' ${indent} ${indent}yet another note EOF - git notes append -C $(git notes list HEAD^) HEAD^ && + note=$(git notes list HEAD^) && + git notes append -C $note HEAD^ && git log -1 HEAD^ >actual && test_cmp expect actual ' @@ -839,7 +865,8 @@ test_expect_success 'create note from other note with "git notes append -c"' ' Notes: ${indent}other note EOF - MSG="other note" git notes append -c $(git notes list HEAD^) && + note=$(git notes list HEAD^) && + MSG="other note" git notes append -c $note && git log -1 >actual && test_cmp expect actual ' @@ -858,7 +885,8 @@ test_expect_success 'append to note from other note with "git notes append -c"' ${indent} ${indent}yet another note EOF - MSG="yet another note" git notes append -c $(git notes list HEAD) && + note=$(git notes list HEAD) && + MSG="yet another note" git notes append -c $note && git log -1 >actual && test_cmp expect actual ' @@ -878,7 +906,9 @@ test_expect_success 'copy note with "git notes copy"' ' git notes copy 8th 4th && git log 3rd..4th >actual && test_cmp expect actual && - test "$(git note list 4th)" = "$(git note list 8th)" + git notes list 4th >expect && + git notes list 8th >actual && + test_cmp expect actual ' test_expect_success 'copy note with "git notes copy" with default' ' @@ -899,14 +929,30 @@ test_expect_success 'copy note with "git notes copy" with default' ' git notes copy HEAD^ && git log -1 >actual && test_cmp expect actual && - test "$(git notes list HEAD)" = "$(git notes list HEAD^)" + git notes list HEAD^ >expect && + git notes list HEAD >actual && + test_cmp expect actual ' test_expect_success 'prevent overwrite with "git notes copy"' ' test_must_fail git notes copy HEAD~2 HEAD && + cat >expect <<-EOF && + commit $commit + Author: A U Thor <author@example.com> + Date: Thu Apr 7 15:23:13 2005 -0700 + + ${indent}11th + + Notes: + ${indent}other note + ${indent} + ${indent}yet another note + EOF git log -1 >actual && test_cmp expect actual && - test "$(git notes list HEAD)" = "$(git notes list HEAD^)" + git notes list HEAD^ >expect && + git notes list HEAD >actual && + test_cmp expect actual ' test_expect_success 'allow overwrite with "git notes copy -f"' ' @@ -924,7 +970,9 @@ test_expect_success 'allow overwrite with "git notes copy -f"' ' git notes copy -f HEAD~3 HEAD && git log -1 >actual && test_cmp expect actual && - test "$(git notes list HEAD)" = "$(git notes list HEAD~3)" + git notes list HEAD~3 >expect && + git notes list HEAD >actual && + test_cmp expect actual ' test_expect_success 'allow overwrite with "git notes copy -f" with default' ' @@ -944,7 +992,9 @@ test_expect_success 'allow overwrite with "git notes copy -f" with default' ' git notes copy -f HEAD~2 && git log -1 >actual && test_cmp expect actual && - test "$(git notes list HEAD)" = "$(git notes list HEAD~2)" + git notes list HEAD~2 >expect && + git notes list HEAD >actual && + test_cmp expect actual ' test_expect_success 'cannot copy note from object without notes' ' @@ -979,13 +1029,21 @@ test_expect_success 'git notes copy --stdin' ' ${indent} ${indent}yet another note EOF - (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) && - echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) | - git notes copy --stdin && + from=$(git rev-parse HEAD~3) && + to=$(git rev-parse HEAD^) && + echo "$from" "$to" >copy && + from=$(git rev-parse HEAD~2) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >>copy && + git notes copy --stdin <copy && git log -2 >actual && test_cmp expect actual && - test "$(git notes list HEAD)" = "$(git notes list HEAD~2)" && - test "$(git notes list HEAD^)" = "$(git notes list HEAD~3)" + git notes list HEAD~2 >expect && + git notes list HEAD >actual && + test_cmp expect actual && + git notes list HEAD~3 >expect && + git notes list HEAD^ >actual && + test_cmp expect actual ' test_expect_success 'git notes copy --for-rewrite (unconfigured)' ' @@ -1006,9 +1064,13 @@ test_expect_success 'git notes copy --for-rewrite (unconfigured)' ' ${indent}14th EOF - (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) && - echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) | - git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD~3) && + to=$(git rev-parse HEAD^) && + echo "$from" "$to" >copy && + from=$(git rev-parse HEAD~2) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >>copy && + git notes copy --for-rewrite=foo <copy && git log -2 >actual && test_cmp expect actual ' @@ -1041,17 +1103,23 @@ test_expect_success 'git notes copy --for-rewrite (enabled)' ' EOF test_config notes.rewriteMode overwrite && test_config notes.rewriteRef "refs/notes/*" && - (echo $(git rev-parse HEAD~3) $(git rev-parse HEAD^) && - echo $(git rev-parse HEAD~2) $(git rev-parse HEAD)) | - git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD~3) && + to=$(git rev-parse HEAD^) && + echo "$from" "$to" >copy && + from=$(git rev-parse HEAD~2) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >>copy && + git notes copy --for-rewrite=foo <copy && git log -2 >actual && test_cmp expect actual ' test_expect_success 'git notes copy --for-rewrite (disabled)' ' test_config notes.rewrite.bar false && - echo $(git rev-parse HEAD~3) $(git rev-parse HEAD) | - git notes copy --for-rewrite=bar && + from=$(git rev-parse HEAD~3) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && + git notes copy --for-rewrite=bar <copy && git log -2 >actual && test_cmp expect actual ' @@ -1071,8 +1139,10 @@ test_expect_success 'git notes copy --for-rewrite (overwrite)' ' git notes add -f -m"a fresh note" HEAD^ && test_config notes.rewriteMode overwrite && test_config notes.rewriteRef "refs/notes/*" && - echo $(git rev-parse HEAD^) $(git rev-parse HEAD) | - git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && + git notes copy --for-rewrite=foo <copy && git log -1 >actual && test_cmp expect actual ' @@ -1080,8 +1150,10 @@ test_expect_success 'git notes copy --for-rewrite (overwrite)' ' test_expect_success 'git notes copy --for-rewrite (ignore)' ' test_config notes.rewriteMode ignore && test_config notes.rewriteRef "refs/notes/*" && - echo $(git rev-parse HEAD^) $(git rev-parse HEAD) | - git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && + git notes copy --for-rewrite=foo <copy && git log -1 >actual && test_cmp expect actual ' @@ -1103,8 +1175,10 @@ test_expect_success 'git notes copy --for-rewrite (append)' ' git notes add -f -m"another fresh note" HEAD^ && test_config notes.rewriteMode concatenate && test_config notes.rewriteRef "refs/notes/*" && - echo $(git rev-parse HEAD^) $(git rev-parse HEAD) | - git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && + git notes copy --for-rewrite=foo <copy && git log -1 >actual && test_cmp expect actual ' @@ -1131,9 +1205,13 @@ test_expect_success 'git notes copy --for-rewrite (append two to one)' ' git notes add -f -m"append 2" HEAD^^ && test_config notes.rewriteMode concatenate && test_config notes.rewriteRef "refs/notes/*" && - (echo $(git rev-parse HEAD^) $(git rev-parse HEAD) && - echo $(git rev-parse HEAD^^) $(git rev-parse HEAD)) | - git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && + from=$(git rev-parse HEAD^^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >>copy && + git notes copy --for-rewrite=foo <copy && git log -1 >actual && test_cmp expect actual ' @@ -1142,8 +1220,10 @@ test_expect_success 'git notes copy --for-rewrite (append empty)' ' git notes remove HEAD^ && test_config notes.rewriteMode concatenate && test_config notes.rewriteRef "refs/notes/*" && - echo $(git rev-parse HEAD^) $(git rev-parse HEAD) | - git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && + git notes copy --for-rewrite=foo <copy && git log -1 >actual && test_cmp expect actual ' @@ -1163,8 +1243,10 @@ test_expect_success 'GIT_NOTES_REWRITE_MODE works' ' test_config notes.rewriteMode concatenate && test_config notes.rewriteRef "refs/notes/*" && git notes add -f -m"replacement note 1" HEAD^ && - echo $(git rev-parse HEAD^) $(git rev-parse HEAD) | - GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo && + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && + GIT_NOTES_REWRITE_MODE=overwrite git notes copy --for-rewrite=foo <copy && git log -1 >actual && test_cmp expect actual ' @@ -1184,9 +1266,11 @@ test_expect_success 'GIT_NOTES_REWRITE_REF works' ' git notes add -f -m"replacement note 2" HEAD^ && test_config notes.rewriteMode overwrite && test_unconfig notes.rewriteRef && - echo $(git rev-parse HEAD^) $(git rev-parse HEAD) | + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && GIT_NOTES_REWRITE_REF=refs/notes/commits:refs/notes/other \ - git notes copy --for-rewrite=foo && + git notes copy --for-rewrite=foo <copy && git log -1 >actual && test_cmp expect actual ' @@ -1195,9 +1279,11 @@ test_expect_success 'GIT_NOTES_REWRITE_REF overrides config' ' git notes add -f -m"replacement note 3" HEAD^ && test_config notes.rewriteMode overwrite && test_config notes.rewriteRef refs/notes/other && - echo $(git rev-parse HEAD^) $(git rev-parse HEAD) | + from=$(git rev-parse HEAD^) && + to=$(git rev-parse HEAD) && + echo "$from" "$to" >copy && GIT_NOTES_REWRITE_REF=refs/notes/commits \ - git notes copy --for-rewrite=foo && + git notes copy --for-rewrite=foo <copy && git log -1 >actual && grep "replacement note 3" actual ' @@ -1212,26 +1298,36 @@ test_expect_success 'git notes copy diagnoses too many or too few parameters' ' test_expect_success 'git notes get-ref expands refs/heads/master to refs/notes/refs/heads/master' ' test_unconfig core.notesRef && sane_unset GIT_NOTES_REF && - test "$(git notes --ref=refs/heads/master get-ref)" = "refs/notes/refs/heads/master" + echo refs/notes/refs/heads/master >expect && + git notes --ref=refs/heads/master get-ref >actual && + test_cmp expect actual ' test_expect_success 'git notes get-ref (no overrides)' ' test_unconfig core.notesRef && sane_unset GIT_NOTES_REF && - test "$(git notes get-ref)" = "refs/notes/commits" + echo refs/notes/commits >expect && + git notes get-ref >actual && + test_cmp expect actual ' test_expect_success 'git notes get-ref (core.notesRef)' ' test_config core.notesRef refs/notes/foo && - test "$(git notes get-ref)" = "refs/notes/foo" + echo refs/notes/foo >expect && + git notes get-ref >actual && + test_cmp expect actual ' test_expect_success 'git notes get-ref (GIT_NOTES_REF)' ' - test "$(GIT_NOTES_REF=refs/notes/bar git notes get-ref)" = "refs/notes/bar" + echo refs/notes/bar >expect && + GIT_NOTES_REF=refs/notes/bar git notes get-ref >actual && + test_cmp expect actual ' test_expect_success 'git notes get-ref (--ref)' ' - test "$(GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref)" = "refs/notes/baz" + echo refs/notes/baz >expect && + GIT_NOTES_REF=refs/notes/bar git notes --ref=baz get-ref >actual && + test_cmp expect actual ' test_expect_success 'setup testing of empty notes' ' diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh index 831f83d211..3b4753e1b4 100755 --- a/t/t3305-notes-fanout.sh +++ b/t/t3305-notes-fanout.sh @@ -4,6 +4,38 @@ test_description='Test that adding/removing many notes triggers automatic fanout . ./test-lib.sh +path_has_fanout() { + path=$1 && + fanout=$2 && + after_last_slash=$((40 - $fanout * 2)) && + echo $path | grep -q "^\([0-9a-f]\{2\}/\)\{$fanout\}[0-9a-f]\{$after_last_slash\}$" +} + +touched_one_note_with_fanout() { + notes_commit=$1 && + modification=$2 && # 'A' for addition, 'D' for deletion + fanout=$3 && + diff=$(git diff-tree --no-commit-id --name-status --root -r $notes_commit) && + path=$(echo $diff | sed -e "s/^$modification[\t ]//") && + path_has_fanout "$path" $fanout; +} + +all_notes_have_fanout() { + notes_commit=$1 && + fanout=$2 && + git ls-tree -r --name-only $notes_commit 2>/dev/null | + while read path + do + path_has_fanout $path $fanout || return 1 + done +} + +test_expect_success 'tweak test environment' ' + git checkout -b nondeterminism && + test_commit A && + git checkout --orphan with_notes; +' + test_expect_success 'creating many notes with git-notes' ' num_notes=300 && i=0 && @@ -20,7 +52,7 @@ test_expect_success 'creating many notes with git-notes' ' test_expect_success 'many notes created correctly with git-notes' ' git log | grep "^ " > output && - i=300 && + i=$num_notes && while test $i -gt 0 do echo " commit #$i" && @@ -30,34 +62,46 @@ test_expect_success 'many notes created correctly with git-notes' ' test_cmp expect output ' -test_expect_success 'many notes created with git-notes triggers fanout' ' - # Expect entire notes tree to have a fanout == 1 - git ls-tree -r --name-only refs/notes/commits | - while read path +test_expect_success 'stable fanout 0 is followed by stable fanout 1' ' + i=$num_notes && + fanout=0 && + while test $i -gt 0 do - echo $path | grep "^../[0-9a-f]*$" || { - echo "Invalid path \"$path\"" && - return 1; - } - done + i=$(($i - 1)) && + if touched_one_note_with_fanout refs/notes/commits~$i A $fanout + then + continue + elif test $fanout -eq 0 + then + fanout=1 && + if all_notes_have_fanout refs/notes/commits~$i $fanout + then + echo "Fanout 0 -> 1 at refs/notes/commits~$i" && + continue + fi + fi && + echo "Failed fanout=$fanout check at refs/notes/commits~$i" && + git ls-tree -r --name-only refs/notes/commits~$i && + return 1 + done && + all_notes_have_fanout refs/notes/commits 1 ' test_expect_success 'deleting most notes with git-notes' ' - num_notes=250 && + remove_notes=285 && i=0 && git rev-list HEAD | - while test $i -lt $num_notes && read sha1 + while test $i -lt $remove_notes && read sha1 do i=$(($i + 1)) && test_tick && - git notes remove "$sha1" || - exit 1 + git notes remove "$sha1" 2>/dev/null || return 1 done ' test_expect_success 'most notes deleted correctly with git-notes' ' - git log HEAD~250 | grep "^ " > output && - i=50 && + git log HEAD~$remove_notes | grep "^ " > output && + i=$(($num_notes - $remove_notes)) && while test $i -gt 0 do echo " commit #$i" && @@ -67,16 +111,29 @@ test_expect_success 'most notes deleted correctly with git-notes' ' test_cmp expect output ' -test_expect_success 'deleting most notes triggers fanout consolidation' ' - # Expect entire notes tree to have a fanout == 0 - git ls-tree -r --name-only refs/notes/commits | - while read path +test_expect_success 'stable fanout 1 is followed by stable fanout 0' ' + i=$remove_notes && + fanout=1 && + while test $i -gt 0 do - echo $path | grep -v "^../.*" || { - echo "Invalid path \"$path\"" && - return 1; - } - done + i=$(($i - 1)) && + if touched_one_note_with_fanout refs/notes/commits~$i D $fanout + then + continue + elif test $fanout -eq 1 + then + fanout=0 && + if all_notes_have_fanout refs/notes/commits~$i $fanout + then + echo "Fanout 1 -> 0 at refs/notes/commits~$i" && + continue + fi + fi && + echo "Failed fanout=$fanout check at refs/notes/commits~$i" && + git ls-tree -r --name-only refs/notes/commits~$i && + return 1 + done && + all_notes_have_fanout refs/notes/commits 0 ' test_done diff --git a/t/t3308-notes-merge.sh b/t/t3308-notes-merge.sh index d60588ec8f..790e292966 100755 --- a/t/t3308-notes-merge.sh +++ b/t/t3308-notes-merge.sh @@ -20,7 +20,34 @@ test_expect_success setup ' git notes add -m "Notes on 3rd commit" 3rd && git notes add -m "Notes on 4th commit" 4th && # Copy notes to remote-notes - git fetch . refs/notes/*:refs/remote-notes/origin/* + git fetch . refs/notes/*:refs/remote-notes/origin/* && + + test_oid_init && + test_oid_cache <<-EOF + hash4a sha1:5e93d24084d32e1cb61f7070505b9d2530cca987 + hash3a sha1:8366731eeee53787d2bdf8fc1eff7d94757e8da0 + hash2a sha1:eede89064cd42441590d6afec6c37b321ada3389 + hash1a sha1:daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 + hash5b sha1:0f2efbd00262f2fd41dfae33df8765618eeacd99 + hash4b sha1:dec2502dac3ea161543f71930044deff93fa945c + hash3b sha1:4069cdb399fd45463ec6eef8e051a16a03592d91 + hash2c sha1:d000d30e6ddcfce3a8122c403226a2ce2fd04d9d + hash1c sha1:43add6bd0c8c0bc871ac7991e0f5573cfba27804 + hash4d sha1:1f257a3a90328557c452f0817d6cc50c89d315d4 + hash3d sha1:05a4927951bcef347f51486575b878b2b60137f2 + + hash4a sha256:eef876be1d32ac2e2e42240e0429325cec116e55e88cb2969899fac695aa762f + hash3a sha256:cf7cd1bc091d7ba4166a86df864110e42087cd893a5ae96bc50d637e0290939d + hash2a sha256:21ddde7ebce2c285213898cb04deca0fd3209610cf7aaf8222e4e2f45262fae2 + hash1a sha256:f9fe0eda16c6027732ed9d4295689a03abd16f893be69b3dcbf4037ddb191921 + hash5b sha256:20046f2244577797a9e3d3f790ea9eca4d8a6bafb2a5570bcb0e03aa02ce100b + hash4b sha256:f90563d134c61a95bb88afbd45d48ccc9e919c62aa6fbfcd483302b3e4d8dbcb + hash3b sha256:988f2aca9f2d87e93e6a73197c2bb99560cc44a2f92d18653968f956f01221e0 + hash2c sha256:84153b777b4d42827a756c6578dcdb59d8ae5d1360b874fb37c430150c825c26 + hash1c sha256:9beb2bc4eef72e4c4087be168a20573e34d993d9ab1883055f23e322afa06567 + hash4d sha256:32de39dc06e679a7abb2d4a55ede7709b3124340a4a90aa305971b1c72ac319d + hash3d sha256:fa73b20e41cbb7541c4c81d1535016131dbfbeb05bf6a71f6115e9cad31c7af5 + EOF ' commit_sha1=$(git rev-parse 1st^{commit}) @@ -40,10 +67,10 @@ verify_notes () { } cat <<EOF | sort >expect_notes_x -5e93d24084d32e1cb61f7070505b9d2530cca987 $commit_sha4 -8366731eeee53787d2bdf8fc1eff7d94757e8da0 $commit_sha3 -eede89064cd42441590d6afec6c37b321ada3389 $commit_sha2 -daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1 +$(test_oid hash4a) $commit_sha4 +$(test_oid hash3a) $commit_sha3 +$(test_oid hash2a) $commit_sha2 +$(test_oid hash1a) $commit_sha1 EOF cat >expect_log_x <<EOF @@ -126,10 +153,10 @@ test_expect_success 'merge previous notes commit (y^ => y) => No-op' ' ' cat <<EOF | sort >expect_notes_y -0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 -dec2502dac3ea161543f71930044deff93fa945c $commit_sha4 -4069cdb399fd45463ec6eef8e051a16a03592d91 $commit_sha3 -daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1 +$(test_oid hash5b) $commit_sha5 +$(test_oid hash4b) $commit_sha4 +$(test_oid hash3b) $commit_sha3 +$(test_oid hash1a) $commit_sha1 EOF cat >expect_log_y <<EOF @@ -193,11 +220,11 @@ test_expect_success 'merge empty notes ref (z => y)' ' ' cat <<EOF | sort >expect_notes_y -0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 -dec2502dac3ea161543f71930044deff93fa945c $commit_sha4 -4069cdb399fd45463ec6eef8e051a16a03592d91 $commit_sha3 -d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 -43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1 +$(test_oid hash5b) $commit_sha5 +$(test_oid hash4b) $commit_sha4 +$(test_oid hash3b) $commit_sha3 +$(test_oid hash2c) $commit_sha2 +$(test_oid hash1c) $commit_sha1 EOF cat >expect_log_y <<EOF @@ -231,9 +258,9 @@ test_expect_success 'change notes on other notes ref (y)' ' ' cat <<EOF | sort >expect_notes_x -0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 -1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4 -daa55ffad6cb99bf64226532147ffcaf5ce8bdd1 $commit_sha1 +$(test_oid hash5b) $commit_sha5 +$(test_oid hash4d) $commit_sha4 +$(test_oid hash1a) $commit_sha1 EOF cat >expect_log_x <<EOF @@ -262,10 +289,10 @@ test_expect_success 'change notes on notes ref (x)' ' ' cat <<EOF | sort >expect_notes_x -0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 -1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4 -d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 -43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1 +$(test_oid hash5b) $commit_sha5 +$(test_oid hash4d) $commit_sha4 +$(test_oid hash2c) $commit_sha2 +$(test_oid hash1c) $commit_sha1 EOF cat >expect_log_x <<EOF @@ -296,8 +323,8 @@ test_expect_success 'merge y into x => Non-conflicting 3-way merge' ' ' cat <<EOF | sort >expect_notes_w -05a4927951bcef347f51486575b878b2b60137f2 $commit_sha3 -d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 +$(test_oid hash3d) $commit_sha3 +$(test_oid hash2c) $commit_sha2 EOF cat >expect_log_w <<EOF @@ -326,11 +353,11 @@ test_expect_success 'create notes on new, separate notes ref (w)' ' ' cat <<EOF | sort >expect_notes_x -0f2efbd00262f2fd41dfae33df8765618eeacd99 $commit_sha5 -1f257a3a90328557c452f0817d6cc50c89d315d4 $commit_sha4 -05a4927951bcef347f51486575b878b2b60137f2 $commit_sha3 -d000d30e6ddcfce3a8122c403226a2ce2fd04d9d $commit_sha2 -43add6bd0c8c0bc871ac7991e0f5573cfba27804 $commit_sha1 +$(test_oid hash5b) $commit_sha5 +$(test_oid hash4d) $commit_sha4 +$(test_oid hash3d) $commit_sha3 +$(test_oid hash2c) $commit_sha2 +$(test_oid hash1c) $commit_sha1 EOF cat >expect_log_x <<EOF diff --git a/t/t3309-notes-merge-auto-resolve.sh b/t/t3309-notes-merge-auto-resolve.sh index 14c2adf970..141d3e4ca4 100755 --- a/t/t3309-notes-merge-auto-resolve.sh +++ b/t/t3309-notes-merge-auto-resolve.sh @@ -23,7 +23,67 @@ test_expect_success 'setup commits' ' test_commit 12th && test_commit 13th && test_commit 14th && - test_commit 15th + test_commit 15th && + + test_oid_cache <<-EOF + hash15a sha1:457a85d6c814ea208550f15fcc48f804ac8dc023 + hash14a sha1:b0c95b954301d69da2bc3723f4cb1680d355937c + hash13a sha1:5d30216a129eeffa97d9694ffe8c74317a560315 + hash12a sha1:dd161bc149470fd890dd4ab52a4cbd79bbd18c36 + hash11a sha1:7abbc45126d680336fb24294f013a7cdfa3ed545 + hash10a sha1:b8d03e173f67f6505a76f6e00cf93440200dd9be + hash09a sha1:20c613c835011c48a5abe29170a2402ca6354910 + hash08a sha1:a3daf8a1e4e5dc3409a303ad8481d57bfea7f5d6 + hash07a sha1:897003322b53bc6ca098e9324ee508362347e734 + hash06a sha1:11d97fdebfa5ceee540a3da07bce6fa0222bc082 + hash15b sha1:68b8630d25516028bed862719855b3d6768d7833 + hash14b sha1:5de7ea7ad4f47e7ff91989fb82234634730f75df + hash13b sha1:3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc + hash12b sha1:a66055fa82f7a03fe0c02a6aba3287a85abf7c62 + hash05b sha1:154508c7a0bcad82b6fe4b472bc4c26b3bf0825b + hash04b sha1:e2bfd06a37dd2031684a59a6e2b033e212239c78 + hash03b sha1:5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 + hash15c sha1:9b4b2c61f0615412da3c10f98ff85b57c04ec765 + hash11c sha1:7e3c53503a3db8dd996cb62e37c66e070b44b54d + hash08c sha1:851e1638784a884c7dd26c5d41f3340f6387413a + hash05c sha1:99fc34adfc400b95c67b013115e37e31aa9a6d23 + hash02c sha1:283b48219aee9a4105f6cab337e789065c82c2b9 + hash15d sha1:7c4e546efd0fe939f876beb262ece02797880b54 + hash05d sha1:6c841cc36ea496027290967ca96bd2bef54dbb47 + hash15e sha1:d682107b8bf7a7aea1e537a8d5cb6a12b60135f1 + hash05e sha1:357b6ca14c7afd59b7f8b8aaaa6b8b723771135b + hash15f sha1:6be90240b5f54594203e25d9f2f64b7567175aee + hash05f sha1:660311d7f78dc53db12ac373a43fca7465381a7e + + hash15a sha256:45b1558e5c1b75f570010fa48aaa67bb2289fcd431b34ad81cb4c8b95f4f872a + hash14a sha256:6e7af179ea4dd28afdc83ae6912ba0098cdeff764b26a8b750b157dd81749092 + hash13a sha256:7353089961baf555388e1bac68c67c8ea94b08ccbd97532201cf7f6790703052 + hash12a sha256:5863e4521689ee1879ceab3b38d39e93ab5b51ec70aaf6a96ad388fbdedfa25e + hash11a sha256:82a0ec0338b4ecf8b44304badf4ad38d7469dc41827f38d7ba6c42e3bae3ee98 + hash10a sha256:e84f2564e92de9792c93b8d197262c735d7ccb1de6025cef8759af8f6c3308eb + hash09a sha256:4dd07764bcec696f195c0ea71ae89e174876403af1637e4642b8f4453fd23028 + hash08a sha256:02132c4546cd88a1d0aa5854dd55da120927f7904ba16afe36fe03e91a622067 + hash07a sha256:369baf7d00c6720efdc10273493555f943051f84a4706fb24caeb353fa4789db + hash06a sha256:52d32c10353583b2d96a5849b1f1f43c8018e76f3e8ef1b0d46eb5cff7cdefaf + hash15b sha256:345e6660b345fa174738a31a7a59423c394bdf414804e200bc510c65d971ae96 + hash14b sha256:7653a6596021c52e405cba979eea15a729993e7102b9a61ba4667e34f0ead4a1 + hash13b sha256:0f202a0b6b9690de2349c173dfd766a37e82744f61c14f1c389306f1d69f470b + hash12b sha256:eb00f219c026136ea6535b16ff8ec3efa510e6bf50098ca041e1a2a1d4b79840 + hash05b sha256:993b2290cd0c24c27c849d99f1904f3b590f77af0f539932734ad05679ac5a2f + hash04b sha256:c7fba0d6104917fbf35258f40b9fa4fc697cfa992deecd1570a3b08d0a5587a9 + hash03b sha256:7287a2d78a3766c181b08df38951d784b08b72a44f571ed6d855bd0be22c70f6 + hash15c sha256:62316660a22bf97857dc4a16709ec4d93a224e8c9f37d661ef91751e1f4c4166 + hash11c sha256:51c3763de9b08309370adc5036d58debb331980e73097902957c444602551daa + hash08c sha256:22cf1fa29599898a7218c51135d66ed85d22aad584f77db3305dedce4c3d4798 + hash05c sha256:2508fd86db980f0508893a1c1571bdf3b2ee113dc25ddb1a3a2fb94bd6cd0d58 + hash02c sha256:63bb527e0b4e1c8e1dd0d54dd778ca7c3718689fd6e37c473044cfbcf1cacfdb + hash15d sha256:667acb4e2d5f8df15e5aea4506dfd16d25bc7feca70fdb0d965a7222f983bb88 + hash05d sha256:09e6b5a6fe666c4a027674b6611a254b7d2528cd211c6b5288d1b4db6c741dfa + hash15e sha256:e8cbf52f6fcadc6de3c7761e64a89e9fe38d19a03d3e28ef6ca8596d93fc4f3a + hash05e sha256:cdb1e19f7ba1539f95af51a57edeb88a7ecc97d3c2f52da8c4c86af308595607 + hash15f sha256:29c14cb92da448a923963b8a43994268b19c2e57913de73f3667421fd2c0eeec + hash05f sha256:14a6e641b2c0a9f398ebac6b4d34afa5efea4c52d2631382f45f8f662266903b + EOF ' commit_sha1=$(git rev-parse 1st^{commit}) @@ -68,16 +128,16 @@ test_expect_success 'setup merge base (x)' ' ' cat <<EOF | sort >expect_notes_x -457a85d6c814ea208550f15fcc48f804ac8dc023 $commit_sha15 -b0c95b954301d69da2bc3723f4cb1680d355937c $commit_sha14 -5d30216a129eeffa97d9694ffe8c74317a560315 $commit_sha13 -dd161bc149470fd890dd4ab52a4cbd79bbd18c36 $commit_sha12 -7abbc45126d680336fb24294f013a7cdfa3ed545 $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -20c613c835011c48a5abe29170a2402ca6354910 $commit_sha9 -a3daf8a1e4e5dc3409a303ad8481d57bfea7f5d6 $commit_sha8 -897003322b53bc6ca098e9324ee508362347e734 $commit_sha7 -11d97fdebfa5ceee540a3da07bce6fa0222bc082 $commit_sha6 +$(test_oid hash15a) $commit_sha15 +$(test_oid hash14a) $commit_sha14 +$(test_oid hash13a) $commit_sha13 +$(test_oid hash12a) $commit_sha12 +$(test_oid hash11a) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash09a) $commit_sha9 +$(test_oid hash08a) $commit_sha8 +$(test_oid hash07a) $commit_sha7 +$(test_oid hash06a) $commit_sha6 EOF cat >expect_log_x <<EOF @@ -141,16 +201,16 @@ test_expect_success 'setup local branch (y)' ' ' cat <<EOF | sort >expect_notes_y -68b8630d25516028bed862719855b3d6768d7833 $commit_sha15 -5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 -3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 -a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 -7abbc45126d680336fb24294f013a7cdfa3ed545 $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -20c613c835011c48a5abe29170a2402ca6354910 $commit_sha9 -154508c7a0bcad82b6fe4b472bc4c26b3bf0825b $commit_sha5 -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 +$(test_oid hash15b) $commit_sha15 +$(test_oid hash14b) $commit_sha14 +$(test_oid hash13b) $commit_sha13 +$(test_oid hash12b) $commit_sha12 +$(test_oid hash11a) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash09a) $commit_sha9 +$(test_oid hash05b) $commit_sha5 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash03b) $commit_sha3 EOF cat >expect_log_y <<EOF @@ -214,16 +274,16 @@ test_expect_success 'setup remote branch (z)' ' ' cat <<EOF | sort >expect_notes_z -9b4b2c61f0615412da3c10f98ff85b57c04ec765 $commit_sha15 -5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 -5d30216a129eeffa97d9694ffe8c74317a560315 $commit_sha13 -7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 -897003322b53bc6ca098e9324ee508362347e734 $commit_sha7 -99fc34adfc400b95c67b013115e37e31aa9a6d23 $commit_sha5 -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +$(test_oid hash15c) $commit_sha15 +$(test_oid hash14b) $commit_sha14 +$(test_oid hash13a) $commit_sha13 +$(test_oid hash11c) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash08c) $commit_sha8 +$(test_oid hash07a) $commit_sha7 +$(test_oid hash05c) $commit_sha5 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash02c) $commit_sha2 EOF cat >expect_log_z <<EOF @@ -306,16 +366,16 @@ test_expect_success 'merge z into y with invalid configuration option => Fail/No ' cat <<EOF | sort >expect_notes_ours -68b8630d25516028bed862719855b3d6768d7833 $commit_sha15 -5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 -3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 -a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 -7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -154508c7a0bcad82b6fe4b472bc4c26b3bf0825b $commit_sha5 -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +$(test_oid hash15b) $commit_sha15 +$(test_oid hash14b) $commit_sha14 +$(test_oid hash13b) $commit_sha13 +$(test_oid hash12b) $commit_sha12 +$(test_oid hash11c) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash05b) $commit_sha5 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash02c) $commit_sha2 EOF cat >expect_log_ours <<EOF @@ -395,16 +455,16 @@ test_expect_success 'reset to pre-merge state (y)' ' ' cat <<EOF | sort >expect_notes_theirs -9b4b2c61f0615412da3c10f98ff85b57c04ec765 $commit_sha15 -5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 -3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 -7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 -99fc34adfc400b95c67b013115e37e31aa9a6d23 $commit_sha5 -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +$(test_oid hash15c) $commit_sha15 +$(test_oid hash14b) $commit_sha14 +$(test_oid hash13b) $commit_sha13 +$(test_oid hash11c) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash08c) $commit_sha8 +$(test_oid hash05c) $commit_sha5 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash02c) $commit_sha2 EOF cat >expect_log_theirs <<EOF @@ -473,17 +533,17 @@ test_expect_success 'reset to pre-merge state (y)' ' ' cat <<EOF | sort >expect_notes_union -7c4e546efd0fe939f876beb262ece02797880b54 $commit_sha15 -5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 -3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 -a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 -7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 -6c841cc36ea496027290967ca96bd2bef54dbb47 $commit_sha5 -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +$(test_oid hash15d) $commit_sha15 +$(test_oid hash14b) $commit_sha14 +$(test_oid hash13b) $commit_sha13 +$(test_oid hash12b) $commit_sha12 +$(test_oid hash11c) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash08c) $commit_sha8 +$(test_oid hash05d) $commit_sha5 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash02c) $commit_sha2 EOF cat >expect_log_union <<EOF @@ -574,17 +634,17 @@ test_expect_success 'merge z into y with "manual" per-ref only checks specific r ' cat <<EOF | sort >expect_notes_union2 -d682107b8bf7a7aea1e537a8d5cb6a12b60135f1 $commit_sha15 -5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 -3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 -a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 -7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 -357b6ca14c7afd59b7f8b8aaaa6b8b723771135b $commit_sha5 -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +$(test_oid hash15e) $commit_sha15 +$(test_oid hash14b) $commit_sha14 +$(test_oid hash13b) $commit_sha13 +$(test_oid hash12b) $commit_sha12 +$(test_oid hash11c) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash08c) $commit_sha8 +$(test_oid hash05e) $commit_sha5 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash02c) $commit_sha2 EOF cat >expect_log_union2 <<EOF @@ -648,17 +708,17 @@ test_expect_success 'reset to pre-merge state (z)' ' ' cat <<EOF | sort >expect_notes_cat_sort_uniq -6be90240b5f54594203e25d9f2f64b7567175aee $commit_sha15 -5de7ea7ad4f47e7ff91989fb82234634730f75df $commit_sha14 -3a631fdb6f41b05b55d8f4baf20728ba8f6fccbc $commit_sha13 -a66055fa82f7a03fe0c02a6aba3287a85abf7c62 $commit_sha12 -7e3c53503a3db8dd996cb62e37c66e070b44b54d $commit_sha11 -b8d03e173f67f6505a76f6e00cf93440200dd9be $commit_sha10 -851e1638784a884c7dd26c5d41f3340f6387413a $commit_sha8 -660311d7f78dc53db12ac373a43fca7465381a7e $commit_sha5 -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 +$(test_oid hash15f) $commit_sha15 +$(test_oid hash14b) $commit_sha14 +$(test_oid hash13b) $commit_sha13 +$(test_oid hash12b) $commit_sha12 +$(test_oid hash11c) $commit_sha11 +$(test_oid hash10a) $commit_sha10 +$(test_oid hash08c) $commit_sha8 +$(test_oid hash05f) $commit_sha5 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash02c) $commit_sha2 EOF cat >expect_log_cat_sort_uniq <<EOF diff --git a/t/t3310-notes-merge-manual-resolve.sh b/t/t3310-notes-merge-manual-resolve.sh index 2dea846e25..d3d72e25fe 100755 --- a/t/t3310-notes-merge-manual-resolve.sh +++ b/t/t3310-notes-merge-manual-resolve.sh @@ -13,7 +13,39 @@ test_expect_success 'setup commits' ' test_commit 2nd && test_commit 3rd && test_commit 4th && - test_commit 5th + test_commit 5th && + + test_oid_cache <<-EOF + hash04a sha1:6e8e3febca3c2bb896704335cc4d0c34cb2f8715 + hash03a sha1:e5388c10860456ee60673025345fe2e153eb8cf8 + hash02a sha1:ceefa674873670e7ecd131814d909723cce2b669 + hash04b sha1:e2bfd06a37dd2031684a59a6e2b033e212239c78 + hash03b sha1:5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 + hash01b sha1:b0a6021ec006d07e80e9b20ec9b444cbd9d560d3 + hash04c sha1:cff59c793c20bb49a4e01bc06fb06bad642e0d54 + hash02c sha1:283b48219aee9a4105f6cab337e789065c82c2b9 + hash01c sha1:0a81da8956346e19bcb27a906f04af327e03e31b + hash04d sha1:00494adecf2d9635a02fa431308d67993f853968 + hash01e sha1:f75d1df88cbfe4258d49852f26cfc83f2ad4494b + hash04f sha1:021faa20e931fb48986ffc6282b4bb05553ac946 + hash01f sha1:0a59e787e6d688aa6309e56e8c1b89431a0fc1c1 + hash05g sha1:304dfb4325cf243025b9957486eb605a9b51c199 + + hash04a sha256:f18a935e65866345098b3b754071dbf9f3aa3520eb27a7b036b278c5e2f1ed7e + hash03a sha256:713035dc94067a64e5fa6e4e1821b7c3bde49a77c7cb3f80eaadefa1ca41b3d2 + hash02a sha256:f160a67e048b6fa75bec3952184154045076692cf5dccd3da21e3fd34b7a3f0f + hash04b sha256:c7fba0d6104917fbf35258f40b9fa4fc697cfa992deecd1570a3b08d0a5587a9 + hash03b sha256:7287a2d78a3766c181b08df38951d784b08b72a44f571ed6d855bd0be22c70f6 + hash01b sha256:da96cf778c15d0a2bb76f98b2a62f6c9c01730fa7030e8f08ef0191048e7d620 + hash04c sha256:cb615d2def4b834d5f55b2351df97dc92bee4f5009d285201427f349081c8aca + hash02c sha256:63bb527e0b4e1c8e1dd0d54dd778ca7c3718689fd6e37c473044cfbcf1cacfdb + hash01c sha256:5b87237ac1fbae0246256fed9f9a1f077c4140fb7e6444925f8dbfa5ae406cd8 + hash04d sha256:eeddc9f9f6cb3d6b39b861659853f10891dc373e0b6eecb09e03e39b6ce64714 + hash01e sha256:108f521b1a74c2e6d0b52a4eda87e09162bf847f7d190cfce496ee1af0b29a5a + hash04f sha256:901acda0454502b3bbd281f130c419e6c8de78afcf72a8def8d45ad31462bce4 + hash01f sha256:a2d99d1b8bf23c8af7d9d91368454adc110dfd5cc068a4cebb486ee8f5a1e16c + hash05g sha256:4fef015b01da8efe929a68e3bb9b8fbad81f53995f097befe8ebc93f12ab98ec + EOF ' commit_sha1=$(git rev-parse 1st^{commit}) @@ -32,10 +64,16 @@ verify_notes () { test_cmp "expect_log_$notes_ref" "output_log_$notes_ref" } +notes_merge_files_gone () { + # No .git/NOTES_MERGE_* files left + { ls .git/NOTES_MERGE_* >output || :; } && + test_must_be_empty output +} + cat <<EOF | sort >expect_notes_x -6e8e3febca3c2bb896704335cc4d0c34cb2f8715 $commit_sha4 -e5388c10860456ee60673025345fe2e153eb8cf8 $commit_sha3 -ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2 +$(test_oid hash04a) $commit_sha4 +$(test_oid hash03a) $commit_sha3 +$(test_oid hash02a) $commit_sha2 EOF cat >expect_log_x <<EOF @@ -63,9 +101,9 @@ test_expect_success 'setup merge base (x)' ' ' cat <<EOF | sort >expect_notes_y -e2bfd06a37dd2031684a59a6e2b033e212239c78 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 -b0a6021ec006d07e80e9b20ec9b444cbd9d560d3 $commit_sha1 +$(test_oid hash04b) $commit_sha4 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash01b) $commit_sha1 EOF cat >expect_log_y <<EOF @@ -95,9 +133,9 @@ test_expect_success 'setup local branch (y)' ' ' cat <<EOF | sort >expect_notes_z -cff59c793c20bb49a4e01bc06fb06bad642e0d54 $commit_sha4 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 -0a81da8956346e19bcb27a906f04af327e03e31b $commit_sha1 +$(test_oid hash04c) $commit_sha4 +$(test_oid hash02c) $commit_sha2 +$(test_oid hash01c) $commit_sha1 EOF cat >expect_log_z <<EOF @@ -193,9 +231,9 @@ test_expect_success 'merge z into m (== y) with default ("manual") resolver => C ' cat <<EOF | sort >expect_notes_z -00494adecf2d9635a02fa431308d67993f853968 $commit_sha4 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 -0a81da8956346e19bcb27a906f04af327e03e31b $commit_sha1 +$(test_oid hash04d) $commit_sha4 +$(test_oid hash02c) $commit_sha2 +$(test_oid hash01c) $commit_sha1 EOF cat >expect_log_z <<EOF @@ -231,8 +269,8 @@ test_expect_success 'cannot do merge w/conflicts when previous merge is unfinish # Setup non-conflicting merge between x and new notes ref w cat <<EOF | sort >expect_notes_w -ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2 -f75d1df88cbfe4258d49852f26cfc83f2ad4494b $commit_sha1 +$(test_oid hash02a) $commit_sha2 +$(test_oid hash01e) $commit_sha1 EOF cat >expect_log_w <<EOF @@ -258,10 +296,10 @@ test_expect_success 'setup unrelated notes ref (w)' ' ' cat <<EOF | sort >expect_notes_w -6e8e3febca3c2bb896704335cc4d0c34cb2f8715 $commit_sha4 -e5388c10860456ee60673025345fe2e153eb8cf8 $commit_sha3 -ceefa674873670e7ecd131814d909723cce2b669 $commit_sha2 -f75d1df88cbfe4258d49852f26cfc83f2ad4494b $commit_sha1 +$(test_oid hash04a) $commit_sha4 +$(test_oid hash03a) $commit_sha3 +$(test_oid hash02a) $commit_sha2 +$(test_oid hash01e) $commit_sha1 EOF cat >expect_log_w <<EOF @@ -291,10 +329,10 @@ test_expect_success 'can do merge without conflicts even if previous merge is un ' cat <<EOF | sort >expect_notes_m -021faa20e931fb48986ffc6282b4bb05553ac946 $commit_sha4 -5772f42408c0dd6f097a7ca2d24de0e78d1c46b1 $commit_sha3 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 -0a59e787e6d688aa6309e56e8c1b89431a0fc1c1 $commit_sha1 +$(test_oid hash04f) $commit_sha4 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash02c) $commit_sha2 +$(test_oid hash01f) $commit_sha1 EOF cat >expect_log_m <<EOF @@ -335,9 +373,7 @@ EOF y and z notes on 4th commit EOF git notes merge --commit && - # No .git/NOTES_MERGE_* files left - test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && - test_must_be_empty output && + notes_merge_files_gone && # Merge commit has pre-merge y and pre-merge z as parents test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" && test "$(git rev-parse refs/notes/m^2)" = "$(cat pre_merge_z)" && @@ -397,9 +433,7 @@ test_expect_success 'redo merge of z into m (== y) with default ("manual") resol test_expect_success 'abort notes merge' ' git notes merge --abort && - # No .git/NOTES_MERGE_* files left - test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && - test_must_be_empty output && + notes_merge_files_gone && # m has not moved (still == y) test "$(git rev-parse refs/notes/m)" = "$(cat pre_merge_y)" && # Verify that other notes refs has not changed (w, x, y and z) @@ -430,9 +464,9 @@ test_expect_success 'redo merge of z into m (== y) with default ("manual") resol ' cat <<EOF | sort >expect_notes_m -304dfb4325cf243025b9957486eb605a9b51c199 $commit_sha5 -283b48219aee9a4105f6cab337e789065c82c2b9 $commit_sha2 -0a59e787e6d688aa6309e56e8c1b89431a0fc1c1 $commit_sha1 +$(test_oid hash05g) $commit_sha5 +$(test_oid hash02c) $commit_sha2 +$(test_oid hash01f) $commit_sha1 EOF cat >expect_log_m <<EOF @@ -464,9 +498,7 @@ EOF echo "new note on 5th commit" > .git/NOTES_MERGE_WORKTREE/$commit_sha5 && # Finalize merge git notes merge --commit && - # No .git/NOTES_MERGE_* files left - test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && - test_must_be_empty output && + notes_merge_files_gone && # Merge commit has pre-merge y and pre-merge z as parents test "$(git rev-parse refs/notes/m^1)" = "$(cat pre_merge_y)" && test "$(git rev-parse refs/notes/m^2)" = "$(cat pre_merge_z)" && @@ -553,9 +585,7 @@ EOF test_expect_success 'resolve situation by aborting the notes merge' ' git notes merge --abort && - # No .git/NOTES_MERGE_* files left - test_might_fail ls .git/NOTES_MERGE_* >output 2>/dev/null && - test_must_be_empty output && + notes_merge_files_gone && # m has not moved (still == w) test "$(git rev-parse refs/notes/m)" = "$(git rev-parse refs/notes/w)" && # Verify that other notes refs has not changed (w, x, y and z) diff --git a/t/t3311-notes-merge-fanout.sh b/t/t3311-notes-merge-fanout.sh index 37151a3adc..5b675417e9 100755 --- a/t/t3311-notes-merge-fanout.sh +++ b/t/t3311-notes-merge-fanout.sh @@ -29,15 +29,10 @@ verify_fanout () { git ls-tree -r --name-only "refs/notes/$notes_ref" | while read path do - case "$path" in - ??/??????????????????????????????????????) - : true - ;; - *) + echo "$path" | grep "^../[0-9a-f]*$" || { echo "Invalid path \"$path\"" && - return 1 - ;; - esac + return 1; + } done } @@ -48,15 +43,10 @@ verify_no_fanout () { git ls-tree -r --name-only "refs/notes/$notes_ref" | while read path do - case "$path" in - ????????????????????????????????????????) - : true - ;; - *) + echo "$path" | grep -v "^../.*" || { echo "Invalid path \"$path\"" && - return 1 - ;; - esac + return 1; + } done } @@ -67,7 +57,27 @@ test_expect_success 'setup a few initial commits with notes (notes ref: x)' ' do test_commit "commit$i" >/dev/null && git notes add -m "notes for commit$i" || return 1 - done + done && + + git log --format=oneline && + + test_oid_cache <<-EOF + hash05a sha1:aed91155c7a72c2188e781fdf40e0f3761b299db + hash04a sha1:99fab268f9d7ee7b011e091a436c78def8eeee69 + hash03a sha1:953c20ae26c7aa0b428c20693fe38bc687f9d1a9 + hash02a sha1:6358796131b8916eaa2dde6902642942a1cb37e1 + hash01a sha1:b02d459c32f0e68f2fe0981033bb34f38776ba47 + hash03b sha1:9f506ee70e20379d7f78204c77b334f43d77410d + hash02b sha1:23a47d6ea7d589895faf800752054818e1e7627b + + hash05a sha256:3aae5d26619d96dba93795f66325716e4cbc486884f95a6adee8fb0615a76d12 + hash04a sha256:07e43dd3d89fe634d3252e253b426aacc7285a995dcdbcf94ac284060a1122cf + hash03a sha256:26fb52eaa7f4866bf735254587be7b31209ec10e525912ffd8e8ba549ba892ff + hash02a sha256:b57ebdf23634e750dcbc4b9a37991d70f90830d568a0e4529ce9de0a3f8d605c + hash01a sha256:377903b1572bd5117087a5518fcb1011b5053cccbc59e3c7c823a8615204173b + hash03b sha256:04e7b392fda7c185bfa17c9179b56db732edc2dc2b3bf887308dcaabb717270d + hash02b sha256:66099aaaec49a485ed990acadd9a9b81232ea592079964113d8f581ff69ef50b + EOF ' commit_sha1=$(git rev-parse commit1^{commit}) @@ -77,11 +87,11 @@ commit_sha4=$(git rev-parse commit4^{commit}) commit_sha5=$(git rev-parse commit5^{commit}) cat <<EOF | sort >expect_notes_x -aed91155c7a72c2188e781fdf40e0f3761b299db $commit_sha5 -99fab268f9d7ee7b011e091a436c78def8eeee69 $commit_sha4 -953c20ae26c7aa0b428c20693fe38bc687f9d1a9 $commit_sha3 -6358796131b8916eaa2dde6902642942a1cb37e1 $commit_sha2 -b02d459c32f0e68f2fe0981033bb34f38776ba47 $commit_sha1 +$(test_oid hash05a) $commit_sha5 +$(test_oid hash04a) $commit_sha4 +$(test_oid hash03a) $commit_sha3 +$(test_oid hash02a) $commit_sha2 +$(test_oid hash01a) $commit_sha1 EOF cat >expect_log_x <<EOF @@ -145,9 +155,9 @@ test_expect_success 'Fast-forward merge (y => x)' ' ' cat <<EOF | sort >expect_notes_z -9f506ee70e20379d7f78204c77b334f43d77410d $commit_sha3 -23a47d6ea7d589895faf800752054818e1e7627b $commit_sha2 -b02d459c32f0e68f2fe0981033bb34f38776ba47 $commit_sha1 +$(test_oid hash03b) $commit_sha3 +$(test_oid hash02b) $commit_sha2 +$(test_oid hash01a) $commit_sha1 EOF cat >expect_log_z <<EOF diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index ab18ac5f28..7c7e085043 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -64,7 +64,7 @@ test_expect_success 'rebase sets ORIG_HEAD to pre-rebase state' ' pre="$(git rev-parse --verify HEAD)" && git rebase master && test_cmp_rev "$pre" ORIG_HEAD && - ! test_cmp_rev "$pre" HEAD + test_cmp_rev ! "$pre" HEAD ' test_expect_success 'rebase, with <onto> and <upstream> specified as :/quuxery' ' @@ -159,19 +159,43 @@ test_expect_success 'fail when upstream arg is missing and not configured' ' test_must_fail git rebase ' -test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg' ' +test_expect_success 'rebase works with format.useAutoBase' ' + test_config format.useAutoBase true && + git checkout topic && + git rebase master +' + +test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg (--merge)' ' git checkout -b default-base master && git checkout -b default topic && git config branch.default.remote . && git config branch.default.merge refs/heads/default-base && - git rebase && + git rebase --merge && git rev-parse --verify default-base >expect && git rev-parse default~1 >actual && test_cmp expect actual && git checkout default-base && git reset --hard HEAD^ && git checkout default && - git rebase && + git rebase --merge && + git rev-parse --verify default-base >expect && + git rev-parse default~1 >actual && + test_cmp expect actual +' + +test_expect_success 'default to common base in @{upstream}s reflog if no upstream arg (--apply)' ' + git checkout -B default-base master && + git checkout -B default topic && + git config branch.default.remote . && + git config branch.default.merge refs/heads/default-base && + git rebase --apply && + git rev-parse --verify default-base >expect && + git rev-parse default~1 >actual && + test_cmp expect actual && + git checkout default-base && + git reset --hard HEAD^ && + git checkout default && + git rebase --apply && git rev-parse --verify default-base >expect && git rev-parse default~1 >actual && test_cmp expect actual @@ -200,9 +224,15 @@ test_expect_success 'cherry-picked commits and fork-point work together' ' test_cmp expect D ' -test_expect_success 'rebase -q is quiet' ' +test_expect_success 'rebase --apply -q is quiet' ' git checkout -b quiet topic && - git rebase -q master >output.out 2>&1 && + git rebase --apply -q master >output.out 2>&1 && + test_must_be_empty output.out +' + +test_expect_success 'rebase --merge -q is quiet' ' + git checkout -B quiet topic && + git rebase --merge -q master >output.out 2>&1 && test_must_be_empty output.out ' @@ -285,7 +315,7 @@ EOF test_cmp From_.msg out ' -test_expect_success 'rebase --am and --show-current-patch' ' +test_expect_success 'rebase --apply and --show-current-patch' ' test_create_repo conflict-apply && ( cd conflict-apply && @@ -295,13 +325,13 @@ test_expect_success 'rebase --am and --show-current-patch' ' echo two >>init.t && git commit -a -m two && git tag two && - test_must_fail git rebase -f --onto init HEAD^ && + test_must_fail git rebase --apply -f --onto init HEAD^ && GIT_TRACE=1 git rebase --show-current-patch >/dev/null 2>stderr && grep "show.*$(git rev-parse two)" stderr ) ' -test_expect_success 'rebase --am and .gitattributes' ' +test_expect_success 'rebase --apply and .gitattributes' ' test_create_repo attributes && ( cd attributes && diff --git a/t/t3401-rebase-and-am-rename.sh b/t/t3401-rebase-and-am-rename.sh index a0b9438b22..f18bae9450 100755 --- a/t/t3401-rebase-and-am-rename.sh +++ b/t/t3401-rebase-and-am-rename.sh @@ -52,13 +52,13 @@ test_expect_success 'rebase --interactive: directory rename detected' ' ) ' -test_expect_failure 'rebase (am): directory rename detected' ' +test_expect_failure 'rebase --apply: directory rename detected' ' ( cd dir-rename && git checkout B^0 && - git -c merge.directoryRenames=true rebase A && + git -c merge.directoryRenames=true rebase --apply A && git ls-files -s >out && test_line_count = 5 out && diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh index 1f5122b632..ee8a8dba52 100755 --- a/t/t3403-rebase-skip.sh +++ b/t/t3403-rebase-skip.sh @@ -7,6 +7,8 @@ test_description='git rebase --merge --skip tests' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + # we assume the default git am -3 --skip strategy is tested independently # and always works :) @@ -20,6 +22,13 @@ test_expect_success setup ' git commit -a -m "hello world" && echo goodbye >> hello && git commit -a -m "goodbye" && + git tag goodbye && + + git checkout --detach && + git checkout HEAD^ . && + test_tick && + git commit -m reverted-goodbye && + git tag reverted-goodbye && git checkout -f skip-reference && echo moo > hello && @@ -76,4 +85,27 @@ test_expect_success 'moved back to branch correctly' ' test_debug 'gitk --all & sleep 1' +test_expect_success 'fixup that empties commit fails' ' + test_when_finished "git rebase --abort" && + ( + set_fake_editor && + test_must_fail env FAKE_LINES="1 fixup 2" git rebase -i \ + goodbye^ reverted-goodbye + ) +' + +test_expect_success 'squash that empties commit fails' ' + test_when_finished "git rebase --abort" && + ( + set_fake_editor && + test_must_fail env FAKE_LINES="1 squash 2" git rebase -i \ + goodbye^ reverted-goodbye + ) +' + +# Must be the last test in this file +test_expect_success '$EDITOR and friends are unchanged' ' + test_editor_unchanged +' + test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index bf0dc756d2..c5ce3ab760 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -72,15 +72,16 @@ test_expect_success 'rebase --keep-empty' ' test_line_count = 6 actual ' -test_expect_success 'rebase -i with empty HEAD' ' +test_expect_success 'rebase -i with empty todo list' ' cat >expect <<-\EOF && error: nothing to do EOF ( set_fake_editor && - test_must_fail env FAKE_LINES="1 exec_true" \ - git rebase -i HEAD^ >actual 2>&1 + test_must_fail env FAKE_LINES="#" \ + git rebase -i HEAD^ >output 2>&1 ) && + tail -n 1 output >actual && # Ignore output about changing todo list test_i18ncmp expect actual ' @@ -222,7 +223,7 @@ test_expect_success 'reflog for the branch shows state before rebase' ' ' test_expect_success 'reflog for the branch shows correct finish message' ' - printf "rebase -i (finish): refs/heads/branch1 onto %s\n" \ + printf "rebase (finish): refs/heads/branch1 onto %s\n" \ "$(git rev-parse branch2)" >expected && git log -g --pretty=%gs -1 refs/heads/branch1 >actual && test_cmp expected actual @@ -1137,7 +1138,7 @@ test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-int git checkout conflict-branch && ( set_fake_editor && - test_must_fail git rebase -f --onto HEAD~2 HEAD~ && + test_must_fail git rebase -f --apply --onto HEAD~2 HEAD~ && test_must_fail git rebase --edit-todo ) && git rebase --abort @@ -1161,10 +1162,10 @@ test_expect_success 'rebase -i produces readable reflog' ' git branch -f branch-reflog-test H && git rebase -i --onto I F branch-reflog-test && cat >expect <<-\EOF && - rebase -i (finish): returning to refs/heads/branch-reflog-test - rebase -i (pick): H - rebase -i (pick): G - rebase -i (start): checkout I + rebase (finish): returning to refs/heads/branch-reflog-test + rebase (pick): H + rebase (pick): G + rebase (start): checkout I EOF git reflog -n4 HEAD | sed "s/[^:]*: //" >actual && @@ -1264,13 +1265,26 @@ test_expect_success SHA1 'short SHA-1 setup' ' test_expect_success SHA1 'short SHA-1 collide' ' test_when_finished "reset_rebase && git checkout master" && git checkout collide && + colliding_sha1=6bcda37 && + test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && ( - unset test_tick && - test_tick && - set_fake_editor && - FAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \ - FAKE_LINES="reword 1 2" git rebase -i HEAD~2 - ) + unset test_tick && + test_tick && + set_fake_editor && + FAKE_COMMIT_MESSAGE="collide2 ac4f2ee" \ + FAKE_LINES="reword 1 break 2" git rebase -i HEAD~2 && + test $colliding_sha1 = "$(git rev-parse HEAD | cut -c 1-7)" && + grep "^pick $colliding_sha1 " \ + .git/rebase-merge/git-rebase-todo.tmp && + grep "^pick [0-9a-f]\{40\}" \ + .git/rebase-merge/git-rebase-todo && + grep "^pick [0-9a-f]\{40\}" \ + .git/rebase-merge/git-rebase-todo.backup && + git rebase --continue + ) && + collide2="$(git rev-parse HEAD~1 | cut -c 1-4)" && + collide3="$(git rev-parse collide3 | cut -c 1-4)" && + test "$collide2" = "$collide3" ' test_expect_success 'respect core.abbrev' ' @@ -1450,6 +1464,127 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' ' test B = $(git cat-file commit HEAD^ | sed -ne \$p) ' +test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = ignore' ' + test_config rebase.missingCommitsCheck ignore && + rebase_setup_and_clean missing-commit && + ( + set_fake_editor && + FAKE_LINES="break 1 2 3 4 5" git rebase -i --root && + FAKE_LINES="1 2 3 4" git rebase --edit-todo && + git rebase --continue 2>actual + ) && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test_i18ngrep \ + "Successfully rebased and updated refs/heads/missing-commit" \ + actual +' + +test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = warn' ' + cat >expect <<-EOF && + error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + Warning: some commits may have been dropped accidentally. + Dropped commits (newer to older): + - $(git rev-list --pretty=oneline --abbrev-commit -1 master) + - $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + To avoid this message, use "drop" to explicitly remove a commit. + EOF + head -n4 expect >expect.2 && + tail -n1 expect >>expect.2 && + tail -n4 expect.2 >expect.3 && + test_config rebase.missingCommitsCheck warn && + rebase_setup_and_clean missing-commit && + ( + set_fake_editor && + test_must_fail env FAKE_LINES="bad 1 2 3 4 5" \ + git rebase -i --root && + cp .git/rebase-merge/git-rebase-todo.backup orig && + FAKE_LINES="2 3 4" git rebase --edit-todo 2>actual.2 && + head -n6 actual.2 >actual && + test_i18ncmp expect actual && + cp orig .git/rebase-merge/git-rebase-todo && + FAKE_LINES="1 2 3 4" git rebase --edit-todo 2>actual.2 && + head -n4 actual.2 >actual && + test_i18ncmp expect.3 actual && + git rebase --continue 2>actual + ) && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test_i18ngrep \ + "Successfully rebased and updated refs/heads/missing-commit" \ + actual +' + +test_expect_success 'rebase --edit-todo respects rebase.missingCommitsCheck = error' ' + cat >expect <<-EOF && + error: invalid line 1: badcmd $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + Warning: some commits may have been dropped accidentally. + Dropped commits (newer to older): + - $(git rev-list --pretty=oneline --abbrev-commit -1 master) + - $(git rev-list --pretty=oneline --abbrev-commit -1 master~4) + To avoid this message, use "drop" to explicitly remove a commit. + + Use '\''git config rebase.missingCommitsCheck'\'' to change the level of warnings. + The possible behaviours are: ignore, warn, error. + + You can fix this with '\''git rebase --edit-todo'\'' and then run '\''git rebase --continue'\''. + Or you can abort the rebase with '\''git rebase --abort'\''. + EOF + tail -n11 expect >expect.2 && + head -n3 expect.2 >expect.3 && + tail -n7 expect.2 >>expect.3 && + test_config rebase.missingCommitsCheck error && + rebase_setup_and_clean missing-commit && + ( + set_fake_editor && + test_must_fail env FAKE_LINES="bad 1 2 3 4 5" \ + git rebase -i --root && + cp .git/rebase-merge/git-rebase-todo.backup orig && + test_must_fail env FAKE_LINES="2 3 4" \ + git rebase --edit-todo 2>actual && + test_i18ncmp expect actual && + test_must_fail git rebase --continue 2>actual && + test_i18ncmp expect.2 actual && + test_must_fail git rebase --edit-todo && + cp orig .git/rebase-merge/git-rebase-todo && + test_must_fail env FAKE_LINES="1 2 3 4" \ + git rebase --edit-todo 2>actual && + test_i18ncmp expect.3 actual && + test_must_fail git rebase --continue 2>actual && + test_i18ncmp expect.3 actual && + cp orig .git/rebase-merge/git-rebase-todo && + FAKE_LINES="1 2 3 4 drop 5" git rebase --edit-todo && + git rebase --continue 2>actual + ) && + test D = $(git cat-file commit HEAD | sed -ne \$p) && + test_i18ngrep \ + "Successfully rebased and updated refs/heads/missing-commit" \ + actual +' + +test_expect_success 'rebase.missingCommitsCheck = error after resolving conflicts' ' + test_config rebase.missingCommitsCheck error && + ( + set_fake_editor && + FAKE_LINES="drop 1 break 2 3 4" git rebase -i A E + ) && + git rebase --edit-todo && + test_must_fail git rebase --continue && + echo x >file1 && + git add file1 && + git rebase --continue +' + +test_expect_success 'rebase.missingCommitsCheck = error when editing for a second time' ' + test_config rebase.missingCommitsCheck error && + ( + set_fake_editor && + FAKE_LINES="1 break 2 3" git rebase -i A D && + cp .git/rebase-merge/git-rebase-todo todo && + test_must_fail env FAKE_LINES=2 git rebase --edit-todo && + GIT_SEQUENCE_EDITOR="cp todo" git rebase --edit-todo && + git rebase --continue + ) +' + test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and exec' ' rebase_setup_and_clean abbrevcmd && test_commit "first" file1.txt "first line" first && diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index b393e1e9fe..61b76f3301 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -18,32 +18,29 @@ test_expect_success 'setup' ' ' test_expect_success 'rebase -m' ' - git rebase -m master >report && - >expect && - sed -n -e "/^Already applied: /p" \ - -e "/^Committed: /p" report >actual && - test_cmp expect actual + git rebase -m master >actual && + test_must_be_empty actual ' test_expect_success 'rebase against master twice' ' - git rebase master >out && + git rebase --apply master >out && test_i18ngrep "Current branch topic is up to date" out ' test_expect_success 'rebase against master twice with --force' ' - git rebase --force-rebase master >out && + git rebase --force-rebase --apply master >out && test_i18ngrep "Current branch topic is up to date, rebase forced" out ' test_expect_success 'rebase against master twice from another branch' ' git checkout topic^ && - git rebase master topic >out && + git rebase --apply master topic >out && test_i18ngrep "Current branch topic is up to date" out ' test_expect_success 'rebase fast-forward to master' ' git checkout topic^ && - git rebase topic >out && + git rebase --apply topic >out && test_i18ngrep "Fast-forwarded HEAD to topic" out ' @@ -92,7 +89,7 @@ test_expect_success 'GIT_REFLOG_ACTION' ' git checkout -b reflog-topic start && test_commit reflog-to-rebase && - git rebase reflog-onto && + git rebase --apply reflog-onto && git log -g --format=%gs -3 >actual && cat >expect <<-\EOF && rebase finished: returning to refs/heads/reflog-topic @@ -102,7 +99,7 @@ test_expect_success 'GIT_REFLOG_ACTION' ' test_cmp expect actual && git checkout -b reflog-prefix reflog-to-rebase && - GIT_REFLOG_ACTION=change-the-reflog git rebase reflog-onto && + GIT_REFLOG_ACTION=change-the-reflog git rebase --apply reflog-onto && git log -g --format=%gs -3 >actual && cat >expect <<-\EOF && rebase finished: returning to refs/heads/reflog-prefix diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh index 910f218284..97efea0f56 100755 --- a/t/t3407-rebase-abort.sh +++ b/t/t3407-rebase-abort.sh @@ -96,14 +96,14 @@ testrebase() { ' } -testrebase "" .git/rebase-apply +testrebase " --apply" .git/rebase-apply testrebase " --merge" .git/rebase-merge -test_expect_success 'rebase --quit' ' +test_expect_success 'rebase --apply --quit' ' cd "$work_dir" && # Clean up the state from the previous one git reset --hard pre-rebase && - test_must_fail git rebase master && + test_must_fail git rebase --apply master && test_path_is_dir .git/rebase-apply && head_before=$(git rev-parse HEAD) && git rebase --quit && diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index 22d218698e..093de9005b 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -25,6 +25,13 @@ test_expect_success setup ' ' test_auto_fixup () { + no_squash= && + if test "x$1" = 'x!' + then + no_squash=true + shift + fi && + git reset --hard base && echo 1 >file1 && git add -u && @@ -35,10 +42,19 @@ test_auto_fixup () { test_tick && git rebase $2 -i HEAD^^^ && git log --oneline >actual && - test_line_count = 3 actual && - git diff --exit-code $1 && - test 1 = "$(git cat-file blob HEAD^:file1)" && - test 1 = $(git cat-file commit HEAD^ | grep first | wc -l) + if test -n "$no_squash" + then + test_line_count = 4 actual + else + test_line_count = 3 actual && + git diff --exit-code $1 && + echo 1 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^ >commit && + grep first commit >actual && + test_line_count = 1 actual + fi } test_expect_success 'auto fixup (option)' ' @@ -48,12 +64,19 @@ test_expect_success 'auto fixup (option)' ' test_expect_success 'auto fixup (config)' ' git config rebase.autosquash true && test_auto_fixup final-fixup-config-true && - test_must_fail test_auto_fixup fixup-config-true-no --no-autosquash && + test_auto_fixup ! fixup-config-true-no --no-autosquash && git config rebase.autosquash false && - test_must_fail test_auto_fixup final-fixup-config-false + test_auto_fixup ! final-fixup-config-false ' test_auto_squash () { + no_squash= && + if test "x$1" = 'x!' + then + no_squash=true + shift + fi && + git reset --hard base && echo 1 >file1 && git add -u && @@ -64,10 +87,19 @@ test_auto_squash () { test_tick && git rebase $2 -i HEAD^^^ && git log --oneline >actual && - test_line_count = 3 actual && - git diff --exit-code $1 && - test 1 = "$(git cat-file blob HEAD^:file1)" && - test 2 = $(git cat-file commit HEAD^ | grep first | wc -l) + if test -n "$no_squash" + then + test_line_count = 4 actual + else + test_line_count = 3 actual && + git diff --exit-code $1 && + echo 1 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^ >commit && + grep first commit >actual && + test_line_count = 2 actual + fi } test_expect_success 'auto squash (option)' ' @@ -77,9 +109,9 @@ test_expect_success 'auto squash (option)' ' test_expect_success 'auto squash (config)' ' git config rebase.autosquash true && test_auto_squash final-squash-config-true && - test_must_fail test_auto_squash squash-config-true-no --no-autosquash && + test_auto_squash ! squash-config-true-no --no-autosquash && git config rebase.autosquash false && - test_must_fail test_auto_squash final-squash-config-false + test_auto_squash ! final-squash-config-false ' test_expect_success 'misspelled auto squash' ' @@ -94,7 +126,8 @@ test_expect_success 'misspelled auto squash' ' git log --oneline >actual && test_line_count = 4 actual && git diff --exit-code final-missquash && - test 0 = $(git rev-list final-missquash...HEAD | wc -l) + git rev-list final-missquash...HEAD >list && + test_must_be_empty list ' test_expect_success 'auto squash that matches 2 commits' ' @@ -113,9 +146,15 @@ test_expect_success 'auto squash that matches 2 commits' ' git log --oneline >actual && test_line_count = 4 actual && git diff --exit-code final-multisquash && - test 1 = "$(git cat-file blob HEAD^^:file1)" && - test 2 = $(git cat-file commit HEAD^^ | grep first | wc -l) && - test 1 = $(git cat-file commit HEAD | grep first | wc -l) + echo 1 >expect && + git cat-file blob HEAD^^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^^ >commit && + grep first commit >actual && + test_line_count = 2 actual && + git cat-file commit HEAD >commit && + grep first commit >actual && + test_line_count = 1 actual ' test_expect_success 'auto squash that matches a commit after the squash' ' @@ -134,25 +173,38 @@ test_expect_success 'auto squash that matches a commit after the squash' ' git log --oneline >actual && test_line_count = 5 actual && git diff --exit-code final-presquash && - test 0 = "$(git cat-file blob HEAD^^:file1)" && - test 1 = "$(git cat-file blob HEAD^:file1)" && - test 1 = $(git cat-file commit HEAD | grep third | wc -l) && - test 1 = $(git cat-file commit HEAD^ | grep third | wc -l) + echo 0 >expect && + git cat-file blob HEAD^^:file1 >actual && + test_cmp expect actual && + echo 1 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD >commit && + grep third commit >actual && + test_line_count = 1 actual && + git cat-file commit HEAD^ >commit && + grep third commit >actual && + test_line_count = 1 actual ' test_expect_success 'auto squash that matches a sha1' ' git reset --hard base && echo 1 >file1 && git add -u && test_tick && - git commit -m "squash! $(git rev-parse --short HEAD^)" && + oid=$(git rev-parse --short HEAD^) && + git commit -m "squash! $oid" && git tag final-shasquash && test_tick && git rebase --autosquash -i HEAD^^^ && git log --oneline >actual && test_line_count = 3 actual && git diff --exit-code final-shasquash && - test 1 = "$(git cat-file blob HEAD^:file1)" && - test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l) + echo 1 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^ >commit && + grep squash commit >actual && + test_line_count = 1 actual ' test_expect_success 'auto squash that matches longer sha1' ' @@ -160,15 +212,20 @@ test_expect_success 'auto squash that matches longer sha1' ' echo 1 >file1 && git add -u && test_tick && - git commit -m "squash! $(git rev-parse --short=11 HEAD^)" && + oid=$(git rev-parse --short=11 HEAD^) && + git commit -m "squash! $oid" && git tag final-longshasquash && test_tick && git rebase --autosquash -i HEAD^^^ && git log --oneline >actual && test_line_count = 3 actual && git diff --exit-code final-longshasquash && - test 1 = "$(git cat-file blob HEAD^:file1)" && - test 1 = $(git cat-file commit HEAD^ | grep squash | wc -l) + echo 1 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^ >commit && + grep squash commit >actual && + test_line_count = 1 actual ' test_auto_commit_flags () { @@ -183,8 +240,12 @@ test_auto_commit_flags () { git log --oneline >actual && test_line_count = 3 actual && git diff --exit-code final-commit-$1 && - test 1 = "$(git cat-file blob HEAD^:file1)" && - test $2 = $(git cat-file commit HEAD^ | grep first | wc -l) + echo 1 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^ >commit && + grep first commit >actual && + test_line_count = $2 actual } test_expect_success 'use commit --fixup' ' @@ -210,11 +271,15 @@ test_auto_fixup_fixup () { ( set_cat_todo_editor && test_must_fail git rebase --autosquash -i HEAD^^^^ >actual && + head=$(git rev-parse --short HEAD) && + parent1=$(git rev-parse --short HEAD^) && + parent2=$(git rev-parse --short HEAD^^) && + parent3=$(git rev-parse --short HEAD^^^) && cat >expected <<-EOF && - pick $(git rev-parse --short HEAD^^^) first commit - $1 $(git rev-parse --short HEAD^) $1! first - $1 $(git rev-parse --short HEAD) $1! $2! first - pick $(git rev-parse --short HEAD^^) second commit + pick $parent3 first commit + $1 $parent1 $1! first + $1 $head $1! $2! first + pick $parent2 second commit EOF test_cmp expected actual ) && @@ -222,13 +287,17 @@ test_auto_fixup_fixup () { git log --oneline >actual && test_line_count = 3 actual git diff --exit-code "final-$1-$2" && - test 2 = "$(git cat-file blob HEAD^:file1)" && + echo 2 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^ >commit && + grep first commit >actual && if test "$1" = "fixup" then - test 1 = $(git cat-file commit HEAD^ | grep first | wc -l) + test_line_count = 1 actual elif test "$1" = "squash" then - test 3 = $(git cat-file commit HEAD^ | grep first | wc -l) + test_line_count = 3 actual else false fi @@ -256,19 +325,25 @@ test_expect_success C_LOCALE_OUTPUT 'autosquash with custom inst format' ' echo 2 >file1 && git add -u && test_tick && - git commit -m "squash! $(git rev-parse --short HEAD^)" && + oid=$(git rev-parse --short HEAD^) && + git commit -m "squash! $oid" && echo 1 >file1 && git add -u && test_tick && - git commit -m "squash! $(git log -n 1 --format=%s HEAD~2)" && + subject=$(git log -n 1 --format=%s HEAD~2) && + git commit -m "squash! $subject" && git tag final-squash-instFmt && test_tick && git rebase --autosquash -i HEAD~4 && git log --oneline >actual && test_line_count = 3 actual && git diff --exit-code final-squash-instFmt && - test 1 = "$(git cat-file blob HEAD^:file1)" && - test 2 = $(git cat-file commit HEAD^ | grep squash | wc -l) + echo 1 >expect && + git cat-file blob HEAD^:file1 >actual && + test_cmp expect actual && + git cat-file commit HEAD^ >commit && + grep squash commit >actual && + test_line_count = 2 actual ' test_expect_success 'autosquash with empty custom instructionFormat' ' diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh index 49f548cdb9..94552669ae 100755 --- a/t/t3419-rebase-patch-id.sh +++ b/t/t3419-rebase-patch-id.sh @@ -80,7 +80,8 @@ do_tests () { git commit -q -m "change big file again" && git checkout -q other^{} && git rebase master && - test_must_fail test -n "$(git rev-list master...HEAD~)" + git rev-list master...HEAD~ >revs && + test_must_be_empty revs ' test_expect_success $pr 'do not drop patch' ' diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index 5f7e73cf83..b97ea62363 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -34,7 +34,7 @@ test_expect_success setup ' remove_progress_re="$(printf "s/.*\\r//")" ' -create_expected_success_am () { +create_expected_success_apply () { cat >expected <<-EOF $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual) First, rewinding head to replay your work on top of it... @@ -44,7 +44,7 @@ create_expected_success_am () { EOF } -create_expected_success_interactive () { +create_expected_success_merge () { q_to_cr >expected <<-EOF $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual) Applied autostash. @@ -52,7 +52,7 @@ create_expected_success_interactive () { EOF } -create_expected_failure_am () { +create_expected_failure_apply () { cat >expected <<-EOF $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual) First, rewinding head to replay your work on top of it... @@ -64,7 +64,7 @@ create_expected_failure_am () { EOF } -create_expected_failure_interactive () { +create_expected_failure_merge () { cat >expected <<-EOF $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual) Applying autostash resulted in conflicts. @@ -101,9 +101,9 @@ testrebase () { test_expect_success "rebase$type --autostash: check output" ' test_when_finished git branch -D rebased-feature-branch && - suffix=${type#\ --} && suffix=${suffix:-am} && - if test ${suffix} = "merge"; then - suffix=interactive + suffix=${type#\ --} && suffix=${suffix:-apply} && + if test ${suffix} = "interactive"; then + suffix=merge fi && create_expected_success_$suffix && sed "$remove_progress_re" <actual >actual2 && @@ -202,9 +202,9 @@ testrebase () { test_expect_success "rebase$type: check output with conflicting stash" ' test_when_finished git branch -D rebased-feature-branch && - suffix=${type#\ --} && suffix=${suffix:-am} && - if test ${suffix} = "merge"; then - suffix=interactive + suffix=${type#\ --} && suffix=${suffix:-apply} && + if test ${suffix} = "interactive"; then + suffix=merge fi && create_expected_failure_$suffix && sed "$remove_progress_re" <actual >actual2 && @@ -234,7 +234,7 @@ test_expect_success "rebase: noop rebase" ' git checkout feature-branch ' -testrebase "" .git/rebase-apply +testrebase " --apply" .git/rebase-apply testrebase " --merge" .git/rebase-merge testrebase " --interactive" .git/rebase-merge diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh index b847064f91..cf8dfd6c20 100755 --- a/t/t3421-rebase-topology-linear.sh +++ b/t/t3421-rebase-topology-linear.sh @@ -26,7 +26,7 @@ test_run_rebase () { test_linear_range 'd e' c.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -50,7 +50,7 @@ test_run_rebase () { test_cmp_rev e HEAD " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -61,12 +61,12 @@ test_run_rebase () { test_expect_$result "rebase $* -f rewrites even if upstream is an ancestor" " reset_rebase && git rebase $* -f b e && - ! test_cmp_rev e HEAD && + test_cmp_rev ! e HEAD && test_cmp_rev b HEAD~2 && test_linear_range 'd e' b.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success --fork-point test_run_rebase success -m test_run_rebase success -i @@ -78,12 +78,12 @@ test_run_rebase () { test_expect_$result "rebase $* -f rewrites even if remote upstream is an ancestor" " reset_rebase && git rebase $* -f branch-b branch-e && - ! test_cmp_rev branch-e origin/branch-e && + test_cmp_rev ! branch-e origin/branch-e && test_cmp_rev branch-b HEAD~2 && test_linear_range 'd e' branch-b.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success --fork-point test_run_rebase success -m test_run_rebase success -i @@ -98,7 +98,7 @@ test_run_rebase () { test_cmp_rev e HEAD " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success --fork-point test_run_rebase success -m test_run_rebase success -i @@ -139,7 +139,7 @@ test_run_rebase () { test_linear_range 'd i' h.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -154,7 +154,7 @@ test_run_rebase () { test_linear_range 'd' h.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -169,7 +169,7 @@ test_run_rebase () { test_linear_range 'd i' f.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -184,7 +184,7 @@ test_run_rebase () { test_linear_range 'd gp i' h.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -205,17 +205,17 @@ test_expect_success 'setup of linear history for empty commit tests' ' test_run_rebase () { result=$1 shift - test_expect_$result "rebase $* drops empty commit" " + test_expect_$result "rebase $* keeps begin-empty commits" " reset_rebase && - git rebase $* c l && - test_cmp_rev c HEAD~2 && - test_linear_range 'd l' c.. + git rebase $* j l && + test_cmp_rev c HEAD~4 && + test_linear_range 'j d k l' c.. " } -test_run_rebase success '' +test_run_rebase failure --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p +test_have_prereq !REBASE_P || test_run_rebase failure -p test_run_rebase () { result=$1 @@ -227,10 +227,10 @@ test_run_rebase () { test_linear_range 'd k l' c.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p +test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -242,10 +242,10 @@ test_run_rebase () { test_linear_range 'd k l' j.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p +test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase success --rebase-merges # m @@ -282,7 +282,7 @@ test_run_rebase () { test_linear_range 'x y' c.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -297,7 +297,7 @@ test_run_rebase () { test_linear_range 'x y' c.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase failure -p @@ -312,7 +312,7 @@ test_run_rebase () { test_linear_range 'x y' m.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -328,7 +328,7 @@ test_run_rebase () { " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase failure -p @@ -343,7 +343,7 @@ test_run_rebase () { test_linear_range 'x y' m.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase failure -p @@ -368,7 +368,7 @@ test_run_rebase () { test_expect_$result "rebase $* -f --root on linear history causes re-write" " reset_rebase && git rebase $* -f --root c && - ! test_cmp_rev a HEAD~2 && + test_cmp_rev ! a HEAD~2 && test_linear_range 'a b c' HEAD " } diff --git a/t/t3424-rebase-empty.sh b/t/t3424-rebase-empty.sh new file mode 100755 index 0000000000..98fc2a558a --- /dev/null +++ b/t/t3424-rebase-empty.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +test_description='git rebase of commits that start or become empty' + +. ./test-lib.sh + +test_expect_success 'setup test repository' ' + test_write_lines 1 2 3 4 5 6 7 8 9 10 >numbers && + test_write_lines A B C D E F G H I J >letters && + git add numbers letters && + git commit -m A && + + git branch upstream && + git branch localmods && + + git checkout upstream && + test_write_lines A B C D E >letters && + git add letters && + git commit -m B && + + test_write_lines 1 2 3 4 five 6 7 8 9 ten >numbers && + git add numbers && + git commit -m C && + + git checkout localmods && + test_write_lines 1 2 3 4 five 6 7 8 9 10 >numbers && + git add numbers && + git commit -m C2 && + + git commit --allow-empty -m D && + + test_write_lines A B C D E >letters && + git add letters && + git commit -m "Five letters ought to be enough for anybody" +' + +test_expect_failure 'rebase (apply-backend)' ' + test_when_finished "git rebase --abort" && + git checkout -B testing localmods && + # rebase (--apply) should not drop commits that start empty + git rebase --apply upstream && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --merge --empty=drop' ' + git checkout -B testing localmods && + git rebase --merge --empty=drop upstream && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --merge uses default of --empty=drop' ' + git checkout -B testing localmods && + git rebase --merge upstream && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --merge --empty=keep' ' + git checkout -B testing localmods && + git rebase --merge --empty=keep upstream && + + test_write_lines D C2 C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --merge --empty=ask' ' + git checkout -B testing localmods && + test_must_fail git rebase --merge --empty=ask upstream && + + git rebase --skip && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --interactive --empty=drop' ' + git checkout -B testing localmods && + git rebase --interactive --empty=drop upstream && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --interactive --empty=keep' ' + git checkout -B testing localmods && + git rebase --interactive --empty=keep upstream && + + test_write_lines D C2 C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --interactive --empty=ask' ' + git checkout -B testing localmods && + test_must_fail git rebase --interactive --empty=ask upstream && + + git rebase --skip && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'rebase --interactive uses default of --empty=ask' ' + git checkout -B testing localmods && + test_must_fail git rebase --interactive upstream && + + git rebase --skip && + + test_write_lines D C B A >expect && + git log --format=%s >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh index fd8efe84fe..e42faa44e7 100755 --- a/t/t3425-rebase-topology-merges.sh +++ b/t/t3425-rebase-topology-merges.sh @@ -54,7 +54,7 @@ test_run_rebase () { test_linear_range 'n o' e.. " } -test_run_rebase success '' +test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i @@ -70,7 +70,7 @@ test_run_rebase () { test_linear_range "\'"$expected"\'" d.. " } -test_run_rebase success 'n o e' '' +test_run_rebase success 'n o e' --apply test_run_rebase success 'n o e' -m test_run_rebase success 'n o e' -i @@ -86,7 +86,7 @@ test_run_rebase () { test_linear_range "\'"$expected"\'" c.. " } -test_run_rebase success 'd n o e' '' +test_run_rebase success 'd n o e' --apply test_run_rebase success 'd n o e' -m test_run_rebase success 'd n o e' -i @@ -102,7 +102,7 @@ test_run_rebase () { test_linear_range "\'"$expected"\'" c.. " } -test_run_rebase success 'd n o e' '' +test_run_rebase success 'd n o e' --apply test_run_rebase success 'd n o e' -m test_run_rebase success 'd n o e' -i diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh index bec48e6a1f..79e43a370b 100755 --- a/t/t3427-rebase-subtree.sh +++ b/t/t3427-rebase-subtree.sh @@ -85,23 +85,23 @@ test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges -- verbose test "$(commit_message HEAD)" = "Empty commit" ' -test_expect_success 'Rebase -Xsubtree --keep-empty --onto commit' ' +test_expect_success 'Rebase -Xsubtree --empty=ask --onto commit' ' reset_rebase && git checkout -b rebase-onto to-rebase && - test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --onto files-master master && + test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --onto files-master master && : first pick results in no changes && - git rebase --continue && + git rebase --skip && verbose test "$(commit_message HEAD~2)" = "master4" && verbose test "$(commit_message HEAD~)" = "files_subtree/master5" && verbose test "$(commit_message HEAD)" = "Empty commit" ' -test_expect_success 'Rebase -Xsubtree --keep-empty --rebase-merges --onto commit' ' +test_expect_success 'Rebase -Xsubtree --empty=ask --rebase-merges --onto commit' ' reset_rebase && git checkout -b rebase-merges-onto to-rebase && - test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --rebase-merges --onto files-master --root && + test_must_fail git rebase -Xsubtree=files_subtree --empty=ask --rebase-merges --onto files-master --root && : first pick results in no changes && - git rebase --continue && + git rebase --skip && verbose test "$(commit_message HEAD~2)" = "master4" && verbose test "$(commit_message HEAD~)" = "files_subtree/master5" && verbose test "$(commit_message HEAD)" = "Empty commit" diff --git a/t/t3429-rebase-edit-todo.sh b/t/t3429-rebase-edit-todo.sh index aaeac6eade..7024d49ae7 100755 --- a/t/t3429-rebase-edit-todo.sh +++ b/t/t3429-rebase-edit-todo.sh @@ -52,4 +52,34 @@ test_expect_success 'todo is re-read after reword and squash' ' test_cmp expected actual ' +test_expect_success 're-reading todo doesnt interfere with revert --edit' ' + git reset --hard third && + + git revert --edit third second && + + cat >expect <<-\EOF && + Revert "second" + Revert "third" + third + second + first + EOF + git log --format="%s" >actual && + test_cmp expect actual +' + +test_expect_success 're-reading todo doesnt interfere with cherry-pick --edit' ' + git reset --hard first && + + git cherry-pick --edit second third && + + cat >expect <<-\EOF && + third + second + first + EOF + git log --format="%s" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 9efcf4808a..e72ca348ea 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -346,7 +346,7 @@ test_expect_success 'A root commit can be a cousin, treat it that way' ' git merge --allow-unrelated-histories khnum && test_tick && git rebase -f -r HEAD^ && - ! test_cmp_rev HEAD^2 khnum && + test_cmp_rev ! HEAD^2 khnum && test_cmp_graph HEAD^.. <<-\EOF && * Merge branch '\''khnum'\'' into asherah |\ @@ -408,7 +408,7 @@ test_expect_success 'octopus merges' ' | | * three | * | two | |/ - * | one + * / one |/ o before-octopus EOF @@ -468,4 +468,31 @@ test_expect_success '--rebase-merges with strategies' ' test_cmp expect G.t ' +test_expect_success '--rebase-merges with commit that can generate bad characters for filename' ' + git checkout -b colon-in-label E && + git merge -m "colon: this should work" G && + git rebase --rebase-merges --force-rebase E +' + +test_expect_success '--rebase-merges with message matched with onto label' ' + git checkout -b onto-label E && + git merge -m onto G && + git rebase --rebase-merges --force-rebase E && + test_cmp_graph <<-\EOF + * onto + |\ + | * G + | * F + * | E + |\ \ + | * | B + * | | D + | |/ + |/| + * | C + |/ + * A + EOF +' + test_done diff --git a/t/t3432-rebase-fast-forward.sh b/t/t3432-rebase-fast-forward.sh index 034ffc7e76..6c9d4a1375 100755 --- a/t/t3432-rebase-fast-forward.sh +++ b/t/t3432-rebase-fast-forward.sh @@ -28,8 +28,10 @@ test_rebase_same_head () { shift && cmp_f="$1" && shift && - test_rebase_same_head_ $status_n $what_n $cmp_n "" "$*" && - test_rebase_same_head_ $status_f $what_f $cmp_f " --no-ff" "$*" + test_rebase_same_head_ $status_n $what_n $cmp_n " --apply" "$*" && + test_rebase_same_head_ $status_f $what_f $cmp_f " --apply --no-ff" "$*" + test_rebase_same_head_ $status_n $what_n $cmp_n " --merge" "$*" && + test_rebase_same_head_ $status_f $what_f $cmp_f " --merge --no-ff" "$*" } test_rebase_same_head_ () { @@ -44,19 +46,15 @@ test_rebase_same_head_ () { test_expect_$status "git rebase$flag $* with $changes is $what with $cmp HEAD" " oldhead=\$(git rev-parse HEAD) && test_when_finished 'git reset --hard \$oldhead' && + cp .git/logs/HEAD expect && git rebase$flag $* >stdout && if test $what = work then - # Must check this case first, for 'is up to - # date, rebase forced[...]rewinding head' cases - test_i18ngrep 'rewinding head' stdout + old=\$(wc -l <expect) && + test_line_count '-gt' \$old .git/logs/HEAD elif test $what = noop then - test_i18ngrep 'is up to date' stdout && - test_i18ngrep ! 'rebase forced' stdout - elif test $what = noop-force - then - test_i18ngrep 'is up to date, rebase forced' stdout + test_cmp expect .git/logs/HEAD fi && newhead=\$(git rev-parse HEAD) && if test $cmp = same @@ -64,21 +62,21 @@ test_rebase_same_head_ () { test_cmp_rev \$oldhead \$newhead elif test $cmp = diff then - ! test_cmp_rev \$oldhead \$newhead + test_cmp_rev ! \$oldhead \$newhead fi " } changes='no changes' test_rebase_same_head success noop same success work same -test_rebase_same_head success noop same success noop-force same master -test_rebase_same_head success noop same success noop-force diff --onto B B -test_rebase_same_head success noop same success noop-force diff --onto B... B -test_rebase_same_head success noop same success noop-force same --onto master... master -test_rebase_same_head success noop same success noop-force same --keep-base master -test_rebase_same_head success noop same success noop-force same --keep-base -test_rebase_same_head success noop same success noop-force same --no-fork-point -test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point +test_rebase_same_head success noop same success work same master +test_rebase_same_head success noop same success work diff --onto B B +test_rebase_same_head success noop same success work diff --onto B... B +test_rebase_same_head success noop same success work same --onto master... master +test_rebase_same_head success noop same success work same --keep-base master +test_rebase_same_head success noop same success work same --keep-base +test_rebase_same_head success noop same success work same --no-fork-point +test_rebase_same_head success noop same success work same --keep-base --no-fork-point test_rebase_same_head success noop same success work same --fork-point master test_rebase_same_head success noop same success work diff --fork-point --onto B B test_rebase_same_head success noop same success work diff --fork-point --onto B... B @@ -91,14 +89,14 @@ test_expect_success 'add work same to side' ' changes='our changes' test_rebase_same_head success noop same success work same -test_rebase_same_head success noop same success noop-force same master -test_rebase_same_head success noop same success noop-force diff --onto B B -test_rebase_same_head success noop same success noop-force diff --onto B... B -test_rebase_same_head success noop same success noop-force same --onto master... master -test_rebase_same_head success noop same success noop-force same --keep-base master -test_rebase_same_head success noop same success noop-force same --keep-base -test_rebase_same_head success noop same success noop-force same --no-fork-point -test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point +test_rebase_same_head success noop same success work same master +test_rebase_same_head success noop same success work diff --onto B B +test_rebase_same_head success noop same success work diff --onto B... B +test_rebase_same_head success noop same success work same --onto master... master +test_rebase_same_head success noop same success work same --keep-base master +test_rebase_same_head success noop same success work same --keep-base +test_rebase_same_head success noop same success work same --no-fork-point +test_rebase_same_head success noop same success work same --keep-base --no-fork-point test_rebase_same_head success noop same success work same --fork-point master test_rebase_same_head success noop same success work diff --fork-point --onto B B test_rebase_same_head success noop same success work diff --fork-point --onto B... B @@ -112,8 +110,8 @@ test_expect_success 'add work same to upstream' ' ' changes='our and their changes' -test_rebase_same_head success noop same success noop-force diff --onto B B -test_rebase_same_head success noop same success noop-force diff --onto B... B +test_rebase_same_head success noop same success work diff --onto B B +test_rebase_same_head success noop same success work diff --onto B... B test_rebase_same_head success noop same success work diff --onto master... master test_rebase_same_head success noop same success work diff --keep-base master test_rebase_same_head success noop same success work diff --keep-base diff --git a/t/t3433-rebase-across-mode-change.sh b/t/t3433-rebase-across-mode-change.sh new file mode 100755 index 0000000000..05df964670 --- /dev/null +++ b/t/t3433-rebase-across-mode-change.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +test_description='git rebase across mode change' + +. ./test-lib.sh + +test_expect_success 'setup' ' + mkdir DS && + >DS/whatever && + git add DS && + git commit -m base && + + git branch side1 && + git branch side2 && + + git checkout side1 && + git rm -rf DS && + test_ln_s_add unrelated DS && + git commit -m side1 && + + git checkout side2 && + >unrelated && + git add unrelated && + git commit -m commit1 && + + echo >>unrelated && + git commit -am commit2 +' + +test_expect_success 'rebase changes with the apply backend' ' + test_when_finished "git rebase --abort || true" && + git checkout -b apply-backend side2 && + git rebase side1 +' + +test_expect_success 'rebase changes with the merge backend' ' + test_when_finished "git rebase --abort || true" && + git checkout -b merge-backend side2 && + git rebase -m side1 +' + +test_expect_success 'rebase changes with the merge backend with a delay' ' + test_when_finished "git rebase --abort || true" && + git checkout -b merge-delay-backend side2 && + git rebase -m --exec "sleep 1" side1 +' + +test_done diff --git a/t/t3434-rebase-i18n.sh b/t/t3434-rebase-i18n.sh new file mode 100755 index 0000000000..c7c835cde9 --- /dev/null +++ b/t/t3434-rebase-i18n.sh @@ -0,0 +1,84 @@ +#!/bin/sh +# +# Copyright (c) 2019 Doan Tran Cong Danh +# + +test_description='rebase with changing encoding + +Initial setup: + +1 - 2 master + \ + 3 - 4 first + \ + 5 - 6 second +' + +. ./test-lib.sh + +compare_msg () { + iconv -f "$2" -t "$3" "$TEST_DIRECTORY/t3434/$1" >expect && + git cat-file commit HEAD >raw && + sed "1,/^$/d" raw >actual && + test_cmp expect actual +} + +test_expect_success setup ' + test_commit one && + git branch first && + test_commit two && + git switch first && + test_commit three && + git branch second && + test_commit four && + git switch second && + test_commit five && + test_commit six +' + +test_expect_success 'rebase --rebase-merges update encoding eucJP to UTF-8' ' + git switch -c merge-eucJP-UTF-8 first && + git config i18n.commitencoding eucJP && + git merge -F "$TEST_DIRECTORY/t3434/eucJP.txt" second && + git config i18n.commitencoding UTF-8 && + git rebase --rebase-merges master && + compare_msg eucJP.txt eucJP UTF-8 +' + +test_expect_success 'rebase --rebase-merges update encoding eucJP to ISO-2022-JP' ' + git switch -c merge-eucJP-ISO-2022-JP first && + git config i18n.commitencoding eucJP && + git merge -F "$TEST_DIRECTORY/t3434/eucJP.txt" second && + git config i18n.commitencoding ISO-2022-JP && + git rebase --rebase-merges master && + compare_msg eucJP.txt eucJP ISO-2022-JP +' + +test_rebase_continue_update_encode () { + old=$1 + new=$2 + msgfile=$3 + test_expect_success "rebase --continue update from $old to $new" ' + (git rebase --abort || : abort current git-rebase failure) && + git switch -c conflict-$old-$new one && + echo for-conflict >two.t && + git add two.t && + git config i18n.commitencoding $old && + git commit -F "$TEST_DIRECTORY/t3434/$msgfile" && + git config i18n.commitencoding $new && + test_must_fail git rebase -m master && + test -f .git/rebase-merge/message && + git stripspace <.git/rebase-merge/message >two.t && + git add two.t && + git rebase --continue && + compare_msg $msgfile $old $new && + : git-commit assume invalid utf-8 is latin1 && + test_cmp expect two.t + ' +} + +test_rebase_continue_update_encode ISO-8859-1 UTF-8 ISO8859-1.txt +test_rebase_continue_update_encode eucJP UTF-8 eucJP.txt +test_rebase_continue_update_encode eucJP ISO-2022-JP eucJP.txt + +test_done diff --git a/t/t3434/ISO8859-1.txt b/t/t3434/ISO8859-1.txt new file mode 100644 index 0000000000..7cbef0ee6f --- /dev/null +++ b/t/t3434/ISO8859-1.txt @@ -0,0 +1,3 @@ +ÄËÑÏÖ + +Ábçdèfg diff --git a/t/t3434/eucJP.txt b/t/t3434/eucJP.txt new file mode 100644 index 0000000000..546f2aac01 --- /dev/null +++ b/t/t3434/eucJP.txt @@ -0,0 +1,4 @@ +¤Ï¤ì¤Ò¤Û¤Õ + +¤·¤Æ¤¤¤ë¤Î¤¬¡¢¤¤¤ë¤Î¤Ç¡£ +ßÀÉͤۤì¤×¤ê¤Ý¤ì¤Þ¤Ó¤°¤ê¤í¤Ø¡£ diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index d1c68af8c5..7c1da21df1 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -106,7 +106,7 @@ test_expect_success 'cherry-pick on unborn branch' ' rm -rf * && git cherry-pick initial && git diff --quiet initial && - ! test_cmp_rev initial HEAD + test_cmp_rev ! initial HEAD ' test_expect_success 'cherry-pick "-" to pick from previous branch' ' @@ -150,7 +150,7 @@ test_expect_success 'cherry-pick works with dirty renamed file' ' test_tick && git commit -m renamed && echo modified >renamed && - git cherry-pick refs/heads/unrelated >out && + git cherry-pick refs/heads/unrelated && test $(git rev-parse :0:renamed) = $(git rev-parse HEAD~2:to-rename.t) && grep -q "^modified$" renamed ' diff --git a/t/t3504-cherry-pick-rerere.sh b/t/t3504-cherry-pick-rerere.sh index a267b2d144..80a0d08706 100755 --- a/t/t3504-cherry-pick-rerere.sh +++ b/t/t3504-cherry-pick-rerere.sh @@ -94,8 +94,10 @@ test_expect_success 'cherry-pick --rerere-autoupdate more than once' ' test_expect_success 'cherry-pick conflict without rerere' ' test_config rerere.enabled false && - test_must_fail git cherry-pick master && - test_must_fail test_cmp expect foo + test_must_fail git cherry-pick foo-master && + grep ===== foo && + grep foo-dev foo && + grep foo-master foo ' test_done diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index 9b9b4ca8d4..9bd482ce3b 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -168,7 +168,7 @@ test_expect_success 'successful final commit clears cherry-pick state' ' echo resolved >foo && test_path_is_file .git/sequencer/todo && git commit -a && - test_must_fail test_path_exists .git/sequencer + test_path_is_missing .git/sequencer ' test_expect_success 'reset after final pick clears cherry-pick state' ' @@ -178,7 +178,7 @@ test_expect_success 'reset after final pick clears cherry-pick state' ' echo resolved >foo && test_path_is_file .git/sequencer/todo && git reset && - test_must_fail test_path_exists .git/sequencer + test_path_is_missing .git/sequencer ' test_expect_success 'failed cherry-pick produces dirty index' ' @@ -381,23 +381,23 @@ test_expect_success 'failed commit does not clear REVERT_HEAD' ' ' test_expect_success 'successful final commit clears revert state' ' - pristine_detach picked-signed && + pristine_detach picked-signed && - test_must_fail git revert picked-signed base && - echo resolved >foo && - test_path_is_file .git/sequencer/todo && - git commit -a && - test_must_fail test_path_exists .git/sequencer + test_must_fail git revert picked-signed base && + echo resolved >foo && + test_path_is_file .git/sequencer/todo && + git commit -a && + test_path_is_missing .git/sequencer ' test_expect_success 'reset after final pick clears revert state' ' - pristine_detach picked-signed && + pristine_detach picked-signed && - test_must_fail git revert picked-signed base && - echo resolved >foo && - test_path_is_file .git/sequencer/todo && - git reset && - test_must_fail test_path_exists .git/sequencer + test_must_fail git revert picked-signed base && + echo resolved >foo && + test_path_is_file .git/sequencer/todo && + git reset && + test_path_is_missing .git/sequencer ' test_expect_success 'revert conflict, diff3 -m style' ' diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh index b457333e18..23070a7b73 100755 --- a/t/t3508-cherry-pick-many-commits.sh +++ b/t/t3508-cherry-pick-many-commits.sh @@ -5,7 +5,7 @@ test_description='test cherry-picking many commits' . ./test-lib.sh check_head_differs_from() { - ! test_cmp_rev HEAD "$1" + test_cmp_rev ! HEAD "$1" } check_head_equals() { diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 8c8cca5bfb..f2c0168941 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -113,9 +113,10 @@ test_expect_success '"rm" command printed' ' echo frotz >test-file && git add test-file && git commit -m "add file for rm test" && - git rm test-file >rm-output && - test $(grep "^rm " rm-output | wc -l) = 1 && - rm -f test-file rm-output && + git rm test-file >rm-output.raw && + grep "^rm " rm-output.raw >rm-output && + test_line_count = 1 rm-output && + rm -f test-file rm-output.raw rm-output && git commit -m "remove file from rm test" ' @@ -250,6 +251,7 @@ test_expect_success 'choking "git rm" should not let it die with cruft' ' echo "100644 $hash 0 some-file-$i" i=$(( $i + 1 )) done | git update-index --index-info && + # git command is intentionally placed upstream of pipe to induce SIGPIPE git rm -n "some-file-*" | : && test_path_is_missing .git/index.lock ' @@ -303,7 +305,8 @@ EOF test_expect_success 'rm removes empty submodules from work tree' ' mkdir submod && - git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) submod && + hash=$(git rev-parse HEAD) && + git update-index --add --cacheinfo 160000 "$hash" submod && git config -f .gitmodules submodule.sub.url ./. && git config -f .gitmodules submodule.sub.path submod && git submodule init && @@ -422,6 +425,13 @@ test_expect_success 'rm will error out on a modified .gitmodules file unless sta git status -s -uno >actual && test_cmp expect actual ' +test_expect_success 'rm will not error out on .gitmodules file with zero stat data' ' + git reset --hard && + git submodule update && + git read-tree HEAD && + git rm submod && + test_path_is_missing submod +' test_expect_success 'rm issues a warning when section is not found in .gitmodules' ' git reset --hard && @@ -622,7 +632,8 @@ test_expect_success 'setup subsubmodule' ' git submodule update && ( cd submod && - git update-index --add --cacheinfo 160000 $(git rev-parse HEAD) subsubmod && + hash=$(git rev-parse HEAD) && + git update-index --add --cacheinfo 160000 "$hash" subsubmod && git config -f .gitmodules submodule.sub.url ../. && git config -f .gitmodules submodule.sub.path subsubmod && git submodule init && diff --git a/t/t3700-add.sh b/t/t3700-add.sh index c325167b90..88bc799807 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -326,7 +326,9 @@ test_expect_success 'git add --dry-run of an existing file output' " cat >expect.err <<\EOF The following paths are ignored by one of your .gitignore files: ignored-file -Use -f if you really want to add them. +hint: Use -f if you really want to add them. +hint: Turn this message off by running +hint: "git config advice.addIgnoredFile false" EOF cat >expect.out <<\EOF add 'track-this' diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index d50e165ca8..5bae6e50f1 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -23,6 +23,17 @@ diff_cmp () { test_cmp "$1.filtered" "$2.filtered" } +# This function uses a trick to manipulate the interactive add to use color: +# the `want_color()` function special-cases the situation where a pager was +# spawned and Git now wants to output colored text: to detect that situation, +# the environment variable `GIT_PAGER_IN_USE` is set. However, color is +# suppressed despite that environment variable if the `TERM` variable +# indicates a dumb terminal, so we set that variable, too. + +force_color () { + env GIT_PAGER_IN_USE=true TERM=vt100 "$@" +} + test_expect_success 'setup (initial)' ' echo content >file && git add file && @@ -57,6 +68,15 @@ test_expect_success 'revert works (initial)' ' ! grep . output ' +test_expect_success 'add untracked (multiple)' ' + test_when_finished "git reset && rm [1-9]" && + touch $(test_seq 9) && + test_write_lines a "2-5 8-" | git add -i -- [1-9] && + test_write_lines 2 3 4 5 8 9 >expected && + git ls-files [1-9] >output && + test_cmp expected output +' + test_expect_success 'setup (commit)' ' echo baseline >file && git add file && @@ -94,7 +114,6 @@ test_expect_success 'revert works (commit)' ' grep "unchanged *+3/-0 file" output ' - test_expect_success 'setup expected' ' cat >expected <<-\EOF EOF @@ -263,6 +282,35 @@ test_expect_success FILEMODE 'stage mode and hunk' ' # end of tests disabled when filemode is not usable +test_expect_success 'different prompts for mode change/deleted' ' + git reset --hard && + >file && + >deleted && + git add --chmod=+x file deleted && + echo changed >file && + rm deleted && + test_write_lines n n n | + git -c core.filemode=true add -p >actual && + sed -n "s/^\(([0-9/]*) Stage .*?\).*/\1/p" actual >actual.filtered && + cat >expect <<-\EOF && + (1/1) Stage deletion [y,n,q,a,d,?]? + (1/2) Stage mode change [y,n,q,a,d,j,J,g,/,?]? + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? + EOF + test_cmp expect actual.filtered +' + +test_expect_success 'correct message when there is nothing to do' ' + git reset --hard && + git add -p 2>err && + test_i18ngrep "No changes" err && + printf "\\0123" >binary && + git add binary && + printf "\\0abc" >binary && + git add -p 2>err && + test_i18ngrep "Only binary files changed" err +' + test_expect_success 'setup again' ' git reset --hard && test_chmod +x file && @@ -374,6 +422,36 @@ test_expect_success 'split hunk setup' ' test_write_lines 10 15 20 21 22 23 24 30 40 50 60 >test ' +test_expect_success 'goto hunk' ' + test_when_finished "git reset" && + tr _ " " >expect <<-EOF && + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? + 1: -1,2 +1,3 +15 + _ 2: -2,4 +3,8 +21 + go to which hunk? @@ -1,2 +1,3 @@ + _10 + +15 + _20 + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_ + EOF + test_write_lines s y g 1 | git add -p >actual && + tail -n 7 <actual >actual.trimmed && + test_cmp expect actual.trimmed +' + +test_expect_success 'navigate to hunk via regex' ' + test_when_finished "git reset" && + tr _ " " >expect <<-EOF && + (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? @@ -1,2 +1,3 @@ + _10 + +15 + _20 + (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?_ + EOF + test_write_lines s y /1,2 | git add -p >actual && + tail -n 5 <actual >actual.trimmed && + test_cmp expect actual.trimmed +' + test_expect_success 'split hunk "add -p (edit)"' ' # Split, say Edit and do nothing. Then: # @@ -403,6 +481,40 @@ test_expect_failure 'split hunk "add -p (no, yes, edit)"' ' ! grep "^+31" actual ' +test_expect_success 'split hunk with incomplete line at end' ' + git reset --hard && + printf "missing LF" >>test && + git add test && + test_write_lines before 10 20 30 40 50 60 70 >test && + git grep --cached missing && + test_write_lines s n y q | git add -p && + test_must_fail git grep --cached missing && + git grep before && + test_must_fail git grep --cached before +' + +test_expect_failure 'edit, adding lines to the first hunk' ' + test_write_lines 10 11 20 30 40 50 51 60 >test && + git reset && + tr _ " " >patch <<-EOF && + @@ -1,5 +1,6 @@ + _10 + +11 + +12 + _20 + +21 + +22 + _30 + EOF + # test sequence is s(plit), e(dit), n(o) + # q n q q is there to make sure we exit at the end. + printf "%s\n" s e n q n q q | + EDITOR=./fake_editor.sh git add -p 2>error && + test_must_be_empty error && + git diff --cached >actual && + grep "^+22" actual +' + test_expect_success 'patch mode ignores unmerged entries' ' git reset --hard && test_commit conflict && @@ -429,35 +541,61 @@ test_expect_success 'patch mode ignores unmerged entries' ' diff_cmp expected diff ' -test_expect_success TTY 'diffs can be colorized' ' +test_expect_success 'diffs can be colorized' ' git reset --hard && echo content >test && - printf y | test_terminal git add -p >output 2>&1 && + printf y >y && + force_color git add -p >output 2>&1 <y && # We do not want to depend on the exact coloring scheme # git uses for diffs, so just check that we saw some kind of color. grep "$(printf "\\033")" output ' -test_expect_success TTY 'diffFilter filters diff' ' +test_expect_success 'colorized diffs respect diff.wsErrorHighlight' ' + git reset --hard && + + echo "old " >test && + git add test && + echo "new " >test && + + printf y >y && + force_color git -c diff.wsErrorHighlight=all add -p >output.raw 2>&1 <y && + test_decode_color <output.raw >output && + grep "old<" output +' + +test_expect_success 'diffFilter filters diff' ' git reset --hard && echo content >test && test_config interactive.diffFilter "sed s/^/foo:/" && - printf y | test_terminal git add -p >output 2>&1 && + printf y >y && + force_color git add -p >output 2>&1 <y && # avoid depending on the exact coloring or content of the prompts, # and just make sure we saw our diff prefixed grep foo:.*content output ' -test_expect_success TTY 'detect bogus diffFilter output' ' +test_expect_success 'detect bogus diffFilter output' ' git reset --hard && echo content >test && - test_config interactive.diffFilter "echo too-short" && - printf y | test_must_fail test_terminal git add -p + test_config interactive.diffFilter "sed 1d" && + printf y >y && + test_must_fail force_color git add -p <y +' + +test_expect_success 'diff.algorithm is passed to `git diff-files`' ' + git reset --hard && + + >file && + git add file && + echo changed >file && + test_must_fail git -c diff.algorithm=bogus add -p 2>err && + test_i18ngrep "error: option diff-algorithm accepts " err ' test_expect_success 'patch-mode via -i prompts for files' ' @@ -647,4 +785,29 @@ test_expect_success 'checkout -p works with pathological context lines' ' test_write_lines a b a b a a b a b a >expect && test_cmp expect a ' + +test_expect_success 'show help from add--helper' ' + git reset --hard && + cat >expect <<-EOF && + + <BOLD>*** Commands ***<RESET> + 1: <BOLD;BLUE>s<RESET>tatus 2: <BOLD;BLUE>u<RESET>pdate 3: <BOLD;BLUE>r<RESET>evert 4: <BOLD;BLUE>a<RESET>dd untracked + 5: <BOLD;BLUE>p<RESET>atch 6: <BOLD;BLUE>d<RESET>iff 7: <BOLD;BLUE>q<RESET>uit 8: <BOLD;BLUE>h<RESET>elp + <BOLD;BLUE>What now<RESET>> <BOLD;RED>status - show paths with changes<RESET> + <BOLD;RED>update - add working tree state to the staged set of changes<RESET> + <BOLD;RED>revert - revert staged set of changes back to the HEAD version<RESET> + <BOLD;RED>patch - pick hunks and update selectively<RESET> + <BOLD;RED>diff - view diff between HEAD and index<RESET> + <BOLD;RED>add untracked - add contents of untracked files to the staged set of changes<RESET> + <BOLD>*** Commands ***<RESET> + 1: <BOLD;BLUE>s<RESET>tatus 2: <BOLD;BLUE>u<RESET>pdate 3: <BOLD;BLUE>r<RESET>evert 4: <BOLD;BLUE>a<RESET>dd untracked + 5: <BOLD;BLUE>p<RESET>atch 6: <BOLD;BLUE>d<RESET>iff 7: <BOLD;BLUE>q<RESET>uit 8: <BOLD;BLUE>h<RESET>elp + <BOLD;BLUE>What now<RESET>>$SP + Bye. + EOF + test_write_lines h | force_color git add -i >actual.colored && + test_decode_color <actual.colored >actual && + test_i18ncmp expect actual +' + test_done diff --git a/t/t3704-add-pathspec-file.sh b/t/t3704-add-pathspec-file.sh new file mode 100755 index 0000000000..9e35c1fbca --- /dev/null +++ b/t/t3704-add-pathspec-file.sh @@ -0,0 +1,159 @@ +#!/bin/sh + +test_description='add --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + test_commit file0 && + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t +' + +restore_checkpoint () { + git reset +} + +verify_expect () { + git status --porcelain --untracked-files=no -- fileA.t fileB.t fileC.t fileD.t >actual && + test_cmp expect actual +} + +test_expect_success '--pathspec-from-file from stdin' ' + restore_checkpoint && + + echo fileA.t | git add --pathspec-from-file=- && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect +' + +test_expect_success '--pathspec-from-file from file' ' + restore_checkpoint && + + echo fileA.t >list && + git add --pathspec-from-file=list && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect +' + +test_expect_success 'NUL delimiters' ' + restore_checkpoint && + + printf "fileA.t\0fileB.t\0" | git add --pathspec-from-file=- --pathspec-file-nul && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'LF delimiters' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t\n" | git add --pathspec-from-file=- && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'no trailing delimiter' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t" | git add --pathspec-from-file=- && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'CRLF delimiters' ' + restore_checkpoint && + + printf "fileA.t\r\nfileB.t\r\n" | git add --pathspec-from-file=- && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'quotes' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + git add --pathspec-from-file=list && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect +' + +test_expect_success 'quotes not compatible with --pathspec-file-nul' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + test_must_fail git add --pathspec-from-file=list --pathspec-file-nul +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + printf "fileB.t\nfileC.t\n" | git add --pathspec-from-file=- && + + cat >expect <<-\EOF && + A fileB.t + A fileC.t + EOF + verify_expect +' + +test_expect_success 'error conditions' ' + restore_checkpoint && + echo fileA.t >list && + >empty_list && + + test_must_fail git add --pathspec-from-file=list --interactive 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err && + + test_must_fail git add --pathspec-from-file=list --patch 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err && + + test_must_fail git add --pathspec-from-file=list --edit 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --edit" err && + + test_must_fail git add --pathspec-from-file=list -- fileA.t 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err && + + test_must_fail git add --pathspec-file-nul 2>err && + test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err && + + # This case succeeds, but still prints to stderr + git add --pathspec-from-file=empty_list 2>err && + test_i18ngrep -e "Nothing specified, nothing added." err +' + +test_done diff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh index b92ff95977..d277a9f4b7 100755 --- a/t/t3900-i18n-commit.sh +++ b/t/t3900-i18n-commit.sh @@ -204,4 +204,41 @@ test_commit_autosquash_flags eucJP fixup test_commit_autosquash_flags ISO-2022-JP squash +test_commit_autosquash_multi_encoding () { + flag=$1 + old=$2 + new=$3 + msg=$4 + test_expect_success "commit --$flag into $old from $new" ' + git checkout -b $flag-$old-$new C0 && + git config i18n.commitencoding $old && + echo $old >>F && + git commit -a -F "$TEST_DIRECTORY"/t3900/$msg && + test_tick && + echo intermediate stuff >>G && + git add G && + git commit -a -m "intermediate commit" && + test_tick && + git config i18n.commitencoding $new && + echo $new-$flag >>F && + git commit -a --$flag HEAD^ && + git rebase --autosquash -i HEAD^^^ && + git rev-list HEAD >actual && + test_line_count = 3 actual && + iconv -f $old -t UTF-8 "$TEST_DIRECTORY"/t3900/$msg >expect && + if test $flag = squash; then + subject="$(head -1 expect)" && + printf "\nsquash! %s\n" "$subject" >>expect + fi && + git cat-file commit HEAD^ >raw && + (sed "1,/^$/d" raw | iconv -f $new -t utf-8) >actual && + test_cmp expect actual + ' +} + +test_commit_autosquash_multi_encoding fixup UTF-8 ISO-8859-1 1-UTF-8.txt +test_commit_autosquash_multi_encoding squash ISO-8859-1 UTF-8 ISO8859-1.txt +test_commit_autosquash_multi_encoding squash eucJP ISO-2022-JP eucJP.txt +test_commit_autosquash_multi_encoding fixup ISO-2022-JP UTF-8 ISO-2022-JP.txt + test_done diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index a4da72f0ab..ea56e85e70 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -244,8 +244,11 @@ test_expect_success 'save -q is quiet' ' test_must_be_empty output.out ' -test_expect_success 'pop -q is quiet' ' +test_expect_success 'pop -q works and is quiet' ' git stash pop -q >output.out 2>&1 && + echo bar >expect && + git show :file >actual && + test_cmp expect actual && test_must_be_empty output.out ' @@ -254,6 +257,8 @@ test_expect_success 'pop -q --index works and is quiet' ' git add file && git stash save --quiet && git stash pop -q --index >output.out 2>&1 && + git diff-files file2 >file2.diff && + test_must_be_empty file2.diff && test foo = "$(git show :file)" && test_must_be_empty output.out ' diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh index 29ca76f2fb..f075c7f1f3 100755 --- a/t/t3905-stash-include-untracked.sh +++ b/t/t3905-stash-include-untracked.sh @@ -277,8 +277,8 @@ test_expect_success 'stash -u -- <ignored> leaves ignored file alone' ' test_path_is_file ignored.d/bar ' -test_expect_success 'stash -u -- <non-existant> shows no changes when there are none' ' - git stash push -u -- non-existant >actual && +test_expect_success 'stash -u -- <non-existent> shows no changes when there are none' ' + git stash push -u -- non-existent >actual && echo "No local changes to save" >expect && test_i18ncmp expect actual ' diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 5ac94b390d..dde3f11fec 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -120,6 +120,30 @@ test_expect_success setup ' +*++ [initial] Initial EOF +process_diffs () { + _x04="[0-9a-f][0-9a-f][0-9a-f][0-9a-f]" && + _x07="$_x05[0-9a-f][0-9a-f]" && + sed -e "s/$OID_REGEX/$ZERO_OID/g" \ + -e "s/From $_x40 /From $ZERO_OID /" \ + -e "s/from $_x40)/from $ZERO_OID)/" \ + -e "s/commit $_x40\$/commit $ZERO_OID/" \ + -e "s/commit $_x40 (/commit $ZERO_OID (/" \ + -e "s/$_x40 $_x40 $_x40/$ZERO_OID $ZERO_OID $ZERO_OID/" \ + -e "s/$_x40 $_x40 /$ZERO_OID $ZERO_OID /" \ + -e "s/^$_x40 $_x40$/$ZERO_OID $ZERO_OID/" \ + -e "s/^$_x40 /$ZERO_OID /" \ + -e "s/^$_x40$/$ZERO_OID/" \ + -e "s/$_x07\.\.$_x07/fffffff..fffffff/g" \ + -e "s/$_x07,$_x07\.\.$_x07/fffffff,fffffff..fffffff/g" \ + -e "s/$_x07 $_x07 $_x07/fffffff fffffff fffffff/g" \ + -e "s/$_x07 $_x07 /fffffff fffffff /g" \ + -e "s/Merge: $_x07 $_x07/Merge: fffffff fffffff/g" \ + -e "s/$_x07\.\.\./fffffff.../g" \ + -e "s/ $_x04\.\.\./ ffff.../g" \ + -e "s/ $_x04/ ffff/g" \ + "$1" +} + V=$(git version | sed -e 's/^git version //' -e 's/\./\\./g') while read magic cmd do @@ -158,13 +182,15 @@ do } >"$actual" && if test -f "$expect" then + process_diffs "$actual" >actual && + process_diffs "$expect" >expect && case $cmd in *format-patch* | *-stat*) - test_i18ncmp "$expect" "$actual";; + test_i18ncmp expect actual;; *) - test_cmp "$expect" "$actual";; + test_cmp expect actual;; esac && - rm -f "$actual" + rm -f "$actual" actual expect else # this is to help developing new tests. cp "$actual" "$expect" @@ -383,16 +409,22 @@ test_expect_success 'log -S requires an argument' ' test_expect_success 'diff --cached on unborn branch' ' echo ref: refs/heads/unborn >.git/HEAD && git diff --cached >result && - test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached" result + process_diffs result >actual && + process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--cached" >expected && + test_cmp expected actual ' test_expect_success 'diff --cached -- file on unborn branch' ' git diff --cached -- file0 >result && - test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" result + process_diffs result >actual && + process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--cached_--_file0" >expected && + test_cmp expected actual ' test_expect_success 'diff --line-prefix with spaces' ' git diff --line-prefix="| | | " --cached -- file0 >result && - test_cmp "$TEST_DIRECTORY/t4013/diff.diff_--line-prefix_--cached_--_file0" result + process_diffs result >actual && + process_diffs "$TEST_DIRECTORY/t4013/diff.diff_--line-prefix_--cached_--_file0" >expected && + test_cmp expected actual ' test_expect_success 'diff-tree --stdin with log formatting' ' diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 69267b16f0..b653dd7d44 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -793,6 +793,38 @@ test_expect_success 'format-patch with multiple notes refs' ' ! grep "this is note 2" out ' +test_expect_success 'format-patch with multiple notes refs in config' ' + test_when_finished "test_unconfig format.notes" && + + git notes --ref note1 add -m "this is note 1" HEAD && + test_when_finished git notes --ref note1 remove HEAD && + git notes --ref note2 add -m "this is note 2" HEAD && + test_when_finished git notes --ref note2 remove HEAD && + + git config format.notes note1 && + git format-patch -1 --stdout >out && + grep "this is note 1" out && + ! grep "this is note 2" out && + git config format.notes note2 && + git format-patch -1 --stdout >out && + ! grep "this is note 1" out && + grep "this is note 2" out && + git config --add format.notes note1 && + git format-patch -1 --stdout >out && + grep "this is note 1" out && + grep "this is note 2" out && + + git config --replace-all format.notes note1 && + git config --add format.notes false && + git format-patch -1 --stdout >out && + ! grep "this is note 1" out && + ! grep "this is note 2" out && + git config --add format.notes note2 && + git format-patch -1 --stdout >out && + ! grep "this is note 1" out && + grep "this is note 2" out +' + echo "fatal: --name-only does not make sense" >expect.name-only echo "fatal: --name-status does not make sense" >expect.name-status echo "fatal: --check does not make sense" >expect.check @@ -1939,10 +1971,9 @@ test_expect_success 'format-patch errors out when history involves criss-cross' test_must_fail git format-patch --base=auto -1 ' -test_expect_success 'format-patch format.useAutoBaseoption' ' - test_when_finished "git config --unset format.useAutoBase" && +test_expect_success 'format-patch format.useAutoBase option' ' git checkout local && - git config format.useAutoBase true && + test_config format.useAutoBase true && git format-patch --stdout -1 >patch && grep "^base-commit:" patch >actual && git rev-parse upstream >commit-id-base && @@ -1951,8 +1982,7 @@ test_expect_success 'format-patch format.useAutoBaseoption' ' ' test_expect_success 'format-patch --base overrides format.useAutoBase' ' - test_when_finished "git config --unset format.useAutoBase" && - git config format.useAutoBase true && + test_config format.useAutoBase true && git format-patch --stdout --base=HEAD~1 -1 >patch && grep "^base-commit:" patch >actual && git rev-parse HEAD~1 >commit-id-base && @@ -1960,6 +1990,12 @@ test_expect_success 'format-patch --base overrides format.useAutoBase' ' test_cmp expect actual ' +test_expect_success 'format-patch --no-base overrides format.useAutoBase' ' + test_config format.useAutoBase true && + git format-patch --stdout --no-base -1 >patch && + ! grep "^base-commit:" patch +' + test_expect_success 'format-patch --base with --attach' ' git format-patch --attach=mimemime --stdout --base=HEAD~ -1 >patch && sed -n -e "/^base-commit:/s/.*/1/p" -e "/^---*mimemime--$/s/.*/2/p" \ diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index eadaf57262..88d3026894 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -16,7 +16,8 @@ test_expect_success "Ray Lehtiniemi's example" ' } while (0); EOF git update-index --add x && - before=$(git rev-parse --short $(git hash-object x)) && + old_hash_x=$(git hash-object x) && + before=$(git rev-parse --short "$old_hash_x") && cat <<-\EOF >x && do @@ -25,7 +26,8 @@ test_expect_success "Ray Lehtiniemi's example" ' } while (0); EOF - after=$(git rev-parse --short $(git hash-object x)) && + new_hash_x=$(git hash-object x) && + after=$(git rev-parse --short "$new_hash_x") && cat <<-EOF >expect && diff --git a/x b/x @@ -63,7 +65,8 @@ test_expect_success 'another test, without options' ' EOF git update-index x && - before=$(git rev-parse --short $(git hash-object x)) && + old_hash_x=$(git hash-object x) && + before=$(git rev-parse --short "$old_hash_x") && tr "_" " " <<-\EOF >x && _ whitespace at beginning @@ -73,7 +76,8 @@ test_expect_success 'another test, without options' ' unchanged line CR at end EOF - after=$(git rev-parse --short $(git hash-object x)) && + new_hash_x=$(git hash-object x) && + after=$(git rev-parse --short "$new_hash_x") && tr "Q_" "\015 " <<-EOF >expect && diff --git a/x b/x @@ -526,13 +530,15 @@ test_expect_success 'ignore-blank-lines: mix changes and blank lines' ' test_expect_success 'check mixed spaces and tabs in indent' ' # This is indented with SP HT SP. echo " foo();" >x && - git diff --check | grep "space before tab in indent" + test_must_fail git diff --check >check && + grep "space before tab in indent" check ' test_expect_success 'check mixed tabs and spaces in indent' ' # This is indented with HT SP HT. echo " foo();" >x && - git diff --check | grep "space before tab in indent" + test_must_fail git diff --check >check && + grep "space before tab in indent" check ' test_expect_success 'check with no whitespace errors' ' @@ -753,20 +759,23 @@ test_expect_success 'check tab-in-indent excluded from wildcard whitespace attri test_expect_success 'line numbers in --check output are correct' ' echo "" >x && echo "foo(); " >>x && - git diff --check | grep "x:2:" + test_must_fail git diff --check >check && + grep "x:2:" check ' test_expect_success 'checkdiff detects new trailing blank lines (1)' ' echo "foo();" >x && echo "" >>x && - git diff --check | grep "new blank line" + test_must_fail git diff --check >check && + grep "new blank line" check ' test_expect_success 'checkdiff detects new trailing blank lines (2)' ' - { echo a; echo b; echo; echo; } >x && + test_write_lines a b "" "" >x && git add x && - { echo a; echo; echo; echo; echo; } >x && - git diff --check | grep "new blank line" + test_write_lines a "" "" "" "" >x && + test_must_fail git diff --check >check && + grep "new blank line" check ' test_expect_success 'checkdiff allows new blank lines' ' @@ -794,14 +803,16 @@ test_expect_success 'whitespace-only changes reported across renames' ' git reset --hard && for i in 1 2 3 4 5 6 7 8 9; do echo "$i$i$i$i$i$i"; done >x && git add x && - before=$(git rev-parse --short $(git hash-object x)) && + hash_x=$(git hash-object x) && + before=$(git rev-parse --short "$hash_x") && git commit -m "base" && sed -e "5s/^/ /" x >z && git rm x && git add z && - after=$(git rev-parse --short $(git hash-object z)) && - git diff -w -M --cached | - sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" >actual && + hash_z=$(git hash-object z) && + after=$(git rev-parse --short "$hash_z") && + git diff -w -M --cached >actual.raw && + sed -e "/^similarity index /s/[0-9][0-9]*/NUM/" actual.raw >actual && cat <<-EOF >expect && diff --git a/x b/z similarity index NUM% @@ -840,7 +851,8 @@ test_expect_success 'combined diff with autocrlf conversion' ' git config core.autocrlf true && test_must_fail git merge master && - git diff | sed -e "1,/^@@@/d" >actual && + git diff >actual.raw && + sed -e "1,/^@@@/d" actual.raw >actual && ! grep "^-" actual ' @@ -864,11 +876,14 @@ test_expect_success 'diff that introduces a line with only tabs' ' git config core.whitespace blank-at-eol && git reset --hard && echo "test" >x && - before=$(git rev-parse --short $(git hash-object x)) && + old_hash_x=$(git hash-object x) && + before=$(git rev-parse --short "$old_hash_x") && git commit -m "initial" x && echo "{NTN}" | tr "NT" "\n\t" >>x && - after=$(git rev-parse --short $(git hash-object x)) && - git diff --color | test_decode_color >current && + new_hash_x=$(git hash-object x) && + after=$(git rev-parse --short "$new_hash_x") && + git diff --color >current.raw && + test_decode_color <current.raw >current && cat >expected <<-EOF && <BOLD>diff --git a/x b/x<RESET> @@ -891,17 +906,19 @@ test_expect_success 'diff that introduces and removes ws breakages' ' echo "0. blank-at-eol " && echo "1. blank-at-eol " } >x && - before=$(git rev-parse --short $(git hash-object x)) && + old_hash_x=$(git hash-object x) && + before=$(git rev-parse --short "$old_hash_x") && git commit -a --allow-empty -m preimage && { echo "0. blank-at-eol " && echo "1. still-blank-at-eol " && echo "2. and a new line " } >x && - after=$(git rev-parse --short $(git hash-object x)) && + new_hash_x=$(git hash-object x) && + after=$(git rev-parse --short "$new_hash_x") && - git diff --color | - test_decode_color >current && + git diff --color >current.raw && + test_decode_color <current.raw >current && cat >expected <<-EOF && <BOLD>diff --git a/x b/x<RESET> @@ -925,14 +942,16 @@ test_expect_success 'ws-error-highlight test setup' ' echo "0. blank-at-eol " && echo "1. blank-at-eol " } >x && - before=$(git rev-parse --short $(git hash-object x)) && + old_hash_x=$(git hash-object x) && + before=$(git rev-parse --short "$old_hash_x") && git commit -a --allow-empty -m preimage && { echo "0. blank-at-eol " && echo "1. still-blank-at-eol " && echo "2. and a new line " } >x && - after=$(git rev-parse --short $(git hash-object x)) && + new_hash_x=$(git hash-object x) && + after=$(git rev-parse --short "$new_hash_x") && cat >expect.default-old <<-EOF && <BOLD>diff --git a/x b/x<RESET> @@ -974,32 +993,32 @@ test_expect_success 'ws-error-highlight test setup' ' test_expect_success 'test --ws-error-highlight option' ' - git diff --color --ws-error-highlight=default,old | - test_decode_color >current && + git diff --color --ws-error-highlight=default,old >current.raw && + test_decode_color <current.raw >current && test_cmp expect.default-old current && - git diff --color --ws-error-highlight=all | - test_decode_color >current && + git diff --color --ws-error-highlight=all >current.raw && + test_decode_color <current.raw >current && test_cmp expect.all current && - git diff --color --ws-error-highlight=none | - test_decode_color >current && + git diff --color --ws-error-highlight=none >current.raw && + test_decode_color <current.raw >current && test_cmp expect.none current ' test_expect_success 'test diff.wsErrorHighlight config' ' - git -c diff.wsErrorHighlight=default,old diff --color | - test_decode_color >current && + git -c diff.wsErrorHighlight=default,old diff --color >current.raw && + test_decode_color <current.raw >current && test_cmp expect.default-old current && - git -c diff.wsErrorHighlight=all diff --color | - test_decode_color >current && + git -c diff.wsErrorHighlight=all diff --color >current.raw && + test_decode_color <current.raw >current && test_cmp expect.all current && - git -c diff.wsErrorHighlight=none diff --color | - test_decode_color >current && + git -c diff.wsErrorHighlight=none diff --color >current.raw && + test_decode_color <current.raw >current && test_cmp expect.none current ' @@ -1007,18 +1026,18 @@ test_expect_success 'test diff.wsErrorHighlight config' ' test_expect_success 'option overrides diff.wsErrorHighlight' ' git -c diff.wsErrorHighlight=none \ - diff --color --ws-error-highlight=default,old | - test_decode_color >current && + diff --color --ws-error-highlight=default,old >current.raw && + test_decode_color <current.raw >current && test_cmp expect.default-old current && git -c diff.wsErrorHighlight=default \ - diff --color --ws-error-highlight=all | - test_decode_color >current && + diff --color --ws-error-highlight=all >current.raw && + test_decode_color <current.raw >current && test_cmp expect.all current && git -c diff.wsErrorHighlight=all \ - diff --color --ws-error-highlight=none | - test_decode_color >current && + diff --color --ws-error-highlight=none >current.raw && + test_decode_color <current.raw >current && test_cmp expect.none current ' @@ -1038,7 +1057,8 @@ test_expect_success 'detect moved code, complete file' ' git mv test.c main.c && test_config color.diff.oldMoved "normal red" && test_config color.diff.newMoved "normal green" && - git diff HEAD --color-moved=zebra --color --no-renames | test_decode_color >actual && + git diff HEAD --color-moved=zebra --color --no-renames >actual.raw && + test_decode_color <actual.raw >actual && cat >expected <<-EOF && <BOLD>diff --git a/main.c b/main.c<RESET> <BOLD>new file mode 100644<RESET> @@ -1141,9 +1161,12 @@ test_expect_success 'detect malicious moved code, inside file' ' bar(); } EOF - after_main=$(git rev-parse --short $(git hash-object main.c)) && - after_test=$(git rev-parse --short $(git hash-object test.c)) && - git diff HEAD --no-renames --color-moved=zebra --color | test_decode_color >actual && + hash_main=$(git hash-object main.c) && + after_main=$(git rev-parse --short "$hash_main") && + hash_test=$(git hash-object test.c) && + after_test=$(git rev-parse --short "$hash_test") && + git diff HEAD --no-renames --color-moved=zebra --color >actual.raw && + test_decode_color <actual.raw >actual && cat <<-EOF >expected && <BOLD>diff --git a/main.c b/main.c<RESET> <BOLD>index $before_main..$after_main 100644<RESET> @@ -1192,7 +1215,8 @@ test_expect_success 'plain moved code, inside file' ' test_config color.diff.oldMovedAlternative "blue" && test_config color.diff.newMovedAlternative "yellow" && # needs previous test as setup - git diff HEAD --no-renames --color-moved=plain --color | test_decode_color >actual && + git diff HEAD --no-renames --color-moved=plain --color >actual.raw && + test_decode_color <actual.raw >actual && cat <<-EOF >expected && <BOLD>diff --git a/main.c b/main.c<RESET> <BOLD>index $before_main..$after_main 100644<RESET> @@ -1771,7 +1795,8 @@ test_expect_success 'move detection with submodules' ' ! grep BRED decoded_actual && # nor did we mess with it another way - git diff --submodule=diff --color | test_decode_color >expect && + git diff --submodule=diff --color >expect.raw && + test_decode_color <expect.raw >expect && test_cmp expect decoded_actual && rm -rf bananas && git submodule deinit bananas @@ -2025,11 +2050,6 @@ test_expect_success 'compare mixed whitespace delta across moved blocks' ' test_cmp expected actual ' -# Note that the "6" in the expected hunk header below is funny, since we only -# show 5 lines (the missing one was blank and thus ignored). This is how -# --ignore-blank-lines behaves even without --function-context, and this test -# is just checking the interaction of the two features. Don't take it as an -# endorsement of that output. test_expect_success 'combine --ignore-blank-lines with --function-context' ' test_write_lines 1 "" 2 3 4 5 >a && test_write_lines 1 2 3 4 >b && @@ -2039,6 +2059,7 @@ test_expect_success 'combine --ignore-blank-lines with --function-context' ' cat <<-\EOF >expect && @@ -1,6 +1,4 @@ 1 + - 2 3 4 @@ -2047,4 +2068,27 @@ test_expect_success 'combine --ignore-blank-lines with --function-context' ' test_cmp expect actual ' +test_expect_success 'combine --ignore-blank-lines with --function-context 2' ' + test_write_lines a b c "" function 1 2 3 4 5 "" 6 7 8 9 >a && + test_write_lines "" a b c "" function 1 2 3 4 5 6 7 8 >b && + test_must_fail git diff --no-index \ + --ignore-blank-lines --function-context a b >actual.raw && + sed -n "/@@/,\$p" <actual.raw >actual && + cat <<-\EOF >expect && + @@ -5,11 +6,9 @@ c + function + 1 + 2 + 3 + 4 + 5 + - + 6 + 7 + 8 + -9 + EOF + test_cmp expect actual +' + test_done diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh index 6f5ef0035e..02255a08bf 100755 --- a/t/t4018-diff-funcname.sh +++ b/t/t4018-diff-funcname.sh @@ -32,6 +32,7 @@ diffpatterns=" csharp css dts + elixir fortran fountain golang @@ -105,7 +106,6 @@ do result=success fi test_expect_$result "hunk header: $i" " - test_when_finished 'cat actual' && # for debugging only git diff -U1 $i >actual && grep '@@ .* @@.*RIGHT' actual " diff --git a/t/t4018/elixir-do-not-pick-end b/t/t4018/elixir-do-not-pick-end new file mode 100644 index 0000000000..fae08ba7e8 --- /dev/null +++ b/t/t4018/elixir-do-not-pick-end @@ -0,0 +1,5 @@ +defmodule RIGHT do +end +# +# +# ChangeMe; do not pick up 'end' line diff --git a/t/t4018/elixir-ex-unit-test b/t/t4018/elixir-ex-unit-test new file mode 100644 index 0000000000..0560a2b697 --- /dev/null +++ b/t/t4018/elixir-ex-unit-test @@ -0,0 +1,6 @@ +defmodule Test do + test "RIGHT" do + assert true == true + assert ChangeMe + end +end diff --git a/t/t4018/elixir-function b/t/t4018/elixir-function new file mode 100644 index 0000000000..d452f495a7 --- /dev/null +++ b/t/t4018/elixir-function @@ -0,0 +1,5 @@ +def function(RIGHT, arg) do + # comment + # comment + ChangeMe +end diff --git a/t/t4018/elixir-macro b/t/t4018/elixir-macro new file mode 100644 index 0000000000..4f925e9ad4 --- /dev/null +++ b/t/t4018/elixir-macro @@ -0,0 +1,5 @@ +defmacro foo(RIGHT) do + # Code + # Code + ChangeMe +end diff --git a/t/t4018/elixir-module b/t/t4018/elixir-module new file mode 100644 index 0000000000..91a4e7aa20 --- /dev/null +++ b/t/t4018/elixir-module @@ -0,0 +1,9 @@ +defmodule RIGHT do + @moduledoc """ + Foo bar + """ + + def ChangeMe(a) where is_map(a) do + a + end +end diff --git a/t/t4018/elixir-module-func b/t/t4018/elixir-module-func new file mode 100644 index 0000000000..c9910d0675 --- /dev/null +++ b/t/t4018/elixir-module-func @@ -0,0 +1,8 @@ +defmodule Foo do + def fun(RIGHT) do + # Code + # Code + # Code + ChangeMe + end +end diff --git a/t/t4018/elixir-nested-module b/t/t4018/elixir-nested-module new file mode 100644 index 0000000000..771ebc5c42 --- /dev/null +++ b/t/t4018/elixir-nested-module @@ -0,0 +1,9 @@ +defmodule MyApp.RIGHT do + @moduledoc """ + Foo bar + """ + + def ChangeMe(a) where is_map(a) do + a + end +end diff --git a/t/t4018/elixir-private-function b/t/t4018/elixir-private-function new file mode 100644 index 0000000000..1aabe33b7a --- /dev/null +++ b/t/t4018/elixir-private-function @@ -0,0 +1,5 @@ +defp function(RIGHT, arg) do + # comment + # comment + ChangeMe +end diff --git a/t/t4018/elixir-protocol b/t/t4018/elixir-protocol new file mode 100644 index 0000000000..7d9173691e --- /dev/null +++ b/t/t4018/elixir-protocol @@ -0,0 +1,6 @@ +defprotocol RIGHT do + @doc """ + Calculates the size (and not the length!) of a data structure + """ + def size(data, ChangeMe) +end diff --git a/t/t4018/elixir-protocol-implementation b/t/t4018/elixir-protocol-implementation new file mode 100644 index 0000000000..f9234bbfc4 --- /dev/null +++ b/t/t4018/elixir-protocol-implementation @@ -0,0 +1,5 @@ +defimpl RIGHT do + # Docs + # Docs + def foo(ChangeMe), do: :ok +end diff --git a/t/t4018/python-async-def b/t/t4018/python-async-def new file mode 100644 index 0000000000..87640e03d2 --- /dev/null +++ b/t/t4018/python-async-def @@ -0,0 +1,4 @@ +async def RIGHT(pi: int = 3.14): + while True: + break + return ChangeMe() diff --git a/t/t4018/python-class b/t/t4018/python-class new file mode 100644 index 0000000000..ba9e741430 --- /dev/null +++ b/t/t4018/python-class @@ -0,0 +1,4 @@ +class RIGHT(int, str): + # comment + # another comment + # ChangeMe diff --git a/t/t4018/python-def b/t/t4018/python-def new file mode 100644 index 0000000000..e50b31b0ad --- /dev/null +++ b/t/t4018/python-def @@ -0,0 +1,4 @@ +def RIGHT(pi: int = 3.14): + while True: + break + return ChangeMe() diff --git a/t/t4018/python-indented-async-def b/t/t4018/python-indented-async-def new file mode 100644 index 0000000000..f5d03258af --- /dev/null +++ b/t/t4018/python-indented-async-def @@ -0,0 +1,7 @@ +class Foo: + async def RIGHT(self, x: int): + return [ + 1, + 2, + ChangeMe, + ] diff --git a/t/t4018/python-indented-class b/t/t4018/python-indented-class new file mode 100644 index 0000000000..19b4f35c4c --- /dev/null +++ b/t/t4018/python-indented-class @@ -0,0 +1,5 @@ +if TYPE_CHECKING: + class RIGHT: + # comment + # another comment + # ChangeMe diff --git a/t/t4018/python-indented-def b/t/t4018/python-indented-def new file mode 100644 index 0000000000..208fbadd2b --- /dev/null +++ b/t/t4018/python-indented-def @@ -0,0 +1,7 @@ +class Foo: + def RIGHT(self, x: int): + return [ + 1, + 2, + ChangeMe, + ] diff --git a/t/t4026-color.sh b/t/t4026-color.sh index 671e951ee5..c0b642c1ab 100755 --- a/t/t4026-color.sh +++ b/t/t4026-color.sh @@ -30,6 +30,14 @@ test_expect_success 'attribute before color name' ' color "bold red" "[1;31m" ' +test_expect_success 'aixterm bright fg color' ' + color "brightred" "[91m" +' + +test_expect_success 'aixterm bright bg color' ' + color "green brightblue" "[32;104m" +' + test_expect_success 'color name before attribute' ' color "red bold" "[1;31m" ' @@ -74,6 +82,10 @@ test_expect_success '0-7 are aliases for basic ANSI color names' ' color "0 7" "[30;47m" ' +test_expect_success '8-15 are aliases for aixterm color names' ' + color "12 13" "[94;105m" +' + test_expect_success '256 colors' ' color "254 bold 255" "[1;38;5;254;48;5;255m" ' diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh index b5a56895e8..94680836ce 100755 --- a/t/t4038-diff-combined.sh +++ b/t/t4038-diff-combined.sh @@ -354,7 +354,7 @@ test_expect_failure 'combine diff coalesce three parents' ' ' # Test for a bug reported at -# https://public-inbox.org/git/20130515143508.GO25742@login.drsnuggles.stderr.nl/ +# https://lore.kernel.org/git/20130515143508.GO25742@login.drsnuggles.stderr.nl/ # where a delete lines were missing from combined diff output when they # occurred exactly before the context lines of a later change. test_expect_success 'combine diff missing delete bug' ' diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh index 619bf97098..f852136585 100755 --- a/t/t4041-diff-submodule-option.sh +++ b/t/t4041-diff-submodule-option.sh @@ -284,7 +284,7 @@ test_expect_success 'submodule contains untracked content (all ignored)' ' test_must_be_empty actual ' -test_expect_success 'submodule contains untracked and modifed content' ' +test_expect_success 'submodule contains untracked and modified content' ' echo new > sm1/foo6 && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && @@ -294,7 +294,7 @@ test_expect_success 'submodule contains untracked and modifed content' ' test_cmp expected actual ' -test_expect_success 'submodule contains untracked and modifed content (untracked ignored)' ' +test_expect_success 'submodule contains untracked and modified content (untracked ignored)' ' echo new > sm1/foo6 && git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && cat >expected <<-EOF && @@ -303,19 +303,19 @@ test_expect_success 'submodule contains untracked and modifed content (untracked test_cmp expected actual ' -test_expect_success 'submodule contains untracked and modifed content (dirty ignored)' ' +test_expect_success 'submodule contains untracked and modified content (dirty ignored)' ' echo new > sm1/foo6 && git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && test_must_be_empty actual ' -test_expect_success 'submodule contains untracked and modifed content (all ignored)' ' +test_expect_success 'submodule contains untracked and modified content (all ignored)' ' echo new > sm1/foo6 && git diff-index -p --ignore-submodules --submodule=log HEAD >actual && test_must_be_empty actual ' -test_expect_success 'submodule contains modifed content' ' +test_expect_success 'submodule contains modified content' ' rm -f sm1/new-file && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && @@ -369,7 +369,7 @@ test_expect_success 'modified submodule contains untracked content (all ignored) test_must_be_empty actual ' -test_expect_success 'modified submodule contains untracked and modifed content' ' +test_expect_success 'modified submodule contains untracked and modified content' ' echo modification >> sm1/foo6 && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && @@ -381,7 +381,7 @@ test_expect_success 'modified submodule contains untracked and modifed content' test_cmp expected actual ' -test_expect_success 'modified submodule contains untracked and modifed content (untracked ignored)' ' +test_expect_success 'modified submodule contains untracked and modified content (untracked ignored)' ' echo modification >> sm1/foo6 && git diff-index -p --ignore-submodules=untracked --submodule=log HEAD >actual && cat >expected <<-EOF && @@ -392,7 +392,7 @@ test_expect_success 'modified submodule contains untracked and modifed content ( test_cmp expected actual ' -test_expect_success 'modified submodule contains untracked and modifed content (dirty ignored)' ' +test_expect_success 'modified submodule contains untracked and modified content (dirty ignored)' ' echo modification >> sm1/foo6 && git diff-index -p --ignore-submodules=dirty --submodule=log HEAD >actual && cat >expected <<-EOF && @@ -402,13 +402,13 @@ test_expect_success 'modified submodule contains untracked and modifed content ( test_cmp expected actual ' -test_expect_success 'modified submodule contains untracked and modifed content (all ignored)' ' +test_expect_success 'modified submodule contains untracked and modified content (all ignored)' ' echo modification >> sm1/foo6 && git diff-index -p --ignore-submodules --submodule=log HEAD >actual && test_must_be_empty actual ' -test_expect_success 'modified submodule contains modifed content' ' +test_expect_success 'modified submodule contains modified content' ' rm -f sm1/new-file && git diff-index -p --submodule=log HEAD >actual && cat >expected <<-EOF && diff --git a/t/t4054-diff-bogus-tree.sh b/t/t4054-diff-bogus-tree.sh index fcae82fffa..8c95f152b2 100755 --- a/t/t4054-diff-bogus-tree.sh +++ b/t/t4054-diff-bogus-tree.sh @@ -4,8 +4,9 @@ test_description='test diff with a bogus tree containing the null sha1' . ./test-lib.sh test_expect_success 'create bogus tree' ' + name=$(echo $ZERO_OID | sed -e "s/00/Q/g") && bogus_tree=$( - printf "100644 fooQQQQQQQQQQQQQQQQQQQQQ" | + printf "100644 fooQ$name" | q_to_nul | git hash-object -w --stdin -t tree ) diff --git a/t/t4057-diff-combined-paths.sh b/t/t4057-diff-combined-paths.sh index dff36b77ec..4f4b541658 100755 --- a/t/t4057-diff-combined-paths.sh +++ b/t/t4057-diff-combined-paths.sh @@ -33,7 +33,7 @@ test_expect_success 'trivial merge - combine-diff empty' ' ' -test_expect_success 'only one trully conflicting path' ' +test_expect_success 'only one truly conflicting path' ' git checkout side && for i in $(test_seq 2 9) do diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh index 9dcb69df5c..fc8229c726 100755 --- a/t/t4060-diff-submodule-option-diff-format.sh +++ b/t/t4060-diff-submodule-option-diff-format.sh @@ -42,6 +42,17 @@ commit_file () { git commit "$@" -m "Commit $*" >/dev/null } +diff_cmp () { + for i in "$1" "$2" + do + sed -e 's/^index 0000000\.\.[0-9a-f]*/index 0000000..1234567/' \ + -e 's/^index [0-9a-f]*\.\.[0-9a-f]*/index 1234567..89abcde/' \ + "$i" >"$i.compare" || return 1 + done && + test_cmp "$1.compare" "$2.compare" && + rm -f "$1.compare" "$2.compare" +} + test_expect_success 'setup repository' ' test_create_repo sm1 && add_file . foo && @@ -69,7 +80,7 @@ test_expect_success 'added submodule' ' @@ -0,0 +1 @@ +foo2 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'added submodule, set diff.submodule' ' @@ -93,7 +104,7 @@ test_expect_success 'added submodule, set diff.submodule' ' @@ -0,0 +1 @@ +foo2 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success '--submodule=short overrides diff.submodule' ' @@ -109,7 +120,7 @@ test_expect_success '--submodule=short overrides diff.submodule' ' @@ -0,0 +1 @@ +Subproject commit $fullhead1 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'diff.submodule does not affect plumbing' ' @@ -124,7 +135,7 @@ test_expect_success 'diff.submodule does not affect plumbing' ' @@ -0,0 +1 @@ +Subproject commit $fullhead1 EOF - test_cmp expected actual + diff_cmp expected actual ' commit_file sm1 && @@ -142,7 +153,7 @@ test_expect_success 'modified submodule(forward)' ' @@ -0,0 +1 @@ +foo3 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule(forward)' ' @@ -157,7 +168,7 @@ test_expect_success 'modified submodule(forward)' ' @@ -0,0 +1 @@ +foo3 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule(forward) --submodule' ' @@ -166,7 +177,7 @@ test_expect_success 'modified submodule(forward) --submodule' ' Submodule sm1 $head1..$head2: > Add foo3 ($added foo3) EOF - test_cmp expected actual + diff_cmp expected actual ' fullhead2=$(cd sm1; git rev-parse --verify HEAD) @@ -181,7 +192,7 @@ test_expect_success 'modified submodule(forward) --submodule=short' ' -Subproject commit $fullhead1 +Subproject commit $fullhead2 EOF - test_cmp expected actual + diff_cmp expected actual ' commit_file sm1 && @@ -210,7 +221,7 @@ test_expect_success 'modified submodule(backward)' ' @@ -1 +0,0 @@ -foo3 EOF - test_cmp expected actual + diff_cmp expected actual ' head4=$(add_file sm1 foo4 foo5) @@ -247,7 +258,7 @@ test_expect_success 'modified submodule(backward and forward)' ' @@ -0,0 +1 @@ +foo5 EOF - test_cmp expected actual + diff_cmp expected actual ' commit_file sm1 && @@ -291,7 +302,7 @@ test_expect_success 'typechanged submodule(submodule->blob), --cached' ' @@ -0,0 +1 @@ +sm1 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'typechanged submodule(submodule->blob)' ' @@ -327,7 +338,7 @@ test_expect_success 'typechanged submodule(submodule->blob)' ' @@ -0,0 +1 @@ +foo5 EOF - test_cmp expected actual + diff_cmp expected actual ' rm -rf sm1 && @@ -344,7 +355,7 @@ test_expect_success 'typechanged submodule(submodule->blob)' ' @@ -0,0 +1 @@ +sm1 EOF - test_cmp expected actual + diff_cmp expected actual ' rm -f sm1 && @@ -356,7 +367,7 @@ test_expect_success 'nonexistent commit' ' cat >expected <<-EOF && Submodule sm1 $head4...$head6 (commits not present) EOF - test_cmp expected actual + diff_cmp expected actual ' commit_file @@ -386,11 +397,12 @@ test_expect_success 'typechanged submodule(blob->submodule)' ' @@ -0,0 +1 @@ +foo7 EOF - test_cmp expected actual + diff_cmp expected actual ' commit_file sm1 && test_expect_success 'submodule is up to date' ' + head7=$(git -C sm1 rev-parse --short --verify HEAD) && git diff-index -p --submodule=diff HEAD >actual && test_must_be_empty actual ' @@ -401,7 +413,7 @@ test_expect_success 'submodule contains untracked content' ' cat >expected <<-EOF && Submodule sm1 contains untracked content EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'submodule contains untracked content (untracked ignored)' ' @@ -433,7 +445,7 @@ test_expect_success 'submodule contains untracked and modified content' ' -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' # NOT OK @@ -450,7 +462,7 @@ test_expect_success 'submodule contains untracked and modified content (untracke -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'submodule contains untracked and modified content (dirty ignored)' ' @@ -478,7 +490,7 @@ test_expect_success 'submodule contains modified content' ' -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' (cd sm1; git commit -mchange foo6 >/dev/null) && @@ -486,7 +498,7 @@ head8=$(cd sm1; git rev-parse --short --verify HEAD) && test_expect_success 'submodule is modified' ' git diff-index -p --submodule=diff HEAD >actual && cat >expected <<-EOF && - Submodule sm1 17243c9..$head8: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..3e75765 100644 --- a/sm1/foo6 @@ -495,7 +507,7 @@ test_expect_success 'submodule is modified' ' -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule contains untracked content' ' @@ -503,7 +515,7 @@ test_expect_success 'modified submodule contains untracked content' ' git diff-index -p --submodule=diff HEAD >actual && cat >expected <<-EOF && Submodule sm1 contains untracked content - Submodule sm1 17243c9..$head8: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..3e75765 100644 --- a/sm1/foo6 @@ -512,13 +524,13 @@ test_expect_success 'modified submodule contains untracked content' ' -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule contains untracked content (untracked ignored)' ' git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual && cat >expected <<-EOF && - Submodule sm1 17243c9..$head8: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..3e75765 100644 --- a/sm1/foo6 @@ -527,13 +539,13 @@ test_expect_success 'modified submodule contains untracked content (untracked ig -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule contains untracked content (dirty ignored)' ' git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual && cat >expected <<-EOF && - Submodule sm1 17243c9..cfce562: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..3e75765 100644 --- a/sm1/foo6 @@ -542,7 +554,7 @@ test_expect_success 'modified submodule contains untracked content (dirty ignore -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule contains untracked content (all ignored)' ' @@ -556,7 +568,7 @@ test_expect_success 'modified submodule contains untracked and modified content' cat >expected <<-EOF && Submodule sm1 contains untracked content Submodule sm1 contains modified content - Submodule sm1 17243c9..cfce562: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..dfda541 100644 --- a/sm1/foo6 @@ -566,7 +578,7 @@ test_expect_success 'modified submodule contains untracked and modified content' +new +modification EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule contains untracked and modified content (untracked ignored)' ' @@ -574,7 +586,7 @@ test_expect_success 'modified submodule contains untracked and modified content git diff-index -p --ignore-submodules=untracked --submodule=diff HEAD >actual && cat >expected <<-EOF && Submodule sm1 contains modified content - Submodule sm1 17243c9..cfce562: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..e20e2d9 100644 --- a/sm1/foo6 @@ -585,14 +597,14 @@ test_expect_success 'modified submodule contains untracked and modified content +modification +modification EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule contains untracked and modified content (dirty ignored)' ' echo modification >> sm1/foo6 && git diff-index -p --ignore-submodules=dirty --submodule=diff HEAD >actual && cat >expected <<-EOF && - Submodule sm1 17243c9..cfce562: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..3e75765 100644 --- a/sm1/foo6 @@ -601,7 +613,7 @@ test_expect_success 'modified submodule contains untracked and modified content -foo6 +new EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'modified submodule contains untracked and modified content (all ignored)' ' @@ -616,7 +628,7 @@ test_expect_success 'modified submodule contains modified content' ' git diff-index -p --submodule=diff HEAD >actual && cat >expected <<-EOF && Submodule sm1 contains modified content - Submodule sm1 17243c9..cfce562: + Submodule sm1 $head7..$head8: diff --git a/sm1/foo6 b/sm1/foo6 index 462398b..ac466ca 100644 --- a/sm1/foo6 @@ -629,29 +641,29 @@ test_expect_success 'modified submodule contains modified content' ' +modification +modification EOF - test_cmp expected actual + diff_cmp expected actual ' rm -rf sm1 test_expect_success 'deleted submodule' ' git diff-index -p --submodule=diff HEAD >actual && cat >expected <<-EOF && - Submodule sm1 17243c9...0000000 (submodule deleted) + Submodule sm1 $head7...0000000 (submodule deleted) EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'create second submodule' ' test_create_repo sm2 && - head7=$(add_file sm2 foo8 foo9) && + head9=$(add_file sm2 foo8 foo9) && git add sm2 ' test_expect_success 'multiple submodules' ' git diff-index -p --submodule=diff HEAD >actual && cat >expected <<-EOF && - Submodule sm1 17243c9...0000000 (submodule deleted) - Submodule sm2 0000000...a5a65c9 (new submodule) + Submodule sm1 $head7...0000000 (submodule deleted) + Submodule sm2 0000000...$head9 (new submodule) diff --git a/sm2/foo8 b/sm2/foo8 new file mode 100644 index 0000000..db9916b @@ -667,13 +679,13 @@ test_expect_success 'multiple submodules' ' @@ -0,0 +1 @@ +foo9 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'path filter' ' git diff-index -p --submodule=diff HEAD sm2 >actual && cat >expected <<-EOF && - Submodule sm2 0000000...a5a65c9 (new submodule) + Submodule sm2 0000000...$head9 (new submodule) diff --git a/sm2/foo8 b/sm2/foo8 new file mode 100644 index 0000000..db9916b @@ -689,15 +701,15 @@ test_expect_success 'path filter' ' @@ -0,0 +1 @@ +foo9 EOF - test_cmp expected actual + diff_cmp expected actual ' commit_file sm2 test_expect_success 'given commit' ' git diff-index -p --submodule=diff HEAD^ >actual && cat >expected <<-EOF && - Submodule sm1 17243c9...0000000 (submodule deleted) - Submodule sm2 0000000...a5a65c9 (new submodule) + Submodule sm1 $head7...0000000 (submodule deleted) + Submodule sm2 0000000...$head9 (new submodule) diff --git a/sm2/foo8 b/sm2/foo8 new file mode 100644 index 0000000..db9916b @@ -713,7 +725,7 @@ test_expect_success 'given commit' ' @@ -0,0 +1 @@ +foo9 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'setup .git file for sm2' ' @@ -726,8 +738,8 @@ test_expect_success 'setup .git file for sm2' ' test_expect_success 'diff --submodule=diff with .git file' ' git diff --submodule=diff HEAD^ >actual && cat >expected <<-EOF && - Submodule sm1 17243c9...0000000 (submodule deleted) - Submodule sm2 0000000...a5a65c9 (new submodule) + Submodule sm1 $head7...0000000 (submodule deleted) + Submodule sm2 0000000...$head9 (new submodule) diff --git a/sm2/foo8 b/sm2/foo8 new file mode 100644 index 0000000..db9916b @@ -743,25 +755,27 @@ test_expect_success 'diff --submodule=diff with .git file' ' @@ -0,0 +1 @@ +foo9 EOF - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'setup nested submodule' ' git submodule add -f ./sm2 && git commit -a -m "add sm2" && git -C sm2 submodule add ../sm2 nested && - git -C sm2 commit -a -m "nested sub" + git -C sm2 commit -a -m "nested sub" && + head10=$(git -C sm2 rev-parse --short --verify HEAD) ' test_expect_success 'move nested submodule HEAD' ' echo "nested content" >sm2/nested/file && git -C sm2/nested add file && - git -C sm2/nested commit --allow-empty -m "new HEAD" + git -C sm2/nested commit --allow-empty -m "new HEAD" && + head11=$(git -C sm2/nested rev-parse --short --verify HEAD) ' test_expect_success 'diff --submodule=diff with moved nested submodule HEAD' ' cat >expected <<-EOF && - Submodule nested a5a65c9..b55928c: + Submodule nested $head9..$head11: diff --git a/nested/file b/nested/file new file mode 100644 index 0000000..ca281f5 @@ -772,13 +786,13 @@ test_expect_success 'diff --submodule=diff with moved nested submodule HEAD' ' EOF git -C sm2 diff --submodule=diff >actual 2>err && test_must_be_empty err && - test_cmp expected actual + diff_cmp expected actual ' test_expect_success 'diff --submodule=diff recurses into nested submodules' ' cat >expected <<-EOF && Submodule sm2 contains modified content - Submodule sm2 a5a65c9..280969a: + Submodule sm2 $head9..$head10: diff --git a/sm2/.gitmodules b/sm2/.gitmodules new file mode 100644 index 0000000..3a816b8 @@ -788,7 +802,7 @@ test_expect_success 'diff --submodule=diff recurses into nested submodules' ' +[submodule "nested"] + path = nested + url = ../sm2 - Submodule nested 0000000...b55928c (new submodule) + Submodule nested 0000000...$head11 (new submodule) diff --git a/sm2/nested/file b/sm2/nested/file new file mode 100644 index 0000000..ca281f5 @@ -813,7 +827,7 @@ test_expect_success 'diff --submodule=diff recurses into nested submodules' ' EOF git diff --submodule=diff >actual 2>err && test_must_be_empty err && - test_cmp expected actual + diff_cmp expected actual ' test_done diff --git a/t/t4066-diff-emit-delay.sh b/t/t4066-diff-emit-delay.sh index 5df6b5e64e..6331f63b12 100755 --- a/t/t4066-diff-emit-delay.sh +++ b/t/t4066-diff-emit-delay.sh @@ -18,7 +18,7 @@ test_expect_success 'set up history with a merge' ' ' test_expect_success 'log --cc -p --stat --color-moved' ' - cat >expect <<-\EOF && + cat >expect <<-EOF && commit D --- D.t | 1 + @@ -26,7 +26,7 @@ test_expect_success 'log --cc -p --stat --color-moved' ' diff --git a/D.t b/D.t new file mode 100644 - index 0000000..1784810 + index 0000000..$(git rev-parse --short D:D.t) --- /dev/null +++ b/D.t @@ -0,0 +1 @@ @@ -42,7 +42,7 @@ test_expect_success 'log --cc -p --stat --color-moved' ' diff --git a/C.t b/C.t new file mode 100644 - index 0000000..3cc58df + index 0000000..$(git rev-parse --short C:C.t) --- /dev/null +++ b/C.t @@ -0,0 +1 @@ @@ -54,7 +54,7 @@ test_expect_success 'log --cc -p --stat --color-moved' ' diff --git a/B.t b/B.t new file mode 100644 - index 0000000..223b783 + index 0000000..$(git rev-parse --short B:B.t) --- /dev/null +++ b/B.t @@ -0,0 +1 @@ @@ -66,7 +66,7 @@ test_expect_success 'log --cc -p --stat --color-moved' ' diff --git a/A.t b/A.t new file mode 100644 - index 0000000..f70f10e + index 0000000..$(git rev-parse --short A:A.t) --- /dev/null +++ b/A.t @@ -0,0 +1 @@ diff --git a/t/t4100/t-apply-1.patch b/t/t4100/t-apply-1.patch index 90ab54f0f5..43394f8285 100644 --- a/t/t4100/t-apply-1.patch +++ b/t/t4100/t-apply-1.patch @@ -75,8 +75,8 @@ diff --git a/Documentation/git.txt b/Documentation/git.txt +link:git-ssh-pull.html[git-ssh-pull]:: Pulls from a remote repository over ssh connection - Interogators: -@@ -156,8 +156,8 @@ Interogators: + Interrogators: +@@ -156,8 +156,8 @@ Interrogators: link:git-diff-helper.html[git-diff-helper]:: Generates patch format output for git-diff-* diff --git a/t/t4100/t-apply-3.patch b/t/t4100/t-apply-3.patch index 90cdbaa5bb..cac172e779 100644 --- a/t/t4100/t-apply-3.patch +++ b/t/t4100/t-apply-3.patch @@ -211,7 +211,7 @@ dissimilarity index 82% - - /* If this is an exact directory match, we may have - * directory files following this path. Match on them. -- * Otherwise, we're at a pach subcomponent, and we need +- * Otherwise, we're at a patch subcomponent, and we need - * to try to match again. - */ - if (mtype == 0) diff --git a/t/t4100/t-apply-5.patch b/t/t4100/t-apply-5.patch index 5f6ddc1059..57ec79d887 100644 --- a/t/t4100/t-apply-5.patch +++ b/t/t4100/t-apply-5.patch @@ -185,8 +185,8 @@ diff a/Documentation/git.txt b/Documentation/git.txt +link:git-ssh-pull.html[git-ssh-pull]:: Pulls from a remote repository over ssh connection - Interogators: -@@ -156,8 +156,8 @@ Interogators: + Interrogators: +@@ -156,8 +156,8 @@ Interrogators: link:git-diff-helper.html[git-diff-helper]:: Generates patch format output for git-diff-* diff --git a/t/t4100/t-apply-7.patch b/t/t4100/t-apply-7.patch index 07c6589e74..fa24305108 100644 --- a/t/t4100/t-apply-7.patch +++ b/t/t4100/t-apply-7.patch @@ -335,7 +335,7 @@ diff a/ls-tree.c b/ls-tree.c - /* If this is an exact directory match, we may have - * directory files following this path. Match on them. -- * Otherwise, we're at a pach subcomponent, and we need +- * Otherwise, we're at a patch subcomponent, and we need - * to try to match again. + if (e->directory) { + /* If this is a directory, we have the following cases: diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh index ff51e9e789..971a5a7512 100755 --- a/t/t4124-apply-ws-rule.sh +++ b/t/t4124-apply-ws-rule.sh @@ -35,9 +35,15 @@ prepare_test_file () { } apply_patch () { + cmd_prefix= && + if test "x$1" = 'x!' + then + cmd_prefix=test_must_fail && + shift + fi && >target && sed -e "s|\([ab]\)/file|\1/target|" <patch | - git apply "$@" + $cmd_prefix git apply "$@" } test_fix () { @@ -99,7 +105,7 @@ test_expect_success 'whitespace=warn, default rule' ' test_expect_success 'whitespace=error-all, default rule' ' - test_must_fail apply_patch --whitespace=error-all && + apply_patch ! --whitespace=error-all && test_must_be_empty target ' diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh index 0043930ca6..99ed4cc546 100755 --- a/t/t4134-apply-submodule.sh +++ b/t/t4134-apply-submodule.sh @@ -8,6 +8,7 @@ test_description='git apply submodule tests' . ./test-lib.sh test_expect_success setup ' + test_oid_init && cat > create-sm.patch <<EOF && diff --git a/dir/sm b/dir/sm new file mode 160000 @@ -15,7 +16,7 @@ index 0000000..0123456 --- /dev/null +++ b/dir/sm @@ -0,0 +1 @@ -+Subproject commit 0123456789abcdef0123456789abcdef01234567 ++Subproject commit $(test_oid numeric) EOF cat > remove-sm.patch <<EOF diff --git a/dir/sm b/dir/sm @@ -24,7 +25,7 @@ index 0123456..0000000 --- a/dir/sm +++ /dev/null @@ -1 +0,0 @@ --Subproject commit 0123456789abcdef0123456789abcdef01234567 +-Subproject commit $(test_oid numeric) EOF ' diff --git a/t/t4138-apply-ws-expansion.sh b/t/t4138-apply-ws-expansion.sh index 3b636a63a3..b19faeb67a 100755 --- a/t/t4138-apply-ws-expansion.sh +++ b/t/t4138-apply-ws-expansion.sh @@ -17,8 +17,8 @@ test_expect_success setup ' printf "\t%s\n" 1 2 3 >after && printf "%64s\n" a b c >>after && printf "\t%s\n" 4 5 6 >>after && - git diff --no-index before after | - sed -e "s/before/test-1/" -e "s/after/test-1/" >patch1.patch && + test_expect_code 1 git diff --no-index before after >patch1.patch.raw && + sed -e "s/before/test-1/" -e "s/after/test-1/" patch1.patch.raw >patch1.patch && printf "%64s\n" 1 2 3 4 5 6 >test-1 && printf "%64s\n" 1 2 3 a b c 4 5 6 >expect-1 && @@ -33,8 +33,8 @@ test_expect_success setup ' x=$(( $x + 1 )) done && printf "\t%s\n" d e f >>after && - git diff --no-index before after | - sed -e "s/before/test-2/" -e "s/after/test-2/" >patch2.patch && + test_expect_code 1 git diff --no-index before after >patch2.patch.raw && + sed -e "s/before/test-2/" -e "s/after/test-2/" patch2.patch.raw >patch2.patch && printf "%64s\n" a b c d e f >test-2 && printf "%64s\n" a b c >expect-2 && x=1 && @@ -56,8 +56,8 @@ test_expect_success setup ' x=$(( $x + 1 )) done && printf "\t%s\n" d e f >>after && - git diff --no-index before after | - sed -e "s/before/test-3/" -e "s/after/test-3/" >patch3.patch && + test_expect_code 1 git diff --no-index before after >patch3.patch.raw && + sed -e "s/before/test-3/" -e "s/after/test-3/" patch3.patch.raw >patch3.patch && printf "%64s\n" a b c d e f >test-3 && printf "%64s\n" a b c >expect-3 && x=0 && @@ -84,8 +84,8 @@ test_expect_success setup ' printf "\t%02d\n" $x >>after x=$(( $x + 1 )) done && - git diff --no-index before after | - sed -e "s/before/test-4/" -e "s/after/test-4/" >patch4.patch && + test_expect_code 1 git diff --no-index before after >patch4.patch.raw && + sed -e "s/before/test-4/" -e "s/after/test-4/" patch4.patch.raw >patch4.patch && >test-4 && x=0 && while test $x -lt 50 diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index 55b7750ade..831d424c47 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -25,6 +25,7 @@ test_description='git rerere . ./test-lib.sh test_expect_success 'setup' ' + test_oid_init && cat >a1 <<-\EOF && Some title ========== @@ -210,7 +211,7 @@ test_expect_success 'set up for garbage collection tests' ' echo Hello >$rr/preimage && echo World >$rr/postimage && - sha2=4000000000000000000000000000000000000000 && + sha2=$(test_oid deadbeef) && rr2=.git/rr-cache/$sha2 && mkdir $rr2 && echo Hello >$rr2/preimage && diff --git a/t/t4202-log.sh b/t/t4202-log.sh index e803ba402e..192347a3e1 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -87,12 +87,12 @@ test_expect_success 'format %w(,1,2)' ' ' cat > expect << EOF -804a787 sixth -394ef78 fifth -5d31159 fourth -2fbe8c0 third -f7dab8e second -3a2fdcb initial +$(git rev-parse --short :/sixth ) sixth +$(git rev-parse --short :/fifth ) fifth +$(git rev-parse --short :/fourth ) fourth +$(git rev-parse --short :/third ) third +$(git rev-parse --short :/second ) second +$(git rev-parse --short :/initial) initial EOF test_expect_success 'oneline' ' @@ -173,43 +173,45 @@ test_expect_success 'git config log.follow is overridden by --no-follow' ' verbose test "$actual" = "$expect" ' +# Note that these commits are intentionally listed out of order. +last_three="$(git rev-parse :/fourth :/sixth :/fifth)" cat > expect << EOF -804a787 sixth -394ef78 fifth -5d31159 fourth +$(git rev-parse --short :/sixth ) sixth +$(git rev-parse --short :/fifth ) fifth +$(git rev-parse --short :/fourth) fourth EOF test_expect_success 'git log --no-walk <commits> sorts by commit time' ' - git log --no-walk --oneline 5d31159 804a787 394ef78 > actual && + git log --no-walk --oneline $last_three > actual && test_cmp expect actual ' test_expect_success 'git log --no-walk=sorted <commits> sorts by commit time' ' - git log --no-walk=sorted --oneline 5d31159 804a787 394ef78 > actual && + git log --no-walk=sorted --oneline $last_three > actual && test_cmp expect actual ' cat > expect << EOF -=== 804a787 sixth -=== 394ef78 fifth -=== 5d31159 fourth +=== $(git rev-parse --short :/sixth ) sixth +=== $(git rev-parse --short :/fifth ) fifth +=== $(git rev-parse --short :/fourth) fourth EOF test_expect_success 'git log --line-prefix="=== " --no-walk <commits> sorts by commit time' ' - git log --line-prefix="=== " --no-walk --oneline 5d31159 804a787 394ef78 > actual && + git log --line-prefix="=== " --no-walk --oneline $last_three > actual && test_cmp expect actual ' cat > expect << EOF -5d31159 fourth -804a787 sixth -394ef78 fifth +$(git rev-parse --short :/fourth) fourth +$(git rev-parse --short :/sixth ) sixth +$(git rev-parse --short :/fifth ) fifth EOF test_expect_success 'git log --no-walk=unsorted <commits> leaves list of commits as given' ' - git log --no-walk=unsorted --oneline 5d31159 804a787 394ef78 > actual && + git log --no-walk=unsorted --oneline $last_three > actual && test_cmp expect actual ' test_expect_success 'git show <commits> leaves list of commits as given' ' - git show --oneline -s 5d31159 804a787 394ef78 > actual && + git show --oneline -s $last_three > actual && test_cmp expect actual ' @@ -667,7 +669,7 @@ cat > expect <<\EOF * | | fifth * | | fourth |/ / -* | third +* / third |/ * second * initial @@ -957,7 +959,7 @@ cat >expect <<\EOF | | | | diff --git a/reach.t b/reach.t | | new file mode 100644 -| | index 0000000..10c9591 +| | index BEFORE..AFTER | | --- /dev/null | | +++ b/reach.t | | @@ -0,0 +1 @@ @@ -980,7 +982,7 @@ cat >expect <<\EOF | | | | | | diff --git a/octopus-b.t b/octopus-b.t | | | new file mode 100644 -| | | index 0000000..d5fcad0 +| | | index BEFORE..AFTER | | | --- /dev/null | | | +++ b/octopus-b.t | | | @@ -0,0 +1 @@ @@ -996,7 +998,7 @@ cat >expect <<\EOF | | | | diff --git a/octopus-a.t b/octopus-a.t | | new file mode 100644 -| | index 0000000..11ee015 +| | index BEFORE..AFTER | | --- /dev/null | | +++ b/octopus-a.t | | @@ -0,0 +1 @@ @@ -1012,7 +1014,7 @@ cat >expect <<\EOF | | diff --git a/seventh.t b/seventh.t | new file mode 100644 -| index 0000000..9744ffc +| index BEFORE..AFTER | --- /dev/null | +++ b/seventh.t | @@ -0,0 +1 @@ @@ -1046,7 +1048,7 @@ cat >expect <<\EOF | | | | | | | | diff --git a/tangle-a b/tangle-a | | | | new file mode 100644 -| | | | index 0000000..7898192 +| | | | index BEFORE..AFTER | | | | --- /dev/null | | | | +++ b/tangle-a | | | | @@ -0,0 +1 @@ @@ -1068,7 +1070,7 @@ cat >expect <<\EOF | | | | | | | | diff --git a/2 b/2 | | | | new file mode 100644 -| | | | index 0000000..0cfbf08 +| | | | index BEFORE..AFTER | | | | --- /dev/null | | | | +++ b/2 | | | | @@ -0,0 +1 @@ @@ -1084,7 +1086,7 @@ cat >expect <<\EOF | | | | | | | | diff --git a/1 b/1 | | | | new file mode 100644 -| | | | index 0000000..d00491f +| | | | index BEFORE..AFTER | | | | --- /dev/null | | | | +++ b/1 | | | | @@ -0,0 +1 @@ @@ -1100,7 +1102,7 @@ cat >expect <<\EOF | | | | | | | | diff --git a/one b/one | | | | new file mode 100644 -| | | | index 0000000..9a33383 +| | | | index BEFORE..AFTER | | | | --- /dev/null | | | | +++ b/one | | | | @@ -0,0 +1 @@ @@ -1116,7 +1118,7 @@ cat >expect <<\EOF | | | | | | diff --git a/a/two b/a/two | | | deleted file mode 100644 -| | | index 9245af5..0000000 +| | | index BEFORE..AFTER | | | --- a/a/two | | | +++ /dev/null | | | @@ -1 +0,0 @@ @@ -1132,7 +1134,7 @@ cat >expect <<\EOF | | | | | | diff --git a/a/two b/a/two | | | new file mode 100644 -| | | index 0000000..9245af5 +| | | index BEFORE..AFTER | | | --- /dev/null | | | +++ b/a/two | | | @@ -0,0 +1 @@ @@ -1148,7 +1150,7 @@ cat >expect <<\EOF | | | | diff --git a/ein b/ein | | new file mode 100644 -| | index 0000000..9d7e69f +| | index BEFORE..AFTER | | --- /dev/null | | +++ b/ein | | @@ -0,0 +1 @@ @@ -1165,14 +1167,14 @@ cat >expect <<\EOF | | diff --git a/ichi b/ichi | new file mode 100644 -| index 0000000..9d7e69f +| index BEFORE..AFTER | --- /dev/null | +++ b/ichi | @@ -0,0 +1 @@ | +ichi | diff --git a/one b/one | deleted file mode 100644 -| index 9d7e69f..0000000 +| index BEFORE..AFTER | --- a/one | +++ /dev/null | @@ -1 +0,0 @@ @@ -1187,7 +1189,7 @@ cat >expect <<\EOF | 1 file changed, 1 insertion(+), 1 deletion(-) | | diff --git a/one b/one -| index 5626abf..9d7e69f 100644 +| index BEFORE..AFTER 100644 | --- a/one | +++ b/one | @@ -1 +1 @@ @@ -1204,7 +1206,7 @@ cat >expect <<\EOF diff --git a/one b/one new file mode 100644 - index 0000000..5626abf + index BEFORE..AFTER --- /dev/null +++ b/one @@ -0,0 +1 @@ @@ -1221,7 +1223,8 @@ sanitize_output () { -e 's/, 0 insertions(+)//' \ -e 's/ 1 files changed, / 1 file changed, /' \ -e 's/, 1 deletions(-)/, 1 deletion(-)/' \ - -e 's/, 1 insertions(+)/, 1 insertion(+)/' + -e 's/, 1 insertions(+)/, 1 insertion(+)/' \ + -e 's/index [0-9a-f]*\.\.[0-9a-f]*/index BEFORE..AFTER/' } test_expect_success 'log --graph with diff and stats' ' @@ -1247,7 +1250,7 @@ cat >expect <<\EOF *** | | *** | | diff --git a/reach.t b/reach.t *** | | new file mode 100644 -*** | | index 0000000..10c9591 +*** | | index BEFORE..AFTER *** | | --- /dev/null *** | | +++ b/reach.t *** | | @@ -0,0 +1 @@ @@ -1270,7 +1273,7 @@ cat >expect <<\EOF *** | | | *** | | | diff --git a/octopus-b.t b/octopus-b.t *** | | | new file mode 100644 -*** | | | index 0000000..d5fcad0 +*** | | | index BEFORE..AFTER *** | | | --- /dev/null *** | | | +++ b/octopus-b.t *** | | | @@ -0,0 +1 @@ @@ -1286,7 +1289,7 @@ cat >expect <<\EOF *** | | *** | | diff --git a/octopus-a.t b/octopus-a.t *** | | new file mode 100644 -*** | | index 0000000..11ee015 +*** | | index BEFORE..AFTER *** | | --- /dev/null *** | | +++ b/octopus-a.t *** | | @@ -0,0 +1 @@ @@ -1302,7 +1305,7 @@ cat >expect <<\EOF *** | *** | diff --git a/seventh.t b/seventh.t *** | new file mode 100644 -*** | index 0000000..9744ffc +*** | index BEFORE..AFTER *** | --- /dev/null *** | +++ b/seventh.t *** | @@ -0,0 +1 @@ @@ -1336,7 +1339,7 @@ cat >expect <<\EOF *** | | | | *** | | | | diff --git a/tangle-a b/tangle-a *** | | | | new file mode 100644 -*** | | | | index 0000000..7898192 +*** | | | | index BEFORE..AFTER *** | | | | --- /dev/null *** | | | | +++ b/tangle-a *** | | | | @@ -0,0 +1 @@ @@ -1358,7 +1361,7 @@ cat >expect <<\EOF *** | | | | *** | | | | diff --git a/2 b/2 *** | | | | new file mode 100644 -*** | | | | index 0000000..0cfbf08 +*** | | | | index BEFORE..AFTER *** | | | | --- /dev/null *** | | | | +++ b/2 *** | | | | @@ -0,0 +1 @@ @@ -1374,7 +1377,7 @@ cat >expect <<\EOF *** | | | | *** | | | | diff --git a/1 b/1 *** | | | | new file mode 100644 -*** | | | | index 0000000..d00491f +*** | | | | index BEFORE..AFTER *** | | | | --- /dev/null *** | | | | +++ b/1 *** | | | | @@ -0,0 +1 @@ @@ -1390,7 +1393,7 @@ cat >expect <<\EOF *** | | | | *** | | | | diff --git a/one b/one *** | | | | new file mode 100644 -*** | | | | index 0000000..9a33383 +*** | | | | index BEFORE..AFTER *** | | | | --- /dev/null *** | | | | +++ b/one *** | | | | @@ -0,0 +1 @@ @@ -1406,7 +1409,7 @@ cat >expect <<\EOF *** | | | *** | | | diff --git a/a/two b/a/two *** | | | deleted file mode 100644 -*** | | | index 9245af5..0000000 +*** | | | index BEFORE..AFTER *** | | | --- a/a/two *** | | | +++ /dev/null *** | | | @@ -1 +0,0 @@ @@ -1422,7 +1425,7 @@ cat >expect <<\EOF *** | | | *** | | | diff --git a/a/two b/a/two *** | | | new file mode 100644 -*** | | | index 0000000..9245af5 +*** | | | index BEFORE..AFTER *** | | | --- /dev/null *** | | | +++ b/a/two *** | | | @@ -0,0 +1 @@ @@ -1438,7 +1441,7 @@ cat >expect <<\EOF *** | | *** | | diff --git a/ein b/ein *** | | new file mode 100644 -*** | | index 0000000..9d7e69f +*** | | index BEFORE..AFTER *** | | --- /dev/null *** | | +++ b/ein *** | | @@ -0,0 +1 @@ @@ -1455,14 +1458,14 @@ cat >expect <<\EOF *** | *** | diff --git a/ichi b/ichi *** | new file mode 100644 -*** | index 0000000..9d7e69f +*** | index BEFORE..AFTER *** | --- /dev/null *** | +++ b/ichi *** | @@ -0,0 +1 @@ *** | +ichi *** | diff --git a/one b/one *** | deleted file mode 100644 -*** | index 9d7e69f..0000000 +*** | index BEFORE..AFTER *** | --- a/one *** | +++ /dev/null *** | @@ -1 +0,0 @@ @@ -1477,7 +1480,7 @@ cat >expect <<\EOF *** | 1 file changed, 1 insertion(+), 1 deletion(-) *** | *** | diff --git a/one b/one -*** | index 5626abf..9d7e69f 100644 +*** | index BEFORE..AFTER 100644 *** | --- a/one *** | +++ b/one *** | @@ -1 +1 @@ @@ -1494,7 +1497,7 @@ cat >expect <<\EOF *** *** diff --git a/one b/one *** new file mode 100644 -*** index 0000000..5626abf +*** index BEFORE..AFTER *** --- /dev/null *** +++ b/one *** @@ -0,0 +1 @@ @@ -1570,6 +1573,14 @@ test_expect_success GPG 'setup signed branch' ' git commit -S -m signed_commit ' +test_expect_success GPG 'setup signed branch with subkey' ' + test_when_finished "git reset --hard && git checkout master" && + git checkout -b signed-subkey master && + echo foo >foo && + git add foo && + git commit -SB7227189 -m signed_commit +' + test_expect_success GPGSM 'setup signed branch x509' ' test_when_finished "git reset --hard && git checkout master" && git checkout -b signed-x509 master && @@ -1580,6 +1591,18 @@ test_expect_success GPGSM 'setup signed branch x509' ' git commit -S -m signed_commit ' +test_expect_success GPGSM 'log x509 fingerprint' ' + echo "F8BF62E0693D0694816377099909C779FA23FD65 | " >expect && + git log -n1 --format="%GF | %GP" signed-x509 >actual && + test_cmp expect actual +' + +test_expect_success GPGSM 'log OpenPGP fingerprint' ' + echo "D4BE22311AD3131E5EDA29A461092E85B7227189" > expect && + git log -n1 --format="%GP" signed-subkey >actual && + test_cmp expect actual +' + test_expect_success GPG 'log --graph --show-signature' ' git log --graph --show-signature -n1 signed >actual && grep "^| gpg: Signature made" actual && @@ -1689,10 +1712,10 @@ test_expect_success 'set up --source tests' ' ' test_expect_success 'log --source paints branch names' ' - cat >expect <<-\EOF && - 09e12a9 source-b three - 8e393e1 source-a two - 1ac6c77 source-b one + cat >expect <<-EOF && + $(git rev-parse --short :/three) source-b three + $(git rev-parse --short :/two ) source-a two + $(git rev-parse --short :/one ) source-b one EOF git log --oneline --source source-a source-b >actual && test_cmp expect actual @@ -1700,19 +1723,19 @@ test_expect_success 'log --source paints branch names' ' test_expect_success 'log --source paints tag names' ' git tag -m tagged source-tag && - cat >expect <<-\EOF && - 09e12a9 source-tag three - 8e393e1 source-a two - 1ac6c77 source-tag one + cat >expect <<-EOF && + $(git rev-parse --short :/three) source-tag three + $(git rev-parse --short :/two ) source-a two + $(git rev-parse --short :/one ) source-tag one EOF git log --oneline --source source-tag source-a >actual && test_cmp expect actual ' test_expect_success 'log --source paints symmetric ranges' ' - cat >expect <<-\EOF && - 09e12a9 source-b three - 8e393e1 source-a two + cat >expect <<-EOF && + $(git rev-parse --short :/three) source-b three + $(git rev-parse --short :/two ) source-a two EOF git log --oneline --source source-a...source-b >actual && test_cmp expect actual diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh index 0288c17ec6..8ff8bd84c7 100755 --- a/t/t4204-patch-id.sh +++ b/t/t4204-patch-id.sh @@ -25,7 +25,7 @@ test_expect_success 'setup' ' test_expect_success 'patch-id output is well-formed' ' git log -p -1 | git patch-id >output && - grep "^[a-f0-9]\{40\} $(git rev-parse HEAD)$" output + grep "^$OID_REGEX $(git rev-parse HEAD)$" output ' #calculate patch id. Make sure output is not empty. diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index f42a69faa2..204c149d5a 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -134,6 +134,36 @@ test_expect_failure C_LOCALE_OUTPUT 'NUL termination with --stat' ' test_cmp expected actual ' +for p in short medium full fuller email raw +do + test_expect_success "NUL termination with --reflog --pretty=$p" ' + revs="$(git rev-list --reflog)" && + for r in $revs + do + git show -s "$r" --pretty="$p" && + printf "\0" || return 1 + done >expect && + { + git log -z --reflog --pretty="$p" && + printf "\0" + } >actual && + test_cmp expect actual + ' +done + +test_expect_success 'NUL termination with --reflog --pretty=oneline' ' + revs="$(git rev-list --reflog)" && + for r in $revs + do + git show -s --pretty=oneline "$r" >raw && + cat raw | lf_to_nul || exit 1 + done >expect && + # the trailing NUL is already produced so we do not need to + # output another one + git log -z --pretty=oneline --reflog >actual && + test_cmp expect actual +' + test_expect_success 'setup more commits' ' test_commit "message one" one one message-one && test_commit "message two" two two message-two && @@ -503,6 +533,12 @@ test_expect_success 'ISO and ISO-strict date formats display the same values' ' test_cmp expected actual ' +test_expect_success 'short date' ' + git log --format=%ad%n%cd --date=short >expected && + git log --format=%as%n%cs >actual && + test_cmp expected actual +' + # get new digests (with no abbreviations) test_expect_success 'set up log decoration tests' ' head1=$(git rev-parse --verify HEAD~0) && @@ -640,7 +676,7 @@ test_expect_success 'pretty format %(trailers:key=foo) multiple keys' ' test_cmp expect actual ' -test_expect_success '%(trailers:key=nonexistant) becomes empty' ' +test_expect_success '%(trailers:key=nonexistent) becomes empty' ' git log --no-walk --pretty="x%(trailers:key=Nacked-by)x" >actual && echo "xx" >expect && test_cmp expect actual @@ -788,4 +824,47 @@ test_expect_success '%S in git log --format works with other placeholders (part test_cmp expect actual ' +test_expect_success 'log --pretty=reference' ' + git log --pretty="tformat:%h (%s, %as)" >expect && + git log --pretty=reference >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty=reference with log.date is overridden by short date' ' + git log --pretty="tformat:%h (%s, %as)" >expect && + test_config log.date rfc && + git log --pretty=reference >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty=reference with explicit date overrides short date' ' + git log --date=rfc --pretty="tformat:%h (%s, %ad)" >expect && + git log --date=rfc --pretty=reference >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty=reference is never unabbreviated' ' + git log --pretty="tformat:%h (%s, %as)" >expect && + git log --no-abbrev-commit --pretty=reference >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty=reference is never decorated' ' + git log --pretty="tformat:%h (%s, %as)" >expect && + git log --decorate=short --pretty=reference >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty=reference does not output reflog info' ' + git log --walk-reflogs --pretty="tformat:%h (%s, %as)" >expect && + git log --walk-reflogs --pretty=reference >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty=reference is colored appropriately' ' + git log --color=always --pretty="tformat:%C(auto)%h (%s, %as)" >expect && + git log --color=always --pretty=reference >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index 6e61f57f09..c3792081e6 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -70,7 +70,7 @@ do then force_regex=.* fi - test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " + test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not find non-reencoded values (latin1 + locale)" " cat >expect <<-\EOF && latin1 utf8 @@ -84,7 +84,7 @@ do test_must_be_empty actual " - test_expect_success !MINGW,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" " + test_expect_success !MINGW,!REGEX_ILLSEQ,GETTEXT_LOCALE,$prereq "-c grep.patternType=$engine log --grep does not die on invalid UTF-8 value (latin1 + locale + invalid needle)" " LC_ALL=\"$is_IS_locale\" git -c grep.patternType=$engine log --encoding=ISO-8859-1 --format=%s --grep=\"$force_regex$invalid_e\" >actual && test_must_be_empty actual " diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index 8319163744..cda58186c2 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -4,6 +4,7 @@ test_description='test log -L' . ./test-lib.sh test_expect_success 'setup (import history)' ' + test_oid_init && git fast-import < "$TEST_DIRECTORY"/t4211/history.export && git reset --hard ' @@ -11,7 +12,7 @@ test_expect_success 'setup (import history)' ' canned_test_1 () { test_expect_$1 "$2" " git log $2 >actual && - test_cmp \"\$TEST_DIRECTORY\"/t4211/expect.$3 actual + test_cmp \"\$TEST_DIRECTORY\"/t4211/$(test_oid algo)/expect.$3 actual " } diff --git a/t/t4211/expect.beginning-of-file b/t/t4211/sha1/expect.beginning-of-file index 91b4054898..91b4054898 100644 --- a/t/t4211/expect.beginning-of-file +++ b/t/t4211/sha1/expect.beginning-of-file diff --git a/t/t4211/expect.end-of-file b/t/t4211/sha1/expect.end-of-file index bd25bb2f59..bd25bb2f59 100644 --- a/t/t4211/expect.end-of-file +++ b/t/t4211/sha1/expect.end-of-file diff --git a/t/t4211/expect.move-support-f b/t/t4211/sha1/expect.move-support-f index c905e01bc2..c905e01bc2 100644 --- a/t/t4211/expect.move-support-f +++ b/t/t4211/sha1/expect.move-support-f diff --git a/t/t4211/expect.multiple b/t/t4211/sha1/expect.multiple index 76ad5b598c..76ad5b598c 100644 --- a/t/t4211/expect.multiple +++ b/t/t4211/sha1/expect.multiple diff --git a/t/t4211/expect.multiple-overlapping b/t/t4211/sha1/expect.multiple-overlapping index d930b6eec4..d930b6eec4 100644 --- a/t/t4211/expect.multiple-overlapping +++ b/t/t4211/sha1/expect.multiple-overlapping diff --git a/t/t4211/expect.multiple-superset b/t/t4211/sha1/expect.multiple-superset index d930b6eec4..d930b6eec4 100644 --- a/t/t4211/expect.multiple-superset +++ b/t/t4211/sha1/expect.multiple-superset diff --git a/t/t4211/expect.parallel-change-f-to-main b/t/t4211/sha1/expect.parallel-change-f-to-main index 052def8074..052def8074 100644 --- a/t/t4211/expect.parallel-change-f-to-main +++ b/t/t4211/sha1/expect.parallel-change-f-to-main diff --git a/t/t4211/expect.simple-f b/t/t4211/sha1/expect.simple-f index a1f5bc49c8..a1f5bc49c8 100644 --- a/t/t4211/expect.simple-f +++ b/t/t4211/sha1/expect.simple-f diff --git a/t/t4211/expect.simple-f-to-main b/t/t4211/sha1/expect.simple-f-to-main index a475768710..a475768710 100644 --- a/t/t4211/expect.simple-f-to-main +++ b/t/t4211/sha1/expect.simple-f-to-main diff --git a/t/t4211/expect.simple-main b/t/t4211/sha1/expect.simple-main index 39ce39bebe..39ce39bebe 100644 --- a/t/t4211/expect.simple-main +++ b/t/t4211/sha1/expect.simple-main diff --git a/t/t4211/expect.simple-main-to-end b/t/t4211/sha1/expect.simple-main-to-end index 8480bd9cc4..8480bd9cc4 100644 --- a/t/t4211/expect.simple-main-to-end +++ b/t/t4211/sha1/expect.simple-main-to-end diff --git a/t/t4211/expect.two-ranges b/t/t4211/sha1/expect.two-ranges index 6109aa0dce..6109aa0dce 100644 --- a/t/t4211/expect.two-ranges +++ b/t/t4211/sha1/expect.two-ranges diff --git a/t/t4211/expect.vanishes-early b/t/t4211/sha1/expect.vanishes-early index 1f7cd06941..1f7cd06941 100644 --- a/t/t4211/expect.vanishes-early +++ b/t/t4211/sha1/expect.vanishes-early diff --git a/t/t4211/sha256/expect.beginning-of-file b/t/t4211/sha256/expect.beginning-of-file new file mode 100644 index 0000000000..5adfdfc1a1 --- /dev/null +++ b/t/t4211/sha256/expect.beginning-of-file @@ -0,0 +1,43 @@ +commit 62a40b38fa4f00800004aee81ef287b7201317594ebcb990f38cbe493b01d200 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:47:40 2013 +0100 + + change at very beginning + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -1,3 +1,4 @@ ++#include <unistd.h> + #include <stdio.h> + + long f(long x) + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -1,3 +1,3 @@ + #include <stdio.h> + +-int f(int x) ++long f(long x) + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +1,3 @@ ++#include <stdio.h> ++ ++int f(int x) diff --git a/t/t4211/sha256/expect.end-of-file b/t/t4211/sha256/expect.end-of-file new file mode 100644 index 0000000000..03ab5c1784 --- /dev/null +++ b/t/t4211/sha256/expect.end-of-file @@ -0,0 +1,62 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -20,3 +20,5 @@ + printf("%ld\n", f(15)); + return 0; +-} +\ No newline at end of file ++} ++ ++/* incomplete lines are bad! */ + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -20,3 +20,3 @@ + printf("%ld\n", f(15)); + return 0; +-} ++} +\ No newline at end of file + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -19,3 +19,3 @@ +- printf("%d\n", f(15)); ++ printf("%ld\n", f(15)); + return 0; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +18,3 @@ ++ printf("%d\n", f(15)); ++ return 0; ++} diff --git a/t/t4211/sha256/expect.move-support-f b/t/t4211/sha256/expect.move-support-f new file mode 100644 index 0000000000..223b4ed2a0 --- /dev/null +++ b/t/t4211/sha256/expect.move-support-f @@ -0,0 +1,80 @@ +commit 4f7a58195a92c400e28a2354328587f1ff14fb77f5cf894536f17ccbc72931b9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:49:50 2013 +0100 + + another simple change + +diff --git a/b.c b/b.c +--- a/b.c ++++ b/b.c +@@ -4,9 +4,9 @@ + long f(long x) + { + int s = 0; + while (x) { +- x >>= 1; ++ x /= 2; + s++; + } + return s; + } + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,9 +3,9 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,8 +3,9 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,8 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} diff --git a/t/t4211/sha256/expect.multiple b/t/t4211/sha256/expect.multiple new file mode 100644 index 0000000000..ca00409b9a --- /dev/null +++ b/t/t4211/sha256/expect.multiple @@ -0,0 +1,104 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,7 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} +\ No newline at end of file ++} ++ ++/* incomplete lines are bad! */ + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,5 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} ++} +\ No newline at end of file + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,9 +3,9 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } +@@ -17,5 +17,5 @@ + int main () + { +- printf("%d\n", f(15)); ++ printf("%ld\n", f(15)); + return 0; + } + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,8 +3,9 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,8 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} diff --git a/t/t4211/sha256/expect.multiple-overlapping b/t/t4211/sha256/expect.multiple-overlapping new file mode 100644 index 0000000000..9015a45a25 --- /dev/null +++ b/t/t4211/sha256/expect.multiple-overlapping @@ -0,0 +1,187 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -4,19 +4,21 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * This is only an example! + */ + + int main () + { + printf("%ld\n", f(15)); + return 0; +-} +\ No newline at end of file ++} ++ ++/* incomplete lines are bad! */ + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -4,19 +4,19 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * This is only an example! + */ + + int main () + { + printf("%ld\n", f(15)); + return 0; +-} ++} +\ No newline at end of file + +commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:41 2013 +0100 + + touch comment + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,19 +3,19 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* +- * A comment. ++ * This is only an example! + */ + + int main () + { + printf("%ld\n", f(15)); + return 0; + } + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,19 +3,19 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * A comment. + */ + + int main () + { +- printf("%d\n", f(15)); ++ printf("%ld\n", f(15)); + return 0; + } + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,18 +3,19 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + + /* + * A comment. + */ + + int main () + { + printf("%d\n", f(15)); + return 0; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,18 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} ++ ++/* ++ * A comment. ++ */ ++ ++int main () ++{ ++ printf("%d\n", f(15)); ++ return 0; ++} diff --git a/t/t4211/sha256/expect.multiple-superset b/t/t4211/sha256/expect.multiple-superset new file mode 100644 index 0000000000..9015a45a25 --- /dev/null +++ b/t/t4211/sha256/expect.multiple-superset @@ -0,0 +1,187 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -4,19 +4,21 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * This is only an example! + */ + + int main () + { + printf("%ld\n", f(15)); + return 0; +-} +\ No newline at end of file ++} ++ ++/* incomplete lines are bad! */ + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -4,19 +4,19 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * This is only an example! + */ + + int main () + { + printf("%ld\n", f(15)); + return 0; +-} ++} +\ No newline at end of file + +commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:41 2013 +0100 + + touch comment + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,19 +3,19 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* +- * A comment. ++ * This is only an example! + */ + + int main () + { + printf("%ld\n", f(15)); + return 0; + } + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,19 +3,19 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * A comment. + */ + + int main () + { +- printf("%d\n", f(15)); ++ printf("%ld\n", f(15)); + return 0; + } + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,18 +3,19 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + + /* + * A comment. + */ + + int main () + { + printf("%d\n", f(15)); + return 0; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,18 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} ++ ++/* ++ * A comment. ++ */ ++ ++int main () ++{ ++ printf("%d\n", f(15)); ++ return 0; ++} diff --git a/t/t4211/sha256/expect.parallel-change-f-to-main b/t/t4211/sha256/expect.parallel-change-f-to-main new file mode 100644 index 0000000000..e68f8928ea --- /dev/null +++ b/t/t4211/sha256/expect.parallel-change-f-to-main @@ -0,0 +1,160 @@ +commit 98117c2059b76c36995748fb97b02542aef477fe26379e94c18fd70f7790bc67 +Merge: b511694 4f7a581 +Author: Thomas Rast <trast@inf.ethz.ch> +Date: Fri Apr 12 16:16:24 2013 +0200 + + Merge across the rename + + +commit 4f7a58195a92c400e28a2354328587f1ff14fb77f5cf894536f17ccbc72931b9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:49:50 2013 +0100 + + another simple change + +diff --git a/b.c b/b.c +--- a/b.c ++++ b/b.c +@@ -4,14 +4,14 @@ + long f(long x) + { + int s = 0; + while (x) { +- x >>= 1; ++ x /= 2; + s++; + } + return s; + } + + /* + * This is only an example! + */ + + +commit b511694f5337663fbd697622993a5f8e1099eca84be4df313f2b3ee94a098b42 +Author: Thomas Rast <trast@inf.ethz.ch> +Date: Fri Apr 12 16:15:57 2013 +0200 + + change on another line of history while rename happens + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -4,14 +4,14 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* +- * This is only an example! ++ * This is only a short example! + */ + + +commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:41 2013 +0100 + + touch comment + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,14 +3,14 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* +- * A comment. ++ * This is only an example! + */ + + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,14 +3,14 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * A comment. + */ + + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,13 +3,14 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + + /* + * A comment. + */ + + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,13 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} ++ ++/* ++ * A comment. ++ */ ++ diff --git a/t/t4211/sha256/expect.simple-f b/t/t4211/sha256/expect.simple-f new file mode 100644 index 0000000000..65508d7c0b --- /dev/null +++ b/t/t4211/sha256/expect.simple-f @@ -0,0 +1,59 @@ +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,9 +3,9 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,8 +3,9 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,8 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} diff --git a/t/t4211/sha256/expect.simple-f-to-main b/t/t4211/sha256/expect.simple-f-to-main new file mode 100644 index 0000000000..77b721c196 --- /dev/null +++ b/t/t4211/sha256/expect.simple-f-to-main @@ -0,0 +1,100 @@ +commit 5a1b3989063d55e71e7685efa3392f133385b4034bddde530dcb5090d8b8b8ca +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:41 2013 +0100 + + touch comment + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,14 +3,14 @@ + long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* +- * A comment. ++ * This is only an example! + */ + + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,14 +3,14 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } + + /* + * A comment. + */ + + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,13 +3,14 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + + /* + * A comment. + */ + + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,13 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} ++ ++/* ++ * A comment. ++ */ ++ diff --git a/t/t4211/sha256/expect.simple-main b/t/t4211/sha256/expect.simple-main new file mode 100644 index 0000000000..d20708c9f9 --- /dev/null +++ b/t/t4211/sha256/expect.simple-main @@ -0,0 +1,68 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,5 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} +\ No newline at end of file ++} + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,5 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} ++} +\ No newline at end of file + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -17,5 +17,5 @@ + int main () + { +- printf("%d\n", f(15)); ++ printf("%ld\n", f(15)); + return 0; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +16,5 @@ ++int main () ++{ ++ printf("%d\n", f(15)); ++ return 0; ++} diff --git a/t/t4211/sha256/expect.simple-main-to-end b/t/t4211/sha256/expect.simple-main-to-end new file mode 100644 index 0000000000..617cdf3481 --- /dev/null +++ b/t/t4211/sha256/expect.simple-main-to-end @@ -0,0 +1,70 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,7 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} +\ No newline at end of file ++} ++ ++/* incomplete lines are bad! */ + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,5 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} ++} +\ No newline at end of file + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -17,5 +17,5 @@ + int main () + { +- printf("%d\n", f(15)); ++ printf("%ld\n", f(15)); + return 0; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +16,5 @@ ++int main () ++{ ++ printf("%d\n", f(15)); ++ return 0; ++} diff --git a/t/t4211/sha256/expect.two-ranges b/t/t4211/sha256/expect.two-ranges new file mode 100644 index 0000000000..af57c8b997 --- /dev/null +++ b/t/t4211/sha256/expect.two-ranges @@ -0,0 +1,102 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,5 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} +\ No newline at end of file ++} + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -18,5 +18,5 @@ + int main () + { + printf("%ld\n", f(15)); + return 0; +-} ++} +\ No newline at end of file + +commit ccf97b9878189c40a981da50b15713bb80a35755326320ec80900caf22ced46f +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:45:16 2013 +0100 + + touch both functions + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,9 +3,9 @@ +-int f(int x) ++long f(long x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } + return s; + } +@@ -17,5 +17,5 @@ + int main () + { +- printf("%d\n", f(15)); ++ printf("%ld\n", f(15)); + return 0; + } + +commit f6434acd34260a6c9f61e96d96bf9a323d330561df5b1ca2631104f82026dfed +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:55 2013 +0100 + + change f() + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -3,8 +3,9 @@ + int f(int x) + { + int s = 0; + while (x) { + x >>= 1; + s++; + } ++ return s; + } + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +3,8 @@ ++int f(int x) ++{ ++ int s = 0; ++ while (x) { ++ x >>= 1; ++ s++; ++ } ++} diff --git a/t/t4211/sha256/expect.vanishes-early b/t/t4211/sha256/expect.vanishes-early new file mode 100644 index 0000000000..11ec9bdecf --- /dev/null +++ b/t/t4211/sha256/expect.vanishes-early @@ -0,0 +1,39 @@ +commit 5526ed05c2476b56af8b7be499e8f78bd50f490740733a9ca7e1f55878fa90a9 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:43 2013 +0100 + + change back to complete line + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -22,1 +24,1 @@ +-} +\ No newline at end of file ++/* incomplete lines are bad! */ + +commit 29f32ac3141c48b22803e5c4127b719917b67d0f8ca8c5248bebfa2a19f7da10 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:48:10 2013 +0100 + + change to an incomplete line at end + +diff --git a/a.c b/a.c +--- a/a.c ++++ b/a.c +@@ -22,1 +22,1 @@ +-} ++} +\ No newline at end of file + +commit 1dd7e9b2b1699324b53b341e728653b913bc192a14dfea168c5b51f2b3d03592 +Author: Thomas Rast <trast@student.ethz.ch> +Date: Thu Feb 28 10:44:48 2013 +0100 + + initial + +diff --git a/a.c b/a.c +--- /dev/null ++++ b/a.c +@@ -0,0 +20,1 @@ ++} diff --git a/t/t4213-log-tabexpand.sh b/t/t4213-log-tabexpand.sh index 7f90f58c03..53a4af3244 100755 --- a/t/t4213-log-tabexpand.sh +++ b/t/t4213-log-tabexpand.sh @@ -36,7 +36,7 @@ count_expand () esac # Prefix the output with the command line arguments, and - # replace SP with a dot both in the expecte and actual output + # replace SP with a dot both in the expected and actual output # so that test_cmp would show the difference together with the # breakage in a way easier to consume by the debugging user. { diff --git a/t/t4214-log-graph-octopus.sh b/t/t4214-log-graph-octopus.sh index 3ae8e51e50..40d27db674 100755 --- a/t/t4214-log-graph-octopus.sh +++ b/t/t4214-log-graph-octopus.sh @@ -26,15 +26,14 @@ test_expect_success 'set up merge history' ' test_expect_success 'log --graph with tricky octopus merge, no color' ' cat >expect.uncolored <<-\EOF && * left - | *---. octopus-merge - | |\ \ \ - |/ / / / + | *-. octopus-merge + |/|\ \ | | | * 4 | | * | 3 | | |/ - | * | 2 + | * / 2 | |/ - * | 1 + * / 1 |/ * initial EOF @@ -47,15 +46,14 @@ test_expect_success 'log --graph with tricky octopus merge with colors' ' test_config log.graphColors red,green,yellow,blue,magenta,cyan && cat >expect.colors <<-\EOF && * left - <RED>|<RESET> *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge - <RED>|<RESET> <RED>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <MAGENTA>\<RESET> - <RED>|<RESET><RED>/<RESET> <YELLOW>/<RESET> <BLUE>/<RESET> <MAGENTA>/<RESET> + <RED>|<RESET> *<MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge + <RED>|<RESET><RED>/<RESET><YELLOW>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET> <RED>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4 <RED>|<RESET> <YELLOW>|<RESET> * <MAGENTA>|<RESET> 3 <RED>|<RESET> <YELLOW>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET> - <RED>|<RESET> * <MAGENTA>|<RESET> 2 + <RED>|<RESET> * <MAGENTA>/<RESET> 2 <RED>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET> - * <MAGENTA>|<RESET> 1 + * <MAGENTA>/<RESET> 1 <MAGENTA>|<RESET><MAGENTA>/<RESET> * initial EOF @@ -74,9 +72,9 @@ test_expect_success 'log --graph with normal octopus merge, no color' ' | | | * 4 | | * | 3 | | |/ - | * | 2 + | * / 2 | |/ - * | 1 + * / 1 |/ * initial EOF @@ -92,9 +90,9 @@ test_expect_success 'log --graph with normal octopus merge with colors' ' <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 4 <RED>|<RESET> <GREEN>|<RESET> * <BLUE>|<RESET> 3 <RED>|<RESET> <GREEN>|<RESET> <BLUE>|<RESET><BLUE>/<RESET> - <RED>|<RESET> * <BLUE>|<RESET> 2 + <RED>|<RESET> * <BLUE>/<RESET> 2 <RED>|<RESET> <BLUE>|<RESET><BLUE>/<RESET> - * <BLUE>|<RESET> 1 + * <BLUE>/<RESET> 1 <BLUE>|<RESET><BLUE>/<RESET> * initial EOF @@ -112,9 +110,9 @@ test_expect_success 'log --graph with normal octopus merge and child, no color' | | | * 4 | | * | 3 | | |/ - | * | 2 + | * / 2 | |/ - * | 1 + * / 1 |/ * initial EOF @@ -123,7 +121,7 @@ test_expect_success 'log --graph with normal octopus merge and child, no color' test_cmp expect.uncolored actual ' -test_expect_failure 'log --graph with normal octopus and child merge with colors' ' +test_expect_success 'log --graph with normal octopus and child merge with colors' ' cat >expect.colors <<-\EOF && * after-merge *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge @@ -131,9 +129,9 @@ test_expect_failure 'log --graph with normal octopus and child merge with colors <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4 <GREEN>|<RESET> <YELLOW>|<RESET> * <MAGENTA>|<RESET> 3 <GREEN>|<RESET> <YELLOW>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET> - <GREEN>|<RESET> * <MAGENTA>|<RESET> 2 + <GREEN>|<RESET> * <MAGENTA>/<RESET> 2 <GREEN>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET> - * <MAGENTA>|<RESET> 1 + * <MAGENTA>/<RESET> 1 <MAGENTA>|<RESET><MAGENTA>/<RESET> * initial EOF @@ -147,15 +145,14 @@ test_expect_success 'log --graph with tricky octopus merge and its child, no col cat >expect.uncolored <<-\EOF && * left | * after-merge - | *---. octopus-merge - | |\ \ \ - |/ / / / + | *-. octopus-merge + |/|\ \ | | | * 4 | | * | 3 | | |/ - | * | 2 + | * / 2 | |/ - * | 1 + * / 1 |/ * initial EOF @@ -164,20 +161,19 @@ test_expect_success 'log --graph with tricky octopus merge and its child, no col test_cmp expect.uncolored actual ' -test_expect_failure 'log --graph with tricky octopus merge and its child with colors' ' +test_expect_success 'log --graph with tricky octopus merge and its child with colors' ' test_config log.graphColors red,green,yellow,blue,magenta,cyan && cat >expect.colors <<-\EOF && * left <RED>|<RESET> * after-merge - <RED>|<RESET> *<MAGENTA>-<RESET><MAGENTA>-<RESET><CYAN>-<RESET><CYAN>.<RESET> octopus-merge - <RED>|<RESET> <RED>|<RESET><BLUE>\<RESET> <MAGENTA>\<RESET> <CYAN>\<RESET> - <RED>|<RESET><RED>/<RESET> <BLUE>/<RESET> <MAGENTA>/<RESET> <CYAN>/<RESET> + <RED>|<RESET> *<CYAN>-<RESET><CYAN>.<RESET> octopus-merge + <RED>|<RESET><RED>/<RESET><BLUE>|<RESET><MAGENTA>\<RESET> <CYAN>\<RESET> <RED>|<RESET> <BLUE>|<RESET> <MAGENTA>|<RESET> * 4 <RED>|<RESET> <BLUE>|<RESET> * <CYAN>|<RESET> 3 <RED>|<RESET> <BLUE>|<RESET> <CYAN>|<RESET><CYAN>/<RESET> - <RED>|<RESET> * <CYAN>|<RESET> 2 + <RED>|<RESET> * <CYAN>/<RESET> 2 <RED>|<RESET> <CYAN>|<RESET><CYAN>/<RESET> - * <CYAN>|<RESET> 1 + * <CYAN>/<RESET> 1 <CYAN>|<RESET><CYAN>/<RESET> * initial EOF @@ -209,7 +205,7 @@ test_expect_success 'log --graph with crossover in octopus merge, no color' ' test_cmp expect.uncolored actual ' -test_expect_failure 'log --graph with crossover in octopus merge with colors' ' +test_expect_success 'log --graph with crossover in octopus merge with colors' ' test_config log.graphColors red,green,yellow,blue,magenta,cyan && cat >expect.colors <<-\EOF && * after-4 @@ -257,7 +253,7 @@ test_expect_success 'log --graph with crossover in octopus merge and its child, test_cmp expect.uncolored actual ' -test_expect_failure 'log --graph with crossover in octopus merge and its child with colors' ' +test_expect_success 'log --graph with crossover in octopus merge and its child with colors' ' test_config log.graphColors red,green,yellow,blue,magenta,cyan && cat >expect.colors <<-\EOF && * after-4 @@ -353,7 +349,7 @@ test_expect_success 'log --graph with unrelated commit and octopus child, no col test_cmp expect.uncolored actual ' -test_expect_failure 'log --graph with unrelated commit and octopus child with colors' ' +test_expect_success 'log --graph with unrelated commit and octopus child with colors' ' test_config log.graphColors red,green,yellow,blue,magenta,cyan && cat >expect.colors <<-\EOF && * after-initial diff --git a/t/t4215-log-skewed-merges.sh b/t/t4215-log-skewed-merges.sh new file mode 100755 index 0000000000..1d0d3240ff --- /dev/null +++ b/t/t4215-log-skewed-merges.sh @@ -0,0 +1,376 @@ +#!/bin/sh + +test_description='git log --graph of skewed merges' + +. ./test-lib.sh + +check_graph () { + cat >expect && + git log --graph --pretty=tformat:%s "$@" >actual.raw && + sed "s/ *$//" actual.raw >actual && + test_cmp expect actual +} + +test_expect_success 'log --graph with merge fusing with its left and right neighbors' ' + git checkout --orphan _p && + test_commit A && + test_commit B && + git checkout -b _q @^ && test_commit C && + git checkout -b _r @^ && test_commit D && + git checkout _p && git merge --no-ff _q _r -m E && + git checkout _r && test_commit F && + git checkout _p && git merge --no-ff _r -m G && + git checkout @^^ && git merge --no-ff _p -m H && + + check_graph <<-\EOF + * H + |\ + | * G + | |\ + | | * F + | * | E + |/|\| + | | * D + | * | C + | |/ + * / B + |/ + * A + EOF +' + +test_expect_success 'log --graph with left-skewed merge' ' + git checkout --orphan 0_p && test_commit 0_A && + git checkout -b 0_q 0_p && test_commit 0_B && + git checkout -b 0_r 0_p && + test_commit 0_C && + test_commit 0_D && + git checkout -b 0_s 0_p && test_commit 0_E && + git checkout -b 0_t 0_p && git merge --no-ff 0_r^ 0_s -m 0_F && + git checkout 0_p && git merge --no-ff 0_s -m 0_G && + git checkout @^ && git merge --no-ff 0_q 0_r 0_t 0_p -m 0_H && + + check_graph <<-\EOF + *-----. 0_H + |\ \ \ \ + | | | | * 0_G + | |_|_|/| + |/| | | | + | | | * | 0_F + | |_|/|\| + |/| | | | + | | | | * 0_E + | |_|_|/ + |/| | | + | | * | 0_D + | | |/ + | | * 0_C + | |/ + |/| + | * 0_B + |/ + * 0_A + EOF +' + +test_expect_success 'log --graph with nested left-skewed merge' ' + git checkout --orphan 1_p && + test_commit 1_A && + test_commit 1_B && + test_commit 1_C && + git checkout -b 1_q @^ && test_commit 1_D && + git checkout 1_p && git merge --no-ff 1_q -m 1_E && + git checkout -b 1_r @~3 && test_commit 1_F && + git checkout 1_p && git merge --no-ff 1_r -m 1_G && + git checkout @^^ && git merge --no-ff 1_p -m 1_H && + + check_graph <<-\EOF + * 1_H + |\ + | * 1_G + | |\ + | | * 1_F + | * | 1_E + |/| | + | * | 1_D + * | | 1_C + |/ / + * / 1_B + |/ + * 1_A + EOF +' + +test_expect_success 'log --graph with nested left-skewed merge following normal merge' ' + git checkout --orphan 2_p && + test_commit 2_A && + test_commit 2_B && + test_commit 2_C && + git checkout -b 2_q @^^ && + test_commit 2_D && + test_commit 2_E && + git checkout -b 2_r @^ && test_commit 2_F && + git checkout 2_q && + git merge --no-ff 2_r -m 2_G && + git merge --no-ff 2_p^ -m 2_H && + git checkout -b 2_s @^^ && git merge --no-ff 2_q -m 2_J && + git checkout 2_p && git merge --no-ff 2_s -m 2_K && + + check_graph <<-\EOF + * 2_K + |\ + | * 2_J + | |\ + | | * 2_H + | | |\ + | | * | 2_G + | |/| | + | | * | 2_F + | * | | 2_E + | |/ / + | * | 2_D + * | | 2_C + | |/ + |/| + * | 2_B + |/ + * 2_A + EOF +' + +test_expect_success 'log --graph with nested right-skewed merge following left-skewed merge' ' + git checkout --orphan 3_p && + test_commit 3_A && + git checkout -b 3_q && + test_commit 3_B && + test_commit 3_C && + git checkout -b 3_r @^ && + test_commit 3_D && + git checkout 3_q && git merge --no-ff 3_r -m 3_E && + git checkout 3_p && git merge --no-ff 3_q -m 3_F && + git checkout 3_r && test_commit 3_G && + git checkout 3_p && git merge --no-ff 3_r -m 3_H && + git checkout @^^ && git merge --no-ff 3_p -m 3_J && + + check_graph <<-\EOF + * 3_J + |\ + | * 3_H + | |\ + | | * 3_G + | * | 3_F + |/| | + | * | 3_E + | |\| + | | * 3_D + | * | 3_C + | |/ + | * 3_B + |/ + * 3_A + EOF +' + +test_expect_success 'log --graph with right-skewed merge following a left-skewed one' ' + git checkout --orphan 4_p && + test_commit 4_A && + test_commit 4_B && + test_commit 4_C && + git checkout -b 4_q @^^ && test_commit 4_D && + git checkout -b 4_r 4_p^ && git merge --no-ff 4_q -m 4_E && + git checkout -b 4_s 4_p^^ && + git merge --no-ff 4_r -m 4_F && + git merge --no-ff 4_p -m 4_G && + git checkout @^^ && git merge --no-ff 4_s -m 4_H && + + check_graph --date-order <<-\EOF + * 4_H + |\ + | * 4_G + | |\ + | * | 4_F + |/| | + | * | 4_E + | |\ \ + | | * | 4_D + | |/ / + |/| | + | | * 4_C + | |/ + | * 4_B + |/ + * 4_A + EOF +' + +test_expect_success 'log --graph with octopus merge with column joining its penultimate parent' ' + git checkout --orphan 5_p && + test_commit 5_A && + git branch 5_q && + git branch 5_r && + test_commit 5_B && + git checkout 5_q && test_commit 5_C && + git checkout 5_r && test_commit 5_D && + git checkout 5_p && + git merge --no-ff 5_q 5_r -m 5_E && + git checkout 5_q && test_commit 5_F && + git checkout -b 5_s 5_p^ && + git merge --no-ff 5_p 5_q -m 5_G && + git checkout 5_r && + git merge --no-ff 5_s -m 5_H && + + check_graph <<-\EOF + * 5_H + |\ + | *-. 5_G + | |\ \ + | | | * 5_F + | | * | 5_E + | |/|\ \ + | |_|/ / + |/| | / + | | |/ + * | | 5_D + | | * 5_C + | |/ + |/| + | * 5_B + |/ + * 5_A + EOF +' + +test_expect_success 'log --graph with multiple tips' ' + git checkout --orphan 6_1 && + test_commit 6_A && + git branch 6_2 && + git branch 6_4 && + test_commit 6_B && + git branch 6_3 && + test_commit 6_C && + git checkout 6_2 && test_commit 6_D && + git checkout 6_3 && test_commit 6_E && + git checkout -b 6_5 6_1 && + git merge --no-ff 6_2 -m 6_F && + git checkout 6_4 && test_commit 6_G && + git checkout 6_3 && + git merge --no-ff 6_4 -m 6_H && + git checkout 6_1 && + git merge --no-ff 6_2 -m 6_I && + + check_graph 6_1 6_3 6_5 <<-\EOF + * 6_I + |\ + | | * 6_H + | | |\ + | | | * 6_G + | | * | 6_E + | | | | * 6_F + | |_|_|/| + |/| | |/ + | | |/| + | |/| | + | * | | 6_D + | | |/ + | |/| + * | | 6_C + | |/ + |/| + * | 6_B + |/ + * 6_A + EOF +' + +test_expect_success 'log --graph with multiple tips and colors' ' + test_config log.graphColors red,green,yellow,blue,magenta,cyan && + cat >expect.colors <<-\EOF && + * 6_I + <RED>|<RESET><GREEN>\<RESET> + <RED>|<RESET> <GREEN>|<RESET> * 6_H + <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET><BLUE>\<RESET> + <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 6_G + <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 6_F + <RED>|<RESET> <GREEN>|<RESET><RED>_<RESET><YELLOW>|<RESET><RED>_<RESET><BLUE>|<RESET><RED>/<RESET><GREEN>|<RESET> + <RED>|<RESET><RED>/<RESET><GREEN>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET><GREEN>/<RESET> + <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET><GREEN>/<RESET><BLUE>|<RESET> + <RED>|<RESET> <GREEN>|<RESET><GREEN>/<RESET><YELLOW>|<RESET> <BLUE>|<RESET> + <RED>|<RESET> <GREEN>|<RESET> * <BLUE>|<RESET> 6_E + <RED>|<RESET> * <CYAN>|<RESET> <BLUE>|<RESET> 6_D + <RED>|<RESET> <BLUE>|<RESET> <CYAN>|<RESET><BLUE>/<RESET> + <RED>|<RESET> <BLUE>|<RESET><BLUE>/<RESET><CYAN>|<RESET> + * <BLUE>|<RESET> <CYAN>|<RESET> 6_C + <CYAN>|<RESET> <BLUE>|<RESET><CYAN>/<RESET> + <CYAN>|<RESET><CYAN>/<RESET><BLUE>|<RESET> + * <BLUE>|<RESET> 6_B + <BLUE>|<RESET><BLUE>/<RESET> + * 6_A + EOF + git log --color=always --graph --date-order --pretty=tformat:%s 6_1 6_3 6_5 >actual.colors.raw && + test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors && + test_cmp expect.colors actual.colors +' + +test_expect_success 'log --graph with multiple tips' ' + git checkout --orphan 7_1 && + test_commit 7_A && + test_commit 7_B && + test_commit 7_C && + git checkout -b 7_2 7_1~2 && + test_commit 7_D && + test_commit 7_E && + git checkout -b 7_3 7_1~1 && + test_commit 7_F && + test_commit 7_G && + git checkout -b 7_4 7_2~1 && + test_commit 7_H && + git checkout -b 7_5 7_1~2 && + test_commit 7_I && + git checkout -b 7_6 7_3~1 && + test_commit 7_J && + git checkout -b M_1 7_1 && + git merge --no-ff 7_2 -m 7_M1 && + git checkout -b M_3 7_3 && + git merge --no-ff 7_4 -m 7_M2 && + git checkout -b M_5 7_5 && + git merge --no-ff 7_6 -m 7_M3 && + git checkout -b M_7 7_1 && + git merge --no-ff 7_2 7_3 -m 7_M4 && + + check_graph M_1 M_3 M_5 M_7 <<-\EOF + * 7_M1 + |\ + | | * 7_M2 + | | |\ + | | | * 7_H + | | | | * 7_M3 + | | | | |\ + | | | | | * 7_J + | | | | * | 7_I + | | | | | | * 7_M4 + | |_|_|_|_|/|\ + |/| | | | |/ / + | | |_|_|/| / + | |/| | | |/ + | | | |_|/| + | | |/| | | + | | * | | | 7_G + | | | |_|/ + | | |/| | + | | * | | 7_F + | * | | | 7_E + | | |/ / + | |/| | + | * | | 7_D + | | |/ + | |/| + * | | 7_C + | |/ + |/| + * | 7_B + |/ + * 7_A + EOF +' + +test_done diff --git a/t/t4256-am-format-flowed.sh b/t/t4256-am-format-flowed.sh index 6340310e9a..2369c4e17a 100755 --- a/t/t4256-am-format-flowed.sh +++ b/t/t4256-am-format-flowed.sh @@ -11,7 +11,7 @@ test_expect_success 'setup' ' ' test_expect_success 'am with format=flowed' ' - git am <"$TEST_DIRECTORY/t4256/1/patch" >stdout 2>stderr && + git am <"$TEST_DIRECTORY/t4256/1/patch" 2>stderr && test_i18ngrep "warning: Patch sent with format=flowed" stderr && test_cmp "$TEST_DIRECTORY/t4256/1/mailinfo.c" mailinfo.c ' diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh index d87cc7d9ef..e59601e5fe 100755 --- a/t/t4300-merge-tree.sh +++ b/t/t4300-merge-tree.sh @@ -11,16 +11,16 @@ test_expect_success setup ' ' test_expect_success 'file add A, !B' ' - cat >expected <<\EXPECTED && + git reset --hard initial && + test_commit "add-a-not-b" "ONE" "AAA" && + git merge-tree initial initial add-a-not-b >actual && + cat >expected <<EXPECTED && added in remote - their 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE + their 100644 $(git rev-parse HEAD:ONE) ONE @@ -0,0 +1 @@ +AAA EXPECTED - git reset --hard initial && - test_commit "add-a-not-b" "ONE" "AAA" && - git merge-tree initial initial add-a-not-b >actual && test_cmp expected actual ' @@ -41,10 +41,15 @@ test_expect_success 'file add A, B (same)' ' ' test_expect_success 'file add A, B (different)' ' - cat >expected <<\EXPECTED && + git reset --hard initial && + test_commit "add-a-b-diff-A" "ONE" "AAA" && + git reset --hard initial && + test_commit "add-a-b-diff-B" "ONE" "BBB" && + git merge-tree initial add-a-b-diff-A add-a-b-diff-B >actual && + cat >expected <<EXPECTED && added in both - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE - their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE + our 100644 $(git rev-parse add-a-b-diff-A:ONE) ONE + their 100644 $(git rev-parse add-a-b-diff-B:ONE) ONE @@ -1 +1,5 @@ +<<<<<<< .our AAA @@ -53,11 +58,6 @@ added in both +>>>>>>> .their EXPECTED - git reset --hard initial && - test_commit "add-a-b-diff-A" "ONE" "AAA" && - git reset --hard initial && - test_commit "add-a-b-diff-B" "ONE" "BBB" && - git merge-tree initial add-a-b-diff-A add-a-b-diff-B >actual && test_cmp expected actual ' @@ -69,18 +69,18 @@ test_expect_success 'file change A, !B' ' ' test_expect_success 'file change !A, B' ' - cat >expected <<\EXPECTED && + git reset --hard initial && + test_commit "change-not-a-b" "initial-file" "BBB" && + git merge-tree initial initial change-not-a-b >actual && + cat >expected <<EXPECTED && merged - result 100644 ba629238ca89489f2b350e196ca445e09d8bb834 initial-file - our 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file + result 100644 $(git rev-parse change-a-not-b:initial-file) initial-file + our 100644 $(git rev-parse initial:initial-file ) initial-file @@ -1 +1 @@ -initial +BBB EXPECTED - git reset --hard initial && - test_commit "change-not-a-b" "initial-file" "BBB" && - git merge-tree initial initial change-not-a-b >actual && test_cmp expected actual ' @@ -94,11 +94,16 @@ test_expect_success 'file change A, B (same)' ' ' test_expect_success 'file change A, B (different)' ' - cat >expected <<\EXPECTED && + git reset --hard initial && + test_commit "change-a-b-diff-A" "initial-file" "AAA" && + git reset --hard initial && + test_commit "change-a-b-diff-B" "initial-file" "BBB" && + git merge-tree initial change-a-b-diff-A change-a-b-diff-B >actual && + cat >expected <<EXPECTED && changed in both - base 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d initial-file - their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 initial-file + base 100644 $(git rev-parse initial:initial-file ) initial-file + our 100644 $(git rev-parse change-a-b-diff-A:initial-file) initial-file + their 100644 $(git rev-parse change-a-b-diff-B:initial-file) initial-file @@ -1 +1,5 @@ +<<<<<<< .our AAA @@ -107,34 +112,10 @@ changed in both +>>>>>>> .their EXPECTED - git reset --hard initial && - test_commit "change-a-b-diff-A" "initial-file" "AAA" && - git reset --hard initial && - test_commit "change-a-b-diff-B" "initial-file" "BBB" && - git merge-tree initial change-a-b-diff-A change-a-b-diff-B >actual && test_cmp expected actual ' test_expect_success 'file change A, B (mixed)' ' - cat >expected <<\EXPECTED && -changed in both - base 100644 f4f1f998c7776568c4ff38f516d77fef9399b5a7 ONE - our 100644 af14c2c3475337c73759d561ef70b59e5c731176 ONE - their 100644 372d761493f524d44d59bd24700c3bdf914c973c ONE -@@ -7,7 +7,11 @@ - AAA - AAA - AAA -+<<<<<<< .our - BBB -+======= -+CCC -+>>>>>>> .their - AAA - AAA - AAA -EXPECTED - git reset --hard initial && test_commit "change-a-b-mix-base" "ONE" " AAA @@ -159,6 +140,26 @@ AAA" && "$(sed -e "1{s/AAA/BBB/;}" -e "10{s/AAA/CCC/;}" <ONE)" && git merge-tree change-a-b-mix-base change-a-b-mix-A change-a-b-mix-B \ >actual && + + cat >expected <<EXPECTED && +changed in both + base 100644 $(git rev-parse change-a-b-mix-base:ONE) ONE + our 100644 $(git rev-parse change-a-b-mix-A:ONE ) ONE + their 100644 $(git rev-parse change-a-b-mix-B:ONE ) ONE +@@ -7,7 +7,11 @@ + AAA + AAA + AAA ++<<<<<<< .our + BBB ++======= ++CCC ++>>>>>>> .their + AAA + AAA + AAA +EXPECTED + test_cmp expected actual ' @@ -173,20 +174,20 @@ test_expect_success 'file remove A, !B' ' ' test_expect_success 'file remove !A, B' ' - cat >expected <<\EXPECTED && -removed in remote - base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE -@@ -1 +0,0 @@ --AAA -EXPECTED - git reset --hard initial && test_commit "rm-not-a-b-base" "ONE" "AAA" && git rm ONE && git commit -m "rm-not-a-b" && git tag "rm-not-a-b" && git merge-tree rm-a-not-b-base rm-a-not-b-base rm-a-not-b >actual && + cat >expected <<EXPECTED && +removed in remote + base 100644 $(git rev-parse rm-a-not-b-base:ONE) ONE + our 100644 $(git rev-parse rm-a-not-b-base:ONE) ONE +@@ -1 +0,0 @@ +-AAA +EXPECTED + test_cmp expected actual ' @@ -201,14 +202,6 @@ test_expect_success 'file remove A, B (same)' ' ' test_expect_success 'file change A, remove B' ' - cat >expected <<\EXPECTED && -removed in remote - base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE - our 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE -@@ -1 +0,0 @@ --BBB -EXPECTED - git reset --hard initial && test_commit "change-a-rm-b-base" "ONE" "AAA" && test_commit "change-a-rm-b-A" "ONE" "BBB" && @@ -218,16 +211,18 @@ EXPECTED git tag "change-a-rm-b-B" && git merge-tree change-a-rm-b-base change-a-rm-b-A change-a-rm-b-B \ >actual && + cat >expected <<EXPECTED && +removed in remote + base 100644 $(git rev-parse change-a-rm-b-base:ONE) ONE + our 100644 $(git rev-parse change-a-rm-b-A:ONE ) ONE +@@ -1 +0,0 @@ +-BBB +EXPECTED + test_cmp expected actual ' test_expect_success 'file remove A, change B' ' - cat >expected <<\EXPECTED && -removed in local - base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE - their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 ONE -EXPECTED - git reset --hard initial && test_commit "rm-a-change-b-base" "ONE" "AAA" && @@ -238,6 +233,11 @@ EXPECTED test_commit "rm-a-change-b-B" "ONE" "BBB" && git merge-tree rm-a-change-b-base rm-a-change-b-A rm-a-change-b-B \ >actual && + cat >expected <<EXPECTED && +removed in local + base 100644 $(git rev-parse rm-a-change-b-base:ONE) ONE + their 100644 $(git rev-parse rm-a-change-b-B:ONE ) ONE +EXPECTED test_cmp expected actual ' @@ -250,10 +250,17 @@ test_expect_success 'tree add A, B (same)' ' ' test_expect_success 'tree add A, B (different)' ' - cat >expect <<-\EOF && + git reset --hard initial && + mkdir sub && + test_commit "add sub/file" "sub/file" "AAA" add-tree-a-b-A && + git reset --hard initial && + mkdir sub && + test_commit "add sub/file" "sub/file" "BBB" add-tree-a-b-B && + git merge-tree initial add-tree-a-b-A add-tree-a-b-B >actual && + cat >expect <<-EOF && added in both - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file - their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 sub/file + our 100644 $(git rev-parse add-tree-a-b-A:sub/file) sub/file + their 100644 $(git rev-parse add-tree-a-b-B:sub/file) sub/file @@ -1 +1,5 @@ +<<<<<<< .our AAA @@ -261,24 +268,10 @@ test_expect_success 'tree add A, B (different)' ' +BBB +>>>>>>> .their EOF - git reset --hard initial && - mkdir sub && - test_commit "add sub/file" "sub/file" "AAA" add-tree-a-b-A && - git reset --hard initial && - mkdir sub && - test_commit "add sub/file" "sub/file" "BBB" add-tree-a-b-B && - git merge-tree initial add-tree-a-b-A add-tree-a-b-B >actual && test_cmp expect actual ' test_expect_success 'tree unchanged A, removed B' ' - cat >expect <<-\EOF && - removed in remote - base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file - @@ -1 +0,0 @@ - -AAA - EOF git reset --hard initial && mkdir sub && test_commit "add sub/file" "sub/file" "AAA" tree-remove-b-initial && @@ -287,6 +280,13 @@ test_expect_success 'tree unchanged A, removed B' ' git commit -m "remove sub/file" && git tag tree-remove-b-B && git merge-tree tree-remove-b-initial tree-remove-b-initial tree-remove-b-B >actual && + cat >expect <<-EOF && + removed in remote + base 100644 $(git rev-parse tree-remove-b-initial:sub/file) sub/file + our 100644 $(git rev-parse tree-remove-b-initial:sub/file) sub/file + @@ -1 +0,0 @@ + -AAA + EOF test_cmp expect actual ' @@ -296,14 +296,14 @@ test_expect_success 'turn file to tree' ' mkdir initial-file && test_commit "turn-file-to-tree" "initial-file/ONE" "CCC" && git merge-tree initial initial turn-file-to-tree >actual && - cat >expect <<-\EOF && + cat >expect <<-EOF && added in remote - their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 initial-file/ONE + their 100644 $(git rev-parse turn-file-to-tree:initial-file/ONE) initial-file/ONE @@ -0,0 +1 @@ +CCC removed in remote - base 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file - our 100644 e79c5e8f964493290a409888d5413a737e8e5dd5 initial-file + base 100644 $(git rev-parse initial:initial-file) initial-file + our 100644 $(git rev-parse initial:initial-file) initial-file @@ -1 +0,0 @@ -initial EOF @@ -318,14 +318,14 @@ test_expect_success 'turn tree to file' ' rm -fr dir && test_commit "make-file" "dir" "CCC" && git merge-tree add-tree add-another-tree make-file >actual && - cat >expect <<-\EOF && + cat >expect <<-EOF && removed in remote - base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path + base 100644 $(git rev-parse add-tree:dir/path) dir/path + our 100644 $(git rev-parse add-tree:dir/path) dir/path @@ -1 +0,0 @@ -AAA added in remote - their 100644 43aa4fdec31eb92e1fdc2f0ce6ea9ddb7c32bcf7 dir + their 100644 $(git rev-parse make-file:dir) dir @@ -0,0 +1 @@ +CCC EOF diff --git a/t/t5100-mailinfo.sh b/t/t5100-mailinfo.sh index 9690dcad4f..147e616533 100755 --- a/t/t5100-mailinfo.sh +++ b/t/t5100-mailinfo.sh @@ -213,4 +213,19 @@ test_expect_failure 'mailinfo -b separated double [PATCH]' ' test z"$subj" = z"Subject: [other] message" ' +test_expect_success 'mailinfo handles unusual header whitespace' ' + git mailinfo /dev/null /dev/null >actual <<-\EOF && + From:Real Name <user@example.com> + Subject: extra spaces + EOF + + cat >expect <<-\EOF && + Author: Real Name + Email: user@example.com + Subject: extra spaces + + EOF + test_cmp expect actual +' + test_done diff --git a/t/t5150-request-pull.sh b/t/t5150-request-pull.sh index 852dcd913f..1ad4ecc29a 100755 --- a/t/t5150-request-pull.sh +++ b/t/t5150-request-pull.sh @@ -4,6 +4,12 @@ test_description='Test workflows involving pull request.' . ./test-lib.sh +if ! test_have_prereq PERL +then + skip_all='skipping request-pull tests, perl not available' + test_done +fi + test_expect_success 'setup' ' git init --bare upstream.git && diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh index 91d51b35f9..ad07f2f7fc 100755 --- a/t/t5302-pack-index.sh +++ b/t/t5302-pack-index.sh @@ -6,9 +6,10 @@ test_description='pack index with 64-bit offsets and object CRC' . ./test-lib.sh -test_expect_success \ - 'setup' \ - 'rm -rf .git && +test_expect_success 'setup' ' + test_oid_init && + rawsz=$(test_oid rawsz) && + rm -rf .git && git init && git config pack.threads 1 && i=1 && @@ -32,7 +33,8 @@ test_expect_success \ echo $tree && git ls-tree $tree | sed -e "s/.* \\([0-9a-f]*\\) .*/\\1/" } >obj-list && - git update-ref HEAD $commit' + git update-ref HEAD $commit +' test_expect_success \ 'pack-objects with index version 1' \ @@ -157,10 +159,11 @@ test_expect_success \ offs_101=$(index_obj_offset 1.idx $sha1_101) && nr_099=$(index_obj_nr 1.idx $sha1_099) && chmod +w ".git/objects/pack/pack-${pack1}.pack" && + recordsz=$((rawsz + 4)) && dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($offs_101 + 1)) \ if=".git/objects/pack/pack-${pack1}.idx" \ - skip=$((4 + 256 * 4 + $nr_099 * 24)) \ - bs=1 count=20 conv=notrunc && + skip=$((4 + 256 * 4 + $nr_099 * recordsz)) \ + bs=1 count=$rawsz conv=notrunc && git cat-file blob $sha1_101 > file_101_foo1' test_expect_success \ @@ -200,8 +203,8 @@ test_expect_success \ chmod +w ".git/objects/pack/pack-${pack1}.pack" && dd of=".git/objects/pack/pack-${pack1}.pack" seek=$(($offs_101 + 1)) \ if=".git/objects/pack/pack-${pack1}.idx" \ - skip=$((8 + 256 * 4 + $nr_099 * 20)) \ - bs=1 count=20 conv=notrunc && + skip=$((8 + 256 * 4 + $nr_099 * rawsz)) \ + bs=1 count=$rawsz conv=notrunc && git cat-file blob $sha1_101 > file_101_foo2' test_expect_success \ @@ -226,7 +229,7 @@ test_expect_success \ nr=$(index_obj_nr ".git/objects/pack/pack-${pack1}.idx" $obj) && chmod +w ".git/objects/pack/pack-${pack1}.idx" && printf xxxx | dd of=".git/objects/pack/pack-${pack1}.idx" conv=notrunc \ - bs=1 count=4 seek=$((8 + 256 * 4 + $(wc -l <obj-list) * 20 + $nr * 4)) && + bs=1 count=4 seek=$((8 + 256 * 4 + $(wc -l <obj-list) * rawsz + $nr * 4)) && ( while read obj do git cat-file -p $obj >/dev/null || exit 1 done <obj-list ) && diff --git a/t/t5309-pack-delta-cycles.sh b/t/t5309-pack-delta-cycles.sh index 491556dad9..55b787630f 100755 --- a/t/t5309-pack-delta-cycles.sh +++ b/t/t5309-pack-delta-cycles.sh @@ -4,15 +4,9 @@ test_description='test index-pack handling of delta cycles in packfiles' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pack.sh -if ! test_have_prereq SHA1 -then - skip_all='not using SHA-1 for objects' - test_done -fi - # Two similar-ish objects that we have computed deltas between. -A=01d7713666f4de822776c7622c10f1b07de280dc -B=e68fe8129b546b101aee9510c5328e7f21ca1d18 +A=$(test_oid packlib_7_0) +B=$(test_oid packlib_7_76) # double-check our hand-constucted packs test_expect_success 'index-pack works with a single delta (A->B)' ' @@ -62,13 +56,13 @@ test_expect_success 'index-pack detects REF_DELTA cycles' ' test_must_fail git index-pack --fix-thin --stdin <cycle.pack ' -test_expect_failure 'failover to an object in another pack' ' +test_expect_success 'failover to an object in another pack' ' clear_packs && git index-pack --stdin <ab.pack && - git index-pack --stdin --fix-thin <cycle.pack + test_must_fail git index-pack --stdin --fix-thin <cycle.pack ' -test_expect_failure 'failover to a duplicate object in the same pack' ' +test_expect_success 'failover to a duplicate object in the same pack' ' clear_packs && { pack_header 3 && @@ -77,7 +71,7 @@ test_expect_failure 'failover to a duplicate object in the same pack' ' pack_obj $A } >recoverable.pack && pack_trailer recoverable.pack && - git index-pack --fix-thin --stdin <recoverable.pack + test_must_fail git index-pack --fix-thin --stdin <recoverable.pack ' test_done diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index 6640329ebf..8318781d2b 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -74,16 +74,24 @@ rev_list_tests() { test_cmp expect actual ' - test_expect_success "enumerate --objects ($state)" ' - git rev-list --objects --use-bitmap-index HEAD >tmp && - cut -d" " -f1 <tmp >tmp2 && - sort <tmp2 >actual && - git rev-list --objects HEAD >tmp && - cut -d" " -f1 <tmp >tmp2 && - sort <tmp2 >expect && + test_expect_success "counting objects via bitmap ($state)" ' + git rev-list --count --objects HEAD >expect && + git rev-list --use-bitmap-index --count --objects HEAD >actual && test_cmp expect actual ' + test_expect_success "enumerate commits ($state)" ' + git rev-list --use-bitmap-index HEAD >actual && + git rev-list HEAD >expect && + test_bitmap_traversal --no-confirm-bitmaps expect actual + ' + + test_expect_success "enumerate --objects ($state)" ' + git rev-list --objects --use-bitmap-index HEAD >actual && + git rev-list --objects HEAD >expect && + test_bitmap_traversal expect actual + ' + test_expect_success "bitmap --objects handles non-commit objects ($state)" ' git rev-list --objects --use-bitmap-index HEAD tagged-blob >actual && grep $blob actual @@ -99,6 +107,20 @@ test_expect_success 'clone from bitmapped repository' ' test_cmp expect actual ' +test_expect_success 'partial clone from bitmapped repository' ' + test_config uploadpack.allowfilter true && + git clone --no-local --bare --filter=blob:none . partial-clone.git && + ( + cd partial-clone.git && + pack=$(echo objects/pack/*.pack) && + git verify-pack -v "$pack" >have && + awk "/blob/ { print \$1 }" <have >blobs && + # we expect this single blob because of the direct ref + git rev-parse refs/tags/tagged-blob >expect && + test_cmp expect blobs + ) +' + test_expect_success 'setup further non-bitmapped commits' ' test_commit_bulk --id=further 10 ' diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh index f1708d415e..2a4557efc2 100755 --- a/t/t5313-pack-bounds-checks.sh +++ b/t/t5313-pack-bounds-checks.sh @@ -38,16 +38,27 @@ munge () { # for the initial, and another ofs(4*nr) past that for the extended. # ofs_table () { - echo $((4 + 4 + 4*256 + 20*$1 + 4*$1)) + echo $((4 + 4 + 4*256 + $(test_oid rawsz)*$1 + 4*$1)) } extended_table () { echo $(($(ofs_table "$1") + 4*$1)) } +test_expect_success 'setup' ' + test_oid_init && + test_oid_cache <<-EOF + oid000 sha1:1485 + oid000 sha256:4222 + + oidfff sha1:74 + oidfff sha256:1350 + EOF +' + test_expect_success 'set up base packfile and variables' ' # the hash of this content starts with ff, which # makes some later computations much simpler - echo 74 >file && + echo $(test_oid oidfff) >file && git add file && git commit -m base && git repack -ad && @@ -140,10 +151,10 @@ test_expect_success 'bogus offset inside v2 extended table' ' # an extended table (if the first object were larger than 2^31). # # Note that the value is important here. We want $object as - # the second entry in sorted-sha1 order. The sha1 of 1485 starts + # the second entry in sorted-hash order. The hash of this object starts # with "000", which sorts before that of $object (which starts # with "fff"). - second=$(echo 1485 | git hash-object -w --stdin) && + second=$(test_oid oid000 | git hash-object -w --stdin) && do_pack "$object $second" --index-version=2 && # We have to make extra room for the table, so we cannot diff --git a/t/t5314-pack-cycle-detection.sh b/t/t5314-pack-cycle-detection.sh index e525466de0..0aec8619e2 100755 --- a/t/t5314-pack-cycle-detection.sh +++ b/t/t5314-pack-cycle-detection.sh @@ -53,7 +53,7 @@ immediately after the lookup for "dummy". -# Create a pack containing the the tree $1 and blob $1:file, with +# Create a pack containing the tree $1 and blob $1:file, with # the latter stored as a delta against $2:file. # # We convince pack-objects to make the delta in the direction of our choosing diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh index 2d2f5d0229..dc0446574b 100755 --- a/t/t5317-pack-objects-filter-objects.sh +++ b/t/t5317-pack-objects-filter-objects.sh @@ -45,12 +45,7 @@ test_expect_success 'verify blob:none packfile has no blobs' ' git -C r1 index-pack ../filter.pack && git -C r1 verify-pack -v ../filter.pack >verify_result && - grep blob verify_result | - awk -f print_1.awk | - sort >observed && - - nr=$(wc -l <observed) && - test 0 -eq $nr + ! grep blob verify_result ' test_expect_success 'verify normal and blob:none packfiles have same commits/trees' ' @@ -72,7 +67,8 @@ test_expect_success 'get an error for missing tree object' ' echo foo >r5/foo && git -C r5 add foo && git -C r5 commit -m "foo" && - del=$(git -C r5 rev-parse HEAD^{tree} | sed "s|..|&/|") && + git -C r5 rev-parse HEAD^{tree} >tree && + del=$(sed "s|..|&/|" tree) && rm r5/.git/objects/$del && test_must_fail git -C r5 pack-objects --revs --stdout 2>bad_tree <<-EOF && HEAD @@ -148,12 +144,7 @@ test_expect_success 'verify blob:limit=500 omits all blobs' ' git -C r2 index-pack ../filter.pack && git -C r2 verify-pack -v ../filter.pack >verify_result && - grep blob verify_result | - awk -f print_1.awk | - sort >observed && - - nr=$(wc -l <observed) && - test 0 -eq $nr + ! grep blob verify_result ' test_expect_success 'verify blob:limit=1000' ' @@ -163,12 +154,7 @@ test_expect_success 'verify blob:limit=1000' ' git -C r2 index-pack ../filter.pack && git -C r2 verify-pack -v ../filter.pack >verify_result && - grep blob verify_result | - awk -f print_1.awk | - sort >observed && - - nr=$(wc -l <observed) && - test 0 -eq $nr + ! grep blob verify_result ' test_expect_success 'verify blob:limit=1001' ' @@ -230,10 +216,9 @@ test_expect_success 'verify explicitly specifying oversized blob in input' ' awk -f print_2.awk ls_files_result | sort >expected && - git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k >filter.pack <<-EOF && - HEAD - $(git -C r2 rev-parse HEAD:large.10000) - EOF + echo HEAD >objects && + git -C r2 rev-parse HEAD:large.10000 >>objects && + git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k <objects >filter.pack && git -C r2 index-pack ../filter.pack && git -C r2 verify-pack -v ../filter.pack >verify_result && @@ -377,7 +362,8 @@ test_expect_success 'verify sparse:oid=OID' ' awk -f print_2.awk ls_files_result | sort >expected && - oid=$(git -C r4 ls-files -s pattern | awk -f print_2.awk) && + git -C r4 ls-files -s pattern >staged && + oid=$(awk -f print_2.awk staged) && git -C r4 pack-objects --revs --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF && HEAD EOF diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index d42b3efe39..9bf920ae17 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -19,8 +19,8 @@ test_expect_success 'verify graph with no graph file' ' test_expect_success 'write graph with no packs' ' cd "$TRASH_DIRECTORY/full" && - git commit-graph write --object-dir . && - test_path_is_missing info/commit-graph + git commit-graph write --object-dir $objdir && + test_path_is_missing $objdir/info/commit-graph ' test_expect_success 'exit with correct error on bad input to --stdin-packs' ' @@ -85,7 +85,7 @@ graph_read_expect() { num_commits: $1 chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL EOF - git commit-graph read >output && + test-tool read-graph >output && test_cmp expect output } @@ -132,7 +132,7 @@ test_expect_success 'commit-graph write progress off for redirected stderr' ' test_expect_success 'commit-graph write force progress on for stderr' ' cd "$TRASH_DIRECTORY/full" && - git commit-graph write --progress 2>err && + GIT_PROGRESS_DELAY=0 git commit-graph write --progress 2>err && test_file_not_empty err ' @@ -150,7 +150,7 @@ test_expect_success 'commit-graph verify progress off for redirected stderr' ' test_expect_success 'commit-graph verify force progress on for stderr' ' cd "$TRASH_DIRECTORY/full" && - git commit-graph verify --progress 2>err && + GIT_PROGRESS_DELAY=0 git commit-graph verify --progress 2>err && test_file_not_empty err ' @@ -481,7 +481,7 @@ test_expect_success 'detect bad version' ' ' test_expect_success 'detect bad hash version' ' - corrupt_graph_and_verify $GRAPH_BYTE_HASH "\02" \ + corrupt_graph_and_verify $GRAPH_BYTE_HASH "\03" \ "hash version" ' @@ -629,7 +629,7 @@ test_expect_success 'corrupt commit-graph write (broken parent)' ' empty="$(git mktree </dev/null)" && cat >broken <<-EOF && tree $empty - parent 0000000000000000000000000000000000000000 + parent $ZERO_OID author whatever <whatever@example.com> 1234 -0000 committer whatever <whatever@example.com> 1234 -0000 @@ -650,7 +650,7 @@ test_expect_success 'corrupt commit-graph write (missing tree)' ' cd repo && tree="$(git mktree </dev/null)" && cat >broken <<-EOF && - parent 0000000000000000000000000000000000000000 + parent $ZERO_OID author whatever <whatever@example.com> 1234 -0000 committer whatever <whatever@example.com> 1234 -0000 @@ -660,7 +660,7 @@ test_expect_success 'corrupt commit-graph write (missing tree)' ' git commit-tree -p "$broken" -m "good" "$tree" >good && test_must_fail git commit-graph write --stdin-commits \ <good 2>test_err && - test_i18ngrep "unable to get tree for" test_err + test_i18ngrep "unable to parse commit" test_err ) ' diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index cd2f87be6a..43a7a66c9d 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -28,6 +28,20 @@ midx_read_expect () { test_cmp expect actual } +test_expect_success 'setup' ' + test_oid_init && + test_oid_cache <<-EOF + idxoff sha1:2999 + idxoff sha256:3739 + + packnameoff sha1:652 + packnameoff sha256:940 + + fanoutoff sha1:1 + fanoutoff sha256:3 + EOF +' + test_expect_success 'write midx with no packs' ' test_when_finished rm -f pack/multi-pack-index && git multi-pack-index --object-dir=. write && @@ -225,7 +239,7 @@ test_expect_success 'verify bad signature' ' "multi-pack-index signature" ' -HASH_LEN=20 +HASH_LEN=$(test_oid rawsz) NUM_OBJECTS=74 MIDX_BYTE_VERSION=4 MIDX_BYTE_OID_VERSION=5 @@ -238,9 +252,9 @@ MIDX_CHUNK_LOOKUP_WIDTH=12 MIDX_OFFSET_PACKNAMES=$(($MIDX_HEADER_SIZE + \ $MIDX_NUM_CHUNKS * $MIDX_CHUNK_LOOKUP_WIDTH)) MIDX_BYTE_PACKNAME_ORDER=$(($MIDX_OFFSET_PACKNAMES + 2)) -MIDX_OFFSET_OID_FANOUT=$(($MIDX_OFFSET_PACKNAMES + 652)) +MIDX_OFFSET_OID_FANOUT=$(($MIDX_OFFSET_PACKNAMES + $(test_oid packnameoff))) MIDX_OID_FANOUT_WIDTH=4 -MIDX_BYTE_OID_FANOUT_ORDER=$((MIDX_OFFSET_OID_FANOUT + 250 * $MIDX_OID_FANOUT_WIDTH + 1)) +MIDX_BYTE_OID_FANOUT_ORDER=$((MIDX_OFFSET_OID_FANOUT + 250 * $MIDX_OID_FANOUT_WIDTH + $(test_oid fanoutoff))) MIDX_OFFSET_OID_LOOKUP=$(($MIDX_OFFSET_OID_FANOUT + 256 * $MIDX_OID_FANOUT_WIDTH)) MIDX_BYTE_OID_LOOKUP=$(($MIDX_OFFSET_OID_LOOKUP + 16 * $HASH_LEN)) MIDX_OFFSET_OBJECT_OFFSETS=$(($MIDX_OFFSET_OID_LOOKUP + $NUM_OBJECTS * $HASH_LEN)) @@ -304,12 +318,12 @@ test_expect_success 'verify incorrect pack-int-id' ' ' test_expect_success 'verify incorrect offset' ' - corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\07" $objdir \ + corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\377" $objdir \ "incorrect object offset" ' test_expect_success 'git-fsck incorrect offset' ' - corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\07" $objdir \ + corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\377" $objdir \ "incorrect object offset" \ "git -c core.multipackindex=true fsck" ' @@ -387,7 +401,7 @@ test_expect_success 'force some 64-bit offsets with pack-objects' ' pack64=$(git pack-objects --index-version=2,0x40 objects64/pack/test-64 <obj-list) && idx64=objects64/pack/test-64-$pack64.idx && chmod u+w $idx64 && - corrupt_data $idx64 2999 "\02" && + corrupt_data $idx64 $(test_oid idxoff) "\02" && midx64=$(git multi-pack-index --object-dir=objects64 write) && midx_read_expect 1 63 5 objects64 " large-offsets" ' diff --git a/t/t5321-pack-large-objects.sh b/t/t5321-pack-large-objects.sh index a75eab87d3..8a56d98a0e 100755 --- a/t/t5321-pack-large-objects.sh +++ b/t/t5321-pack-large-objects.sh @@ -10,8 +10,8 @@ test_description='git pack-object with "large" deltas . "$TEST_DIRECTORY"/lib-pack.sh # Two similar-ish objects that we have computed deltas between. -A=01d7713666f4de822776c7622c10f1b07de280dc -B=e68fe8129b546b101aee9510c5328e7f21ca1d18 +A=$(test_oid packlib_7_0) +B=$(test_oid packlib_7_76) test_expect_success 'setup' ' clear_packs && diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index 115aabd141..53b2e6b455 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -11,7 +11,14 @@ test_expect_success 'setup repo' ' git config gc.writeCommitGraph false && infodir=".git/objects/info" && graphdir="$infodir/commit-graphs" && - test_oid_init + test_oid_init && + test_oid_cache <<-EOM + shallow sha1:1760 + shallow sha256:2064 + + base sha1:1376 + base sha256:1496 + EOM ' graph_read_expect() { @@ -25,7 +32,7 @@ graph_read_expect() { num_commits: $1 chunks: oid_fanout oid_lookup commit_metadata EOF - git commit-graph read >output && + test-tool read-graph >output && test_cmp expect output } @@ -248,7 +255,7 @@ test_expect_success 'verify hashes along chain, even in shallow' ' cd verify && git commit-graph verify && base_file=$graphdir/graph-$(head -n 1 $graphdir/commit-graph-chain).graph && - corrupt_file "$base_file" 1760 "\01" && + corrupt_file "$base_file" $(test_oid shallow) "\01" && test_must_fail git commit-graph verify --shallow 2>test_err && grep -v "^+" test_err >err && test_i18ngrep "incorrect checksum" err @@ -275,7 +282,7 @@ test_expect_success 'warn on base graph chunk incorrect' ' cd base-chunk && git commit-graph verify && base_file=$graphdir/graph-$(tail -n 1 $graphdir/commit-graph-chain).graph && - corrupt_file "$base_file" 1376 "\01" && + corrupt_file "$base_file" $(test_oid base) "\01" && git commit-graph verify --shallow 2>test_err && grep -v "^+" test_err >err && test_i18ngrep "commit-graph chain does not match" err diff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh index 571d620aed..b84618c925 100755 --- a/t/t5400-send-pack.sh +++ b/t/t5400-send-pack.sh @@ -288,7 +288,7 @@ test_expect_success 'receive-pack de-dupes .have lines' ' $shared .have EOF - GIT_TRACE_PACKET=$(pwd)/trace GIT_TEST_PROTOCOL_VERSION= \ + GIT_TRACE_PACKET=$(pwd)/trace GIT_TEST_PROTOCOL_VERSION=0 \ git push \ --receive-pack="unset GIT_TRACE_PACKET; git-receive-pack" \ fork HEAD:foo && diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh index 7344253bfb..80750a817e 100755 --- a/t/t5407-post-rewrite-hook.sh +++ b/t/t5407-post-rewrite-hook.sh @@ -53,10 +53,10 @@ test_expect_success 'git commit --amend --no-post-rewrite' ' test ! -f post-rewrite.data ' -test_expect_success 'git rebase' ' +test_expect_success 'git rebase --apply' ' git reset --hard D && clear_hook_input && - test_must_fail git rebase --onto A B && + test_must_fail git rebase --apply --onto A B && echo C > foo && git add foo && git rebase --continue && @@ -68,10 +68,10 @@ test_expect_success 'git rebase' ' verify_hook_input ' -test_expect_success 'git rebase --skip' ' +test_expect_success 'git rebase --apply --skip' ' git reset --hard D && clear_hook_input && - test_must_fail git rebase --onto A B && + test_must_fail git rebase --apply --onto A B && test_must_fail git rebase --skip && echo D > foo && git add foo && @@ -84,10 +84,10 @@ test_expect_success 'git rebase --skip' ' verify_hook_input ' -test_expect_success 'git rebase --skip the last one' ' +test_expect_success 'git rebase --apply --skip the last one' ' git reset --hard F && clear_hook_input && - test_must_fail git rebase --onto D A && + test_must_fail git rebase --apply --onto D A && git rebase --skip && echo rebase >expected.args && cat >expected.data <<-EOF && @@ -128,7 +128,7 @@ test_expect_success 'git rebase -m --skip' ' verify_hook_input ' -test_expect_success 'git rebase with implicit use of interactive backend' ' +test_expect_success 'git rebase with implicit use of merge backend' ' git reset --hard D && clear_hook_input && test_must_fail git rebase --keep-empty --onto A B && @@ -143,7 +143,7 @@ test_expect_success 'git rebase with implicit use of interactive backend' ' verify_hook_input ' -test_expect_success 'git rebase --skip with implicit use of interactive backend' ' +test_expect_success 'git rebase --skip with implicit use of merge backend' ' git reset --hard D && clear_hook_input && test_must_fail git rebase --keep-empty --onto A B && diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index 6b97923964..baa1a99f45 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -440,11 +440,12 @@ test_expect_success 'setup tests for the --stdin parameter' ' ' test_expect_success 'setup fetch refs from cmdline v[12]' ' + cp -r client client0 && cp -r client client1 && cp -r client client2 ' -for version in '' 1 2 +for version in '' 0 1 2 do test_expect_success "protocol.version=$version fetch refs from cmdline" " ( @@ -638,7 +639,7 @@ test_expect_success 'fetch-pack cannot fetch a raw sha1 that is not advertised a git init client && # Some protocol versions (e.g. 2) support fetching # unadvertised objects, so restrict this test to v0. - test_must_fail env GIT_TEST_PROTOCOL_VERSION= git -C client fetch-pack ../server \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 git -C client fetch-pack ../server \ $(git -C server rev-parse refs/heads/master^) 2>err && test_i18ngrep "Server does not allow request for unadvertised object" err ' @@ -917,7 +918,10 @@ test_expect_success 'filtering by size' ' git -C client fetch-pack --filter=blob:limit=0 ../server HEAD && # Ensure that object is not inadvertently fetched - test_must_fail git -C client cat-file -e $(git hash-object server/one.t) + commit=$(git -C server rev-parse HEAD) && + blob=$(git hash-object server/one.t) && + git -C client rev-list --objects --missing=allow-any "$commit" >oids && + ! grep "$blob" oids ' test_expect_success 'filtering by size has no effect if support for it is not advertised' ' @@ -929,7 +933,10 @@ test_expect_success 'filtering by size has no effect if support for it is not ad git -C client fetch-pack --filter=blob:limit=0 ../server HEAD 2> err && # Ensure that object is fetched - git -C client cat-file -e $(git hash-object server/one.t) && + commit=$(git -C server rev-parse HEAD) && + blob=$(git hash-object server/one.t) && + git -C client rev-list --objects --missing=allow-any "$commit" >oids && + grep "$blob" oids && test_i18ngrep "filtering not recognized by server" err ' @@ -951,9 +958,11 @@ fetch_filter_blob_limit_zero () { git -C client fetch --filter=blob:limit=0 origin HEAD:somewhere && # Ensure that commit is fetched, but blob is not - test_config -C client extensions.partialclone "arbitrary string" && - git -C client cat-file -e $(git -C "$SERVER" rev-parse two) && - test_must_fail git -C client cat-file -e $(git hash-object "$SERVER/two.t") + commit=$(git -C "$SERVER" rev-parse two) && + blob=$(git hash-object server/two.t) && + git -C client rev-list --objects --missing=allow-any "$commit" >oids && + grep "$commit" oids && + ! grep "$blob" oids } test_expect_success 'fetch with --filter=blob:limit=0' ' diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index fdfe179b11..645b4c78d3 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -4,6 +4,7 @@ test_description='fetch/receive strict mode' . ./test-lib.sh test_expect_success 'setup and inject "corrupt or missing" object' ' + test_oid_init && echo hello >greetings && git add greetings && git commit -m greetings && @@ -144,11 +145,11 @@ test_expect_success 'fsck with no skipList input' ' test_expect_success 'setup sorted and unsorted skipLists' ' cat >SKIP.unsorted <<-EOF && - 0000000000000000000000000000000000000004 - 0000000000000000000000000000000000000002 + $(test_oid 004) + $(test_oid 002) $commit - 0000000000000000000000000000000000000001 - 0000000000000000000000000000000000000003 + $(test_oid 001) + $(test_oid 003) EOF sort SKIP.unsorted >SKIP.sorted ' @@ -172,14 +173,14 @@ test_expect_success 'fsck with invalid or bogus skipList input' ' test_expect_success 'fsck with other accepted skipList input (comments & empty lines)' ' cat >SKIP.with-comment <<-EOF && # Some bad commit - 0000000000000000000000000000000000000001 + $(test_oid 001) EOF test_must_fail git -c fsck.skipList=SKIP.with-comment fsck 2>err-with-comment && test_i18ngrep "missingEmail" err-with-comment && cat >SKIP.with-empty-line <<-EOF && - 0000000000000000000000000000000000000001 + $(test_oid 001) - 0000000000000000000000000000000000000002 + $(test_oid 002) EOF test_must_fail git -c fsck.skipList=SKIP.with-empty-line fsck 2>err-with-empty-line && test_i18ngrep "missingEmail" err-with-empty-line @@ -204,7 +205,7 @@ test_expect_success 'fsck with exhaustive accepted skipList input (various types echo " # Comment after whitespace" >>SKIP.exhaustive && echo "$commit # Our bad commit (with leading whitespace and trailing comment)" >>SKIP.exhaustive && echo "# Some bad commit (leading whitespace)" >>SKIP.exhaustive && - echo " 0000000000000000000000000000000000000001" >>SKIP.exhaustive && + echo " $(test_oid 001)" >>SKIP.exhaustive && git -c fsck.skipList=SKIP.exhaustive fsck 2>err && test_must_be_empty err ' diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 883b32efa0..dda81b7d07 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -734,15 +734,53 @@ test_expect_success 'reject adding remote with an invalid name' ' # the last two ones check if the config is updated. test_expect_success 'rename a remote' ' + test_config_global remote.pushDefault origin && git clone one four && ( cd four && + git config branch.master.pushRemote origin && git remote rename origin upstream && test -z "$(git for-each-ref refs/remotes/origin)" && test "$(git symbolic-ref refs/remotes/upstream/HEAD)" = "refs/remotes/upstream/master" && test "$(git rev-parse upstream/master)" = "$(git rev-parse master)" && test "$(git config remote.upstream.fetch)" = "+refs/heads/*:refs/remotes/upstream/*" && - test "$(git config branch.master.remote)" = "upstream" + test "$(git config branch.master.remote)" = "upstream" && + test "$(git config branch.master.pushRemote)" = "upstream" && + test "$(git config --global remote.pushDefault)" = "origin" + ) +' + +test_expect_success 'rename a remote renames repo remote.pushDefault' ' + git clone one four.1 && + ( + cd four.1 && + git config remote.pushDefault origin && + git remote rename origin upstream && + test "$(git config --local remote.pushDefault)" = "upstream" + ) +' + +test_expect_success 'rename a remote renames repo remote.pushDefault but ignores global' ' + test_config_global remote.pushDefault other && + git clone one four.2 && + ( + cd four.2 && + git config remote.pushDefault origin && + git remote rename origin upstream && + test "$(git config --global remote.pushDefault)" = "other" && + test "$(git config --local remote.pushDefault)" = "upstream" + ) +' + +test_expect_success 'rename a remote renames repo remote.pushDefault but keeps global' ' + test_config_global remote.pushDefault origin && + git clone one four.3 && + ( + cd four.3 && + git config remote.pushDefault origin && + git remote rename origin upstream && + test "$(git config --global remote.pushDefault)" = "origin" && + test "$(git config --local remote.pushDefault)" = "upstream" ) ' @@ -784,6 +822,54 @@ test_expect_success 'rename succeeds with existing remote.<target>.prune' ' git -C four.four remote rename origin upstream ' +test_expect_success 'remove a remote' ' + test_config_global remote.pushDefault origin && + git clone one four.five && + ( + cd four.five && + git config branch.master.pushRemote origin && + git remote remove origin && + test -z "$(git for-each-ref refs/remotes/origin)" && + test_must_fail git config branch.master.remote && + test_must_fail git config branch.master.pushRemote && + test "$(git config --global remote.pushDefault)" = "origin" + ) +' + +test_expect_success 'remove a remote removes repo remote.pushDefault' ' + git clone one four.five.1 && + ( + cd four.five.1 && + git config remote.pushDefault origin && + git remote remove origin && + test_must_fail git config --local remote.pushDefault + ) +' + +test_expect_success 'remove a remote removes repo remote.pushDefault but ignores global' ' + test_config_global remote.pushDefault other && + git clone one four.five.2 && + ( + cd four.five.2 && + git config remote.pushDefault origin && + git remote remove origin && + test "$(git config --global remote.pushDefault)" = "other" && + test_must_fail git config --local remote.pushDefault + ) +' + +test_expect_success 'remove a remote removes repo remote.pushDefault but keeps global' ' + test_config_global remote.pushDefault origin && + git clone one four.five.3 && + ( + cd four.five.3 && + git config remote.pushDefault origin && + git remote remove origin && + test "$(git config --global remote.pushDefault)" = "origin" && + test_must_fail git config --local remote.pushDefault + ) +' + cat >remotes_origin <<EOF URL: $(pwd)/one Push: refs/heads/master:refs/heads/upstream diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 4b60282689..566994cede 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -11,7 +11,7 @@ D=$(pwd) test_bundle_object_count () { git verify-pack -v "$1" >verify.out && - test "$2" = $(grep '^[0-9a-f]\{40\} ' verify.out | wc -l) + test "$2" = $(grep "^$OID_REGEX " verify.out | wc -l) } convert_bundle_to_pack () { @@ -174,6 +174,30 @@ test_expect_success 'fetch --prune --tags with refspec prunes based on refspec' git rev-parse sometag ' +test_expect_success '--refmap="" ignores configured refspec' ' + cd "$TRASH_DIRECTORY" && + git clone "$D" remote-refs && + git -C remote-refs rev-parse remotes/origin/master >old && + git -C remote-refs update-ref refs/remotes/origin/master master~1 && + git -C remote-refs rev-parse remotes/origin/master >new && + git -C remote-refs fetch --refmap= origin "+refs/heads/*:refs/hidden/origin/*" && + git -C remote-refs rev-parse remotes/origin/master >actual && + test_cmp new actual && + git -C remote-refs fetch origin && + git -C remote-refs rev-parse remotes/origin/master >actual && + test_cmp old actual +' + +test_expect_success '--refmap="" and --prune' ' + git -C remote-refs update-ref refs/remotes/origin/foo/otherbranch master && + git -C remote-refs update-ref refs/hidden/foo/otherbranch master && + git -C remote-refs fetch --prune --refmap="" origin +refs/heads/*:refs/hidden/* && + git -C remote-refs rev-parse remotes/origin/foo/otherbranch && + test_must_fail git -C remote-refs rev-parse refs/hidden/foo/otherbranch && + git -C remote-refs fetch --prune origin && + test_must_fail git -C remote-refs rev-parse remotes/origin/foo/otherbranch +' + test_expect_success 'fetch tags when there is no tags' ' cd "$D" && @@ -261,9 +285,10 @@ test_expect_success 'create bundle 1' ' ' test_expect_success 'header of bundle looks right' ' + head -n 4 "$D"/bundle1 && head -n 1 "$D"/bundle1 | grep "^#" && - head -n 2 "$D"/bundle1 | grep "^-[0-9a-f]\{40\} " && - head -n 3 "$D"/bundle1 | grep "^[0-9a-f]\{40\} " && + head -n 2 "$D"/bundle1 | grep "^-$OID_REGEX " && + head -n 3 "$D"/bundle1 | grep "^$OID_REGEX " && head -n 4 "$D"/bundle1 | grep "^$" ' @@ -289,7 +314,7 @@ test_expect_success 'bundle 1 has only 3 files ' ' test_expect_success 'unbundle 2' ' cd "$D/bundle" && git fetch ../bundle2 master:master && - test "tip" = "$(git log -1 --pretty=oneline master | cut -b42-)" + test "tip" = "$(git log -1 --pretty=oneline master | cut -d" " -f2)" ' test_expect_success 'bundle does not prerequisite objects' ' diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 43e1d8d4d2..04b35402c7 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -225,49 +225,50 @@ test_expect_success 'ls-remote --symref' ' EOF # Protocol v2 supports sending symrefs for refs other than HEAD, so use # protocol v0 here. - GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref >actual && + GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref >actual && test_cmp expect actual ' test_expect_success 'ls-remote with filtered symref (refname)' ' - cat >expect <<-\EOF && + rev=$(git rev-parse HEAD) && + cat >expect <<-EOF && ref: refs/heads/master HEAD - 1bd44cb9d13204b0fe1958db0082f5028a16eb3a HEAD + $rev HEAD EOF # Protocol v2 supports sending symrefs for refs other than HEAD, so use # protocol v0 here. - GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref . HEAD >actual && + GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . HEAD >actual && test_cmp expect actual ' test_expect_failure 'ls-remote with filtered symref (--heads)' ' git symbolic-ref refs/heads/foo refs/tags/mark && - cat >expect <<-\EOF && + cat >expect <<-EOF && ref: refs/tags/mark refs/heads/foo - 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/foo - 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/master + $rev refs/heads/foo + $rev refs/heads/master EOF # Protocol v2 supports sending symrefs for refs other than HEAD, so use # protocol v0 here. - GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref --heads . >actual && + GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual && test_cmp expect actual ' test_expect_success 'ls-remote --symref omits filtered-out matches' ' - cat >expect <<-\EOF && - 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/foo - 1bd44cb9d13204b0fe1958db0082f5028a16eb3a refs/heads/master + cat >expect <<-EOF && + $rev refs/heads/foo + $rev refs/heads/master EOF # Protocol v2 supports sending symrefs for refs other than HEAD, so use # protocol v0 here. - GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref --heads . >actual && + GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref --heads . >actual && test_cmp expect actual && - GIT_TEST_PROTOCOL_VERSION= git ls-remote --symref . "refs/heads/*" >actual && + GIT_TEST_PROTOCOL_VERSION=0 git ls-remote --symref . "refs/heads/*" >actual && test_cmp expect actual ' test_lazy_prereq GIT_DAEMON ' - git env--helper --type=bool --default=true --exit-code GIT_TEST_GIT_DAEMON + test_bool_env GIT_TEST_GIT_DAEMON true ' # This test spawns a daemon, so run it only if the user would be OK with diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh index 961eb35c99..9d6a46ff56 100755 --- a/t/t5515-fetch-merge-logic.sh +++ b/t/t5515-fetch-merge-logic.sh @@ -8,15 +8,60 @@ test_description='Merge logic in fetch' # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. -GIT_TEST_PROTOCOL_VERSION= +GIT_TEST_PROTOCOL_VERSION=0 +export GIT_TEST_PROTOCOL_VERSION . ./test-lib.sh +build_script () { + script="$1" && + for i in one three_file master master2 one_tree three two two2 three2 + do + echo "s/$(test_oid --hash=sha1 "$i")/$(test_oid "$i")/g" >>"$script" + done +} + +convert_expected () { + file="$1" && + script="$2" && + sed -f "$script" "$file" >"$file.tmp" && + mv "$file.tmp" "$file" +} + test_expect_success setup ' GIT_AUTHOR_DATE="2006-06-26 00:00:00 +0000" && GIT_COMMITTER_DATE="2006-06-26 00:00:00 +0000" && export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && + test_oid_cache <<-EOF && + one sha1:8e32a6d901327a23ef831511badce7bf3bf46689 + one sha256:8739546433ab1ac72ee93088dce611210effee072b2b586ceac6dde43ebec9ce + + three_file sha1:0e3b14047d3ee365f4f2a1b673db059c3972589c + three_file sha256:bc4447d50c07497a8bfe6eef817f2364ecca9d471452e43b52756cc1a908bd32 + + master sha1:6c9dec2b923228c9ff994c6cfe4ae16c12408dc5 + master sha256:8521c3072461fcfe8f32d67f95cc6e6b832a2db2fa29769ffc788bce85ebcd75 + + one_tree sha1:22feea448b023a2d864ef94b013735af34d238ba + one_tree sha256:6e4743f4ef2356b881dda5e91f5c7cdffe870faf350bf7b312f80a20935f5d83 + + three sha1:c61a82b60967180544e3c19f819ddbd0c9f89899 + three sha256:0cc6d1eda617ded715170786e31ba4e2d0185404ec5a3508dd0d73b324860c6a + + two sha1:525b7fb068d59950d185a8779dc957c77eed73ba + two sha256:3b21de3440cd38c2a9e9b464adb923f7054949ed4c918e1a0ac4c95cd52774db + + master2 sha1:754b754407bf032e9a2f9d5a9ad05ca79a6b228f + master2 sha256:6c7abaea8a6d8ef4d89877e68462758dc6774690fbbbb0e6d7dd57415c9abde0 + + two2 sha1:6134ee8f857693b96ff1cc98d3e2fd62b199e5a8 + two2 sha256:87a2d3ee29c83a3dc7afd41c0606b11f67603120b910a7be7840accdc18344d4 + + three2 sha1:0567da4d5edd2ff4bb292a465ba9e64dcad9536b + three2 sha256:cceb3e8eca364fa9a0a39a1efbebecacc664af86cbbd8070571f5faeb5f0e8c3 + EOF + echo >file original && git add file && git commit -a -m One && @@ -86,7 +131,8 @@ test_expect_success setup ' git config branch.br-$remote-octopus.remote $remote && git config branch.br-$remote-octopus.merge refs/heads/one && git config --add branch.br-$remote-octopus.merge two - done + done && + build_script sed_script ' # Merge logic depends on branch properties and Pull: or .fetch lines @@ -137,6 +183,10 @@ do actual_r="$pfx-refs.$test" test_expect_success "$cmd" ' + cp "$expect_f" expect_f && + convert_expected expect_f sed_script && + cp "$expect_r" expect_r && + convert_expected expect_r sed_script && { echo "# $cmd" set x $cmd; shift @@ -152,18 +202,18 @@ do cat .git/FETCH_HEAD } >"$actual_f" && git show-ref >"$actual_r" && - if test -f "$expect_f" + if test -f "expect_f" then - test_cmp "$expect_f" "$actual_f" && + test_cmp "expect_f" "$actual_f" && rm -f "$actual_f" else # this is to help developing new tests. cp "$actual_f" "$expect_f" false fi && - if test -f "$expect_r" + if test -f "expect_r" then - test_cmp "$expect_r" "$actual_r" && + test_cmp "expect_r" "$actual_r" && rm -f "$actual_r" else # this is to help developing new tests. diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index c81ca360ac..f12cbef097 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1151,7 +1151,7 @@ test_expect_success 'fetch exact SHA1' ' # unadvertised objects, so restrict this test to v0. # fetching the hidden object should fail by default - test_must_fail env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git fetch -v ../testrepo $the_commit:refs/heads/copy 2>err && test_i18ngrep "Server does not allow request for unadvertised object" err && test_must_fail git rev-parse --verify refs/heads/copy && @@ -1210,7 +1210,7 @@ do cd shallow && # Some protocol versions (e.g. 2) support fetching # unadvertised objects, so restrict this test to v0. - test_must_fail env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git fetch --depth=1 ../testrepo/.git $SHA1 && git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true && git fetch --depth=1 ../testrepo/.git $SHA1 && @@ -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 env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git fetch ../testrepo/.git $SHA1_3 && - test_must_fail env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git fetch ../testrepo/.git $SHA1_1 && git --git-dir=../testrepo/.git config uploadpack.allowreachablesha1inwant true && git fetch ../testrepo/.git $SHA1_1 && @@ -1251,7 +1251,7 @@ 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 env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git fetch ../testrepo/.git $SHA1_3 2>err && test_i18ngrep "remote error:.*not our ref.*$SHA1_3\$" err ) @@ -1291,7 +1291,7 @@ test_expect_success 'peeled advertisements are not considered ref tips' ' 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= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git fetch testrepo $oid 2>err && test_i18ngrep "Server does not allow request for unadvertised object" err ' diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index cf4cc32fd0..2f86fca042 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -5,7 +5,7 @@ test_description='pulling into void' . ./test-lib.sh modify () { - sed -e "$1" <"$2" >"$2.x" && + sed -e "$1" "$2" >"$2.x" && mv "$2.x" "$2" } @@ -15,8 +15,10 @@ test_pull_autostash () { git add new_file && git pull "$@" . copy && test_cmp_rev HEAD^ copy && - test "$(cat new_file)" = dirty && - test "$(cat file)" = "modified again" + echo dirty >expect && + test_cmp expect new_file && + echo "modified again" >expect && + test_cmp expect file } test_pull_autostash_fail () { @@ -39,8 +41,8 @@ test_expect_success 'pulling into void' ' cd cloned && git pull .. ) && - test -f file && - test -f cloned/file && + test_path_is_file file && + test_path_is_file cloned/file && test_cmp file cloned/file ' @@ -50,8 +52,8 @@ test_expect_success 'pulling into void using master:master' ' cd cloned-uho && git pull .. master:master ) && - test -f file && - test -f cloned-uho/file && + test_path_is_file file && + test_path_is_file cloned-uho/file && test_cmp file cloned-uho/file ' @@ -99,7 +101,7 @@ test_expect_success 'pulling into void must not create an octopus' ' ( cd cloned-octopus && test_must_fail git pull .. master master && - ! test -f file + test_path_is_missing file ) ' @@ -110,9 +112,11 @@ test_expect_success 'test . as a remote' ' echo updated >file && git commit -a -m updated && git checkout copy && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && git pull && - test "$(cat file)" = updated && + echo updated >expect && + test_cmp expect file && git reflog -1 >reflog.actual && sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && echo "OBJID HEAD@{0}: pull: Fast-forward" >reflog.expected && @@ -125,9 +129,11 @@ test_expect_success 'the default remote . should not break explicit pull' ' git commit -a -m modified && git checkout copy && git reset --hard HEAD^ && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && git pull . second && - test "$(cat file)" = modified && + echo modified >expect && + test_cmp expect file && git reflog -1 >reflog.actual && sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && echo "OBJID HEAD@{0}: pull . second: Fast-forward" >reflog.expected && @@ -137,10 +143,11 @@ test_expect_success 'the default remote . should not break explicit pull' ' test_expect_success 'fail if wildcard spec does not match any refs' ' git checkout -b test copy^ && test_when_finished "git checkout -f copy && git branch -D test" && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && test_must_fail git pull . "refs/nonexisting1/*:refs/nonexisting2/*" 2>err && test_i18ngrep "no candidates for merging" err && - test "$(cat file)" = file + test_cmp expect file ' test_expect_success 'fail if no branches specified with non-default remote' ' @@ -148,11 +155,12 @@ test_expect_success 'fail if no branches specified with non-default remote' ' test_when_finished "git remote remove test_remote" && git checkout -b test copy^ && test_when_finished "git checkout -f copy && git branch -D test" && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && test_config branch.test.remote origin && test_must_fail git pull test_remote 2>err && test_i18ngrep "specify a branch on the command line" err && - test "$(cat file)" = file + test_cmp expect file ' test_expect_success 'fail if not on a branch' ' @@ -160,10 +168,11 @@ test_expect_success 'fail if not on a branch' ' test_when_finished "git remote remove origin" && git checkout HEAD^ && test_when_finished "git checkout -f copy" && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && test_must_fail git pull 2>err && test_i18ngrep "not currently on a branch" err && - test "$(cat file)" = file + test_cmp expect file ' test_expect_success 'fail if no configuration for current branch' ' @@ -172,10 +181,11 @@ test_expect_success 'fail if no configuration for current branch' ' git checkout -b test copy^ && test_when_finished "git checkout -f copy && git branch -D test" && test_config branch.test.remote test_remote && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && test_must_fail git pull 2>err && test_i18ngrep "no tracking information" err && - test "$(cat file)" = file + test_cmp expect file ' test_expect_success 'pull --all: fail if no configuration for current branch' ' @@ -184,10 +194,11 @@ test_expect_success 'pull --all: fail if no configuration for current branch' ' git checkout -b test copy^ && test_when_finished "git checkout -f copy && git branch -D test" && test_config branch.test.remote test_remote && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && test_must_fail git pull --all 2>err && test_i18ngrep "There is no tracking information" err && - test "$(cat file)" = file + test_cmp expect file ' test_expect_success 'fail if upstream branch does not exist' ' @@ -195,26 +206,31 @@ test_expect_success 'fail if upstream branch does not exist' ' test_when_finished "git checkout -f copy && git branch -D test" && test_config branch.test.remote . && test_config branch.test.merge refs/heads/nonexisting && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && test_must_fail git pull 2>err && test_i18ngrep "no such ref was fetched" err && - test "$(cat file)" = file + test_cmp expect file ' test_expect_success 'fail if the index has unresolved entries' ' git checkout -b third second^ && test_when_finished "git checkout -f copy && git branch -D third" && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && test_commit modified2 file && - test -z "$(git ls-files -u)" && + git ls-files -u >unmerged && + test_must_be_empty unmerged && test_must_fail git pull . second && - test -n "$(git ls-files -u)" && + git ls-files -u >unmerged && + test_file_not_empty unmerged && cp file expected && test_must_fail git pull . second 2>err && test_i18ngrep "Pulling is not possible because you have unmerged files." err && test_cmp expected file && git add file && - test -z "$(git ls-files -u)" && + git ls-files -u >unmerged && + test_must_be_empty unmerged && test_must_fail git pull . second 2>err && test_i18ngrep "You have not concluded your merge" err && test_cmp expected file @@ -223,47 +239,66 @@ test_expect_success 'fail if the index has unresolved entries' ' test_expect_success 'fast-forwards working tree if branch head is updated' ' git checkout -b third second^ && test_when_finished "git checkout -f copy && git branch -D third" && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && git pull . second:third 2>err && test_i18ngrep "fetch updated the current branch head" err && - test "$(cat file)" = modified && - test "$(git rev-parse third)" = "$(git rev-parse second)" + echo modified >expect && + test_cmp expect file && + test_cmp_rev third second ' test_expect_success 'fast-forward fails with conflicting work tree' ' git checkout -b third second^ && test_when_finished "git checkout -f copy && git branch -D third" && - test "$(cat file)" = file && + echo file >expect && + test_cmp expect file && echo conflict >file && test_must_fail git pull . second:third 2>err && test_i18ngrep "Cannot fast-forward your working tree" err && - test "$(cat file)" = conflict && - test "$(git rev-parse third)" = "$(git rev-parse second)" + echo conflict >expect && + test_cmp expect file && + test_cmp_rev third second ' test_expect_success '--rebase' ' git branch to-rebase && - echo modified again > file && + echo modified again >file && git commit -m file file && git checkout to-rebase && - echo new > file2 && + echo new >file2 && git add file2 && git commit -m "new file" && git tag before-rebase && git pull --rebase . copy && - test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" && - test new = "$(git show HEAD:file2)" + test_cmp_rev HEAD^ copy && + echo new >expect && + git show HEAD:file2 >actual && + test_cmp expect actual ' -test_expect_success '--rebase fast forward' ' +test_expect_success '--rebase (merge) fast forward' ' git reset --hard before-rebase && git checkout -b ff && echo another modification >file && git commit -m third file && git checkout to-rebase && - git pull --rebase . ff && - test "$(git rev-parse HEAD)" = "$(git rev-parse ff)" && + git -c rebase.backend=merge pull --rebase . ff && + test_cmp_rev HEAD ff && + + # The above only validates the result. Did we actually bypass rebase? + git reflog -1 >reflog.actual && + sed "s/^[0-9a-f][0-9a-f]*/OBJID/" reflog.actual >reflog.fuzzy && + echo "OBJID HEAD@{0}: pull --rebase . ff: Fast-forward" >reflog.expected && + test_cmp reflog.expected reflog.fuzzy +' + +test_expect_success '--rebase (am) fast forward' ' + git reset --hard before-rebase && + + git -c rebase.backend=apply pull --rebase . ff && + test_cmp_rev HEAD ff && # The above only validates the result. Did we actually bypass rebase? git reflog -1 >reflog.actual && @@ -287,7 +322,7 @@ test_expect_success '--rebase --autostash fast forward' ' git checkout behind && echo dirty >file && git pull --rebase --autostash . to-rebase-ff && - test "$(git rev-parse HEAD)" = "$(git rev-parse to-rebase-ff)" + test_cmp_rev HEAD to-rebase-ff ' test_expect_success '--rebase with conflicts shows advice' ' @@ -305,7 +340,7 @@ test_expect_success '--rebase with conflicts shows advice' ' test_tick && git commit -m "Create conflict" seq.txt && test_must_fail git pull --rebase . seq 2>err >out && - test_i18ngrep "Resolve all conflicts manually" out + test_i18ngrep "Resolve all conflicts manually" err ' test_expect_success 'failed --rebase shows advice' ' @@ -319,15 +354,17 @@ test_expect_success 'failed --rebase shows advice' ' git checkout -f -b fails-to-rebase HEAD^ && test_commit v2-without-cr file "2" file2-lf && test_must_fail git pull --rebase . diverging 2>err >out && - test_i18ngrep "Resolve all conflicts manually" out + test_i18ngrep "Resolve all conflicts manually" err ' test_expect_success '--rebase fails with multiple branches' ' git reset --hard before-rebase && test_must_fail git pull --rebase . copy master 2>err && - test "$(git rev-parse HEAD)" = "$(git rev-parse before-rebase)" && + test_cmp_rev HEAD before-rebase && test_i18ngrep "Cannot rebase onto multiple branches" err && - test modified = "$(git show HEAD:file)" + echo modified >expect && + git show HEAD:file >actual && + test_cmp expect actual ' test_expect_success 'pull --rebase succeeds with dirty working directory and rebase.autostash set' ' @@ -377,8 +414,10 @@ test_expect_success 'pull.rebase' ' git reset --hard before-rebase && test_config pull.rebase true && git pull . copy && - test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" && - test new = "$(git show HEAD:file2)" + test_cmp_rev HEAD^ copy && + echo new >expect && + git show HEAD:file2 >actual && + test_cmp expect actual ' test_expect_success 'pull --autostash & pull.rebase=true' ' @@ -395,8 +434,10 @@ test_expect_success 'branch.to-rebase.rebase' ' git reset --hard before-rebase && test_config branch.to-rebase.rebase true && git pull . copy && - test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" && - test new = "$(git show HEAD:file2)" + test_cmp_rev HEAD^ copy && + echo new >expect && + git show HEAD:file2 >actual && + test_cmp expect actual ' test_expect_success 'branch.to-rebase.rebase should override pull.rebase' ' @@ -404,23 +445,29 @@ test_expect_success 'branch.to-rebase.rebase should override pull.rebase' ' test_config pull.rebase true && test_config branch.to-rebase.rebase false && git pull . copy && - test "$(git rev-parse HEAD^)" != "$(git rev-parse copy)" && - test new = "$(git show HEAD:file2)" + test_cmp_rev ! HEAD^ copy && + echo new >expect && + git show HEAD:file2 >actual && + test_cmp expect actual ' -test_expect_success "pull --rebase warns on --verify-signatures" ' +test_expect_success 'pull --rebase warns on --verify-signatures' ' git reset --hard before-rebase && git pull --rebase --verify-signatures . copy 2>err && - test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" && - test new = "$(git show HEAD:file2)" && + test_cmp_rev HEAD^ copy && + echo new >expect && + git show HEAD:file2 >actual && + test_cmp expect actual && test_i18ngrep "ignoring --verify-signatures for rebase" err ' -test_expect_success "pull --rebase does not warn on --no-verify-signatures" ' +test_expect_success 'pull --rebase does not warn on --no-verify-signatures' ' git reset --hard before-rebase && git pull --rebase --no-verify-signatures . copy 2>err && - test "$(git rev-parse HEAD^)" = "$(git rev-parse copy)" && - test new = "$(git show HEAD:file2)" && + test_cmp_rev HEAD^ copy && + echo new >expect && + git show HEAD:file2 >actual && + test_cmp expect actual && test_i18ngrep ! "verify-signatures" err ' @@ -440,25 +487,31 @@ test_expect_success 'pull.rebase=false create a new merge commit' ' git reset --hard before-preserve-rebase && test_config pull.rebase false && git pull . copy && - test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" && - test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" && - test file3 = "$(git show HEAD:file3.t)" + test_cmp_rev HEAD^1 before-preserve-rebase && + test_cmp_rev HEAD^2 copy && + echo file3 >expect && + git show HEAD:file3.t >actual && + test_cmp expect actual ' test_expect_success 'pull.rebase=true flattens keep-merge' ' git reset --hard before-preserve-rebase && test_config pull.rebase true && git pull . copy && - test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" && - test file3 = "$(git show HEAD:file3.t)" + test_cmp_rev HEAD^^ copy && + echo file3 >expect && + git show HEAD:file3.t >actual && + test_cmp expect actual ' test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' ' git reset --hard before-preserve-rebase && test_config pull.rebase 1 && git pull . copy && - test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" && - test file3 = "$(git show HEAD:file3.t)" + test_cmp_rev HEAD^^ copy && + echo file3 >expect && + git show HEAD:file3.t >actual && + test_cmp expect actual ' test_expect_success REBASE_P \ @@ -466,8 +519,8 @@ test_expect_success REBASE_P \ git reset --hard before-preserve-rebase && test_config pull.rebase preserve && git pull . copy && - test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" && - test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)" + test_cmp_rev HEAD^^ copy && + test_cmp_rev HEAD^2 keep-merge ' test_expect_success 'pull.rebase=interactive' ' @@ -478,7 +531,8 @@ test_expect_success 'pull.rebase=interactive' ' test_set_editor "$TRASH_DIRECTORY/fake-editor" && test_when_finished "test_might_fail git rebase --abort" && test_must_fail git pull --rebase=interactive . copy && - test "I was here" = "$(cat fake.out)" + echo "I was here" >expect && + test_cmp expect fake.out ' test_expect_success 'pull --rebase=i' ' @@ -489,30 +543,35 @@ test_expect_success 'pull --rebase=i' ' test_set_editor "$TRASH_DIRECTORY/fake-editor" && test_when_finished "test_might_fail git rebase --abort" && test_must_fail git pull --rebase=i . copy && - test "I was here, too" = "$(cat fake.out)" + echo "I was here, too" >expect && + test_cmp expect fake.out ' test_expect_success 'pull.rebase=invalid fails' ' git reset --hard before-preserve-rebase && test_config pull.rebase invalid && - ! git pull . copy + test_must_fail git pull . copy ' test_expect_success '--rebase=false create a new merge commit' ' git reset --hard before-preserve-rebase && test_config pull.rebase true && git pull --rebase=false . copy && - test "$(git rev-parse HEAD^1)" = "$(git rev-parse before-preserve-rebase)" && - test "$(git rev-parse HEAD^2)" = "$(git rev-parse copy)" && - test file3 = "$(git show HEAD:file3.t)" + test_cmp_rev HEAD^1 before-preserve-rebase && + test_cmp_rev HEAD^2 copy && + echo file3 >expect && + git show HEAD:file3.t >actual && + test_cmp expect actual ' test_expect_success '--rebase=true rebases and flattens keep-merge' ' git reset --hard before-preserve-rebase && test_config pull.rebase preserve && git pull --rebase=true . copy && - test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" && - test file3 = "$(git show HEAD:file3.t)" + test_cmp_rev HEAD^^ copy && + echo file3 >expect && + git show HEAD:file3.t >actual && + test_cmp expect actual ' test_expect_success REBASE_P \ @@ -520,58 +579,62 @@ test_expect_success REBASE_P \ git reset --hard before-preserve-rebase && test_config pull.rebase true && git pull --rebase=preserve . copy && - test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" && - test "$(git rev-parse HEAD^2)" = "$(git rev-parse keep-merge)" + test_cmp_rev HEAD^^ copy && + test_cmp_rev HEAD^2 keep-merge ' test_expect_success '--rebase=invalid fails' ' git reset --hard before-preserve-rebase && - ! git pull --rebase=invalid . copy + test_must_fail git pull --rebase=invalid . copy ' test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' ' git reset --hard before-preserve-rebase && test_config pull.rebase preserve && git pull --rebase . copy && - test "$(git rev-parse HEAD^^)" = "$(git rev-parse copy)" && - test file3 = "$(git show HEAD:file3.t)" + test_cmp_rev HEAD^^ copy && + echo file3 >expect && + git show HEAD:file3.t >actual && + test_cmp expect actual ' test_expect_success '--rebase with rebased upstream' ' - git remote add -f me . && git checkout copy && git tag copy-orig && git reset --hard HEAD^ && - echo conflicting modification > file && + echo conflicting modification >file && git commit -m conflict file && git checkout to-rebase && - echo file > file2 && + echo file >file2 && git commit -m to-rebase file2 && git tag to-rebase-orig && git pull --rebase me copy && - test "conflicting modification" = "$(cat file)" && - test file = "$(cat file2)" - + echo "conflicting modification" >expect && + test_cmp expect file && + echo file >expect && + test_cmp expect file2 ' test_expect_success '--rebase -f with rebased upstream' ' test_when_finished "test_might_fail git rebase --abort" && git reset --hard to-rebase-orig && git pull --rebase -f me copy && - test "conflicting modification" = "$(cat file)" && - test file = "$(cat file2)" + echo "conflicting modification" >expect && + test_cmp expect file && + echo file >expect && + test_cmp expect file2 ' test_expect_success '--rebase with rebased default upstream' ' - git update-ref refs/remotes/me/copy copy-orig && git checkout --track -b to-rebase2 me/copy && git reset --hard to-rebase-orig && git pull --rebase && - test "conflicting modification" = "$(cat file)" && - test file = "$(cat file2)" - + echo "conflicting modification" >expect && + test_cmp expect file && + echo file >expect && + test_cmp expect file2 ' test_expect_success 'rebased upstream + fetch + pull --rebase' ' @@ -582,13 +645,14 @@ test_expect_success 'rebased upstream + fetch + pull --rebase' ' git reset --hard to-rebase-orig && git fetch && git pull --rebase && - test "conflicting modification" = "$(cat file)" && - test file = "$(cat file2)" + echo "conflicting modification" >expect && + test_cmp expect file && + echo file >expect && + test_cmp expect file2 ' test_expect_success 'pull --rebase dies early with dirty working directory' ' - git checkout to-rebase && git update-ref refs/remotes/me/copy copy^ && COPY="$(git rev-parse --verify me/copy)" && @@ -596,23 +660,23 @@ test_expect_success 'pull --rebase dies early with dirty working directory' ' test_config branch.to-rebase.remote me && test_config branch.to-rebase.merge refs/heads/copy && test_config branch.to-rebase.rebase true && - echo dirty >> file && + echo dirty >>file && git add file && test_must_fail git pull && - test "$COPY" = "$(git rev-parse --verify me/copy)" && + test_cmp_rev "$COPY" me/copy && git checkout HEAD -- file && git pull && - test "$COPY" != "$(git rev-parse --verify me/copy)" - + test_cmp_rev ! "$COPY" me/copy ' test_expect_success 'pull --rebase works on branch yet to be born' ' git rev-parse master >expect && mkdir empty_repo && - (cd empty_repo && - git init && - git pull --rebase .. master && - git rev-parse HEAD >../actual + ( + cd empty_repo && + git init && + git pull --rebase .. master && + git rev-parse HEAD >../actual ) && test_cmp expect actual ' @@ -624,10 +688,14 @@ test_expect_success 'pull --rebase fails on unborn branch with staged changes' ' cd empty_repo2 && echo staged-file >staged-file && git add staged-file && - test "$(git ls-files)" = staged-file && + echo staged-file >expect && + git ls-files >actual && + test_cmp expect actual && test_must_fail git pull --rebase .. master 2>err && - test "$(git ls-files)" = staged-file && - test "$(git show :staged-file)" = staged-file && + git ls-files >actual && + test_cmp expect actual && + git show :staged-file >actual && + test_cmp expect actual && test_i18ngrep "unborn branch with changes added to the index" err ) ' @@ -638,7 +706,8 @@ test_expect_success 'pull --rebase fails on corrupt HEAD' ' ( cd corrupt && test_commit one && - obj=$(git rev-parse --verify HEAD | sed "s#^..#&/#") && + git rev-parse --verify HEAD >head && + obj=$(sed "s#^..#&/#" head) && rm -f .git/objects/$obj && test_must_fail git pull --rebase ) @@ -646,66 +715,79 @@ test_expect_success 'pull --rebase fails on corrupt HEAD' ' test_expect_success 'setup for detecting upstreamed changes' ' mkdir src && - (cd src && - git init && - printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff && - git add stuff && - git commit -m "Initial revision" + ( + cd src && + git init && + printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" > stuff && + git add stuff && + git commit -m "Initial revision" ) && git clone src dst && - (cd src && - modify s/5/43/ stuff && - git commit -a -m "5->43" && - modify s/6/42/ stuff && - git commit -a -m "Make it bigger" + ( + cd src && + modify s/5/43/ stuff && + git commit -a -m "5->43" && + modify s/6/42/ stuff && + git commit -a -m "Make it bigger" ) && - (cd dst && - modify s/5/43/ stuff && - git commit -a -m "Independent discovery of 5->43" + ( + cd dst && + modify s/5/43/ stuff && + git commit -a -m "Independent discovery of 5->43" ) ' test_expect_success 'git pull --rebase detects upstreamed changes' ' - (cd dst && - git pull --rebase && - test -z "$(git ls-files -u)" + ( + cd dst && + git pull --rebase && + git ls-files -u >untracked && + test_must_be_empty untracked ) ' test_expect_success 'setup for avoiding reapplying old patches' ' - (cd dst && - test_might_fail git rebase --abort && - git reset --hard origin/master + ( + cd dst && + test_might_fail git rebase --abort && + git reset --hard origin/master ) && git clone --bare src src-replace.git && rm -rf src && mv src-replace.git src && - (cd dst && - modify s/2/22/ stuff && - git commit -a -m "Change 2" && - modify s/3/33/ stuff && - git commit -a -m "Change 3" && - modify s/4/44/ stuff && - git commit -a -m "Change 4" && - git push && - - modify s/44/55/ stuff && - git commit --amend -a -m "Modified Change 4" + ( + cd dst && + modify s/2/22/ stuff && + git commit -a -m "Change 2" && + modify s/3/33/ stuff && + git commit -a -m "Change 3" && + modify s/4/44/ stuff && + git commit -a -m "Change 4" && + git push && + + modify s/44/55/ stuff && + git commit --amend -a -m "Modified Change 4" ) ' test_expect_success 'git pull --rebase does not reapply old patches' ' - (cd dst && - test_must_fail git pull --rebase && - test 1 = $(find .git/rebase-apply -name "000*" | wc -l) + ( + cd dst && + test_must_fail git pull --rebase && + cat .git/rebase-merge/done .git/rebase-merge/git-rebase-todo >work && + grep -v -e \# -e ^$ work >patches && + test_line_count = 1 patches && + rm -f work ) ' test_expect_success 'git pull --rebase against local branch' ' git checkout -b copy2 to-rebase-orig && git pull --rebase . to-rebase && - test "conflicting modification" = "$(cat file)" && - test file = "$(cat file2)" + echo "conflicting modification" >expect && + test_cmp expect file && + echo file >expect && + test_cmp expect file2 ' test_done diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh index 44309566f1..4d1e0c363e 100755 --- a/t/t5528-push-default.sh +++ b/t/t5528-push-default.sh @@ -163,7 +163,7 @@ test_pushdefault_workflow success current master # update parent1's foo (which is our upstream) test_pushdefault_workflow success upstream foo -# upsream is foo which is not the name of the current branch +# upstream is foo which is not the name of the current branch test_pushdefault_workflow failure simple master # master and foo are updated diff --git a/t/t5530-upload-pack-error.sh b/t/t5530-upload-pack-error.sh index a1d3031d40..4ce9a9f704 100755 --- a/t/t5530-upload-pack-error.sh +++ b/t/t5530-upload-pack-error.sh @@ -14,7 +14,7 @@ corrupt_repo () { } test_expect_success 'setup and corrupt repository' ' - + test_oid_init && echo file >file && git add file && git rev-parse :file && @@ -31,9 +31,10 @@ test_expect_success 'fsck fails' ' ' test_expect_success 'upload-pack fails due to error in pack-objects packing' ' - - printf "0032want %s\n00000009done\n0000" \ - $(git rev-parse HEAD) >input && + head=$(git rev-parse HEAD) && + hexsz=$(test_oid hexsz) && + printf "%04xwant %s\n00000009done\n0000" \ + $(($hexsz + 10)) $head >input && test_must_fail git upload-pack . <input >/dev/null 2>output.err && test_i18ngrep "unable to read" output.err && test_i18ngrep "pack-objects died" output.err @@ -51,16 +52,17 @@ test_expect_success 'fsck fails' ' ' test_expect_success 'upload-pack fails due to error in rev-list' ' - printf "0032want %s\n0034shallow %s00000009done\n0000" \ - $(git rev-parse HEAD) $(git rev-parse HEAD^) >input && + printf "%04xwant %s\n%04xshallow %s00000009done\n0000" \ + $(($hexsz + 10)) $(git rev-parse HEAD) \ + $(($hexsz + 12)) $(git rev-parse HEAD^) >input && test_must_fail git upload-pack . <input >/dev/null 2>output.err && grep "bad tree object" output.err ' test_expect_success 'upload-pack fails due to bad want (no object)' ' - printf "0045want %s multi_ack_detailed\n00000009done\n0000" \ - "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef" >input && + printf "%04xwant %s multi_ack_detailed\n00000009done\n0000" \ + $(($hexsz + 29)) $(test_oid deadbeef) >input && test_must_fail git upload-pack . <input >output 2>output.err && grep "not our ref" output.err && grep "ERR" output && @@ -70,8 +72,8 @@ test_expect_success 'upload-pack fails due to bad want (no object)' ' 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 && + printf "%04xwant %s multi_ack_detailed\n00000009done\n0000" \ + $(($hexsz + 29)) "$oid" >input && test_must_fail git upload-pack . <input >output 2>output.err && grep "not our ref" output.err && grep "ERR" output && @@ -80,8 +82,8 @@ test_expect_success 'upload-pack fails due to bad want (not tip)' ' test_expect_success 'upload-pack fails due to error in pack-objects enumeration' ' - printf "0032want %s\n00000009done\n0000" \ - $(git rev-parse HEAD) >input && + printf "%04xwant %s\n00000009done\n0000" \ + $((hexsz + 10)) $(git rev-parse HEAD) >input && test_must_fail git upload-pack . <input >/dev/null 2>output.err && grep "bad tree object" output.err && grep "pack-objects died" output.err diff --git a/t/t5535-fetch-push-symref.sh b/t/t5535-fetch-push-symref.sh index 8ed58d27f2..e8f6d233ff 100755 --- a/t/t5535-fetch-push-symref.sh +++ b/t/t5535-fetch-push-symref.sh @@ -1,6 +1,6 @@ #!/bin/sh -test_description='avoiding conflicting update thru symref aliasing' +test_description='avoiding conflicting update through symref aliasing' . ./test-lib.sh diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh index 97a67728ca..9e16512fe3 100755 --- a/t/t5537-fetch-shallow.sh +++ b/t/t5537-fetch-shallow.sh @@ -15,7 +15,11 @@ test_expect_success 'setup' ' commit 2 && commit 3 && commit 4 && - git config --global transfer.fsckObjects true + git config --global transfer.fsckObjects true && + test_oid_cache <<-EOF + sed sha1:s/0034shallow %s/0036unshallow %s/ + sed sha256:s/004cshallow %s/004eunshallow %s/ + EOF ' test_expect_success 'setup shallow clone' ' @@ -239,7 +243,7 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f # with an empty packfile. This is done by refetching with a shorter # depth (to ensure that the packfile is empty), and overwriting the # shallow line in the response with the unshallow line we want. - printf "s/0034shallow %s/0036unshallow %s/" \ + printf "$(test_oid sed)" \ "$(git -C "$REPO" rev-parse HEAD)" \ "$(git -C "$REPO" rev-parse HEAD^)" \ >"$HTTPD_ROOT_PATH/one-time-sed" && diff --git a/t/t5539-fetch-http-shallow.sh b/t/t5539-fetch-http-shallow.sh index b4ad81f006..c0d02dee89 100755 --- a/t/t5539-fetch-http-shallow.sh +++ b/t/t5539-fetch-http-shallow.sh @@ -69,7 +69,7 @@ test_expect_success 'no shallow lines after receiving ACK ready' ' test_commit new-too && # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. - GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" GIT_TEST_PROTOCOL_VERSION= \ + GIT_TRACE_PACKET="$TRASH_DIRECTORY/trace" GIT_TEST_PROTOCOL_VERSION=0 \ git fetch --depth=2 && grep "fetch-pack< ACK .* ready" ../trace && ! grep "fetch-pack> done" ../trace diff --git a/t/t5540-http-push-webdav.sh b/t/t5540-http-push-webdav.sh index a094fd5e71..d476c33509 100755 --- a/t/t5540-http-push-webdav.sh +++ b/t/t5540-http-push-webdav.sh @@ -134,15 +134,13 @@ test_expect_success 'MKCOL sends directory names with trailing slashes' ' x1="[0-9a-f]" x2="$x1$x1" -x5="$x1$x1$x1$x1$x1" -x38="$x5$x5$x5$x5$x5$x5$x5$x1$x1$x1" -x40="$x38$x2" +xtrunc=$(echo $OID_REGEX | sed -e "s/\[0-9a-f\]\[0-9a-f\]//") test_expect_success 'PUT and MOVE sends object to URLs with SHA-1 hash suffix' ' sed \ -e "s/PUT /OP /" \ -e "s/MOVE /OP /" \ - -e "s|/objects/$x2/${x38}_$x40|WANTED_PATH_REQUEST|" \ + -e "s|/objects/$x2/${xtrunc}_$OID_REGEX|WANTED_PATH_REQUEST|" \ "$HTTPD_ROOT_PATH"/access.log | grep -e "\"OP .*WANTED_PATH_REQUEST HTTP/[.0-9]*\" 20[0-9] " diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index 4c970787b0..23be8ce92d 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -49,7 +49,7 @@ test_expect_success 'no empty path components' ' # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. - if test -z "$GIT_TEST_PROTOCOL_VERSION" + if test "$GIT_TEST_PROTOCOL_VERSION" = 0 then check_access_log exp fi @@ -135,7 +135,7 @@ EOF test_expect_success 'used receive-pack service' ' # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. - if test -z "$GIT_TEST_PROTOCOL_VERSION" + if test "$GIT_TEST_PROTOCOL_VERSION" = 0 then check_access_log exp fi diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh index 04b34c4de1..38e6f7340e 100755 --- a/t/t5545-push-options.sh +++ b/t/t5545-push-options.sh @@ -115,7 +115,7 @@ test_expect_success 'push options and submodules' ' git -C parent submodule add ../upstream workbench && git -C parent/workbench remote add up ../../upstream && - git -C parent commit -m "add submoule" && + git -C parent commit -m "add submodule" && test_commit -C parent/workbench two && git -C parent add workbench && diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index e38e543867..6788aeface 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -43,7 +43,7 @@ test_expect_success 'clone http repository' ' < Cache-Control: no-cache, max-age=0, must-revalidate < Content-Type: application/x-git-upload-pack-result EOF - GIT_TRACE_CURL=true GIT_TEST_PROTOCOL_VERSION= \ + GIT_TRACE_CURL=true GIT_TEST_PROTOCOL_VERSION=0 \ git clone --quiet $HTTPD_URL/smart/repo.git clone 2>err && test_cmp file clone/file && tr '\''\015'\'' Q <err | @@ -84,7 +84,7 @@ test_expect_success 'clone http repository' ' # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. - if test -z "$GIT_TEST_PROTOCOL_VERSION" + if test "$GIT_TEST_PROTOCOL_VERSION" = 0 then sed -e "s/^> Accept-Encoding: .*/> Accept-Encoding: ENCODINGS/" \ actual >actual.smudged && @@ -113,7 +113,7 @@ test_expect_success 'used upload-pack service' ' # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. - if test -z "$GIT_TEST_PROTOCOL_VERSION" + if test "$GIT_TEST_PROTOCOL_VERSION" = 0 then check_access_log exp fi @@ -241,7 +241,7 @@ test_expect_success 'cookies stored in http.cookiefile when http.savecookies set # NEEDSWORK: If the overspecification of the expected result is reduced, we # might be able to run this test in all protocol versions. - if test -z "$GIT_TEST_PROTOCOL_VERSION" + if test "$GIT_TEST_PROTOCOL_VERSION" = 0 then tail -3 cookies.txt | sort >cookies_tail.txt && test_cmp expect_cookies.txt cookies_tail.txt @@ -336,7 +336,7 @@ test_expect_success 'test allowreachablesha1inwant with unreachable' ' git -C test_reachable.git remote add origin "$HTTPD_URL/smart/repo.git" && # Some protocol versions (e.g. 2) support fetching # unadvertised objects, so restrict this test to v0. - test_must_fail env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git -C test_reachable.git fetch origin "$(git rev-parse HEAD)" ' @@ -358,7 +358,7 @@ test_expect_success 'test allowanysha1inwant with unreachable' ' git -C test_reachable.git remote add origin "$HTTPD_URL/smart/repo.git" && # Some protocol versions (e.g. 2) support fetching # unadvertised objects, so restrict this test to v0. - test_must_fail env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git -C test_reachable.git fetch origin "$(git rev-parse HEAD)" && git -C "$server" config uploadpack.allowanysha1inwant 1 && diff --git a/t/t5552-skipping-fetch-negotiator.sh b/t/t5552-skipping-fetch-negotiator.sh index f70cbcc9ca..156c704040 100755 --- a/t/t5552-skipping-fetch-negotiator.sh +++ b/t/t5552-skipping-fetch-negotiator.sh @@ -107,7 +107,11 @@ test_expect_success 'use ref advertisement to filter out commits' ' # The ref advertisement itself is filtered when protocol v2 is used, so # use v0. - GIT_TEST_PROTOCOL_VERSION= trace_fetch client origin to_fetch && + ( + GIT_TEST_PROTOCOL_VERSION=0 && + export GIT_TEST_PROTOCOL_VERSION && + trace_fetch client origin to_fetch + ) && have_sent c5 c4^ c2side && have_not_sent c4 c4^^ c4^^^ ' @@ -169,7 +173,17 @@ test_expect_success 'do not send "have" with ancestors of commits that server AC test_commit -C server commit-on-b1 && test_config -C client fetch.negotiationalgorithm skipping && - trace_fetch client "$(pwd)/server" to_fetch && + + # NEEDSWORK: The number of "have"s sent depends on whether the transport + # is stateful. If the overspecification of the result were reduced, this + # test could be used for both stateful and stateless transports. + ( + # Force protocol v0, in which local transport is stateful (in + # protocol v2 it is stateless). + GIT_TEST_PROTOCOL_VERSION=0 && + export GIT_TEST_PROTOCOL_VERSION && + trace_fetch client "$(pwd)/server" to_fetch + ) && grep " fetch" trace && # fetch-pack sends 2 requests each containing 16 "have" lines before diff --git a/t/t5562-http-backend-content-length.sh b/t/t5562-http-backend-content-length.sh index f0f425b2cf..4a110b307e 100755 --- a/t/t5562-http-backend-content-length.sh +++ b/t/t5562-http-backend-content-length.sh @@ -59,7 +59,7 @@ test_expect_success 'setup' ' printf done | packetize >>fetch_body && test_copy_bytes 10 <fetch_body >fetch_body.trunc && hash_next=$(git commit-tree -p HEAD -m next HEAD^{tree}) && - printf "%s %s refs/heads/newbranch\\0report-status\\n" "$_z40" "$hash_next" | packetize >push_body && + printf "%s %s refs/heads/newbranch\\0report-status\\n" "$ZERO_OID" "$hash_next" | packetize >push_body && printf 0000 >>push_body && echo "$hash_next" | git pack-objects --stdout >>push_body && test_copy_bytes 10 <push_body >push_body.trunc && diff --git a/t/t5573-pull-verify-signatures.sh b/t/t5573-pull-verify-signatures.sh index 3e9876e197..a53dd8550d 100755 --- a/t/t5573-pull-verify-signatures.sh +++ b/t/t5573-pull-verify-signatures.sh @@ -60,6 +60,27 @@ test_expect_success GPG 'pull commit with untrusted signature with --verify-sign test_i18ngrep "has an untrusted GPG signature" pullerror ' +test_expect_success GPG 'pull commit with untrusted signature with --verify-signatures and minTrustLevel=ultimate' ' + test_when_finished "git reset --hard && git checkout initial" && + test_config gpg.minTrustLevel ultimate && + test_must_fail git pull --ff-only --verify-signatures untrusted 2>pullerror && + test_i18ngrep "has an untrusted GPG signature" pullerror +' + +test_expect_success GPG 'pull commit with untrusted signature with --verify-signatures and minTrustLevel=marginal' ' + test_when_finished "git reset --hard && git checkout initial" && + test_config gpg.minTrustLevel marginal && + test_must_fail git pull --ff-only --verify-signatures untrusted 2>pullerror && + test_i18ngrep "has an untrusted GPG signature" pullerror +' + +test_expect_success GPG 'pull commit with untrusted signature with --verify-signatures and minTrustLevel=undefined' ' + test_when_finished "git reset --hard && git checkout initial" && + test_config gpg.minTrustLevel undefined && + git pull --ff-only --verify-signatures untrusted >pulloutput && + test_i18ngrep "has a good GPG signature" pulloutput +' + test_expect_success GPG 'pull signed commit with --verify-signatures' ' test_when_finished "git reset --hard && git checkout initial" && git pull --verify-signatures signed >pulloutput && @@ -79,10 +100,53 @@ test_expect_success GPG 'pull commit with bad signature with --no-verify-signatu ' test_expect_success GPG 'pull unsigned commit into unborn branch' ' + test_when_finished "rm -rf empty-repo" && git init empty-repo && test_must_fail \ git -C empty-repo pull --verify-signatures .. 2>pullerror && test_i18ngrep "does not have a GPG signature" pullerror ' +test_expect_success GPG 'pull commit into unborn branch with bad signature and --verify-signatures' ' + test_when_finished "rm -rf empty-repo" && + git init empty-repo && + test_must_fail \ + git -C empty-repo pull --ff-only --verify-signatures ../bad 2>pullerror && + test_i18ngrep "has a bad GPG signature" pullerror +' + +test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures' ' + test_when_finished "rm -rf empty-repo" && + git init empty-repo && + test_must_fail \ + git -C empty-repo pull --ff-only --verify-signatures ../untrusted 2>pullerror && + test_i18ngrep "has an untrusted GPG signature" pullerror +' + +test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures and minTrustLevel=ultimate' ' + test_when_finished "rm -rf empty-repo" && + git init empty-repo && + test_config_global gpg.minTrustLevel ultimate && + test_must_fail \ + git -C empty-repo pull --ff-only --verify-signatures ../untrusted 2>pullerror && + test_i18ngrep "has an untrusted GPG signature" pullerror +' + +test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures and minTrustLevel=marginal' ' + test_when_finished "rm -rf empty-repo" && + git init empty-repo && + test_config_global gpg.minTrustLevel marginal && + test_must_fail \ + git -C empty-repo pull --ff-only --verify-signatures ../untrusted 2>pullerror && + test_i18ngrep "has an untrusted GPG signature" pullerror +' + +test_expect_success GPG 'pull commit into unborn branch with untrusted signature and --verify-signatures and minTrustLevel=undefined' ' + test_when_finished "rm -rf empty-repo" && + git init empty-repo && + test_config_global gpg.minTrustLevel undefined && + git -C empty-repo pull --ff-only --verify-signatures ../untrusted >pulloutput && + test_i18ngrep "has a good GPG signature" pulloutput +' + test_done diff --git a/t/t5580-clone-push-unc.sh b/t/t5580-unc-paths.sh index b3c8a92450..cf768b3a27 100755 --- a/t/t5580-clone-push-unc.sh +++ b/t/t5580-unc-paths.sh @@ -40,11 +40,23 @@ test_expect_success clone ' git clone "file://$UNCPATH" clone ' +test_expect_success 'clone without file://' ' + git clone "$UNCPATH" clone-without-file +' + test_expect_success 'clone with backslashed path' ' BACKSLASHED="$(echo "$UNCPATH" | tr / \\\\)" && git clone "$BACKSLASHED" backslashed ' +test_expect_success fetch ' + git init to-fetch && + ( + cd to-fetch && + git fetch "$UNCPATH" master + ) +' + test_expect_success push ' ( cd clone && @@ -58,7 +70,7 @@ test_expect_success push ' test_expect_success MINGW 'remote nick cannot contain backslashes' ' BACKSLASHED="$(winpwd | tr / \\\\)" && - git ls-remote "$BACKSLASHED" >out 2>err && + git ls-remote "$BACKSLASHED" 2>err && test_i18ngrep ! "unable to access" err ' diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index ad8c41176e..84ea2a3eb7 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -635,10 +635,10 @@ partial_clone_server () { rm -rf "$SERVER" client && test_create_repo "$SERVER" && test_commit -C "$SERVER" one && - HASH1=$(git hash-object "$SERVER/one.t") && + HASH1=$(git -C "$SERVER" hash-object one.t) && git -C "$SERVER" revert HEAD && test_commit -C "$SERVER" two && - HASH2=$(git hash-object "$SERVER/two.t") && + HASH2=$(git -C "$SERVER" hash-object two.t) && test_config -C "$SERVER" uploadpack.allowfilter 1 && test_config -C "$SERVER" uploadpack.allowanysha1inwant 1 } diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index 4894237ab8..0c74b4e21a 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -326,15 +326,16 @@ test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at obje for raw in $(ls T*.raw) do sed -e "s!/../!/Y/!; s![0-9a-f]\{38,\}!Z!" -e "/commit-graph/d" \ - -e "/multi-pack-index/d" <$raw >$raw.de-sha || return 1 + -e "/multi-pack-index/d" <$raw >$raw.de-sha-1 && + sort $raw.de-sha-1 >$raw.de-sha || return 1 done && cat >expected-files <<-EOF && ./Y/Z ./Y/Z + ./Y/Z ./a-loose-dir/Z ./an-object - ./Y/Z ./info/packs ./pack/pack-Z.idx ./pack/pack-Z.pack diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index b7a3fdf02d..9108ff6fbd 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -64,7 +64,7 @@ test_expect_success 'ridiculously long subject in boundary' ' test -s heads && git fetch long-subject-bundle.bdl && sed -n "/^-/{p;q;}" long-subject-bundle.bdl >boundary && - grep "^-[0-9a-f]\\{40\\} " boundary + grep "^-$OID_REGEX " boundary ' test_expect_success 'prerequisites with an empty commit message' ' diff --git a/t/t5608-clone-2gb.sh b/t/t5608-clone-2gb.sh index 2c6bc07344..eee0842888 100755 --- a/t/t5608-clone-2gb.sh +++ b/t/t5608-clone-2gb.sh @@ -3,7 +3,7 @@ test_description='Test cloning a repository larger than 2 gigabyte' . ./test-lib.sh -if test -z "$GIT_TEST_CLONE_2GB" +if ! test_bool_env GIT_TEST_CLONE_2GB false then say 'Skipping expensive 2GB clone test; enable it with GIT_TEST_CLONE_2GB=t' else diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index eaa33a852b..3988a9cea2 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -304,6 +304,117 @@ test_expect_success 'partial clone with unresolvable sparse filter fails cleanly test_i18ngrep "unable to parse sparse filter data in" err ' +setup_triangle () { + rm -rf big-blob.txt server client promisor-remote && + + printf "line %d\n" $(test_seq 1 100) >big-blob.txt && + + # Create a server with 2 commits: a commit with a big tree and a child + # commit with an incremental change. Also, create a partial clone + # client that only contains the first commit. + git init server && + git -C server config --local uploadpack.allowfilter 1 && + for i in $(test_seq 1 100) + do + echo "make the tree big" >server/file$i && + git -C server add file$i + done && + git -C server commit -m "initial" && + git clone --bare --filter=tree:0 "file://$(pwd)/server" client && + echo another line >>server/file1 && + git -C server commit -am "incremental change" && + + # Create a promisor remote that only contains the tree and blob from + # the first commit. + git init promisor-remote && + git -C server config --local uploadpack.allowanysha1inwant 1 && + TREE_HASH=$(git -C server rev-parse HEAD~1^{tree}) && + git -C promisor-remote fetch --keep "file://$(pwd)/server" "$TREE_HASH" && + git -C promisor-remote count-objects -v >object-count && + test_i18ngrep "count: 0" object-count && + test_i18ngrep "in-pack: 2" object-count && + + # Set it as the promisor remote of client. Thus, whenever + # the client lazy fetches, the lazy fetch will succeed only if it is + # for this tree or blob. + test_commit -C promisor-remote one && # so that ref advertisement is not empty + git -C promisor-remote config --local uploadpack.allowanysha1inwant 1 && + git -C client remote set-url origin "file://$(pwd)/promisor-remote" +} + +# NEEDSWORK: The tests beginning with "fetch lazy-fetches" below only +# test that "fetch" avoid fetching trees and blobs, but not commits or +# tags. Revisit this if Git is ever taught to support partial clones +# with commits and/or tags filtered out. + +test_expect_success 'fetch lazy-fetches only to resolve deltas' ' + setup_triangle && + + # Exercise to make sure it works. Git will not fetch anything from the + # promisor remote other than for the big tree (because it needs to + # resolve the delta). + GIT_TRACE_PACKET="$(pwd)/trace" git -C client \ + fetch "file://$(pwd)/server" master && + + # Verify the assumption that the client needed to fetch the delta base + # to resolve the delta. + git -C server rev-parse HEAD~1^{tree} >hash && + grep "want $(cat hash)" trace +' + +test_expect_success 'fetch lazy-fetches only to resolve deltas, protocol v2' ' + setup_triangle && + + git -C server config --local protocol.version 2 && + git -C client config --local protocol.version 2 && + git -C promisor-remote config --local protocol.version 2 && + + # Exercise to make sure it works. Git will not fetch anything from the + # promisor remote other than for the big blob (because it needs to + # resolve the delta). + GIT_TRACE_PACKET="$(pwd)/trace" git -C client \ + fetch "file://$(pwd)/server" master && + + # Verify that protocol version 2 was used. + grep "fetch< version 2" trace && + + # Verify the assumption that the client needed to fetch the delta base + # to resolve the delta. + git -C server rev-parse HEAD~1^{tree} >hash && + grep "want $(cat hash)" trace +' + +# The following two tests must be in this order, or else +# the first will not fail. It is important that the srv.bare +# repository did not have tags during clone, but has tags +# in the fetch. + +test_expect_failure 'verify fetch succeeds when asking for new tags' ' + git clone --filter=blob:none "file://$(pwd)/srv.bare" tag-test && + for i in I J K + do + test_commit -C src $i && + git -C src branch $i || return 1 + done && + git -C srv.bare fetch --tags origin +refs/heads/*:refs/heads/* && + git -C tag-test -c protocol.version=2 fetch --tags origin +' + +test_expect_success 'verify fetch downloads only one pack when updating refs' ' + git clone --filter=blob:none "file://$(pwd)/srv.bare" pack-test && + ls pack-test/.git/objects/pack/*pack >pack-list && + test_line_count = 2 pack-list && + for i in A B C + do + test_commit -C src $i && + git -C src branch $i || return 1 + done && + git -C srv.bare fetch origin +refs/heads/*:refs/heads/* && + git -C pack-test fetch origin && + ls pack-test/.git/objects/pack/*pack >pack-list && + test_line_count = 3 pack-list +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5700-protocol-v1.sh b/t/t5700-protocol-v1.sh index 2571eb90b7..022901b9eb 100755 --- a/t/t5700-protocol-v1.sh +++ b/t/t5700-protocol-v1.sh @@ -5,7 +5,8 @@ test_description='test git wire-protocol transition' TEST_NO_CREATE_REPO=1 # This is a protocol-specific test. -GIT_TEST_PROTOCOL_VERSION= +GIT_TEST_PROTOCOL_VERSION=0 +export GIT_TEST_PROTOCOL_VERSION . ./test-lib.sh diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index ae9175cedf..7fd7102c87 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -32,7 +32,7 @@ test_expect_success 'list refs with git:// using protocol v2' ' test_cmp expect actual ' -test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' ' +test_expect_success 'ref advertisement is filtered with ls-remote using protocol v2' ' test_when_finished "rm -f log" && GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ @@ -154,7 +154,7 @@ test_expect_success 'list refs with file:// using protocol v2' ' test_cmp expect actual ' -test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' ' +test_expect_success 'ref advertisement is filtered with ls-remote using protocol v2' ' test_when_finished "rm -f log" && GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \ @@ -225,7 +225,7 @@ test_expect_success 'fetch with file:// using protocol v2' ' grep "fetch< version 2" log ' -test_expect_success 'ref advertisment is filtered during fetch using protocol v2' ' +test_expect_success 'ref advertisement is filtered during fetch using protocol v2' ' test_when_finished "rm -f log" && test_commit -C file_parent three && @@ -665,6 +665,18 @@ test_expect_success 'fetch from namespaced repo respects namespaces' ' test_cmp expect actual ' +test_expect_success 'ls-remote with v2 http sends only one POST' ' + test_when_finished "rm -f log" && + + git ls-remote "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" >expect && + GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \ + ls-remote "$HTTPD_URL/smart/http_parent" >actual && + test_cmp expect actual && + + grep "Send header: POST" log >posts && + test_line_count = 1 posts +' + test_expect_success 'push with http:// and a config of v2 does not request v2' ' test_when_finished "rm -f log" && # Till v2 for push is designed, make sure that if a client has @@ -682,9 +694,9 @@ test_expect_success 'push with http:// and a config of v2 does not request v2' ' git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect && test_cmp expect actual && - # Client didnt request to use protocol v2 + # Client did not request to use protocol v2 ! grep "Git-Protocol: version=2" log && - # Server didnt respond using protocol v2 + # Server did not respond using protocol v2 ! grep "git< version 2" log ' diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index 3a2c143c6d..8aeeaac509 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -18,14 +18,16 @@ get_actual_commits () { p }' <out | test-tool pkt-line unpack-sideband >o.pack && git index-pack o.pack && - git verify-pack -v o.idx | grep commit | cut -c-40 | sort >actual_commits + git verify-pack -v o.idx >objs && + grep commit objs | cut -d" " -f1 | sort >actual_commits } check_output () { get_actual_refs && test_cmp expected_refs actual_refs && get_actual_commits && - test_cmp expected_commits actual_commits + sort expected_commits >sorted_commits && + test_cmp sorted_commits actual_commits } # c(o/foo) d(o/bar) @@ -35,6 +37,7 @@ check_output () { # \ | / # a test_expect_success 'setup repository' ' + test_oid_init && test_commit a && git checkout -b o/foo && test_commit b && @@ -75,17 +78,19 @@ test_expect_success 'invalid want-ref line' ' ' test_expect_success 'basic want-ref' ' + oid=$(git rev-parse f) && cat >expected_refs <<-EOF && - $(git rev-parse f) refs/heads/master + $oid refs/heads/master EOF - git rev-parse f | sort >expected_commits && + git rev-parse f >expected_commits && + oid=$(git rev-parse a) && test-tool pkt-line pack >in <<-EOF && command=fetch 0001 no-progress want-ref refs/heads/master - have $(git rev-parse a) + have $oid done 0000 EOF @@ -95,19 +100,22 @@ test_expect_success 'basic want-ref' ' ' test_expect_success 'multiple want-ref lines' ' + oid_c=$(git rev-parse c) && + oid_d=$(git rev-parse d) && cat >expected_refs <<-EOF && - $(git rev-parse c) refs/heads/o/foo - $(git rev-parse d) refs/heads/o/bar + $oid_c refs/heads/o/foo + $oid_d refs/heads/o/bar EOF - git rev-parse c d | sort >expected_commits && + git rev-parse c d >expected_commits && + oid=$(git rev-parse b) && test-tool pkt-line pack >in <<-EOF && command=fetch 0001 no-progress want-ref refs/heads/o/foo want-ref refs/heads/o/bar - have $(git rev-parse b) + have $oid done 0000 EOF @@ -117,10 +125,11 @@ test_expect_success 'multiple want-ref lines' ' ' test_expect_success 'mix want and want-ref' ' + oid=$(git rev-parse f) && cat >expected_refs <<-EOF && - $(git rev-parse f) refs/heads/master + $oid refs/heads/master EOF - git rev-parse e f | sort >expected_commits && + git rev-parse e f >expected_commits && test-tool pkt-line pack >in <<-EOF && command=fetch @@ -138,17 +147,19 @@ test_expect_success 'mix want and want-ref' ' ' test_expect_success 'want-ref with ref we already have commit for' ' + oid=$(git rev-parse c) && cat >expected_refs <<-EOF && - $(git rev-parse c) refs/heads/o/foo + $oid refs/heads/o/foo EOF >expected_commits && + oid=$(git rev-parse c) && test-tool pkt-line pack >in <<-EOF && command=fetch 0001 no-progress want-ref refs/heads/o/foo - have $(git rev-parse c) + have $oid done 0000 EOF @@ -211,13 +222,14 @@ test_expect_success 'fetching with exact OID' ' rm -rf local && cp -r "$LOCAL_PRISTINE" local && + oid=$(git -C "$REPO" rev-parse d) && GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \ - $(git -C "$REPO" rev-parse d):refs/heads/actual && + "$oid":refs/heads/actual && git -C "$REPO" rev-parse "d" >expected && git -C local rev-parse refs/heads/actual >actual && test_cmp expected actual && - grep "want $(git -C "$REPO" rev-parse d)" log + grep "want $oid" log ' test_expect_success 'fetching multiple refs' ' @@ -239,13 +251,14 @@ test_expect_success 'fetching ref and exact OID' ' rm -rf local && cp -r "$LOCAL_PRISTINE" local && + oid=$(git -C "$REPO" rev-parse b) && GIT_TRACE_PACKET="$(pwd)/log" git -C local fetch origin \ - master $(git -C "$REPO" rev-parse b):refs/heads/actual && + master "$oid":refs/heads/actual && git -C "$REPO" rev-parse "master" "b" >expected && git -C local rev-parse refs/remotes/origin/master refs/heads/actual >actual && test_cmp expected actual && - grep "want $(git -C "$REPO" rev-parse b)" log && + grep "want $oid" log && grep "want-ref refs/heads/master" log ' @@ -312,17 +325,16 @@ inconsistency () { # repository appears to change during negotiation, for example, when # different servers in a load-balancing arrangement serve (stateless) # RPCs during a single negotiation. - printf "s/%s/%s/" \ - $(git -C "$REPO" rev-parse $1 | tr -d "\n") \ - $(git -C "$REPO" rev-parse $2 | tr -d "\n") \ - >"$HTTPD_ROOT_PATH/one-time-sed" + oid1=$(git -C "$REPO" rev-parse $1) && + oid2=$(git -C "$REPO" rev-parse $2) && + echo "s/$oid1/$oid2/" >"$HTTPD_ROOT_PATH/one-time-sed" } test_expect_success 'server is initially ahead - no ref in want' ' git -C "$REPO" config uploadpack.allowRefInWant false && rm -rf local && cp -r "$LOCAL_PRISTINE" local && - inconsistency master 1234567890123456789012345678901234567890 && + inconsistency master $(test_oid numeric) && test_must_fail git -C local fetch 2>err && test_i18ngrep "fatal: remote error: upload-pack: not our ref" err ' @@ -331,7 +343,7 @@ test_expect_success 'server is initially ahead - ref in want' ' git -C "$REPO" config uploadpack.allowRefInWant true && rm -rf local && cp -r "$LOCAL_PRISTINE" local && - inconsistency master 1234567890123456789012345678901234567890 && + inconsistency master $(test_oid numeric) && git -C local fetch && git -C "$REPO" rev-parse --verify master >expected && diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index b8cf82349b..3dc1ad8f71 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -104,13 +104,16 @@ test_expect_success 'rev-list can show index objects' ' # - we do not show the root tree; since we updated the index, it # does not have a valid cache tree # - cat >expect <<-\EOF && - 8e4020bb5a8d8c873b25de15933e75cc0fc275df one - d9d3a7417b9605cfd88ee6306b28dadc29e6ab08 only-in-index - 9200b628cf9dc883a85a7abc8d6e6730baee589c two - EOF echo only-in-index >only-in-index && test_when_finished "git reset --hard" && + rev1=$(git rev-parse HEAD:one) && + rev2=$(git rev-parse HEAD:two) && + revi=$(git hash-object only-in-index) && + cat >expect <<-EOF && + $rev1 one + $revi only-in-index + $rev2 two + EOF git add only-in-index && git rev-list --objects --indexed-objects >actual && test_cmp expect actual @@ -148,4 +151,16 @@ test_expect_success 'rev-list --end-of-options' ' test_cmp expect actual ' +test_expect_success 'rev-list --count' ' + count=$(git rev-list --count HEAD) && + git rev-list HEAD >actual && + test_line_count = $count actual +' + +test_expect_success 'rev-list --count --objects' ' + count=$(git rev-list --count --objects HEAD) && + git rev-list --objects HEAD >actual && + test_line_count = $count actual +' + test_done diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index ebdc49c496..7e82e43a63 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -32,6 +32,7 @@ changed_iso88591=$(echo "$changed" | iconv -f utf-8 -t $test_encoding) truncate_count=20 test_expect_success 'setup' ' + test_oid_init && : >foo && git add foo && git config i18n.commitEncoding $test_encoding && @@ -463,9 +464,10 @@ test_expect_success '--abbrev' ' ' test_expect_success '%H is not affected by --abbrev-commit' ' + expected=$(($(test_oid hexsz) + 1)) && git log -1 --format=%H --abbrev-commit --abbrev=20 HEAD >actual && len=$(wc -c <actual) && - test $len = 41 + test $len = $expected ' test_expect_success '%h is not affected by --abbrev-commit' ' diff --git a/t/t6016-rev-list-graph-simplify-history.sh b/t/t6016-rev-list-graph-simplify-history.sh index f7181d1d6a..f5e6e92f5b 100755 --- a/t/t6016-rev-list-graph-simplify-history.sh +++ b/t/t6016-rev-list-graph-simplify-history.sh @@ -67,11 +67,10 @@ test_expect_success '--graph --all' ' echo "| * $C4" >> expected && echo "| * $C3" >> expected && echo "* | $A5" >> expected && - echo "| | " >> expected && - echo "| \\ " >> expected && - echo "*-. \\ $A4" >> expected && - echo "|\\ \\ \\ " >> expected && - echo "| | |/ " >> expected && + echo "| | " >> expected && + echo "| \\ " >> expected && + echo "*-. | $A4" >> expected && + echo "|\\ \\| " >> expected && echo "| | * $C2" >> expected && echo "| | * $C1" >> expected && echo "| * | $B2" >> expected && @@ -97,11 +96,10 @@ test_expect_success '--graph --simplify-by-decoration' ' echo "| * $C4" >> expected && echo "| * $C3" >> expected && echo "* | $A5" >> expected && - echo "| | " >> expected && - echo "| \\ " >> expected && - echo "*-. \\ $A4" >> expected && - echo "|\\ \\ \\ " >> expected && - echo "| | |/ " >> expected && + echo "| | " >> expected && + echo "| \\ " >> expected && + echo "*-. | $A4" >> expected && + echo "|\\ \\| " >> expected && echo "| | * $C2" >> expected && echo "| | * $C1" >> expected && echo "| * | $B2" >> expected && @@ -131,9 +129,8 @@ test_expect_success '--graph --simplify-by-decoration prune branch B' ' echo "| * $C4" >> expected && echo "| * $C3" >> expected && echo "* | $A5" >> expected && - echo "* | $A4" >> expected && - echo "|\\ \\ " >> expected && - echo "| |/ " >> expected && + echo "* | $A4" >> expected && + echo "|\\| " >> expected && echo "| * $C2" >> expected && echo "| * $C1" >> expected && echo "* | $A3" >> expected && @@ -151,9 +148,8 @@ test_expect_success '--graph --full-history -- bar.txt' ' echo "|\\ " >> expected && echo "| * $C4" >> expected && echo "* | $A5" >> expected && - echo "* | $A4" >> expected && - echo "|\\ \\ " >> expected && - echo "| |/ " >> expected && + echo "* | $A4" >> expected && + echo "|\\| " >> expected && echo "* | $A3" >> expected && echo "|/ " >> expected && echo "* $A2" >> expected && @@ -255,7 +251,7 @@ test_expect_success '--graph --boundary ^C3' ' echo "* | | | $A3" >> expected && echo "o | | | $A2" >> expected && echo "|/ / / " >> expected && - echo "o | | $A1" >> expected && + echo "o / / $A1" >> expected && echo " / / " >> expected && echo "| o $C3" >> expected && echo "|/ " >> expected && diff --git a/t/t6019-rev-list-ancestry-path.sh b/t/t6019-rev-list-ancestry-path.sh index beadaf6cca..353f84313f 100755 --- a/t/t6019-rev-list-ancestry-path.sh +++ b/t/t6019-rev-list-ancestry-path.sh @@ -143,14 +143,14 @@ test_expect_success 'setup criss-cross' ' test_expect_success 'criss-cross: rev-list --ancestry-path cb..bc' ' (cd criss-cross && git rev-list --ancestry-path xcb..xbc > actual && - test -z "$(cat actual)") + test_must_be_empty actual) ' # no commits in repository descend from cb test_expect_success 'criss-cross: rev-list --ancestry-path --all ^cb' ' (cd criss-cross && git rev-list --ancestry-path --all ^xcb > actual && - test -z "$(cat actual)") + test_must_be_empty actual) ' test_done diff --git a/t/t6021-merge-criss-cross.sh b/t/t6021-merge-criss-cross.sh index 213deecab1..d254e020b6 100755 --- a/t/t6021-merge-criss-cross.sh +++ b/t/t6021-merge-criss-cross.sh @@ -3,7 +3,7 @@ # Copyright (c) 2005 Fredrik Kuivinen # -# See http://marc.info/?l=git&m=111463358500362&w=2 for a +# See https://lore.kernel.org/git/Pine.LNX.4.44.0504271254120.4678-100000@wax.eds.org/ for a # nice description of what this is about. diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh index 27c7de90ce..332cfc53fd 100755 --- a/t/t6024-recursive-merge.sh +++ b/t/t6024-recursive-merge.sh @@ -14,85 +14,95 @@ test_description='Test merge without common ancestors' GIT_COMMITTER_DATE="2006-12-12 23:28:00 +0100" export GIT_COMMITTER_DATE -test_expect_success "setup tests" ' -echo 1 > a1 && -git add a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:00" git commit -m 1 a1 && - -git checkout -b A master && -echo A > a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:01" git commit -m A a1 && - -git checkout -b B master && -echo B > a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:02" git commit -m B a1 && - -git checkout -b D A && -git rev-parse B > .git/MERGE_HEAD && -echo D > a1 && -git update-index a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:03" git commit -m D && - -git symbolic-ref HEAD refs/heads/other && -echo 2 > a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:04" git commit -m 2 a1 && - -git checkout -b C && -echo C > a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:05" git commit -m C a1 && - -git checkout -b E C && -git rev-parse B > .git/MERGE_HEAD && -echo E > a1 && -git update-index a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:06" git commit -m E && - -git checkout -b G E && -git rev-parse A > .git/MERGE_HEAD && -echo G > a1 && -git update-index a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:07" git commit -m G && - -git checkout -b F D && -git rev-parse C > .git/MERGE_HEAD && -echo F > a1 && -git update-index a1 && -GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F +test_expect_success 'setup tests' ' + echo 1 >a1 && + git add a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:00" git commit -m 1 a1 && + + git checkout -b A master && + echo A >a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:01" git commit -m A a1 && + + git checkout -b B master && + echo B >a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:02" git commit -m B a1 && + + git checkout -b D A && + git rev-parse B >.git/MERGE_HEAD && + echo D >a1 && + git update-index a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:03" git commit -m D && + + git symbolic-ref HEAD refs/heads/other && + echo 2 >a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:04" git commit -m 2 a1 && + + git checkout -b C && + echo C >a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:05" git commit -m C a1 && + + git checkout -b E C && + git rev-parse B >.git/MERGE_HEAD && + echo E >a1 && + git update-index a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:06" git commit -m E && + + git checkout -b G E && + git rev-parse A >.git/MERGE_HEAD && + echo G >a1 && + git update-index a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:07" git commit -m G && + + git checkout -b F D && + git rev-parse C >.git/MERGE_HEAD && + echo F >a1 && + git update-index a1 && + GIT_AUTHOR_DATE="2006-12-12 23:00:08" git commit -m F && + + test_oid_cache <<-EOF + idxstage1 sha1:ec3fe2a791706733f2d8fa7ad45d9a9672031f5e + idxstage1 sha256:b3c8488929903aaebdeb22270cb6d36e5b8724b01ae0d4da24632f158c99676f + EOF ' test_expect_success 'combined merge conflicts' ' test_must_fail env GIT_TEST_COMMIT_GRAPH=0 git merge -m final G ' -cat > expect << EOF -<<<<<<< HEAD -F -======= -G ->>>>>>> G -EOF +test_expect_success 'result contains a conflict' ' + cat >expect <<-\EOF && + <<<<<<< HEAD + F + ======= + G + >>>>>>> G + EOF -test_expect_success "result contains a conflict" "test_cmp expect a1" + test_cmp expect a1 +' + +test_expect_success 'virtual trees were processed' ' + git ls-files --stage >out && -git ls-files --stage > out -cat > expect << EOF -100644 ec3fe2a791706733f2d8fa7ad45d9a9672031f5e 1 a1 -100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1 -100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1 -EOF + cat >expect <<-EOF && + 100644 $(test_oid idxstage1) 1 a1 + 100644 $(git rev-parse F:a1) 2 a1 + 100644 $(git rev-parse G:a1) 3 a1 + EOF -test_expect_success "virtual trees were processed" "test_cmp expect out" + test_cmp expect out +' test_expect_success 'refuse to merge binary files' ' git reset --hard && - printf "\0" > binary-file && + printf "\0" >binary-file && git add binary-file && git commit -m binary && git checkout G && - printf "\0\0" > binary-file && + printf "\0\0" >binary-file && git add binary-file && git commit -m binary2 && - test_must_fail git merge F > merge.out 2> merge.err && + test_must_fail git merge F >merge.out 2>merge.err && grep "Cannot merge binary files: binary-file (HEAD vs. F)" merge.err ' @@ -116,7 +126,6 @@ test_expect_success 'mark rename/delete as unmerged' ' test 1 = $(git ls-files --unmerged | wc -l) && test_must_fail git rev-parse --verify :2:a2 && git rev-parse --verify :3:a2 - ' test_done diff --git a/t/t6025-merge-symlinks.sh b/t/t6025-merge-symlinks.sh index 433c4de08f..6c0a90d044 100755 --- a/t/t6025-merge-symlinks.sh +++ b/t/t6025-merge-symlinks.sh @@ -10,52 +10,53 @@ if core.symlinks is false.' . ./test-lib.sh -test_expect_success \ -'setup' ' -git config core.symlinks false && -> file && -git add file && -git commit -m initial && -git branch b-symlink && -git branch b-file && -l=$(printf file | git hash-object -t blob -w --stdin) && -echo "120000 $l symlink" | git update-index --index-info && -git commit -m master && -git checkout b-symlink && -l=$(printf file-different | git hash-object -t blob -w --stdin) && -echo "120000 $l symlink" | git update-index --index-info && -git commit -m b-symlink && -git checkout b-file && -echo plain-file > symlink && -git add symlink && -git commit -m b-file' - -test_expect_success \ -'merge master into b-symlink, which has a different symbolic link' ' -git checkout b-symlink && -test_must_fail git merge master' - -test_expect_success \ -'the merge result must be a file' ' -test -f symlink' - -test_expect_success \ -'merge master into b-file, which has a file instead of a symbolic link' ' -git reset --hard && git checkout b-file && -test_must_fail git merge master' - -test_expect_success \ -'the merge result must be a file' ' -test -f symlink' - -test_expect_success \ -'merge b-file, which has a file instead of a symbolic link, into master' ' -git reset --hard && -git checkout master && -test_must_fail git merge b-file' - -test_expect_success \ -'the merge result must be a file' ' -test -f symlink' +test_expect_success 'setup' ' + git config core.symlinks false && + >file && + git add file && + git commit -m initial && + git branch b-symlink && + git branch b-file && + l=$(printf file | git hash-object -t blob -w --stdin) && + echo "120000 $l symlink" | git update-index --index-info && + git commit -m master && + git checkout b-symlink && + l=$(printf file-different | git hash-object -t blob -w --stdin) && + echo "120000 $l symlink" | git update-index --index-info && + git commit -m b-symlink && + git checkout b-file && + echo plain-file >symlink && + git add symlink && + git commit -m b-file +' + +test_expect_success 'merge master into b-symlink, which has a different symbolic link' ' + git checkout b-symlink && + test_must_fail git merge master +' + +test_expect_success 'the merge result must be a file' ' + test_path_is_file symlink +' + +test_expect_success 'merge master into b-file, which has a file instead of a symbolic link' ' + git reset --hard && + git checkout b-file && + test_must_fail git merge master +' + +test_expect_success 'the merge result must be a file' ' + test_path_is_file symlink +' + +test_expect_success 'merge b-file, which has a file instead of a symbolic link, into master' ' + git reset --hard && + git checkout master && + test_must_fail git merge b-file +' + +test_expect_success 'the merge result must be a file' ' + test_path_is_file symlink +' test_done diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index bdc42e9440..821a0c88cf 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -482,7 +482,7 @@ test_expect_success 'optimized merge base checks' ' git bisect good > my_bisect_log2.txt && test -f ".git/BISECT_ANCESTORS_OK" && test "$HASH6" = $(git rev-parse --verify HEAD) && - git bisect bad > my_bisect_log3.txt && + git bisect bad && git bisect good "$A_HASH" > my_bisect_log4.txt && test_i18ngrep "merge base must be tested" my_bisect_log4.txt && test_must_fail test -f ".git/BISECT_ANCESTORS_OK" diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 7fddcc8c73..7d73afdcda 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -1532,7 +1532,7 @@ test_expect_success 'setup nested conflicts' ' mv -f b_R1 b && mv -f a_R1 a && git add b a && - test_tick && git commit -m "verson R1 of files" && + test_tick && git commit -m "version R1 of files" && git tag R1 && # Create first merge on left side @@ -1696,7 +1696,7 @@ test_expect_success 'setup virtual merge base with nested conflicts' ' git checkout R && echo right >>content && git add content && - test_tick && git commit -m "verson R1 of content" && + test_tick && git commit -m "version R1 of content" && git tag R1 && # Create L2 diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh index bd2f97ba95..83792c5ef1 100755 --- a/t/t6043-merge-rename-directories.sh +++ b/t/t6043-merge-rename-directories.sh @@ -754,7 +754,7 @@ test_expect_success '3b: Avoid implicit rename if involved as source on current # # What if we were to attempt to do directory rename detection when someone # "mostly" moved a directory but still left some files around, or, -# equivalently, fully renamed a directory in one commmit and then recreated +# equivalently, fully renamed a directory in one commit and then recreated # that directory in a later commit adding some new files and then tried to # merge? # @@ -953,7 +953,7 @@ test_expect_success '5a: Merge directories, other side adds files to original an # Commit B: z/{b,c,d_1,e}, y/d_3 # Expected: y/{b,c,e}, CONFLICT(add/add: y/d_2 vs. y/d_3) # NOTE: If z/d_1 in commit B were to be involved in dir rename detection, as -# we normaly would since z/ is being renamed to y/, then this would be +# we normally would since z/ is being renamed to y/, then this would be # a rename/delete (z/d_1 -> y/d_1 vs. deleted) AND an add/add/add # conflict of y/d_1 vs. y/d_2 vs. y/d_3. Add/add/add is not # representable in the index, so the existence of y/d_3 needs to @@ -2116,7 +2116,7 @@ test_expect_success '8b: Dual-directory rename, one into the others way, with co # # Note: It could easily be argued that the correct resolution here is # y/{b,c,e}, CONFLICT(rename/delete: z/d -> y/d vs deleted) -# and that the modifed version of d should be present in y/ after +# and that the modified version of d should be present in y/ after # the merge, just marked as conflicted. Indeed, I previously did # argue that. But applying directory renames to the side of # history where a file is merely modified results in spurious diff --git a/t/t6047-diff3-conflict-markers.sh b/t/t6047-diff3-conflict-markers.sh index 860542aad0..f4655bb358 100755 --- a/t/t6047-diff3-conflict-markers.sh +++ b/t/t6047-diff3-conflict-markers.sh @@ -186,7 +186,7 @@ test_expect_success 'check multiple merge bases' ' ) ' -test_expect_success 'rebase describes fake ancestor base' ' +test_expect_success 'rebase --merge describes parent of commit being picked' ' test_create_repo rebase && ( cd rebase && @@ -194,7 +194,16 @@ test_expect_success 'rebase describes fake ancestor base' ' test_commit master file && git checkout -b side HEAD^ && test_commit side file && - test_must_fail git -c merge.conflictstyle=diff3 rebase master && + test_must_fail git -c merge.conflictstyle=diff3 rebase --merge master && + grep "||||||| parent of" file + ) +' + +test_expect_success 'rebase --apply describes fake ancestor base' ' + ( + cd rebase && + git rebase --abort && + test_must_fail git -c merge.conflictstyle=diff3 rebase --apply master && grep "||||||| constructed merge base" file ) ' diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh index 28611c978e..52cde097dd 100755 --- a/t/t6102-rev-list-unexpected-objects.sh +++ b/t/t6102-rev-list-unexpected-objects.sh @@ -52,7 +52,7 @@ test_expect_success 'traverse unexpected non-commit parent (lone)' ' ' test_expect_success 'traverse unexpected non-commit parent (seen)' ' - test_must_fail git rev-list --objects $commit $broken_commit \ + test_must_fail git rev-list --objects $blob $broken_commit \ >output 2>&1 && test_i18ngrep "not a commit" output ' diff --git a/t/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh new file mode 100755 index 0000000000..145603f124 --- /dev/null +++ b/t/t6113-rev-list-bitmap-filters.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +test_description='rev-list combining bitmaps and filters' +. ./test-lib.sh + +test_expect_success 'set up bitmapped repo' ' + # one commit will have bitmaps, the other will not + test_commit one && + test_commit much-larger-blob-one && + git repack -adb && + test_commit two && + test_commit much-larger-blob-two +' + +test_expect_success 'filters fallback to non-bitmap traversal' ' + # use a path-based filter, since they are inherently incompatible with + # bitmaps (i.e., this test will never get confused by later code to + # combine the features) + filter=$(echo "!one" | git hash-object -w --stdin) && + git rev-list --objects --filter=sparse:oid=$filter HEAD >expect && + git rev-list --use-bitmap-index \ + --objects --filter=sparse:oid=$filter HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'blob:none filter' ' + git rev-list --objects --filter=blob:none HEAD >expect && + git rev-list --use-bitmap-index \ + --objects --filter=blob:none HEAD >actual && + test_bitmap_traversal expect actual +' + +test_expect_success 'blob:none filter with specified blob' ' + git rev-list --objects --filter=blob:none HEAD HEAD:two.t >expect && + git rev-list --use-bitmap-index \ + --objects --filter=blob:none HEAD HEAD:two.t >actual && + test_bitmap_traversal expect actual +' + +test_expect_success 'blob:limit filter' ' + git rev-list --objects --filter=blob:limit=5 HEAD >expect && + git rev-list --use-bitmap-index \ + --objects --filter=blob:limit=5 HEAD >actual && + test_bitmap_traversal expect actual +' + +test_expect_success 'blob:limit filter with specified blob' ' + git rev-list --objects --filter=blob:limit=5 \ + HEAD HEAD:much-larger-blob-two.t >expect && + git rev-list --use-bitmap-index \ + --objects --filter=blob:limit=5 \ + HEAD HEAD:much-larger-blob-two.t >actual && + test_bitmap_traversal expect actual +' + +test_done diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 45047d0a72..09c50f3f04 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -1,28 +1,27 @@ #!/bin/sh -test_description='test describe +test_description='test describe' + +# o---o-----o----o----o-------o----x +# \ D,R e / +# \---o-------------o-' +# \ B / +# `-o----o----o-' +# A c +# +# First parent of a merge commit is on the same line, second parent below. - B - .--------------o----o----o----x - / / / - o----o----o----o----o----. / - \ A c / - .------------o---o---o - D,R e -' . ./test-lib.sh check_describe () { expect="$1" shift - R=$(git describe "$@" 2>err.actual) - S=$? - cat err.actual >&3 - test_expect_success "describe $*" ' - test $S = 0 && + describe_opts="$@" + test_expect_success "describe $describe_opts" ' + R=$(git describe $describe_opts 2>err.actual) && case "$R" in $expect) echo happy ;; - *) echo "Oops - $R is not $expect"; + *) echo "Oops - $R is not $expect" && false ;; esac ' @@ -382,7 +381,7 @@ test_expect_success 'describe tag object' ' test_i18ngrep "fatal: test-blob-1 is neither a commit nor blob" actual ' -test_expect_failure ULIMIT_STACK_SIZE 'name-rev works in a deep repo' ' +test_expect_success ULIMIT_STACK_SIZE 'name-rev works in a deep repo' ' i=1 && while test $i -lt 8000 do @@ -439,4 +438,45 @@ test_expect_success 'name-rev a rev shortly after epoch' ' test_cmp expect actual ' +# A--------------master +# \ / +# \----------M2 +# \ / +# \---M1-C +# \ / +# B +test_expect_success 'name-rev covers all conditions while looking at parents' ' + git init repo && + ( + cd repo && + + echo A >file && + git add file && + git commit -m A && + A=$(git rev-parse HEAD) && + + git checkout --detach && + echo B >file && + git commit -m B file && + B=$(git rev-parse HEAD) && + + git checkout $A && + git merge --no-ff $B && # M1 + + echo C >file && + git commit -m C file && + + git checkout $A && + git merge --no-ff HEAD@{1} && # M2 + + git checkout master && + git merge --no-ff HEAD@{1} && + + echo "$B master^2^2~1^2" >expect && + git name-rev $B >actual && + + test_cmp expect actual + ) +' + test_done diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh index 37760233a5..ba7902c9cd 100755 --- a/t/t6130-pathspec-noglob.sh +++ b/t/t6130-pathspec-noglob.sh @@ -10,6 +10,7 @@ test_expect_success 'create commits with glob characters' ' # the name "f*" in the worktree, because it is not allowed # on Windows (the tests below do not depend on the presence # of the file in the worktree) + git config core.protectNTFS false && git update-index --add --cacheinfo 100644 "$(git rev-parse HEAD:foo)" "f*" && test_tick && git commit -m star && diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh index c0f04dc6b0..0a69a67117 100755 --- a/t/t6500-gc.sh +++ b/t/t6500-gc.sh @@ -103,14 +103,14 @@ test_expect_success 'auto gc with too many loose objects does not attempt to cre ' test_expect_success 'gc --no-quiet' ' - git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && + GIT_PROGRESS_DELAY=0 git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && test_must_be_empty stdout && - test_line_count = 1 stderr && test_i18ngrep "Computing commit graph generation numbers" stderr ' test_expect_success TTY 'with TTY: gc --no-quiet' ' - test_terminal git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && + test_terminal env GIT_PROGRESS_DELAY=0 \ + git -c gc.writeCommitGraph=true gc --no-quiet >stdout 2>stderr && test_must_be_empty stdout && test_i18ngrep "Enumerating objects" stderr && test_i18ngrep "Computing commit graph generation numbers" stderr diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 80eb13d94e..6db92bd3ba 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -227,10 +227,10 @@ test_expect_success \ test_expect_success \ 'trying to delete two tags, existing and not, should fail in the 2nd' ' tag_exists mytag && - ! tag_exists myhead && - test_must_fail git tag -d mytag anothertag && + ! tag_exists nonexistingtag && + test_must_fail git tag -d mytag nonexistingtag && ! tag_exists mytag && - ! tag_exists myhead + ! tag_exists nonexistingtag ' test_expect_success 'trying to delete an already deleted tag should fail' \ @@ -517,7 +517,6 @@ test_expect_success \ test_expect_success \ 'trying to create tags giving both -m or -F options should fail' ' echo "message file 1" >msgfile1 && - echo "message file 2" >msgfile2 && ! tag_exists msgtag && test_must_fail git tag -m "message 1" -F msgfile1 msgtag && ! tag_exists msgtag && @@ -1420,7 +1419,7 @@ test_expect_success \ get_tag_header reuse $commit commit $time >expect echo "An annotation to be reused" >> expect test_expect_success \ - 'overwriting an annoted tag should use its previous body' ' + 'overwriting an annotated tag should use its previous body' ' git tag -a -m "An annotation to be reused" reuse && GIT_EDITOR=true git tag -f -a reuse && get_tag_msg reuse >actual && diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh index 041e319e79..5c5bc32ccb 100755 --- a/t/t7030-verify-tag.sh +++ b/t/t7030-verify-tag.sh @@ -44,8 +44,8 @@ test_expect_success GPG 'create signed tags' ' test_expect_success GPGSM 'create signed tags x509 ' ' test_config gpg.format x509 && test_config user.signingkey $GIT_COMMITTER_EMAIL && - echo 9 >file && test_tick && git commit -a -m "nineth gpgsm-signed" && - git tag -s -m nineth nineth-signed-x509 + echo 9 >file && test_tick && git commit -a -m "ninth gpgsm-signed" && + git tag -s -m ninth ninth-signed-x509 ' test_expect_success GPG 'verify and show signatures' ' @@ -80,10 +80,34 @@ test_expect_success GPG 'verify and show signatures' ' ' test_expect_success GPGSM 'verify and show signatures x509' ' - git verify-tag nineth-signed-x509 2>actual && + git verify-tag ninth-signed-x509 2>actual && grep "Good signature from" actual && ! grep "BAD signature from" actual && - echo nineth-signed-x509 OK + echo ninth-signed-x509 OK +' + +test_expect_success GPGSM 'verify and show signatures x509 with low minTrustLevel' ' + test_config gpg.minTrustLevel undefined && + git verify-tag ninth-signed-x509 2>actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual && + echo ninth-signed-x509 OK +' + +test_expect_success GPGSM 'verify and show signatures x509 with matching minTrustLevel' ' + test_config gpg.minTrustLevel fully && + git verify-tag ninth-signed-x509 2>actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual && + echo ninth-signed-x509 OK +' + +test_expect_success GPGSM 'verify and show signatures x509 with high minTrustLevel' ' + test_config gpg.minTrustLevel ultimate && + test_must_fail git verify-tag ninth-signed-x509 2>actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual && + echo ninth-signed-x509 OK ' test_expect_success GPG 'detect fudged signature' ' @@ -127,10 +151,10 @@ test_expect_success GPG 'verify signatures with --raw' ' ' test_expect_success GPGSM 'verify signatures with --raw x509' ' - git verify-tag --raw nineth-signed-x509 2>actual && + git verify-tag --raw ninth-signed-x509 2>actual && grep "GOODSIG" actual && ! grep "BADSIG" actual && - echo nineth-signed-x509 OK + echo ninth-signed-x509 OK ' test_expect_success GPG 'verify multiple tags' ' @@ -147,7 +171,7 @@ test_expect_success GPG 'verify multiple tags' ' ' test_expect_success GPGSM 'verify multiple tags x509' ' - tags="seventh-signed nineth-signed-x509" && + tags="seventh-signed ninth-signed-x509" && for i in $tags do git verify-tag -v --raw $i || return 1 diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index 0c394cf995..e4cf5484f9 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -43,11 +43,16 @@ test_expect_success 'status untracked directory with --ignored -u' ' test_cmp expected actual ' cat >expected <<\EOF -?? untracked/uncommitted +?? untracked/ !! untracked/ignored EOF -test_expect_success 'status prefixed untracked directory with --ignored' ' +test_expect_success 'status of untracked directory with --ignored works with or without prefix' ' + git status --porcelain --ignored >tmp && + grep untracked/ tmp >actual && + rm tmp && + test_cmp expected actual && + git status --porcelain --ignored untracked/ >actual && test_cmp expected actual ' diff --git a/t/t7105-reset-patch.sh b/t/t7105-reset-patch.sh index bd10a96727..fc2a6cf5c7 100755 --- a/t/t7105-reset-patch.sh +++ b/t/t7105-reset-patch.sh @@ -38,6 +38,27 @@ test_expect_success PERL 'git reset -p HEAD^' ' test_i18ngrep "Apply" output ' +test_expect_success PERL 'git reset -p HEAD^^{tree}' ' + test_write_lines n y | git reset -p HEAD^^{tree} >output && + verify_state dir/foo work parent && + verify_saved_state bar && + test_i18ngrep "Apply" output +' + +test_expect_success PERL 'git reset -p HEAD^:dir/foo (blob fails)' ' + set_and_save_state dir/foo work work && + test_must_fail git reset -p HEAD^:dir/foo && + verify_saved_state dir/foo && + verify_saved_state bar +' + +test_expect_success PERL 'git reset -p aaaaaaaa (unknown fails)' ' + set_and_save_state dir/foo work work && + test_must_fail git reset -p aaaaaaaa && + verify_saved_state dir/foo && + verify_saved_state bar +' + # The idea in the rest is that bar sorts first, so we always say 'y' # first and if the path limiter fails it'll apply to bar instead of # dir/foo. There's always an extra 'n' to reject edits to dir/foo in diff --git a/t/t7107-reset-pathspec-file.sh b/t/t7107-reset-pathspec-file.sh new file mode 100755 index 0000000000..cad3a9de9e --- /dev/null +++ b/t/t7107-reset-pathspec-file.sh @@ -0,0 +1,173 @@ +#!/bin/sh + +test_description='reset --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t && + git add . && + git commit --include . -m "Commit" && + git tag checkpoint +' + +restore_checkpoint () { + git reset --hard checkpoint +} + +verify_expect () { + git status --porcelain -- fileA.t fileB.t fileC.t fileD.t >actual && + test_cmp expect actual +} + +test_expect_success '--pathspec-from-file from stdin' ' + restore_checkpoint && + + git rm fileA.t && + echo fileA.t | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + EOF + verify_expect +' + +test_expect_success '--pathspec-from-file from file' ' + restore_checkpoint && + + git rm fileA.t && + echo fileA.t >list && + git reset --pathspec-from-file=list && + + cat >expect <<-\EOF && + D fileA.t + EOF + verify_expect +' + +test_expect_success 'NUL delimiters' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\0fileB.t\0" | git reset --pathspec-from-file=- --pathspec-file-nul && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'LF delimiters' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\nfileB.t\n" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'no trailing delimiter' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\nfileB.t" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'CRLF delimiters' ' + restore_checkpoint && + + git rm fileA.t fileB.t && + printf "fileA.t\r\nfileB.t\r\n" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + EOF + verify_expect +' + +test_expect_success 'quotes' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + git rm fileA.t && + git reset --pathspec-from-file=list && + + cat >expect <<-\EOF && + D fileA.t + EOF + verify_expect +' + +test_expect_success 'quotes not compatible with --pathspec-file-nul' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + # Note: "git reset" has not yet learned to fail on wrong pathspecs + git reset --pathspec-from-file=list --pathspec-file-nul && + + cat >expect <<-\EOF && + D fileA.t + EOF + test_must_fail verify_expect +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + git rm fileA.t fileB.t fileC.t fileD.t && + printf "fileB.t\nfileC.t\n" | git reset --pathspec-from-file=- && + + cat >expect <<-\EOF && + D fileA.t + D fileB.t + D fileC.t + D fileD.t + EOF + verify_expect +' + +test_expect_success 'error conditions' ' + restore_checkpoint && + echo fileA.t >list && + git rm fileA.t && + + test_must_fail git reset --pathspec-from-file=list --patch 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --patch" err && + + test_must_fail git reset --pathspec-from-file=list -- fileA.t 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err && + + test_must_fail git reset --pathspec-file-nul 2>err && + test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err && + + test_must_fail git reset --soft --pathspec-from-file=list 2>err && + test_i18ngrep -e "fatal: Cannot do soft reset with paths" err && + + test_must_fail git reset --hard --pathspec-from-file=list 2>err && + test_i18ngrep -e "fatal: Cannot do hard reset with paths" err +' + +test_done diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 6e6d24c1c3..cb5e34d94c 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -737,4 +737,13 @@ test_expect_success MINGW 'handle clean & core.longpaths = false nicely' ' test_i18ngrep "too long" .git/err ' +test_expect_success 'clean untracked paths by pathspec' ' + git init untracked && + mkdir untracked/dir && + echo >untracked/dir/file.txt && + git -C untracked clean -f dir/file.txt && + ls untracked/dir >actual && + test_must_be_empty actual +' + test_done diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 691b5fc3bf..e3e2aab3b0 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -55,6 +55,21 @@ test_expect_success 'add aborts on repository with no commits' ' test_i18ncmp expect actual ' +test_expect_success 'status should ignore inner git repo when not added' ' + rm -fr inner && + mkdir inner && + ( + cd inner && + git init && + >t && + git add t && + git commit -m "initial" + ) && + test_must_fail git submodule status inner 2>output.err && + rm -fr inner && + test_i18ngrep "^error: .*did not match any file(s) known to git" output.err +' + test_expect_success 'setup - repository in init subdirectory' ' mkdir init && ( @@ -156,9 +171,11 @@ test_expect_success 'submodule add to .gitignored path fails' ' ( cd addtest-ignore && cat <<-\EOF >expect && - The following path is ignored by one of your .gitignore files: + The following paths are ignored by one of your .gitignore files: submod - Use -f if you really want to add it. + hint: Use -f if you really want to add them. + hint: Turn this message off by running + hint: "git config advice.addIgnoredFile false" EOF # Does not use test_commit due to the ignore echo "*" > .gitignore && @@ -191,6 +208,17 @@ test_expect_success 'submodule add to reconfigure existing submodule with --forc ) ' +test_expect_success 'submodule add relays add --dry-run stderr' ' + test_when_finished "rm -rf addtest/.git/index.lock" && + ( + cd addtest && + : >.git/index.lock && + ! git submodule add "$submodurl" sub-while-locked 2>output.err && + test_i18ngrep "^fatal: .*index\.lock" output.err && + test_path_is_missing sub-while-locked + ) +' + test_expect_success 'submodule add --branch' ' echo "refs/heads/initial" >expect-head && cat <<-\EOF >expect-heads && @@ -356,6 +384,28 @@ test_expect_success 'status should only print one line' ' test_line_count = 1 lines ' +test_expect_success 'status from subdirectory should have the same SHA1' ' + test_when_finished "rmdir addtest/subdir" && + ( + cd addtest && + mkdir subdir && + git submodule status >output && + awk "{print \$1}" <output >expect && + cd subdir && + git submodule status >../output && + awk "{print \$1}" <../output >../actual && + test_cmp ../expect ../actual && + git -C ../submod checkout HEAD^ && + git submodule status >../output && + awk "{print \$1}" <../output >../actual2 && + cd .. && + git submodule status >output && + awk "{print \$1}" <output >expect2 && + test_cmp expect2 actual2 && + ! test_cmp actual actual2 + ) +' + test_expect_success 'setup - fetch commit name from submodule' ' rev1=$(cd .subrepo && git rev-parse HEAD) && printf "rev1: %s\n" "$rev1" && @@ -377,6 +427,14 @@ test_expect_success 'init should register submodule url in .git/config' ' test_cmp expect url ' +test_expect_success 'status should still be "missing" after initializing' ' + rm -fr init && + mkdir init && + git submodule status >lines && + rm -fr init && + grep "^-$rev1" lines +' + test_failure_with_unknown_submodule () { test_must_fail git submodule $1 no-such-submodule 2>output.err && test_i18ngrep "^error: .*no-such-submodule" output.err diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index df34c994d2..4fb447a143 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -406,12 +406,26 @@ test_expect_success 'submodule update - command in .git/config' ' ) ' -test_expect_success 'submodule update - command in .gitmodules is ignored' ' +test_expect_success 'submodule update - command in .gitmodules is rejected' ' test_when_finished "git -C super reset --hard HEAD^" && git -C super config -f .gitmodules submodule.submodule.update "!false" && git -C super commit -a -m "add command to .gitmodules file" && git -C super/submodule reset --hard $submodulesha1^ && - git -C super submodule update submodule + test_must_fail git -C super submodule update submodule +' + +test_expect_success 'fsck detects command in .gitmodules' ' + git init command-in-gitmodules && + ( + cd command-in-gitmodules && + git submodule add ../submodule submodule && + test_commit adding-submodule && + + git config -f .gitmodules submodule.submodule.update "!false" && + git add .gitmodules && + test_commit configuring-update && + test_must_fail git fsck + ) ' cat << EOF >expect @@ -480,6 +494,9 @@ test_expect_success 'recursive submodule update - command in .git/config catches ' test_expect_success 'submodule init does not copy command into .git/config' ' + test_when_finished "git -C super update-index --force-remove submodule1" && + test_when_finished git config -f super/.gitmodules \ + --remove-section submodule.submodule1 && (cd super && git ls-files -s submodule >out && H=$(cut -d" " -f2 out) && @@ -488,10 +505,9 @@ test_expect_success 'submodule init does not copy command into .git/config' ' git config -f .gitmodules submodule.submodule1.path submodule1 && git config -f .gitmodules submodule.submodule1.url ../submodule && git config -f .gitmodules submodule.submodule1.update !false && - git submodule init submodule1 && - echo "none" >expect && - git config submodule.submodule1.update >actual && - test_cmp expect actual + test_must_fail git submodule init submodule1 && + test_expect_code 1 git config submodule.submodule1.update >actual && + test_must_be_empty actual ) ' @@ -944,7 +960,7 @@ test_expect_success 'submodule update clone shallow submodule outside of depth' mv -f .gitmodules.tmp .gitmodules && # Some protocol versions (e.g. 2) support fetching # unadvertised objects, so restrict this test to v0. - test_must_fail env GIT_TEST_PROTOCOL_VERSION= \ + test_must_fail env GIT_TEST_PROTOCOL_VERSION=0 \ git submodule update --init --depth=1 2>actual && test_i18ngrep "Direct fetching of that commit failed." actual && git -C ../submodule config uploadpack.allowReachableSHA1InWant true && diff --git a/t/t7410-submodule-checkout-to.sh b/t/t7410-submodule-checkout-to.sh deleted file mode 100755 index f1b492ebc4..0000000000 --- a/t/t7410-submodule-checkout-to.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh - -test_description='Combination of submodules and multiple workdirs' - -. ./test-lib.sh - -base_path=$(pwd -P) - -test_expect_success 'setup: make origin' ' - mkdir -p origin/sub && - ( - cd origin/sub && git init && - echo file1 >file1 && - git add file1 && - git commit -m file1 - ) && - mkdir -p origin/main && - ( - cd origin/main && git init && - git submodule add ../sub && - git commit -m "add sub" - ) && - ( - cd origin/sub && - echo file1updated >file1 && - git add file1 && - git commit -m "file1 updated" - ) && - git -C origin/main/sub pull && - ( - cd origin/main && - git add sub && - git commit -m "sub updated" - ) -' - -test_expect_success 'setup: clone' ' - mkdir clone && - git -C clone clone --recursive "$base_path/origin/main" -' - -rev1_hash_main=$(git --git-dir=origin/main/.git show --pretty=format:%h -q "HEAD~1") -rev1_hash_sub=$(git --git-dir=origin/sub/.git show --pretty=format:%h -q "HEAD~1") - -test_expect_success 'checkout main' ' - mkdir default_checkout && - git -C clone/main worktree add "$base_path/default_checkout/main" "$rev1_hash_main" -' - -test_expect_failure 'can see submodule diffs just after checkout' ' - git -C default_checkout/main diff --submodule master"^!" >out && - grep "file1 updated" out -' - -test_expect_success 'checkout main and initialize independent clones' ' - mkdir fully_cloned_submodule && - git -C clone/main worktree add "$base_path/fully_cloned_submodule/main" "$rev1_hash_main" && - git -C fully_cloned_submodule/main submodule update -' - -test_expect_success 'can see submodule diffs after independent cloning' ' - git -C fully_cloned_submodule/main diff --submodule master"^!" >out && - grep "file1 updated" out -' - -test_expect_success 'checkout sub manually' ' - mkdir linked_submodule && - git -C clone/main worktree add "$base_path/linked_submodule/main" "$rev1_hash_main" && - git -C clone/main/sub worktree add "$base_path/linked_submodule/main/sub" "$rev1_hash_sub" -' - -test_expect_success 'can see submodule diffs after manual checkout of linked submodule' ' - git -C linked_submodule/main diff --submodule master"^!" >out && - grep "file1 updated" out -' - -test_done diff --git a/t/t7415-submodule-names.sh b/t/t7415-submodule-names.sh index 49a37efe9c..f70368bc2e 100755 --- a/t/t7415-submodule-names.sh +++ b/t/t7415-submodule-names.sh @@ -191,4 +191,61 @@ test_expect_success 'fsck detects corrupt .gitmodules' ' ) ' +test_expect_success MINGW 'prevent git~1 squatting on Windows' ' + git init squatting && + ( + cd squatting && + mkdir a && + touch a/..git && + git add a/..git && + test_tick && + git commit -m initial && + + modules="$(test_write_lines \ + "[submodule \"b.\"]" "url = ." "path = c" \ + "[submodule \"b\"]" "url = ." "path = d\\\\a" | + git hash-object -w --stdin)" && + rev="$(git rev-parse --verify HEAD)" && + hash="$(echo x | git hash-object -w --stdin)" && + test_must_fail git update-index --add \ + --cacheinfo 160000,$rev,d\\a 2>err && + test_i18ngrep "Invalid path" err && + git -c core.protectNTFS=false update-index --add \ + --cacheinfo 100644,$modules,.gitmodules \ + --cacheinfo 160000,$rev,c \ + --cacheinfo 160000,$rev,d\\a \ + --cacheinfo 100644,$hash,d./a/x \ + --cacheinfo 100644,$hash,d./a/..git && + test_tick && + git -c core.protectNTFS=false commit -m "module" + ) && + test_must_fail git -c core.protectNTFS=false \ + clone --recurse-submodules squatting squatting-clone 2>err && + test_i18ngrep -e "directory not empty" -e "not an empty directory" err && + ! grep gitdir squatting-clone/d/a/git~2 +' + +test_expect_success 'git dirs of sibling submodules must not be nested' ' + git init nested && + test_commit -C nested nested && + ( + cd nested && + cat >.gitmodules <<-EOF && + [submodule "hippo"] + url = . + path = thing1 + [submodule "hippo/hooks"] + url = . + path = thing2 + EOF + git clone . thing1 && + git clone . thing2 && + git add .gitmodules thing1 thing2 && + test_tick && + git commit -m nested + ) && + test_must_fail git clone --recurse-submodules nested clone 2>err && + test_i18ngrep "is inside git dir" err +' + test_done diff --git a/t/t7416-submodule-dash-url.sh b/t/t7416-submodule-dash-url.sh index 1cd2c1c1ea..5ba041f537 100755 --- a/t/t7416-submodule-dash-url.sh +++ b/t/t7416-submodule-dash-url.sh @@ -46,4 +46,18 @@ test_expect_success 'fsck rejects unprotected dash' ' grep gitmodulesUrl err ' +test_expect_success 'trailing backslash is handled correctly' ' + git init testmodule && + test_commit -C testmodule c && + git submodule add ./testmodule && + : ensure that the name ends in a double backslash && + sed -e "s|\\(submodule \"testmodule\\)\"|\\1\\\\\\\\\"|" \ + -e "s|url = .*|url = \" --should-not-be-an-option\"|" \ + <.gitmodules >.new && + mv .new .gitmodules && + git commit -am "Add testmodule" && + test_must_fail git clone --verbose --recurse-submodules . dolly 2>err && + test_i18ngrep ! "unknown option" err +' + test_done diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh index 756af8c4d6..f7e7e94d7b 100755 --- a/t/t7417-submodule-path-url.sh +++ b/t/t7417-submodule-path-url.sh @@ -25,4 +25,21 @@ test_expect_success 'fsck rejects unprotected dash' ' grep gitmodulesPath err ' +test_expect_success MINGW 'submodule paths disallows trailing spaces' ' + git init super && + test_must_fail git -C super submodule add ../upstream "sub " && + + : add "sub", then rename "sub" to "sub ", the hard way && + git -C super submodule add ../upstream sub && + tree=$(git -C super write-tree) && + git -C super ls-tree $tree >tree && + sed "s/sub/sub /" <tree >tree.new && + tree=$(git -C super mktree <tree.new) && + commit=$(echo with space | git -C super commit-tree $tree) && + git -C super update-ref refs/heads/master $commit && + + test_must_fail git clone --recurse-submodules super dst 2>err && + test_i18ngrep "sub " err +' + test_done diff --git a/t/t7420-submodule-set-url.sh b/t/t7420-submodule-set-url.sh new file mode 100755 index 0000000000..ef0cb6e8e1 --- /dev/null +++ b/t/t7420-submodule-set-url.sh @@ -0,0 +1,55 @@ +#!/bin/sh +# +# Copyright (c) 2019 Denton Liu +# + +test_description='Test submodules set-url subcommand + +This test verifies that the set-url 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 >file && + git add file && + git commit -ma + ) && + mkdir super && + ( + cd super && + git init && + git submodule add ../submodule && + git commit -m "add submodule" + ) +' + +test_expect_success 'test submodule set-url' ' + # add a commit and move the submodule (change the url) + ( + cd submodule && + echo b >>file && + git add file && + git commit -mb + ) && + mv submodule newsubmodule && + + git -C newsubmodule show >expect && + ( + cd super && + test_must_fail git submodule update --remote && + git submodule set-url submodule ../newsubmodule && + grep -F "url = ../newsubmodule" .gitmodules && + git submodule update --remote + ) && + git -C super/submodule show >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t7500-commit-template-squash-signoff.sh b/t/t7500-commit-template-squash-signoff.sh index 46a5cd4b73..6d19ece05d 100755 --- a/t/t7500-commit-template-squash-signoff.sh +++ b/t/t7500-commit-template-squash-signoff.sh @@ -382,4 +382,13 @@ test_expect_success 'check commit with unstaged rename and copy' ' ) ' +test_expect_success 'commit without staging files fails and displays hints' ' + echo "initial" >file && + git add file && + git commit -m initial && + echo "changes" >>file && + test_must_fail git commit -m update >actual && + test_i18ngrep "no changes added to commit (use \"git add\" and/or \"git commit -a\")" actual +' + test_done diff --git a/t/t7501-commit-basic-functionality.sh b/t/t7501-commit-basic-functionality.sh index f1349af56e..110b4bf459 100755 --- a/t/t7501-commit-basic-functionality.sh +++ b/t/t7501-commit-basic-functionality.sh @@ -150,7 +150,7 @@ test_expect_success 'setup: commit message from file' ' test_expect_success 'amend commit' ' cat >editor <<-\EOF && #!/bin/sh - sed -e "s/a file/an amend commit/g" < "$1" > "$1-" + sed -e "s/a file/an amend commit/g" <"$1" >"$1-" mv "$1-" "$1" EOF chmod 755 editor && @@ -263,7 +263,7 @@ test_expect_success 'using message from other commit' ' test_expect_success 'editing message from other commit' ' cat >editor <<-\EOF && #!/bin/sh - sed -e "s/amend/older/g" < "$1" > "$1-" + sed -e "s/amend/older/g" <"$1" >"$1-" mv "$1-" "$1" EOF chmod 755 editor && @@ -285,9 +285,8 @@ test_expect_success 'overriding author from command line' ' ' test_expect_success PERL 'interactive add' ' - echo 7 | - git commit --interactive | - grep "What now" + echo 7 | test_must_fail git commit --interactive >out && + grep "What now" out ' test_expect_success PERL "commit --interactive doesn't change index if editor aborts" ' @@ -362,12 +361,12 @@ test_expect_success 'amend commit to fix author' ' oldtick=$GIT_AUTHOR_DATE && test_tick && git reset --hard && - git cat-file -p HEAD | + git cat-file -p HEAD >commit && sed -e "s/author.*/author $author $oldtick/" \ - -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \ - expected && + -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \ + commit >expected && git commit --amend --author="$author" && - git cat-file -p HEAD > current && + git cat-file -p HEAD >current && test_cmp expected current ' @@ -377,12 +376,12 @@ test_expect_success 'amend commit to fix date' ' test_tick && newtick=$GIT_AUTHOR_DATE && git reset --hard && - git cat-file -p HEAD | + git cat-file -p HEAD >commit && sed -e "s/author.*/author $author $newtick/" \ - -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \ - expected && + -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \ + commit >expected && git commit --amend --date="$newtick" && - git cat-file -p HEAD > current && + git cat-file -p HEAD >current && test_cmp expected current ' @@ -409,12 +408,13 @@ test_expect_success 'sign off (1)' ' echo 1 >positive && git add positive && git commit -s -m "thank you" && - git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && + git cat-file commit HEAD >commit && + sed -e "1,/^\$/d" commit >actual && ( echo thank you && echo && - git var GIT_COMMITTER_IDENT | - sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" + git var GIT_COMMITTER_IDENT >ident && + sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident ) >expected && test_cmp expected actual @@ -428,13 +428,14 @@ test_expect_success 'sign off (2)' ' git commit -s -m "thank you $existing" && - git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && + git cat-file commit HEAD >commit && + sed -e "1,/^\$/d" commit >actual && ( echo thank you && echo && echo $existing && - git var GIT_COMMITTER_IDENT | - sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" + git var GIT_COMMITTER_IDENT >ident && + sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident ) >expected && test_cmp expected actual @@ -448,13 +449,14 @@ test_expect_success 'signoff gap' ' git commit -s -m "welcome $alt" && - git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && + git cat-file commit HEAD >commit && + sed -e "1,/^\$/d" commit >actual && ( echo welcome && echo && echo $alt && - git var GIT_COMMITTER_IDENT | - sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" + git var GIT_COMMITTER_IDENT >ident && + sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident ) >expected && test_cmp expected actual ' @@ -468,15 +470,16 @@ test_expect_success 'signoff gap 2' ' We have now $alt" && - git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && + git cat-file commit HEAD >commit && + sed -e "1,/^\$/d" commit >actual && ( echo welcome && echo && echo We have now && echo $alt && echo && - git var GIT_COMMITTER_IDENT | - sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" + git var GIT_COMMITTER_IDENT >ident && + sed -e "s/>.*/>/" -e "s/^/Signed-off-by: /" ident ) >expected && test_cmp expected actual ' @@ -489,7 +492,8 @@ test_expect_success 'signoff respects trailer config' ' non-trailer line Myfooter: x" && - git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && + git cat-file commit HEAD >commit && + sed -e "1,/^\$/d" commit >actual && ( echo subject && echo && @@ -506,7 +510,8 @@ Myfooter: x" && non-trailer line Myfooter: x" && - git cat-file commit HEAD | sed -e "1,/^\$/d" > actual && + git cat-file commit HEAD >commit && + sed -e "1,/^\$/d" commit >actual && ( echo subject && echo && @@ -538,7 +543,8 @@ test_expect_success 'multiple -m' ' >negative && git add negative && git commit -m "one" -m "two" -m "three" && - git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && + git cat-file commit HEAD >commit && + sed -e "1,/^\$/d" commit >actual && ( echo one && echo && @@ -555,23 +561,25 @@ test_expect_success 'amend commit to fix author' ' oldtick=$GIT_AUTHOR_DATE && test_tick && git reset --hard && - git cat-file -p HEAD | + git cat-file -p HEAD >commit && sed -e "s/author.*/author $author $oldtick/" \ - -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \ - expected && + -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" \ + commit >expected && git commit --amend --author="$author" && - git cat-file -p HEAD > current && + git cat-file -p HEAD >current && test_cmp expected current ' test_expect_success 'git commit <file> with dirty index' ' - echo tacocat > elif && - echo tehlulz > chz && + echo tacocat >elif && + echo tehlulz >chz && git add chz && git commit elif -m "tacocat is a palindrome" && - git show --stat | grep elif && - git diff --cached | grep chz + git show --stat >stat && + grep elif stat && + git diff --cached >diff && + grep chz diff ' test_expect_success 'same tree (single parent)' ' @@ -584,7 +592,8 @@ test_expect_success 'same tree (single parent)' ' test_expect_success 'same tree (single parent) --allow-empty' ' git commit --allow-empty -m "forced empty" && - git cat-file commit HEAD | grep forced + git cat-file commit HEAD >commit && + grep forced commit ' diff --git a/t/t7508-status.sh b/t/t7508-status.sh index 4e676cdce8..482ce3510e 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -1571,7 +1571,7 @@ test_expect_success '"status.showStash=true" weaker than "--no-show-stash"' ' test_cmp expected_without_stash actual ' -test_expect_success 'no additionnal info if no stash entries' ' +test_expect_success 'no additional info if no stash entries' ' git stash clear && git -c status.showStash=true status >actual && test_cmp expected_without_stash actual diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 682b23a068..0c06d22a00 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -109,6 +109,21 @@ test_expect_success GPG 'verify-commit exits success on untrusted signature' ' grep "not certified" actual ' +test_expect_success GPG 'verify-commit exits success with matching minTrustLevel' ' + test_config gpg.minTrustLevel ultimate && + git verify-commit sixth-signed +' + +test_expect_success GPG 'verify-commit exits success with low minTrustLevel' ' + test_config gpg.minTrustLevel fully && + git verify-commit sixth-signed +' + +test_expect_success GPG 'verify-commit exits failure with high minTrustLevel' ' + test_config gpg.minTrustLevel ultimate && + test_must_fail git verify-commit eighth-signed-alt +' + test_expect_success GPG 'verify signatures with --raw' ' ( for commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed @@ -219,6 +234,30 @@ test_expect_success GPG 'show untrusted signature with custom format' ' test_cmp expect actual ' +test_expect_success GPG 'show untrusted signature with undefined trust level' ' + cat >expect <<-\EOF && + undefined + 65A0EEA02E30CAD7 + Eris Discordia <discord@example.net> + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 + D4BE22311AD3131E5EDA29A461092E85B7227189 + EOF + git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with ultimate trust level' ' + cat >expect <<-\EOF && + ultimate + 13B6F51ECDDE430D + C O Mitter <committer@example.com> + 73D758744BE721698EC54E8713B6F51ECDDE430D + 73D758744BE721698EC54E8713B6F51ECDDE430D + EOF + git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual && + test_cmp expect actual +' + test_expect_success GPG 'show unknown signature with custom format' ' cat >expect <<-\EOF && E diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index 66d7a62797..29518e0949 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -71,10 +71,10 @@ test_expect_success 'prepare for rebase conflicts' ' ' -test_expect_success 'status when rebase in progress before resolving conflicts' ' +test_expect_success 'status when rebase --apply in progress before resolving conflicts' ' test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short HEAD^^) && - test_must_fail git rebase HEAD^ --onto HEAD^^ && + test_must_fail git rebase --apply HEAD^ --onto HEAD^^ && cat >expected <<EOF && rebase in progress; onto $ONTO You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''. @@ -94,11 +94,11 @@ EOF ' -test_expect_success 'status when rebase in progress before rebase --continue' ' +test_expect_success 'status when rebase --apply in progress before rebase --continue' ' git reset --hard rebase_conflicts && test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short HEAD^^) && - test_must_fail git rebase HEAD^ --onto HEAD^^ && + test_must_fail git rebase --apply HEAD^ --onto HEAD^^ && echo three >main.txt && git add main.txt && cat >expected <<EOF && @@ -688,7 +688,7 @@ EOF ' -test_expect_success 'status when rebase conflicts with statushints disabled' ' +test_expect_success 'status when rebase --apply conflicts with statushints disabled' ' git reset --hard master && git checkout -b statushints_disabled && test_when_finished "git config --local advice.statushints true" && @@ -698,7 +698,7 @@ test_expect_success 'status when rebase conflicts with statushints disabled' ' test_commit three_statushints main.txt three && test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short HEAD^^) && - test_must_fail git rebase HEAD^ --onto HEAD^^ && + test_must_fail git rebase --apply HEAD^ --onto HEAD^^ && cat >expected <<EOF && rebase in progress; onto $ONTO You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''. diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh index f19202b509..6602790b5f 100755 --- a/t/t7513-interpret-trailers.sh +++ b/t/t7513-interpret-trailers.sh @@ -1234,7 +1234,7 @@ test_expect_success 'with simple command' ' test_cmp expected actual ' -test_expect_success 'with command using commiter information' ' +test_expect_success 'with command using committer information' ' git config trailer.sign.ifExists "addIfDifferent" && git config trailer.sign.command "echo \"\$GIT_COMMITTER_NAME <\$GIT_COMMITTER_EMAIL>\"" && cat complex_message_body >expected && diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh index 997d5fb349..fbfdcca000 100755 --- a/t/t7519-status-fsmonitor.sh +++ b/t/t7519-status-fsmonitor.sh @@ -32,11 +32,12 @@ write_integration_script () { echo "$0: exactly 2 arguments expected" exit 2 fi - if test "$1" != 1 + if test "$1" != 2 then echo "Unsupported core.fsmonitor hook version." >&2 exit 1 fi + printf "last_update_token\0" printf "untracked\0" printf "dir1/untracked\0" printf "dir2/untracked\0" @@ -106,6 +107,9 @@ EOF # test that "update-index --fsmonitor-valid" sets the fsmonitor valid bit test_expect_success 'update-index --fsmonitor-valid" sets the fsmonitor valid bit' ' + write_script .git/hooks/fsmonitor-test<<-\EOF && + printf "last_update_token\0" + EOF git update-index --fsmonitor && git update-index --fsmonitor-valid dir1/modified && git update-index --fsmonitor-valid dir2/modified && @@ -164,6 +168,9 @@ EOF # test that newly added files are marked valid test_expect_success 'newly added files are marked valid' ' + write_script .git/hooks/fsmonitor-test<<-\EOF && + printf "last_update_token\0" + EOF git add new && git add dir1/new && git add dir2/new && @@ -203,6 +210,7 @@ EOF # test that *only* files returned by the integration script get flagged as invalid test_expect_success '*only* files returned by the integration script get flagged as invalid' ' write_script .git/hooks/fsmonitor-test<<-\EOF && + printf "last_update_token\0" printf "dir1/modified\0" EOF clean_repo && @@ -218,11 +226,12 @@ test_expect_success '*only* files returned by the integration script get flagged # Ensure commands that call refresh_index() to move the index back in time # properly invalidate the fsmonitor cache test_expect_success 'refresh_index() invalidates fsmonitor cache' ' - write_script .git/hooks/fsmonitor-test<<-\EOF && - EOF clean_repo && dirty_repo && + write_integration_script && git add . && + write_script .git/hooks/fsmonitor-test<<-\EOF && + EOF git commit -m "to reset" && git reset HEAD~1 && git status >actual && @@ -271,6 +280,7 @@ do # (if enabled) files unless it is told about them. test_expect_success "status doesn't detect unreported modifications" ' write_script .git/hooks/fsmonitor-test<<-\EOF && + printf "last_update_token\0" :>marker EOF clean_repo && @@ -294,7 +304,7 @@ do done done -# test that splitting the index dosn't interfere +# test that splitting the index doesn't interfere test_expect_success 'splitting the index results in the same state' ' write_integration_script && dirty_repo && diff --git a/t/t7519/fsmonitor-all b/t/t7519/fsmonitor-all index 691bc94dc2..94ab66bd3d 100755 --- a/t/t7519/fsmonitor-all +++ b/t/t7519/fsmonitor-all @@ -17,7 +17,6 @@ fi if test "$1" != 1 then - echo "Unsupported core.fsmonitor hook version." >&2 exit 1 fi diff --git a/t/t7519/fsmonitor-all-v2 b/t/t7519/fsmonitor-all-v2 new file mode 100755 index 0000000000..061907e88b --- /dev/null +++ b/t/t7519/fsmonitor-all-v2 @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +use strict; +use warnings; +# +# An test hook script to integrate with git to test fsmonitor. +# +# The hook is passed a version (currently 2) and since token +# formatted as a string and outputs to stdout all files that have been +# modified since the given time. Paths must be relative to the root of +# the working tree and separated by a single NUL. +# +#echo "$0 $*" >&2 +my ($version, $last_update_token) = @ARGV; + +if ($version ne 2) { + print "Unsupported query-fsmonitor hook version '$version'.\n"; + exit 1; +} + +print "last_update_token\0/\0" diff --git a/t/t7519/fsmonitor-watchman b/t/t7519/fsmonitor-watchman index 5514edcf68..264b9daf83 100755 --- a/t/t7519/fsmonitor-watchman +++ b/t/t7519/fsmonitor-watchman @@ -23,10 +23,10 @@ my ($version, $time) = @ARGV; if ($version == 1) { # convert nanoseconds to seconds - $time = int $time / 1000000000; + # subtract one second to make sure watchman will return all changes + $time = int ($time / 1000000000) - 1; } else { - die "Unsupported query-fsmonitor hook version '$version'.\n" . - "Falling back to scanning...\n"; + exit 1; } my $git_work_tree; @@ -54,18 +54,12 @@ sub launch_watchman { # # To accomplish this, we're using the "since" generator to use the # recency index to select candidate nodes and "fields" to limit the - # output to file names only. Then we're using the "expression" term to - # further constrain the results. - # - # The category of transient files that we want to ignore will have a - # creation clock (cclock) newer than $time_t value and will also not - # currently exist. + # output to file names only. my $query = <<" END"; ["query", "$git_work_tree", { "since": $time, - "fields": ["name"], - "expression": ["not", ["allof", ["since", $time, "cclock"], ["not", "exists"]]] + "fields": ["name"] }] END diff --git a/t/t7519/fsmonitor-watchman-v2 b/t/t7519/fsmonitor-watchman-v2 new file mode 100755 index 0000000000..14ed0aa42d --- /dev/null +++ b/t/t7519/fsmonitor-watchman-v2 @@ -0,0 +1,173 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + } + my $query = <<" END"; + ["query", "$git_work_tree", { + "since": $last_update_token, + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; <CHLD_OUT>}; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/t/t7526-commit-pathspec-file.sh b/t/t7526-commit-pathspec-file.sh new file mode 100755 index 0000000000..5fbe47ebcd --- /dev/null +++ b/t/t7526-commit-pathspec-file.sh @@ -0,0 +1,164 @@ +#!/bin/sh + +test_description='commit --pathspec-from-file' + +. ./test-lib.sh + +test_tick + +test_expect_success setup ' + test_commit file0 && + git tag checkpoint && + + echo A >fileA.t && + echo B >fileB.t && + echo C >fileC.t && + echo D >fileD.t && + git add fileA.t fileB.t fileC.t fileD.t +' + +restore_checkpoint () { + git reset --soft checkpoint +} + +verify_expect () { + git diff-tree --no-commit-id --name-status -r HEAD >actual && + test_cmp expect actual +} + +test_expect_success '--pathspec-from-file from stdin' ' + restore_checkpoint && + + echo fileA.t | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect +' + +test_expect_success '--pathspec-from-file from file' ' + restore_checkpoint && + + echo fileA.t >list && + git commit --pathspec-from-file=list -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect +' + +test_expect_success 'NUL delimiters' ' + restore_checkpoint && + + printf "fileA.t\0fileB.t\0" | git commit --pathspec-from-file=- --pathspec-file-nul -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'LF delimiters' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t\n" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'no trailing delimiter' ' + restore_checkpoint && + + printf "fileA.t\nfileB.t" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'CRLF delimiters' ' + restore_checkpoint && + + printf "fileA.t\r\nfileB.t\r\n" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + A fileB.t + EOF + verify_expect +' + +test_expect_success 'quotes' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + git commit --pathspec-from-file=list -m "Commit" && + + cat >expect <<-\EOF && + A fileA.t + EOF + verify_expect expect +' + +test_expect_success 'quotes not compatible with --pathspec-file-nul' ' + restore_checkpoint && + + cat >list <<-\EOF && + "file\101.t" + EOF + + test_must_fail git commit --pathspec-from-file=list --pathspec-file-nul -m "Commit" +' + +test_expect_success 'only touches what was listed' ' + restore_checkpoint && + + printf "fileB.t\nfileC.t\n" | git commit --pathspec-from-file=- -m "Commit" && + + cat >expect <<-\EOF && + A fileB.t + A fileC.t + EOF + verify_expect +' + +test_expect_success 'error conditions' ' + restore_checkpoint && + echo fileA.t >list && + >empty_list && + + test_must_fail git commit --pathspec-from-file=list --interactive -m "Commit" 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err && + + test_must_fail git commit --pathspec-from-file=list --patch -m "Commit" 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with --interactive/--patch" err && + + test_must_fail git commit --pathspec-from-file=list --all -m "Commit" 2>err && + test_i18ngrep -e "--pathspec-from-file with -a does not make sense" err && + + test_must_fail git commit --pathspec-from-file=list -m "Commit" -- fileA.t 2>err && + test_i18ngrep -e "--pathspec-from-file is incompatible with pathspec arguments" err && + + test_must_fail git commit --pathspec-file-nul -m "Commit" 2>err && + test_i18ngrep -e "--pathspec-file-nul requires --pathspec-from-file" err && + + test_must_fail git commit --pathspec-from-file=empty_list --include -m "Commit" 2>err && + test_i18ngrep -e "No paths with --include/--only does not make sense." err && + + test_must_fail git commit --pathspec-from-file=empty_list --only -m "Commit" 2>err && + test_i18ngrep -e "No paths with --include/--only does not make sense." err +' + +test_done diff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh index d99218a725..a426f3a89a 100755 --- a/t/t7612-merge-verify-signatures.sh +++ b/t/t7612-merge-verify-signatures.sh @@ -66,6 +66,20 @@ test_expect_success GPG 'merge commit with untrusted signature with verification test_i18ngrep "has an untrusted GPG signature" mergeerror ' +test_expect_success GPG 'merge commit with untrusted signature with verification and high minTrustLevel' ' + test_when_finished "git reset --hard && git checkout initial" && + test_config gpg.minTrustLevel marginal && + test_must_fail git merge --ff-only --verify-signatures side-untrusted 2>mergeerror && + test_i18ngrep "has an untrusted GPG signature" mergeerror +' + +test_expect_success GPG 'merge commit with untrusted signature with verification and low minTrustLevel' ' + test_when_finished "git reset --hard && git checkout initial" && + test_config gpg.minTrustLevel undefined && + git merge --ff-only --verify-signatures side-untrusted >mergeoutput && + test_i18ngrep "has a good GPG signature" mergeoutput +' + test_expect_success GPG 'merge commit with untrusted signature with merge.verifySignatures=true' ' test_when_finished "git reset --hard && git checkout initial" && test_config merge.verifySignatures true && @@ -73,6 +87,14 @@ test_expect_success GPG 'merge commit with untrusted signature with merge.verify test_i18ngrep "has an untrusted GPG signature" mergeerror ' +test_expect_success GPG 'merge commit with untrusted signature with merge.verifySignatures=true and minTrustLevel' ' + test_when_finished "git reset --hard && git checkout initial" && + test_config merge.verifySignatures true && + test_config gpg.minTrustLevel marginal && + test_must_fail git merge --ff-only side-untrusted 2>mergeerror && + test_i18ngrep "has an untrusted GPG signature" mergeerror +' + test_expect_success GPG 'merge signed commit with verification' ' test_when_finished "git reset --hard && git checkout initial" && git merge --verbose --ff-only --verify-signatures side-signed >mergeoutput && diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index 4e855bc21b..25b235c063 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -4,129 +4,104 @@ test_description='git repack works correctly' . ./test-lib.sh -commit_and_pack() { - test_commit "$@" >/dev/null && - SHA1=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) && - echo pack-${SHA1}.pack +commit_and_pack () { + test_commit "$@" 1>&2 && + incrpackid=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) && + echo pack-${incrpackid}.pack +} + +test_no_missing_in_packs () { + myidx=$(ls -1 .git/objects/pack/*.idx) && + test_path_is_file "$myidx" && + git verify-pack -v alt_objects/pack/*.idx >orig.raw && + sed -n -e "s/^\($OID_REGEX\).*/\1/p" orig.raw | sort >orig && + git verify-pack -v $myidx >dest.raw && + cut -d" " -f1 dest.raw | sort >dest && + comm -23 orig dest >missing && + test_must_be_empty missing +} + +# we expect $packid and $oid to be defined +test_has_duplicate_object () { + want_duplicate_object="$1" + found_duplicate_object=false + for p in .git/objects/pack/*.idx + do + idx=$(basename $p) + test "pack-$packid.idx" = "$idx" && continue + git verify-pack -v $p >packlist || return $? + if grep "^$oid" packlist + then + found_duplicate_object=true + echo "DUPLICATE OBJECT FOUND" + break + fi + done && + test "$want_duplicate_object" = "$found_duplicate_object" } test_expect_success 'objects in packs marked .keep are not repacked' ' - echo content1 > file1 && - echo content2 > file2 && + echo content1 >file1 && + echo content2 >file2 && git add . && test_tick && git commit -m initial_commit && # Create two packs # The first pack will contain all of the objects except one - git rev-list --objects --all | grep -v file2 | - git pack-objects pack > /dev/null && + git rev-list --objects --all >objs && + grep -v file2 objs | git pack-objects pack && # The second pack will contain the excluded object - packsha1=$(git rev-list --objects --all | grep file2 | - git pack-objects pack) && - >pack-$packsha1.keep && - objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 | - sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") && + packid=$(grep file2 objs | git pack-objects pack) && + >pack-$packid.keep && + git verify-pack -v pack-$packid.idx >packlist && + oid=$(head -n 1 packlist | sed -e "s/^\($OID_REGEX\).*/\1/") && mv pack-* .git/objects/pack/ && git repack -A -d -l && git prune-packed && - for p in .git/objects/pack/*.idx; do - idx=$(basename $p) - test "pack-$packsha1.idx" = "$idx" && continue - if git verify-pack -v $p | egrep "^$objsha1"; then - found_duplicate_object=1 - echo "DUPLICATE OBJECT FOUND" - break - fi - done && - test -z "$found_duplicate_object" + test_has_duplicate_object false ' test_expect_success 'writing bitmaps via command-line can duplicate .keep objects' ' - # build on $objsha1, $packsha1, and .keep state from previous + # build on $oid, $packid, and .keep state from previous git repack -Adbl && - test_when_finished "found_duplicate_object=" && - for p in .git/objects/pack/*.idx; do - idx=$(basename $p) - test "pack-$packsha1.idx" = "$idx" && continue - if git verify-pack -v $p | egrep "^$objsha1"; then - found_duplicate_object=1 - echo "DUPLICATE OBJECT FOUND" - break - fi - done && - test "$found_duplicate_object" = 1 + test_has_duplicate_object true ' test_expect_success 'writing bitmaps via config can duplicate .keep objects' ' - # build on $objsha1, $packsha1, and .keep state from previous + # build on $oid, $packid, and .keep state from previous git -c repack.writebitmaps=true repack -Adl && - test_when_finished "found_duplicate_object=" && - for p in .git/objects/pack/*.idx; do - idx=$(basename $p) - test "pack-$packsha1.idx" = "$idx" && continue - if git verify-pack -v $p | egrep "^$objsha1"; then - found_duplicate_object=1 - echo "DUPLICATE OBJECT FOUND" - break - fi - done && - test "$found_duplicate_object" = 1 + test_has_duplicate_object true ' test_expect_success 'loose objects in alternate ODB are not repacked' ' mkdir alt_objects && - echo $(pwd)/alt_objects > .git/objects/info/alternates && - echo content3 > file3 && - objsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) && + echo $(pwd)/alt_objects >.git/objects/info/alternates && + echo content3 >file3 && + oid=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) && git add file3 && test_tick && git commit -m commit_file3 && git repack -a -d -l && git prune-packed && - for p in .git/objects/pack/*.idx; do - if git verify-pack -v $p | egrep "^$objsha1"; then - found_duplicate_object=1 - echo "DUPLICATE OBJECT FOUND" - break - fi - done && - test -z "$found_duplicate_object" + test_has_duplicate_object false ' test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' ' mkdir alt_objects/pack && mv .git/objects/pack/* alt_objects/pack && git repack -a && - myidx=$(ls -1 .git/objects/pack/*.idx) && - test -f "$myidx" && - for p in alt_objects/pack/*.idx; do - git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p" - done | while read sha1 rest; do - if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then - echo "Missing object in local pack: $sha1" - return 1 - fi - done + test_no_missing_in_packs ' test_expect_success 'packed obs in alt ODB are repacked when local repo has packs' ' rm -f .git/objects/pack/* && - echo new_content >> file1 && + echo new_content >>file1 && git add file1 && test_tick && git commit -m more_content && git repack && git repack -a -d && - myidx=$(ls -1 .git/objects/pack/*.idx) && - test -f "$myidx" && - for p in alt_objects/pack/*.idx; do - git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p" - done | while read sha1 rest; do - if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then - echo "Missing object in local pack: $sha1" - return 1 - fi - done + test_no_missing_in_packs ' test_expect_success 'packed obs in alternate ODB kept pack are repacked' ' @@ -134,7 +109,7 @@ test_expect_success 'packed obs in alternate ODB kept pack are repacked' ' for p in alt_objects/pack/*.pack do base_name=$(basename $p .pack) && - if test -f alt_objects/pack/$base_name.keep + if test_path_is_file alt_objects/pack/$base_name.keep then rm alt_objects/pack/$base_name.keep else @@ -142,22 +117,13 @@ test_expect_success 'packed obs in alternate ODB kept pack are repacked' ' fi done && git repack -a -d && - myidx=$(ls -1 .git/objects/pack/*.idx) && - test -f "$myidx" && - for p in alt_objects/pack/*.idx; do - git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p" - done | while read sha1 rest; do - if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then - echo "Missing object in local pack: $sha1" - return 1 - fi - done + test_no_missing_in_packs ' test_expect_success 'packed unreachable obs in alternate ODB are not loosened' ' rm -f alt_objects/pack/*.keep && mv .git/objects/pack/* alt_objects/pack/ && - csha1=$(git rev-parse HEAD^{commit}) && + coid=$(git rev-parse HEAD^{commit}) && git reset --hard HEAD^ && test_tick && git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all && @@ -167,15 +133,15 @@ test_expect_success 'packed unreachable obs in alternate ODB are not loosened' ' --unpack-unreachable </dev/null pack && rm -f .git/objects/pack/* && mv pack-* .git/objects/pack/ && - test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx | - egrep "^$csha1 " | sort | uniq | wc -l) && - echo > .git/objects/info/alternates && - test_must_fail git show $csha1 + git verify-pack -v -- .git/objects/pack/*.idx >packlist && + ! grep "^$coid " packlist && + echo >.git/objects/info/alternates && + test_must_fail git show $coid ' test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' ' - echo $(pwd)/alt_objects > .git/objects/info/alternates && - echo "$csha1" | git pack-objects --non-empty --all --reflog pack && + echo $(pwd)/alt_objects >.git/objects/info/alternates && + echo "$coid" | git pack-objects --non-empty --all --reflog pack && rm -f .git/objects/pack/* && mv pack-* .git/objects/pack/ && # The pack-objects call on the next line is equivalent to @@ -184,10 +150,10 @@ test_expect_success 'local packed unreachable obs that exist in alternate ODB ar --unpack-unreachable </dev/null pack && rm -f .git/objects/pack/* && mv pack-* .git/objects/pack/ && - test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx | - egrep "^$csha1 " | sort | uniq | wc -l) && - echo > .git/objects/info/alternates && - test_must_fail git show $csha1 + git verify-pack -v -- .git/objects/pack/*.idx >packlist && + ! grep "^$coid " && + echo >.git/objects/info/alternates && + test_must_fail git show $coid ' test_expect_success 'objects made unreachable by grafts only are kept' ' @@ -196,7 +162,7 @@ test_expect_success 'objects made unreachable by grafts only are kept' ' H0=$(git rev-parse HEAD) && H1=$(git rev-parse HEAD^) && H2=$(git rev-parse HEAD^^) && - echo "$H0 $H2" > .git/info/grafts && + echo "$H0 $H2" >.git/info/grafts && git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all && git repack -a -d && git cat-file -t $H1 @@ -235,7 +201,7 @@ test_expect_success 'incremental repack does not complain' ' 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 || :) && + bitmap=$(ls bare.git/objects/pack/*.bitmap || :) && test -z "$bitmap" ' diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 6bac9ed180..29b92907e2 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -125,15 +125,14 @@ test_expect_success 'difftool stops on error with --trust-exit-code' ' test_when_finished "rm -f for-diff .git/fail-right-file" && test_when_finished "git reset -- for-diff" && write_script .git/fail-right-file <<-\EOF && - echo "$2" + echo failed exit 1 EOF >for-diff && git add for-diff && - echo file >expect && test_must_fail git difftool -y --trust-exit-code \ --extcmd .git/fail-right-file branch >actual && - test_cmp expect actual + test_line_count = 1 actual ' test_expect_success 'difftool honors exit status if command not found' ' diff --git a/t/t7811-grep-open.sh b/t/t7811-grep-open.sh index d1ebfd88c7..a98785da79 100755 --- a/t/t7811-grep-open.sh +++ b/t/t7811-grep-open.sh @@ -113,7 +113,6 @@ test_expect_success 'modified file' ' subdir/grep.c unrelated EOF - >empty && echo "enum grep_pat_token" >unrelated && test_when_finished "git checkout HEAD unrelated" && diff --git a/t/t7812-grep-icase-non-ascii.sh b/t/t7812-grep-icase-non-ascii.sh index 531eb59d57..03dba6685a 100755 --- a/t/t7812-grep-icase-non-ascii.sh +++ b/t/t7812-grep-icase-non-ascii.sh @@ -70,15 +70,18 @@ test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep ASCII from invalid UT test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-ASCII from invalid UTF-8 data' ' git grep -h "æ" invalid-0x80 >actual && test_cmp expected actual && - git grep -h "(*NO_JIT)æ" invalid-0x80 && + git grep -h "(*NO_JIT)æ" invalid-0x80 >actual && test_cmp expected actual ' test_expect_success GETTEXT_LOCALE,LIBPCRE2 'PCRE v2: grep non-ASCII from invalid UTF-8 data with -i' ' test_might_fail git grep -hi "Æ" invalid-0x80 >actual && - test_cmp expected actual && - test_must_fail git grep -hi "(*NO_JIT)Æ" invalid-0x80 && - test_cmp expected actual + if test -s actual + then + test_cmp expected actual + fi && + test_must_fail git grep -hi "(*NO_JIT)Æ" invalid-0x80 >actual && + ! test_cmp expected actual ' test_done diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh index 946f91fa57..828cb3ba58 100755 --- a/t/t7814-grep-recurse-submodules.sh +++ b/t/t7814-grep-recurse-submodules.sh @@ -345,7 +345,16 @@ test_incompatible_with_recurse_submodules () } test_incompatible_with_recurse_submodules --untracked -test_incompatible_with_recurse_submodules --no-index + +test_expect_success 'grep --recurse-submodules --no-index ignores --recurse-submodules' ' + git grep --recurse-submodules --no-index -e "^(.|.)[\d]" >actual && + cat >expect <<-\EOF && + a:(1|2)d(3|4) + submodule/a:(1|2)d(3|4) + submodule/sub/a:(1|2)d(3|4) + EOF + test_cmp expect actual +' test_expect_success 'grep --recurse-submodules should pass the pattern type along' ' # Fixed diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 997f90b42b..90f61c3400 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -1194,8 +1194,8 @@ test_expect_success $PREREQ 'in-reply-to but no threading' ' --to=nobody@example.com \ --in-reply-to="<in-reply-id@example.com>" \ --no-thread \ - $patches | - grep "In-Reply-To: <in-reply-id@example.com>" + $patches >out && + grep "In-Reply-To: <in-reply-id@example.com>" out ' test_expect_success $PREREQ 'no in-reply-to and no threading' ' @@ -1260,7 +1260,7 @@ test_expect_success $PREREQ 'sendemail.identity: --no-identity clears previous i grep "To: default@example.com" stdout ' -test_expect_success $PREREQ 'sendemail.identity: bool identity variable existance overrides' ' +test_expect_success $PREREQ 'sendemail.identity: bool identity variable existence overrides' ' git -c sendemail.identity=cloud \ -c sendemail.xmailer=true \ -c sendemail.cloud.xmailer=false \ @@ -2066,7 +2066,7 @@ test_expect_success $PREREQ 'leading and trailing whitespaces are removed' ' TO1=$(echo "QTo 1 <to1@example.com>" | q_to_tab) && TO2=$(echo "QZto2" | qz_to_tab_space) && CC1=$(echo "cc1" | append_cr) && - BCC1=$(echo "Q bcc1@example.com Q" | q_to_nul) && + BCC1=$(echo " bcc1@example.com Q" | q_to_nul) && git send-email \ --dry-run \ --from=" Example <from@example.com>" \ diff --git a/t/t9010-svn-fe.sh b/t/t9010-svn-fe.sh index 0b20b07e68..c90fdc5c89 100755 --- a/t/t9010-svn-fe.sh +++ b/t/t9010-svn-fe.sh @@ -53,8 +53,6 @@ text_no_props () { printf "%s\n" "$text" } ->empty - test_expect_success 'empty dump' ' reinit_git && echo "SVN-fs-dump-format-version: 2" >input && @@ -208,7 +206,7 @@ test_expect_failure 'timestamp and empty file' ' test_cmp expect.date actual.date && test_cmp expect.files actual.files && git checkout HEAD empty-file && - test_cmp empty file + test_must_be_empty file ' test_expect_success 'directory with files' ' diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh index dbe8deac0d..aec45bca3b 100755 --- a/t/t9106-git-svn-commit-diff-clobber.sh +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -92,7 +92,8 @@ test_expect_success 'multiple dcommit from git svn will not clobber svn' " test_expect_success 'check that rebase really failed' ' - test -d .git/rebase-apply + git status >output && + grep currently.rebasing output ' test_expect_success 'resolve, continue the rebase and dcommit' " diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh index 45773ee560..0a9f1ef366 100755 --- a/t/t9116-git-svn-log.sh +++ b/t/t9116-git-svn-log.sh @@ -43,14 +43,18 @@ test_expect_success 'setup repository and import' ' test_expect_success 'run log' " git reset --hard origin/a && - git svn log -r2 origin/trunk | grep ^r2 && - git svn log -r4 origin/trunk | grep ^r4 && - git svn log -r3 | grep ^r3 + git svn log -r2 origin/trunk >out && + grep ^r2 out && + git svn log -r4 origin/trunk >out && + grep ^r4 out && + git svn log -r3 >out && + grep ^r3 out " test_expect_success 'run log against a from trunk' " git reset --hard origin/trunk && - git svn log -r3 origin/a | grep ^r3 + git svn log -r3 origin/a >out && + grep ^r3 out " printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4 diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index e707fb861e..ae9950a9c2 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -2143,12 +2143,27 @@ test_expect_success 'R: abort on receiving feature after data command' ' test_must_fail git fast-import <input ' +test_expect_success 'R: import-marks features forbidden by default' ' + >git.marks && + echo "feature import-marks=git.marks" >input && + test_must_fail git fast-import <input && + echo "feature import-marks-if-exists=git.marks" >input && + test_must_fail git fast-import <input +' + test_expect_success 'R: only one import-marks feature allowed per stream' ' + >git.marks && + >git2.marks && cat >input <<-EOF && feature import-marks=git.marks feature import-marks=git2.marks EOF + test_must_fail git fast-import --allow-unsafe-features <input +' + +test_expect_success 'R: export-marks feature forbidden by default' ' + echo "feature export-marks=git.marks" >input && test_must_fail git fast-import <input ' @@ -2162,19 +2177,29 @@ test_expect_success 'R: export-marks feature results in a marks file being creat EOF - cat input | git fast-import && + git fast-import --allow-unsafe-features <input && grep :1 git.marks ' test_expect_success 'R: export-marks options can be overridden by commandline options' ' - cat input | git fast-import --export-marks=other.marks && - grep :1 other.marks + cat >input <<-\EOF && + feature export-marks=feature-sub/git.marks + blob + mark :1 + data 3 + hi + + EOF + git fast-import --allow-unsafe-features \ + --export-marks=cmdline-sub/other.marks <input && + grep :1 cmdline-sub/other.marks && + test_path_is_missing feature-sub ' test_expect_success 'R: catch typo in marks file name' ' test_must_fail git fast-import --import-marks=nonexistent.marks </dev/null && echo "feature import-marks=nonexistent.marks" | - test_must_fail git fast-import + test_must_fail git fast-import --allow-unsafe-features ' test_expect_success 'R: import and output marks can be the same file' ' @@ -2229,7 +2254,8 @@ test_expect_success 'R: --import-marks-if-exists' ' test_expect_success 'R: feature import-marks-if-exists' ' rm -f io.marks && - git fast-import --export-marks=io.marks <<-\EOF && + git fast-import --export-marks=io.marks \ + --allow-unsafe-features <<-\EOF && feature import-marks-if-exists=not_io.marks EOF test_must_be_empty io.marks && @@ -2240,7 +2266,8 @@ test_expect_success 'R: feature import-marks-if-exists' ' echo ":1 $blob" >expect && echo ":2 $blob" >>expect && - git fast-import --export-marks=io.marks <<-\EOF && + git fast-import --export-marks=io.marks \ + --allow-unsafe-features <<-\EOF && feature import-marks-if-exists=io.marks blob mark :2 @@ -2253,7 +2280,8 @@ test_expect_success 'R: feature import-marks-if-exists' ' echo ":3 $blob" >>expect && git fast-import --import-marks=io.marks \ - --export-marks=io.marks <<-\EOF && + --export-marks=io.marks \ + --allow-unsafe-features <<-\EOF && feature import-marks-if-exists=not_io.marks blob mark :3 @@ -2264,7 +2292,8 @@ test_expect_success 'R: feature import-marks-if-exists' ' test_cmp expect io.marks && git fast-import --import-marks-if-exists=not_io.marks \ - --export-marks=io.marks <<-\EOF && + --export-marks=io.marks \ + --allow-unsafe-features <<-\EOF && feature import-marks-if-exists=io.marks EOF test_must_be_empty io.marks @@ -2276,7 +2305,7 @@ test_expect_success 'R: import to output marks works without any content' ' feature export-marks=marks.new EOF - cat input | git fast-import && + git fast-import --allow-unsafe-features <input && test_cmp marks.out marks.new ' @@ -2286,7 +2315,7 @@ test_expect_success 'R: import marks prefers commandline marks file over the str feature export-marks=marks.new EOF - cat input | git fast-import --import-marks=marks.out && + git fast-import --import-marks=marks.out --allow-unsafe-features <input && test_cmp marks.out marks.new ' @@ -2299,7 +2328,8 @@ test_expect_success 'R: multiple --import-marks= should be honoured' ' head -n2 marks.out > one.marks && tail -n +3 marks.out > two.marks && - git fast-import --import-marks=one.marks --import-marks=two.marks <input && + git fast-import --import-marks=one.marks --import-marks=two.marks \ + --allow-unsafe-features <input && test_cmp marks.out combined.marks ' @@ -2312,7 +2342,7 @@ test_expect_success 'R: feature relative-marks should be honoured' ' mkdir -p .git/info/fast-import/ && cp marks.new .git/info/fast-import/relative.in && - git fast-import <input && + git fast-import --allow-unsafe-features <input && test_cmp marks.new .git/info/fast-import/relative.out ' @@ -2324,7 +2354,7 @@ test_expect_success 'R: feature no-relative-marks should be honoured' ' feature export-marks=non-relative.out EOF - git fast-import <input && + git fast-import --allow-unsafe-features <input && test_cmp marks.new non-relative.out ' @@ -2477,9 +2507,6 @@ test_expect_success PIPE 'R: copy using cat-file' ' echo $expect_id blob $expect_len >expect.response && rm -f blobs && - cat >frontend <<-\FRONTEND_END && - #!/bin/sh - FRONTEND_END mkfifo blobs && ( @@ -2594,7 +2621,7 @@ test_expect_success 'R: quiet option results in no stats being output' ' EOF - cat input | git fast-import 2> output && + git fast-import 2>output <input && test_must_be_empty output ' @@ -3164,13 +3191,22 @@ background_import_then_checkpoint () { exec 9<>V.output rm V.output - git fast-import $options <&8 >&9 & - echo $! >V.pid + ( + git fast-import $options <&8 >&9 & + echo $! >&9 + wait $! + echo >&2 "background fast-import terminated too early with exit code $?" + # Un-block the read loop in the main shell process. + echo >&9 UNEXPECTED + ) & + sh_pid=$! + read fi_pid <&9 # We don't mind if fast-import has already died by the time the test # ends. test_when_finished " exec 8>&-; exec 9>&-; - kill $(cat V.pid) && wait $(cat V.pid) + kill $sh_pid && wait $sh_pid + kill $fi_pid && wait $fi_pid true" # Start in the background to ensure we adhere strictly to (blocking) @@ -3190,6 +3226,9 @@ background_import_then_checkpoint () { then error=0 break + elif test "$output" = "UNEXPECTED" + then + break fi # otherwise ignore cruft echo >&2 "cruft: $output" @@ -3202,7 +3241,7 @@ background_import_then_checkpoint () { } background_import_still_running () { - if ! kill -0 "$(cat V.pid)" + if ! kill -0 "$fi_pid" then echo >&2 "background fast-import terminated too early" false diff --git a/t/t9301-fast-import-notes.sh b/t/t9301-fast-import-notes.sh index dadc70b7d5..ca223dca98 100755 --- a/t/t9301-fast-import-notes.sh +++ b/t/t9301-fast-import-notes.sh @@ -275,7 +275,7 @@ $whitespace third note for first commit EXPECT_END -test_expect_success 'add concatentation notes with M command' ' +test_expect_success 'add concatenation notes with M command' ' git fast-import <input && GIT_NOTES_REF=refs/notes/test git log | grep "^ " > actual && diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 2e4e214815..690c90fb82 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -541,7 +541,7 @@ test_expect_success 'tree_tag' ' # NEEDSWORK: not just check return status, but validate the output # Note that these tests DO NOTHING other than print a warning that -# they are ommitting the one tag we asked them to export (because the +# they are omitting the one tag we asked them to export (because the # tags resolve to a tree). They exist just to make sure we do not # abort but instead just warn. test_expect_success 'tree_tag-obj' 'git fast-export tree_tag-obj' @@ -600,9 +600,10 @@ test_expect_success 'directory becomes symlink' ' test_expect_success 'fast-export quotes pathnames' ' git init crazy-paths && + test_config -C crazy-paths core.protectNTFS false && (cd crazy-paths && blob=$(echo foo | git hash-object -w --stdin) && - git update-index --add \ + git -c core.protectNTFS=false update-index --add \ --cacheinfo 100644 $blob "$(printf "path with\\nnewline")" \ --cacheinfo 100644 $blob "path with \"quote\"" \ --cacheinfo 100644 $blob "path with \\backslash" \ diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh index 0796a438bc..e38cbc97d3 100755 --- a/t/t9502-gitweb-standalone-parse-output.sh +++ b/t/t9502-gitweb-standalone-parse-output.sh @@ -188,8 +188,8 @@ test_expect_success 'forks: project_index lists all projects (incl. forks)' ' ' xss() { - echo >&2 "Checking $1..." && - gitweb_run "$1" && + echo >&2 "Checking $*..." && + gitweb_run "$@" && if grep "$TAG" gitweb.body; then echo >&2 "xss: $TAG should have been quoted in output" return 1 @@ -200,7 +200,8 @@ xss() { test_expect_success 'xss checks' ' TAG="<magic-xss-tag>" && xss "a=rss&p=$TAG" && - xss "a=rss&p=foo.git&f=$TAG" + xss "a=rss&p=foo.git&f=$TAG" && + xss "" "$TAG+" ' test_done diff --git a/t/t9809-git-p4-client-view.sh b/t/t9809-git-p4-client-view.sh index 3cff1fce1b..9c9710d8c7 100755 --- a/t/t9809-git-p4-client-view.sh +++ b/t/t9809-git-p4-client-view.sh @@ -407,7 +407,7 @@ test_expect_success 'reinit depot' ' ' # -# What happens when two files of the same name are overlayed together? +# What happens when two files of the same name are overlaid together? # The last-listed file should take preference. # # //depot diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index e90ac565e1..5505e5aa24 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -378,7 +378,7 @@ test_expect_success '__gitdir - finds repo' ' ' -test_expect_success '__gitdir - returns error when cant find repo' ' +test_expect_success '__gitdir - returns error when cannot find repo' ' ( __git_dir="non-existing" && test_must_fail __gitdir >"$actual" @@ -945,7 +945,7 @@ test_expect_success 'setup for filtering matching refs' ' rm -f .git/FETCH_HEAD ' -test_expect_success '__git_refs - dont filter refs unless told so' ' +test_expect_success '__git_refs - do not filter refs unless told so' ' cat >expected <<-EOF && HEAD master @@ -1257,7 +1257,7 @@ test_path_completion () # In the following tests calling this function we only # care about how __git_complete_index_file() deals with # unusual characters in path names. By requesting only - # untracked files we dont have to bother adding any + # untracked files we do not have to bother adding any # paths to the index in those tests. __git_complete_index_file --others && print_comp @@ -1363,6 +1363,63 @@ test_expect_success 'teardown after path completion tests' ' BS\\dir '$'separators\034in\035dir'' ' +test_expect_success '__git_find_on_cmdline - single match' ' + echo list >expect && + ( + words=(git command --opt list) && + cword=${#words[@]} && + __git_find_on_cmdline "add list remove" >actual + ) && + test_cmp expect actual +' + +test_expect_success '__git_find_on_cmdline - multiple matches' ' + echo remove >expect && + ( + words=(git command -o --opt remove list add) && + cword=${#words[@]} && + __git_find_on_cmdline "add list remove" >actual + ) && + test_cmp expect actual +' + +test_expect_success '__git_find_on_cmdline - no match' ' + ( + words=(git command --opt branch) && + cword=${#words[@]} && + __git_find_on_cmdline "add list remove" >actual + ) && + test_must_be_empty actual +' + +test_expect_success '__git_find_on_cmdline - single match with index' ' + echo "3 list" >expect && + ( + words=(git command --opt list) && + cword=${#words[@]} && + __git_find_on_cmdline --show-idx "add list remove" >actual + ) && + test_cmp expect actual +' + +test_expect_success '__git_find_on_cmdline - multiple matches with index' ' + echo "4 remove" >expect && + ( + words=(git command -o --opt remove list add) && + cword=${#words[@]} && + __git_find_on_cmdline --show-idx "add list remove" >actual + ) && + test_cmp expect actual +' + +test_expect_success '__git_find_on_cmdline - no match with index' ' + ( + words=(git command --opt branch) && + cword=${#words[@]} && + __git_find_on_cmdline --show-idx "add list remove" >actual + ) && + test_must_be_empty actual +' test_expect_success '__git_get_config_variables' ' cat >expect <<-EOF && @@ -1438,6 +1495,8 @@ test_expect_success 'double dash "git checkout"' ' --no-guess Z --no-... Z --overlay Z + --pathspec-file-nul Z + --pathspec-from-file=Z EOF ' diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 88bc733ad6..ab5da2cabc 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -163,7 +163,7 @@ test_expect_success 'prompt - inside bare repository' ' ' test_expect_success 'prompt - interactive rebase' ' - printf " (b1|REBASE-i 2/3)" >expected && + printf " (b1|REBASE 2/3)" >expected && write_script fake_editor.sh <<-\EOF && echo "exec echo" >"$1" echo "edit $(git log -1 --format="%h")" >>"$1" @@ -180,7 +180,7 @@ test_expect_success 'prompt - interactive rebase' ' ' test_expect_success 'prompt - rebase merge' ' - printf " (b2|REBASE-i 1/3)" >expected && + printf " (b2|REBASE 1/3)" >expected && git checkout b2 && test_when_finished "git checkout master" && test_must_fail git rebase --merge b1 b2 && @@ -189,11 +189,11 @@ test_expect_success 'prompt - rebase merge' ' test_cmp expected "$actual" ' -test_expect_success 'prompt - rebase' ' +test_expect_success 'prompt - rebase am' ' printf " (b2|REBASE 1/3)" >expected && git checkout b2 && test_when_finished "git checkout master" && - test_must_fail git rebase b1 b2 && + test_must_fail git rebase --apply b1 b2 && test_when_finished "git rebase --abort" && __git_ps1 >"$actual" && test_cmp expected "$actual" diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index b299ecc326..352c213d52 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -308,7 +308,7 @@ test_commit_bulk () { total=$1 add_from= - if git -C "$indir" rev-parse --verify "$ref" + if git -C "$indir" rev-parse --quiet --verify "$ref" then add_from=t fi @@ -1012,19 +1012,30 @@ test_must_be_empty () { fi } -# Tests that its two parameters refer to the same revision +# Tests that its two parameters refer to the same revision, or if '!' is +# provided first, that its other two parameters refer to different +# revisions. test_cmp_rev () { + local op='=' wrong_result=different + + if test $# -ge 1 && test "x$1" = 'x!' + then + op='!=' + wrong_result='the same' + shift + fi if test $# != 2 then error "bug in the test script: test_cmp_rev requires two revisions, but got $#" else local r1 r2 r1=$(git rev-parse --verify "$1") && - r2=$(git rev-parse --verify "$2") && - if test "$r1" != "$r2" + r2=$(git rev-parse --verify "$2") || return 1 + + if ! test "$r1" "$op" "$r2" then cat >&4 <<-EOF - error: two revisions point to different objects: + error: two revisions point to $wrong_result objects: '$1': $r1 '$2': $r2 EOF @@ -1175,6 +1186,34 @@ perl () { command "$PERL_PATH" "$@" 2>&7 } 7>&2 2>&4 +# Given the name of an environment variable with a bool value, normalize +# its value to a 0 (true) or 1 (false or empty string) return code. +# +# test_bool_env GIT_TEST_HTTPD <default-value> +# +# Return with code corresponding to the given default value if the variable +# is unset. +# Abort the test script if either the value of the variable or the default +# are not valid bool values. + +test_bool_env () { + if test $# != 2 + then + BUG "test_bool_env requires two parameters (variable name and default value)" + fi + + git env--helper --type=bool --default="$2" --exit-code "$1" + ret=$? + case $ret in + 0|1) # unset or valid bool value + ;; + *) # invalid bool value or something unexpected + error >&7 "test_bool_env requires bool values both for \$$1 and for the default fallback" + ;; + esac + return $ret +} + # Exit the test suite, either by skipping all remaining tests or by # exiting with an error. If our prerequisite variable $1 falls back # on a default assume we were opportunistically trying to set up some @@ -1183,7 +1222,7 @@ perl () { # The error/skip message should be given by $2. # test_skip_or_die () { - if ! git env--helper --type=bool --default=false --exit-code $1 + if ! test_bool_env "$1" false then skip_all=$2 test_done @@ -1477,3 +1516,30 @@ test_set_port () { port=$(($port + ${GIT_TEST_STRESS_JOB_NR:-0})) eval $var=$port } + +# Compare a file containing rev-list bitmap traversal output to its non-bitmap +# counterpart. You can't just use test_cmp for this, because the two produce +# subtly different output: +# +# - regular output is in traversal order, whereas bitmap is split by type, +# with non-packed objects at the end +# +# - regular output has a space and the pathname appended to non-commit +# objects; bitmap output omits this +# +# This function normalizes and compares the two. The second file should +# always be the bitmap output. +test_bitmap_traversal () { + if test "$1" = "--no-confirm-bitmaps" + then + shift + elif cmp "$1" "$2" + then + echo >&2 "identical raw outputs; are you sure bitmaps were used?" + return 1 + fi && + cut -d' ' -f1 "$1" | sort >"$1.normalized" && + sort "$2" >"$2.normalized" && + test_cmp "$1.normalized" "$2.normalized" && + rm -f "$1.normalized" "$2.normalized" +} diff --git a/t/test-lib.sh b/t/test-lib.sh index 46c4440843..0ea1e5a05e 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1004,6 +1004,12 @@ test_skip () { to_skip=t skipped_reason="GIT_SKIP_TESTS" fi + if test -z "$to_skip" && test -n "$run_list" && + ! match_test_selector_list '--run' $test_count "$run_list" + then + to_skip=t + skipped_reason="--run" + fi if test -z "$to_skip" && test -n "$test_prereq" && ! test_have_prereq "$test_prereq" then @@ -1016,12 +1022,6 @@ test_skip () { fi skipped_reason="missing $missing_prereq${of_prereq}" fi - if test -z "$to_skip" && test -n "$run_list" && - ! match_test_selector_list '--run' $test_count "$run_list" - then - to_skip=t - skipped_reason="--run" - fi case "$to_skip" in t) @@ -1083,7 +1083,8 @@ finalize_junit_xml () { # adjust the overall time junit_time=$(test-tool date getnanos $junit_suite_start) - sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \ + sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \ + -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \ <"$junit_xml_path" >"$junit_xml_path.new" mv "$junit_xml_path.new" "$junit_xml_path" @@ -1406,23 +1407,23 @@ yes () { # The GIT_TEST_FAIL_PREREQS code hooks into test_set_prereq(), and # thus needs to be set up really early, and set an internal variable # for convenience so the hot test_set_prereq() codepath doesn't need -# to call "git env--helper". Only do that work if needed by seeing if -# GIT_TEST_FAIL_PREREQS is set at all. +# to call "git env--helper" (via test_bool_env). Only do that work +# if needed by seeing if GIT_TEST_FAIL_PREREQS is set at all. GIT_TEST_FAIL_PREREQS_INTERNAL= if test -n "$GIT_TEST_FAIL_PREREQS" then - if git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS + if test_bool_env GIT_TEST_FAIL_PREREQS false then GIT_TEST_FAIL_PREREQS_INTERNAL=true test_set_prereq FAIL_PREREQS fi else test_lazy_prereq FAIL_PREREQS ' - git env--helper --type=bool --default=0 --exit-code GIT_TEST_FAIL_PREREQS + test_bool_env GIT_TEST_FAIL_PREREQS false ' fi -# Fix some commands on Windows +# Fix some commands on Windows, and other OS-specific things uname_s=$(uname -s) case $uname_s in *MINGW*) @@ -1453,6 +1454,12 @@ case $uname_s in test_set_prereq SED_STRIPS_CR test_set_prereq GREP_STRIPS_CR ;; +FreeBSD) + test_set_prereq REGEX_ILLSEQ + test_set_prereq POSIXPERM + test_set_prereq BSLASHPSPEC + test_set_prereq EXECKEEPSPID + ;; *) test_set_prereq POSIXPERM test_set_prereq BSLASHPSPEC @@ -1477,7 +1484,7 @@ then fi test_lazy_prereq C_LOCALE_OUTPUT ' - ! git env--helper --type=bool --default=0 --exit-code GIT_TEST_GETTEXT_POISON + ! test_bool_env GIT_TEST_GETTEXT_POISON false ' if test -z "$GIT_TEST_CHECK_CACHE_TREE" |