diff options
Diffstat (limited to 't')
55 files changed, 1097 insertions, 173 deletions
diff --git a/t/.gitignore b/t/.gitignore index 348715f..91cf577 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -2,3 +2,4 @@ /test-results /.prove /chainlinttmp +/out/ @@ -170,6 +170,15 @@ appropriately before running "make". implied by other options like --valgrind and GIT_TEST_INSTALLED. +--no-bin-wrappers:: + By default, the test suite uses the wrappers in + `../bin-wrappers/` to execute `git` and friends. With this option, + `../git` and friends are run directly. This is not recommended + in general, as the wrappers contain safeguards to ensure that no + files from an installed Git are used, but can speed up test runs + especially on platforms where running shell scripts is expensive + (most notably, Windows). + --root=<directory>:: Create "trash" directories used to store all temporary data during testing under <directory>, instead of the t/ directory. @@ -358,6 +367,10 @@ GIT_TEST_INDEX_VERSION=<n> exercises the index read/write code path for the index version specified. Can be set to any valid version (currently 2, 3, or 4). +GIT_TEST_PACK_SPARSE=<boolean> if enabled will default the pack-objects +builtin to use the sparse object walk. This can still be overridden by +the --no-sparse command-line argument. + GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path by overriding the minimum number of cache entries required per thread. @@ -374,6 +387,11 @@ GIT_TEST_MULTI_PACK_INDEX=<boolean>, when true, forces the multi-pack- index to be written after every 'git repack' command, and overrides the 'core.multiPackIndex' setting to true. +GIT_TEST_SIDEBAND_ALL=<boolean>, when true, overrides the +'uploadpack.allowSidebandAll' setting to true, and when false, forces +fetch-pack to not request sideband-all (even if the server advertises +sideband-all). + Naming Tests ------------ diff --git a/t/check-non-portable-shell.pl b/t/check-non-portable-shell.pl index 8037eef..166d64d 100755 --- a/t/check-non-portable-shell.pl +++ b/t/check-non-portable-shell.pl @@ -36,7 +36,7 @@ while (<>) { } /\bcp\s+-a/ and err 'cp -a is not portable'; - /\bsed\s+-i/ and err 'sed -i is not portable'; + /\bsed\s+-[^efn]\s+/ and err 'sed option not portable (use only -n, -e, -f)'; /\becho\s+-[neE]/ and err 'echo with option is not portable (use printf)'; /^\s*declare\s+/ and err 'arrays/declare not portable'; /^\s*[^#]\s*which\s/ and err 'which is not portable (use type)'; diff --git a/t/helper/test-date.c b/t/helper/test-date.c index a083737..b325380 100644 --- a/t/helper/test-date.c +++ b/t/helper/test-date.c @@ -3,10 +3,12 @@ static const char *usage_msg = "\n" " test-tool date relative [time_t]...\n" +" test-tool date human [time_t]...\n" " test-tool date show:<format> [time_t]...\n" " test-tool date parse [date]...\n" " test-tool date approxidate [date]...\n" " test-tool date timestamp [date]...\n" +" test-tool date getnanos [start-nanos]\n" " test-tool date is64bit\n" " test-tool date time_t-is64bit\n"; @@ -16,12 +18,20 @@ static void show_relative_dates(const char **argv, struct timeval *now) for (; *argv; argv++) { time_t t = atoi(*argv); - show_date_relative(t, 0, now, &buf); + show_date_relative(t, now, &buf); printf("%s -> %s\n", *argv, buf.buf); } strbuf_release(&buf); } +static void show_human_dates(const char **argv) +{ + for (; *argv; argv++) { + time_t t = atoi(*argv); + printf("%s -> %s\n", *argv, show_date(t, 0, DATE_MODE(HUMAN))); + } +} + static void show_dates(const char **argv, const char *format) { struct date_mode mode; @@ -82,12 +92,21 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now) } } +static void getnanos(const char **argv) +{ + double seconds = getnanotime() / 1.0e9; + + if (*argv) + seconds -= strtod(*argv, NULL); + printf("%lf\n", seconds); +} + int cmd__date(int argc, const char **argv) { struct timeval now; const char *x; - x = getenv("TEST_DATE_NOW"); + x = getenv("GIT_TEST_DATE_NOW"); if (x) { now.tv_sec = atoi(x); now.tv_usec = 0; @@ -100,6 +119,8 @@ int cmd__date(int argc, const char **argv) usage(usage_msg); if (!strcmp(*argv, "relative")) show_relative_dates(argv+1, &now); + else if (!strcmp(*argv, "human")) + show_human_dates(argv+1); else if (skip_prefix(*argv, "show:", &x)) show_dates(argv+1, x); else if (!strcmp(*argv, "parse")) @@ -108,6 +129,8 @@ int cmd__date(int argc, const char **argv) parse_approxidate(argv+1, &now); else if (!strcmp(*argv, "timestamp")) parse_approx_timestamp(argv+1, &now); + else if (!strcmp(*argv, "getnanos")) + getnanos(argv+1); else if (!strcmp(*argv, "is64bit")) return sizeof(timestamp_t) == 8 ? 0 : 1; else if (!strcmp(*argv, "time_t-is64bit")) diff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c index 08e3684..2786f47 100644 --- a/t/helper/test-dump-fsmonitor.c +++ b/t/helper/test-dump-fsmonitor.c @@ -3,11 +3,11 @@ int cmd__dump_fsmonitor(int ac, const char **av) { - struct index_state *istate = &the_index; + struct index_state *istate = the_repository->index; int i; setup_git_directory(); - if (do_read_index(istate, get_index_file(), 0) < 0) + if (do_read_index(istate, the_repository->index_file, 0) < 0) die("unable to read index file"); if (!istate->fsmonitor_last_update) { printf("no fsmonitor\n"); diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c index 52870eb..cf0f2c7 100644 --- a/t/helper/test-dump-untracked-cache.c +++ b/t/helper/test-dump-untracked-cache.c @@ -1,3 +1,4 @@ +#define USE_THE_INDEX_COMPATIBILITY_MACROS #include "test-tool.h" #include "cache.h" #include "dir.h" diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index ae091d9..5d543ad 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -177,6 +177,14 @@ static int is_dotgitmodules(const char *path) return is_hfs_dotgitmodules(path) || is_ntfs_dotgitmodules(path); } +static int cmp_by_st_size(const void *a, const void *b) +{ + intptr_t x = (intptr_t)((struct string_list_item *)a)->util; + intptr_t y = (intptr_t)((struct string_list_item *)b)->util; + + return x > y ? -1 : (x < y ? +1 : 0); +} + int cmd__path_utils(int argc, const char **argv) { if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) { @@ -291,6 +299,62 @@ int cmd__path_utils(int argc, const char **argv) return !!res; } + if (argc > 2 && !strcmp(argv[1], "file-size")) { + int res = 0, i; + struct stat st; + + for (i = 2; i < argc; i++) + if (stat(argv[i], &st)) + res = error_errno("Cannot stat '%s'", argv[i]); + else + printf("%"PRIuMAX"\n", (uintmax_t)st.st_size); + return !!res; + } + + if (argc == 4 && !strcmp(argv[1], "skip-n-bytes")) { + int fd = open(argv[2], O_RDONLY), offset = atoi(argv[3]); + char buffer[65536]; + + if (fd < 0) + die_errno("could not open '%s'", argv[2]); + if (lseek(fd, offset, SEEK_SET) < 0) + die_errno("could not skip %d bytes", offset); + for (;;) { + ssize_t count = read(fd, buffer, sizeof(buffer)); + if (count < 0) + die_errno("could not read '%s'", argv[2]); + if (!count) + break; + if (write(1, buffer, count) < 0) + die_errno("could not write to stdout"); + } + close(fd); + return 0; + } + + if (argc > 5 && !strcmp(argv[1], "slice-tests")) { + int res = 0; + long offset, stride, i; + struct string_list list = STRING_LIST_INIT_NODUP; + struct stat st; + + offset = strtol(argv[2], NULL, 10); + stride = strtol(argv[3], NULL, 10); + if (stride < 1) + stride = 1; + for (i = 4; i < argc; i++) + if (stat(argv[i], &st)) + res = error_errno("Cannot stat '%s'", argv[i]); + else + string_list_append(&list, argv[i])->util = + (void *)(intptr_t)st.st_size; + QSORT(list.items, list.nr, cmp_by_st_size); + for (i = offset; i < list.nr; i+= stride) + printf("%s\n", list.items[i].string); + + 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-ref-store.c b/t/helper/test-ref-store.c index e9e0541..799fc00 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -233,7 +233,7 @@ static int cmd_update_ref(struct ref_store *refs, const char **argv) { const char *msg = notnull(*argv++, "msg"); const char *refname = notnull(*argv++, "refname"); - const char *new_sha1_buf = notnull(*argv++, "old-sha1"); + const char *new_sha1_buf = notnull(*argv++, "new-sha1"); const char *old_sha1_buf = notnull(*argv++, "old-sha1"); unsigned int flags = arg_flags(*argv++, "flags"); struct object_id old_oid; diff --git a/t/helper/test-repository.c b/t/helper/test-repository.c index 6a84a53..f7f8618 100644 --- a/t/helper/test-repository.c +++ b/t/helper/test-repository.c @@ -17,6 +17,11 @@ static void test_parse_commit_in_graph(const char *gitdir, const char *worktree, setup_git_env(gitdir); + memset(the_repository, 0, sizeof(*the_repository)); + + /* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */ + repo_set_hash_algo(the_repository, GIT_HASH_SHA1); + if (repo_init(&r, gitdir, worktree)) die("Couldn't init repo"); @@ -43,6 +48,11 @@ static void test_get_commit_tree_in_graph(const char *gitdir, setup_git_env(gitdir); + memset(the_repository, 0, sizeof(*the_repository)); + + /* TODO: Needed for temporary hack in hashcmp, see 183a638b7da. */ + repo_set_hash_algo(the_repository, GIT_HASH_SHA1); + if (repo_init(&r, gitdir, worktree)) die("Couldn't init repo"); diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 5b13787..50c55f8 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -51,6 +51,7 @@ static struct test_cmd cmds[] = { { "submodule-nested-repo-config", cmd__submodule_nested_repo_config }, { "subprocess", cmd__subprocess }, { "urlmatch-normalization", cmd__urlmatch_normalization }, + { "xml-encode", cmd__xml_encode }, { "wildmatch", cmd__wildmatch }, #ifdef GIT_WINDOWS_NATIVE { "windows-named-pipe", cmd__windows_named_pipe }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index ca5c88e..a563df4 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -1,6 +1,7 @@ #ifndef TEST_TOOL_H #define TEST_TOOL_H +#define USE_THE_INDEX_COMPATIBILITY_MACROS #include "git-compat-util.h" int cmd__chmtime(int argc, const char **argv); @@ -47,6 +48,7 @@ int cmd__submodule_config(int argc, const char **argv); int cmd__submodule_nested_repo_config(int argc, const char **argv); int cmd__subprocess(int argc, const char **argv); int cmd__urlmatch_normalization(int argc, const char **argv); +int cmd__xml_encode(int argc, const char **argv); int cmd__wildmatch(int argc, const char **argv); #ifdef GIT_WINDOWS_NATIVE int cmd__windows_named_pipe(int argc, const char **argv); diff --git a/t/helper/test-xml-encode.c b/t/helper/test-xml-encode.c new file mode 100644 index 0000000..a648bbd --- /dev/null +++ b/t/helper/test-xml-encode.c @@ -0,0 +1,80 @@ +#include "test-tool.h" + +static const char *utf8_replace_character = "�"; + +/* + * Encodes (possibly incorrect) UTF-8 on <stdin> to <stdout>, to be embedded + * in an XML file. + */ +int cmd__xml_encode(int argc, const char **argv) +{ + unsigned char buf[1024], tmp[4], *tmp2 = NULL; + ssize_t cur = 0, len = 1, remaining = 0; + unsigned char ch; + + for (;;) { + if (++cur == len) { + len = xread(0, buf, sizeof(buf)); + if (!len) + return 0; + if (len < 0) + die_errno("Could not read <stdin>"); + cur = 0; + } + ch = buf[cur]; + + if (tmp2) { + if ((ch & 0xc0) != 0x80) { + fputs(utf8_replace_character, stdout); + tmp2 = NULL; + cur--; + continue; + } + *tmp2 = ch; + tmp2++; + if (--remaining == 0) { + fwrite(tmp, tmp2 - tmp, 1, stdout); + tmp2 = NULL; + } + continue; + } + + if (!(ch & 0x80)) { + /* 0xxxxxxx */ + if (ch == '&') + fputs("&", stdout); + else if (ch == '\'') + fputs("'", stdout); + else if (ch == '"') + fputs(""", stdout); + else if (ch == '<') + fputs("<", stdout); + else if (ch == '>') + fputs(">", stdout); + else if (ch >= 0x20) + fputc(ch, stdout); + else if (ch == 0x09 || ch == 0x0a || ch == 0x0d) + fprintf(stdout, "&#x%02x;", ch); + else + fputs(utf8_replace_character, stdout); + } else if ((ch & 0xe0) == 0xc0) { + /* 110XXXXx 10xxxxxx */ + tmp[0] = ch; + remaining = 1; + tmp2 = tmp + 1; + } else if ((ch & 0xf0) == 0xe0) { + /* 1110XXXX 10Xxxxxx 10xxxxxx */ + tmp[0] = ch; + remaining = 2; + tmp2 = tmp + 1; + } else if ((ch & 0xf8) == 0xf0) { + /* 11110XXX 10XXxxxx 10xxxxxx 10xxxxxx */ + tmp[0] = ch; + remaining = 3; + tmp2 = tmp + 1; + } else + fputs(utf8_replace_character, stdout); + } + + return 0; +} diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index cc4b875..5d63ed9 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -78,6 +78,7 @@ PassEnv GNUPGHOME PassEnv ASAN_OPTIONS PassEnv GIT_TRACE PassEnv GIT_CONFIG_NOSYSTEM +PassEnv GIT_TEST_SIDEBAND_ALL SetEnvIf Git-Protocol ".*" GIT_PROTOCOL=$0 diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 22499bc..71e63d8 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -322,4 +322,24 @@ test_expect_success 'bare repository: test info/attributes' ' ) ' +test_expect_success 'binary macro expanded by -a' ' + echo "file binary" >.gitattributes && + cat >expect <<-\EOF && + file: binary: set + file: diff: unset + file: merge: unset + file: text: unset + EOF + git check-attr -a file >actual && + test_cmp expect actual +' + + +test_expect_success 'query binary macro directly' ' + echo "file binary" >.gitattributes && + echo file: binary: set >expect && + git check-attr binary file >actual && + test_cmp expect actual +' + test_done diff --git a/t/t0006-date.sh b/t/t0006-date.sh index ffb2975..d9fcc82 100755 --- a/t/t0006-date.sh +++ b/t/t0006-date.sh @@ -4,10 +4,10 @@ test_description='test date parsing and printing' . ./test-lib.sh # arbitrary reference time: 2009-08-30 19:20:00 -TEST_DATE_NOW=1251660000; export TEST_DATE_NOW +GIT_TEST_DATE_NOW=1251660000; export GIT_TEST_DATE_NOW check_relative() { - t=$(($TEST_DATE_NOW - $1)) + t=$(($GIT_TEST_DATE_NOW - $1)) echo "$t -> $2" >expect test_expect_${3:-success} "relative date ($2)" " test-tool date relative $t >actual && @@ -128,4 +128,22 @@ check_approxidate '6AM, June 7, 2009' '2009-06-07 06:00:00' check_approxidate '2008-12-01' '2008-12-01 19:20:00' check_approxidate '2009-12-01' '2009-12-01 19:20:00' +check_date_format_human() { + t=$(($GIT_TEST_DATE_NOW - $1)) + echo "$t -> $2" >expect + test_expect_success "human date $t" ' + test-tool date human $t >actual && + test_i18ncmp expect actual +' +} + +check_date_format_human 18000 "5 hours ago" # 5 hours ago +check_date_format_human 432000 "Tue Aug 25 19:20" # 5 days ago +check_date_format_human 1728000 "Mon Aug 10 19:20" # 3 weeks ago +check_date_format_human 13000000 "Thu Apr 2 08:13" # 5 months ago +check_date_format_human 31449600 "Aug 31 2008" # 12 months ago +check_date_format_human 37500000 "Jun 22 2008" # 1 year, 2 months ago +check_date_format_human 55188000 "Dec 1 2007" # 1 year, 9 months ago +check_date_format_human 630000000 "Sep 13 1989" # 20 years ago + test_done diff --git a/t/t0021-conversion.sh b/t/t0021-conversion.sh index fd5f1ac..e10f5f7 100755 --- a/t/t0021-conversion.sh +++ b/t/t0021-conversion.sh @@ -24,7 +24,7 @@ generate_random_characters () { } file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } filter_git () { diff --git a/t/t0025-crlf-renormalize.sh b/t/t0025-crlf-renormalize.sh index 9d9e02a..e13363a 100755 --- a/t/t0025-crlf-renormalize.sh +++ b/t/t0025-crlf-renormalize.sh @@ -27,4 +27,13 @@ test_expect_success 'renormalize CRLF in repo' ' test_cmp expect actual ' +test_expect_success 'ignore-errors not mistaken for renormalize' ' + git reset --hard && + echo "*.txt text=auto" >.gitattributes && + git ls-files --eol >expect && + git add --ignore-errors "*.txt" && + git ls-files --eol >actual && + test_cmp expect actual +' + test_done diff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh index 7e87b5a..e58ecbf 100755 --- a/t/t0028-working-tree-encoding.sh +++ b/t/t0028-working-tree-encoding.sh @@ -11,9 +11,12 @@ test_expect_success 'setup test files' ' text="hallo there!\ncan you read me?" && echo "*.utf16 text working-tree-encoding=utf-16" >.gitattributes && + echo "*.utf16lebom text working-tree-encoding=UTF-16LE-BOM" >>.gitattributes && printf "$text" >test.utf8.raw && printf "$text" | iconv -f UTF-8 -t UTF-16 >test.utf16.raw && printf "$text" | iconv -f UTF-8 -t UTF-32 >test.utf32.raw && + printf "\377\376" >test.utf16lebom.raw && + printf "$text" | iconv -f UTF-8 -t UTF-32LE >>test.utf16lebom.raw && # Line ending tests printf "one\ntwo\nthree\n" >lf.utf8.raw && @@ -32,7 +35,8 @@ test_expect_success 'setup test files' ' # Add only UTF-16 file, we will add the UTF-32 file later cp test.utf16.raw test.utf16 && cp test.utf32.raw test.utf32 && - git add .gitattributes test.utf16 && + cp test.utf16lebom.raw test.utf16lebom && + git add .gitattributes test.utf16 test.utf16lebom && git commit -m initial ' @@ -51,6 +55,12 @@ test_expect_success 're-encode to UTF-16 on checkout' ' test_cmp_bin test.utf16.raw test.utf16 ' +test_expect_success 're-encode to UTF-16-LE-BOM on checkout' ' + rm test.utf16lebom && + git checkout test.utf16lebom && + test_cmp_bin test.utf16lebom.raw test.utf16lebom +' + test_expect_success 'check $GIT_DIR/info/attributes support' ' test_when_finished "rm -f test.utf32.git" && test_when_finished "git reset --hard HEAD" && diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 99a614b..ebc4956 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -166,7 +166,8 @@ test_trace () { expect="$1" shift GIT_TRACE=1 test-tool run-command "$@" run-command true 2>&1 >/dev/null | \ - sed -e 's/.* run_command: //' -e '/trace: .*/d' >actual && + sed -e 's/.* run_command: //' -e '/trace: .*/d' \ + -e '/RUNTIME_PREFIX requested/d' >actual && echo "$expect true" >expect && test_cmp expect actual } @@ -199,4 +200,14 @@ test_expect_success 'GIT_TRACE with environment variables' ' ) ' +test_expect_success MINGW 'verify curlies are quoted properly' ' + : force the rev-parse through the MSYS2 Bash && + git -c alias.r="!git rev-parse" r -- a{b}c >actual && + cat >expect <<-\EOF && + -- + a{b}c + EOF + test_cmp expect actual +' + test_done diff --git a/t/t1050-large.sh b/t/t1050-large.sh index 1a9b21b..dcb4dbb 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -8,7 +8,7 @@ test_description='adding and checking out large blobs' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } test_expect_success setup ' diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 2e5e979..c61f972 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -406,7 +406,7 @@ test_expect_success 'rev-list --verify-objects with bad sha1' ' test_might_fail git rev-list --verify-objects refs/heads/bogus >/dev/null 2>out && cat out && - test_i18ngrep -q "error: sha1 mismatch 63ffffffffffffffffffffffffffffffffffffff" out + test_i18ngrep -q "error: hash mismatch 63ffffffffffffffffffffffffffffffffffffff" out ' test_expect_success 'force fsck to ignore double author' ' diff --git a/t/t1512-rev-parse-disambiguation.sh b/t/t1512-rev-parse-disambiguation.sh index e4d5b56..c19fb50 100755 --- a/t/t1512-rev-parse-disambiguation.sh +++ b/t/t1512-rev-parse-disambiguation.sh @@ -388,4 +388,14 @@ test_expect_success C_LOCALE_OUTPUT 'ambiguous commits are printed by type first done ' +test_expect_success 'cat-file --batch and --batch-check show ambiguous' ' + echo "0000 ambiguous" >expect && + echo 0000 | git cat-file --batch-check >actual 2>err && + test_cmp expect actual && + test_i18ngrep hint: err && + echo 0000 | git cat-file --batch >actual 2>err && + test_cmp expect actual && + test_i18ngrep hint: err +' + test_done diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index 2131fb2..c5014ad 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -198,4 +198,13 @@ test_expect_success 'checkout -B to the current branch works' ' test_dirty_mergeable ' +test_expect_success 'checkout -b after clone --no-checkout does a checkout of HEAD' ' + git init src && + test_commit -C src a && + rev="$(git -C src rev-parse HEAD)" && + git clone --no-checkout src dest && + git -C dest checkout "$rev" -b branch && + test_path_is_file dest/a.t +' + test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 7a440e0..52fa41c 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -147,6 +147,25 @@ test_expect_success 'rebase -i with the exec command checks tree cleanness' ' git rebase --continue ' +test_expect_success 'rebase -x with empty command fails' ' + test_when_finished "git rebase --abort ||:" && + test_must_fail git rebase -x "" @ 2>actual && + test_write_lines "error: empty exec command" >expected && + test_i18ncmp expected actual && + test_must_fail git rebase -x " " @ 2>actual && + test_i18ncmp expected actual +' + +LF=' +' +test_expect_success 'rebase -x with newline in command fails' ' + test_when_finished "git rebase --abort ||:" && + test_must_fail git rebase -x "a${LF}b" @ 2>actual && + test_write_lines "error: exec commands cannot contain newlines" \ + >expected && + test_i18ncmp expected actual +' + test_expect_success 'rebase -i with exec of inexistent command' ' git checkout master && test_when_finished "git rebase --abort" && @@ -156,6 +175,11 @@ test_expect_success 'rebase -i with exec of inexistent command' ' ! grep "Maybe git-rebase is broken" actual ' +test_expect_success 'implicit interactive rebase does not invoke sequence editor' ' + test_when_finished "git rebase --abort ||:" && + GIT_SEQUENCE_EDITOR="echo bad >" git rebase -x"echo one" @^ +' + test_expect_success 'no changes are a nop' ' git checkout branch2 && set_fake_editor && diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh index f64b130..b393e1e 100755 --- a/t/t3406-rebase-message.sh +++ b/t/t3406-rebase-message.sh @@ -17,14 +17,9 @@ test_expect_success 'setup' ' git tag start ' -cat >expect <<\EOF -Already applied: 0001 A -Already applied: 0002 B -Committed: 0003 Z -EOF - 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 diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh index 4c7494c..2d1094e 100755 --- a/t/t3420-rebase-autostash.sh +++ b/t/t3420-rebase-autostash.sh @@ -53,41 +53,6 @@ create_expected_success_interactive () { EOF } -create_expected_success_merge () { - cat >expected <<-EOF - $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual) - HEAD is now at $(git rev-parse --short feature-branch) third commit - First, rewinding head to replay your work on top of it... - Merging unrelated-onto-branch with HEAD~1 - Merging: - $(git rev-parse --short unrelated-onto-branch) unrelated commit - $(git rev-parse --short feature-branch^) second commit - found 1 common ancestor: - $(git rev-parse --short feature-branch~2) initial commit - [detached HEAD $(git rev-parse --short rebased-feature-branch~1)] second commit - Author: A U Thor <author@example.com> - Date: Thu Apr 7 15:14:13 2005 -0700 - 2 files changed, 2 insertions(+) - create mode 100644 file1 - create mode 100644 file2 - Committed: 0001 second commit - Merging unrelated-onto-branch with HEAD~0 - Merging: - $(git rev-parse --short rebased-feature-branch~1) second commit - $(git rev-parse --short feature-branch) third commit - found 1 common ancestor: - $(git rev-parse --short feature-branch~1) second commit - [detached HEAD $(git rev-parse --short rebased-feature-branch)] third commit - Author: A U Thor <author@example.com> - Date: Thu Apr 7 15:15:13 2005 -0700 - 1 file changed, 1 insertion(+) - create mode 100644 file3 - Committed: 0002 third commit - All done. - Applied autostash. - EOF -} - create_expected_failure_am () { cat >expected <<-EOF $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual) @@ -112,43 +77,6 @@ create_expected_failure_interactive () { EOF } -create_expected_failure_merge () { - cat >expected <<-EOF - $(grep "^Created autostash: [0-9a-f][0-9a-f]*\$" actual) - HEAD is now at $(git rev-parse --short feature-branch) third commit - First, rewinding head to replay your work on top of it... - Merging unrelated-onto-branch with HEAD~1 - Merging: - $(git rev-parse --short unrelated-onto-branch) unrelated commit - $(git rev-parse --short feature-branch^) second commit - found 1 common ancestor: - $(git rev-parse --short feature-branch~2) initial commit - [detached HEAD $(git rev-parse --short rebased-feature-branch~1)] second commit - Author: A U Thor <author@example.com> - Date: Thu Apr 7 15:14:13 2005 -0700 - 2 files changed, 2 insertions(+) - create mode 100644 file1 - create mode 100644 file2 - Committed: 0001 second commit - Merging unrelated-onto-branch with HEAD~0 - Merging: - $(git rev-parse --short rebased-feature-branch~1) second commit - $(git rev-parse --short feature-branch) third commit - found 1 common ancestor: - $(git rev-parse --short feature-branch~1) second commit - [detached HEAD $(git rev-parse --short rebased-feature-branch)] third commit - Author: A U Thor <author@example.com> - Date: Thu Apr 7 15:15:13 2005 -0700 - 1 file changed, 1 insertion(+) - create mode 100644 file3 - Committed: 0002 third commit - All done. - Applying autostash resulted in conflicts. - Your changes are safe in the stash. - You can run "git stash pop" or "git stash drop" at any time. - EOF -} - testrebase () { type=$1 dotest=$2 @@ -177,6 +105,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 + fi && create_expected_success_$suffix && test_i18ncmp expected actual ' @@ -274,6 +205,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 + fi && create_expected_failure_$suffix && test_i18ncmp expected actual ' diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh index 23ad4cf..7274dca 100755 --- a/t/t3421-rebase-topology-linear.sh +++ b/t/t3421-rebase-topology-linear.sh @@ -111,7 +111,7 @@ test_run_rebase () { " } test_run_rebase success '' -test_run_rebase failure -m +test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -126,7 +126,7 @@ test_run_rebase () { " } test_run_rebase success '' -test_run_rebase failure -m +test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -141,7 +141,7 @@ test_run_rebase () { " } test_run_rebase success '' -test_run_rebase failure -m +test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -284,7 +284,7 @@ test_run_rebase () { " } test_run_rebase success '' -test_run_rebase failure -m +test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase success -p @@ -315,7 +315,7 @@ test_run_rebase () { " } test_run_rebase success '' -test_run_rebase failure -m +test_run_rebase success -m test_run_rebase success -i test_have_prereq !REBASE_P || test_run_rebase failure -p diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh index 5f892e3..fd8efe8 100755 --- a/t/t3425-rebase-topology-merges.sh +++ b/t/t3425-rebase-topology-merges.sh @@ -70,9 +70,8 @@ test_run_rebase () { test_linear_range "\'"$expected"\'" d.. " } -#TODO: make order consistent across all flavors of rebase -test_run_rebase success 'e n o' '' -test_run_rebase success 'e n o' -m +test_run_rebase success 'n o e' '' +test_run_rebase success 'n o e' -m test_run_rebase success 'n o e' -i test_run_rebase () { @@ -87,9 +86,8 @@ test_run_rebase () { test_linear_range "\'"$expected"\'" c.. " } -#TODO: make order consistent across all flavors of rebase -test_run_rebase success 'd e n o' '' -test_run_rebase success 'd e n o' -m +test_run_rebase success 'd n o e' '' +test_run_rebase success 'd n o e' -m test_run_rebase success 'd n o e' -i test_run_rebase () { @@ -104,9 +102,8 @@ test_run_rebase () { test_linear_range "\'"$expected"\'" c.. " } -#TODO: make order consistent across all flavors of rebase -test_run_rebase success 'd e n o' '' -test_run_rebase success 'd e n o' -m +test_run_rebase success 'd n o e' '' +test_run_rebase success 'd n o e' -m test_run_rebase success 'd n o e' -i if ! test_have_prereq REBASE_P; then diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index cc56468..4c69255 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -125,7 +125,7 @@ test_expect_success '`reset` refuses to overwrite untracked files' ' : >dont-overwrite-untracked.t && echo "reset refs/tags/dont-overwrite-untracked" >script-from-scratch && test_config sequence.editor \""$PWD"/replace-editor.sh\" && - test_must_fail git rebase -r HEAD && + test_must_fail git rebase -ir HEAD && git rebase --abort ' diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 37729ba..be582a5 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -402,4 +402,11 @@ test_expect_success 'all statuses changed in folder if . is given' ' test $(git ls-files --stage | grep ^100755 | wc -l) -eq 0 ' +test_expect_success CASE_INSENSITIVE_FS 'path is case-insensitive' ' + path="$(pwd)/BLUB" && + touch "$path" && + downcased="$(echo "$path" | tr A-Z a-z)" && + git add "$downcased" +' + test_done diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh index a8e01ec..03489af 100755 --- a/t/t4006-diff-mode.sh +++ b/t/t4006-diff-mode.sh @@ -32,28 +32,37 @@ test_expect_success 'prepare binary file' ' git commit -m binbin ' -# test_expect_success '--stat output after text chmod' ' -# test_chmod -x rezrov && -# echo " 0 files changed" >expect && -# git diff HEAD --stat >actual && -# test_i18ncmp expect actual -# ' -# -# test_expect_success '--shortstat output after text chmod' ' -# git diff HEAD --shortstat >actual && -# test_i18ncmp expect actual -# ' -# -# test_expect_success '--stat output after binary chmod' ' -# test_chmod +x binbin && -# echo " 0 files changed" >expect && -# git diff HEAD --stat >actual && -# test_i18ncmp expect actual -# ' -# -# test_expect_success '--shortstat output after binary chmod' ' -# git diff HEAD --shortstat >actual && -# test_i18ncmp expect actual -# ' +test_expect_success '--stat output after text chmod' ' + test_chmod -x rezrov && + cat >expect <<-\EOF && + rezrov | 0 + 1 file changed, 0 insertions(+), 0 deletions(-) + EOF + git diff HEAD --stat >actual && + test_i18ncmp expect actual +' + +test_expect_success '--shortstat output after text chmod' ' + tail -n 1 <expect >expect.short && + git diff HEAD --shortstat >actual && + test_i18ncmp expect.short actual +' + +test_expect_success '--stat output after binary chmod' ' + test_chmod +x binbin && + cat >expect <<-EOF && + binbin | Bin + rezrov | 0 + 2 files changed, 0 insertions(+), 0 deletions(-) + EOF + git diff HEAD --stat >actual && + test_i18ncmp expect actual +' + +test_expect_success '--shortstat output after binary chmod' ' + tail -n 1 <expect >expect.short && + git diff HEAD --shortstat >actual && + test_i18ncmp expect.short actual +' test_done diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 7d985ff..9f8f0e8 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -98,6 +98,12 @@ test_expect_success setup ' git commit -m "update mode" && git checkout -f master && + # Same merge as master, but with parents reversed. Hide it in a + # pseudo-ref to avoid impacting tests with --all. + commit=$(echo reverse | + git commit-tree -p master^2 -p master^1 master^{tree}) && + git update-ref REVERSE $commit && + git config diff.renames false && git show-branch @@ -239,6 +245,8 @@ diff-tree --cc --stat --summary master # stat summary should show the diffstat and summary with the first parent diff-tree -c --stat --summary side diff-tree --cc --stat --summary side +diff-tree --cc --shortstat master +diff-tree --cc --summary REVERSE # improved by Timo's patch diff-tree --cc --patch-with-stat master # improved by Timo's patch @@ -350,6 +358,7 @@ diff --line-prefix=abc master master^ side diff --dirstat master~1 master~2 diff --dirstat initial rearrange diff --dirstat-by-file initial rearrange +diff --dirstat --cc master~1 master # No-index --abbrev and --no-abbrev diff --raw initial :noellipses diff --raw initial diff --git a/t/t4013/diff.diff-tree_--cc_--shortstat_master b/t/t4013/diff.diff-tree_--cc_--shortstat_master new file mode 100644 index 0000000..a4ca42d --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--shortstat_master @@ -0,0 +1,4 @@ +$ git diff-tree --cc --shortstat master +59d314ad6f356dd08601a4cd5e530381da3e3c64 + 2 files changed, 5 insertions(+) +$ diff --git a/t/t4013/diff.diff-tree_--cc_--summary_REVERSE b/t/t4013/diff.diff-tree_--cc_--summary_REVERSE new file mode 100644 index 0000000..e208dd5 --- /dev/null +++ b/t/t4013/diff.diff-tree_--cc_--summary_REVERSE @@ -0,0 +1,6 @@ +$ git diff-tree --cc --summary REVERSE +2562325a7ee916efb2481da93073b82cec801cbc + create mode 100644 file1 + delete mode 100644 file2 + delete mode 100644 file3 +$ diff --git a/t/t4013/diff.diff_--dirstat_--cc_master~1_master b/t/t4013/diff.diff_--dirstat_--cc_master~1_master new file mode 100644 index 0000000..fba4e34 --- /dev/null +++ b/t/t4013/diff.diff_--dirstat_--cc_master~1_master @@ -0,0 +1,3 @@ +$ git diff --dirstat --cc master~1 master + 40.0% dir/ +$ diff --git a/t/t4066-diff-emit-delay.sh b/t/t4066-diff-emit-delay.sh new file mode 100755 index 0000000..5df6b5e --- /dev/null +++ b/t/t4066-diff-emit-delay.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +test_description='test combined/stat/moved interaction' +. ./test-lib.sh + +# This test covers a weird 3-way interaction between "--cc -p", which will run +# the combined diff code, along with "--stat", which will be computed as a +# first-parent stat during the combined diff, and "--color-moved", which +# enables the emitted_symbols list to store the diff in memory. + +test_expect_success 'set up history with a merge' ' + test_commit A && + test_commit B && + git checkout -b side HEAD^ && + test_commit C && + git merge -m M master && + test_commit D +' + +test_expect_success 'log --cc -p --stat --color-moved' ' + cat >expect <<-\EOF && + commit D + --- + D.t | 1 + + 1 file changed, 1 insertion(+) + + diff --git a/D.t b/D.t + new file mode 100644 + index 0000000..1784810 + --- /dev/null + +++ b/D.t + @@ -0,0 +1 @@ + +D + commit M + + B.t | 1 + + 1 file changed, 1 insertion(+) + commit C + --- + C.t | 1 + + 1 file changed, 1 insertion(+) + + diff --git a/C.t b/C.t + new file mode 100644 + index 0000000..3cc58df + --- /dev/null + +++ b/C.t + @@ -0,0 +1 @@ + +C + commit B + --- + B.t | 1 + + 1 file changed, 1 insertion(+) + + diff --git a/B.t b/B.t + new file mode 100644 + index 0000000..223b783 + --- /dev/null + +++ b/B.t + @@ -0,0 +1 @@ + +B + commit A + --- + A.t | 1 + + 1 file changed, 1 insertion(+) + + diff --git a/A.t b/A.t + new file mode 100644 + index 0000000..f70f10e + --- /dev/null + +++ b/A.t + @@ -0,0 +1 @@ + +A + EOF + git log --format="commit %s" --cc -p --stat --color-moved >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t5315-pack-objects-compression.sh b/t/t5315-pack-objects-compression.sh index 34c47da..df970d7 100755 --- a/t/t5315-pack-objects-compression.sh +++ b/t/t5315-pack-objects-compression.sh @@ -7,7 +7,7 @@ test_description='pack-object compression configuration' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } test_expect_success setup ' diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 5fe21db..16d10eb 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -122,7 +122,7 @@ test_expect_success 'write graph with merges' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write && test_path_is_file $objdir/info/commit-graph && - graph_read_expect "10" "large_edges" + graph_read_expect "10" "extra_edges" ' graph_git_behavior 'merge 1 vs 2' full merge/1 merge/2 @@ -157,7 +157,7 @@ test_expect_success 'write graph with new commit' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write && test_path_is_file $objdir/info/commit-graph && - graph_read_expect "11" "large_edges" + graph_read_expect "11" "extra_edges" ' graph_git_behavior 'full graph, commit 8 vs merge 1' full commits/8 merge/1 @@ -167,7 +167,7 @@ test_expect_success 'write graph with nothing new' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write && test_path_is_file $objdir/info/commit-graph && - graph_read_expect "11" "large_edges" + graph_read_expect "11" "extra_edges" ' graph_git_behavior 'cleared graph, commit 8 vs merge 1' full commits/8 merge/1 @@ -177,7 +177,7 @@ test_expect_success 'build graph from latest pack with closure' ' cd "$TRASH_DIRECTORY/full" && cat new-idx | git commit-graph write --stdin-packs && test_path_is_file $objdir/info/commit-graph && - graph_read_expect "9" "large_edges" + graph_read_expect "9" "extra_edges" ' graph_git_behavior 'graph from pack, commit 8 vs merge 1' full commits/8 merge/1 @@ -200,7 +200,7 @@ test_expect_success 'build graph from commits with append' ' cd "$TRASH_DIRECTORY/full" && git rev-parse merge/3 | git commit-graph write --stdin-commits --append && test_path_is_file $objdir/info/commit-graph && - graph_read_expect "10" "large_edges" + graph_read_expect "10" "extra_edges" ' graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 @@ -210,7 +210,7 @@ test_expect_success 'build graph using --reachable' ' cd "$TRASH_DIRECTORY/full" && git commit-graph write --reachable && test_path_is_file $objdir/info/commit-graph && - graph_read_expect "11" "large_edges" + graph_read_expect "11" "extra_edges" ' graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 @@ -231,7 +231,7 @@ test_expect_success 'write graph in bare repo' ' cd "$TRASH_DIRECTORY/bare" && git commit-graph write && test_path_is_file $baredir/info/commit-graph && - graph_read_expect "11" "large_edges" + graph_read_expect "11" "extra_edges" ' graph_git_behavior 'bare repo with graph, commit 8 vs merge 1' bare commits/8 merge/1 @@ -366,9 +366,10 @@ GRAPH_OCTOPUS_DATA_OFFSET=$(($GRAPH_COMMIT_DATA_OFFSET + \ GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4)) GRAPH_BYTE_FOOTER=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4 * $NUM_OCTOPUS_EDGES)) -# usage: corrupt_graph_and_verify <position> <data> <string> +# usage: corrupt_graph_and_verify <position> <data> <string> [<zero_pos>] # Manipulates the commit-graph file at the position -# by inserting the data, then runs 'git commit-graph verify' +# by inserting the data, optionally zeroing the file +# starting at <zero_pos>, then runs 'git commit-graph verify' # and places the output in the file 'err'. Test 'err' for # the given string. corrupt_graph_and_verify() { @@ -376,11 +377,15 @@ corrupt_graph_and_verify() { data="${2:-\0}" grepstr=$3 cd "$TRASH_DIRECTORY/full" && + orig_size=$(wc -c < $objdir/info/commit-graph) && + zero_pos=${4:-${orig_size}} && test_when_finished mv commit-graph-backup $objdir/info/commit-graph && cp $objdir/info/commit-graph commit-graph-backup && printf "$data" | dd of="$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc && + dd of="$objdir/info/commit-graph" bs=1 seek="$zero_pos" count=0 && + dd if=/dev/zero of="$objdir/info/commit-graph" bs=1 seek="$zero_pos" count=$(($orig_size - $zero_pos)) && test_must_fail git commit-graph verify 2>test_err && - grep -v "^+" test_err >err + grep -v "^+" test_err >err && test_i18ngrep "$grepstr" err } @@ -484,6 +489,11 @@ test_expect_success 'detect invalid checksum hash' ' "incorrect checksum" ' +test_expect_success 'detect incorrect chunk count' ' + corrupt_graph_and_verify $GRAPH_BYTE_CHUNK_COUNT "\377" \ + "chunk lookup table entry missing" $GRAPH_CHUNK_LOOKUP_OFFSET +' + test_expect_success 'git fsck (checks commit-graph)' ' cd "$TRASH_DIRECTORY/full" && git fsck && diff --git a/t/t5322-pack-objects-sparse.sh b/t/t5322-pack-objects-sparse.sh new file mode 100755 index 0000000..7124b55 --- /dev/null +++ b/t/t5322-pack-objects-sparse.sh @@ -0,0 +1,136 @@ +#!/bin/sh + +test_description='pack-objects object selection using sparse algorithm' +. ./test-lib.sh + +test_expect_success 'setup repo' ' + test_commit initial && + for i in $(test_seq 1 3) + do + mkdir f$i && + for j in $(test_seq 1 3) + do + mkdir f$i/f$j && + echo $j >f$i/f$j/data.txt + done + done && + git add . && + git commit -m "Initialized trees" && + for i in $(test_seq 1 3) + do + git checkout -b topic$i master && + echo change-$i >f$i/f$i/data.txt && + git commit -a -m "Changed f$i/f$i/data.txt" + done && + cat >packinput.txt <<-EOF && + topic1 + ^topic2 + ^topic3 + EOF + git rev-parse \ + topic1 \ + topic1^{tree} \ + topic1:f1 \ + topic1:f1/f1 \ + topic1:f1/f1/data.txt | sort >expect_objects.txt +' + +test_expect_success 'non-sparse pack-objects' ' + git pack-objects --stdout --revs --no-sparse <packinput.txt >nonsparse.pack && + git index-pack -o nonsparse.idx nonsparse.pack && + git show-index <nonsparse.idx | awk "{print \$2}" >nonsparse_objects.txt && + test_cmp expect_objects.txt nonsparse_objects.txt +' + +test_expect_success 'sparse pack-objects' ' + git pack-objects --stdout --revs --sparse <packinput.txt >sparse.pack && + git index-pack -o sparse.idx sparse.pack && + git show-index <sparse.idx | awk "{print \$2}" >sparse_objects.txt && + test_cmp expect_objects.txt sparse_objects.txt +' + +test_expect_success 'duplicate a folder from f3 and commit to topic1' ' + git checkout topic1 && + echo change-3 >f3/f3/data.txt && + git commit -a -m "Changed f3/f3/data.txt" && + git rev-parse \ + topic1~1 \ + topic1~1^{tree} \ + topic1^{tree} \ + topic1 \ + topic1:f1 \ + topic1:f1/f1 \ + topic1:f1/f1/data.txt | sort >required_objects.txt +' + +test_expect_success 'non-sparse pack-objects' ' + git pack-objects --stdout --revs --no-sparse <packinput.txt >nonsparse.pack && + git index-pack -o nonsparse.idx nonsparse.pack && + git show-index <nonsparse.idx | awk "{print \$2}" >nonsparse_objects.txt && + comm -1 -2 required_objects.txt nonsparse_objects.txt >nonsparse_required_objects.txt && + test_cmp required_objects.txt nonsparse_required_objects.txt +' + +test_expect_success 'sparse pack-objects' ' + git pack-objects --stdout --revs --sparse <packinput.txt >sparse.pack && + git index-pack -o sparse.idx sparse.pack && + git show-index <sparse.idx | awk "{print \$2}" >sparse_objects.txt && + comm -1 -2 required_objects.txt sparse_objects.txt >sparse_required_objects.txt && + test_cmp required_objects.txt sparse_required_objects.txt +' + +# Demonstrate that the algorithms differ when we copy a tree wholesale +# from one folder to another. + +test_expect_success 'duplicate a folder from f1 into f3' ' + mkdir f3/f4 && + cp -r f1/f1/* f3/f4 && + git add f3/f4 && + git commit -m "Copied f1/f1 to f3/f4" && + cat >packinput.txt <<-EOF && + topic1 + ^topic1~1 + EOF + git rev-parse \ + topic1 \ + topic1^{tree} \ + topic1:f3 | sort >required_objects.txt +' + +test_expect_success 'non-sparse pack-objects' ' + git pack-objects --stdout --revs --no-sparse <packinput.txt >nonsparse.pack && + git index-pack -o nonsparse.idx nonsparse.pack && + git show-index <nonsparse.idx | awk "{print \$2}" >nonsparse_objects.txt && + comm -1 -2 required_objects.txt nonsparse_objects.txt >nonsparse_required_objects.txt && + test_cmp required_objects.txt nonsparse_required_objects.txt +' + +test_expect_success 'sparse pack-objects' ' + git rev-parse \ + topic1 \ + topic1^{tree} \ + topic1:f3 \ + topic1:f3/f4 \ + topic1:f3/f4/data.txt | sort >expect_sparse_objects.txt && + git pack-objects --stdout --revs --sparse <packinput.txt >sparse.pack && + git index-pack -o sparse.idx sparse.pack && + git show-index <sparse.idx | awk "{print \$2}" >sparse_objects.txt && + test_cmp expect_sparse_objects.txt sparse_objects.txt +' + +test_expect_success 'pack.useSparse enables algorithm' ' + git config pack.useSparse true && + git pack-objects --stdout --revs <packinput.txt >sparse.pack && + git index-pack -o sparse.idx sparse.pack && + git show-index <sparse.idx | awk "{print \$2}" >sparse_objects.txt && + test_cmp expect_sparse_objects.txt sparse_objects.txt +' + +test_expect_success 'pack.useSparse overridden' ' + git pack-objects --stdout --revs --no-sparse <packinput.txt >sparse.pack && + git index-pack -o sparse.idx sparse.pack && + git show-index <sparse.idx | awk "{print \$2}" >sparse_objects.txt && + test_cmp required_objects.txt sparse_objects.txt +' + +test_done diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh index 9b2a274..a4a5903 100755 --- a/t/t5407-post-rewrite-hook.sh +++ b/t/t5407-post-rewrite-hook.sh @@ -78,6 +78,7 @@ test_expect_success 'git rebase --skip' ' git rebase --continue && echo rebase >expected.args && cat >expected.data <<-EOF && + $(git rev-parse C) $(git rev-parse HEAD^) $(git rev-parse D) $(git rev-parse HEAD) EOF verify_hook_input @@ -91,6 +92,7 @@ test_expect_success 'git rebase --skip the last one' ' echo rebase >expected.args && cat >expected.data <<-EOF && $(git rev-parse E) $(git rev-parse HEAD) + $(git rev-parse F) $(git rev-parse HEAD) EOF verify_hook_input ' @@ -120,6 +122,38 @@ test_expect_success 'git rebase -m --skip' ' git rebase --continue && echo rebase >expected.args && cat >expected.data <<-EOF && + $(git rev-parse C) $(git rev-parse HEAD^) + $(git rev-parse D) $(git rev-parse HEAD) + EOF + verify_hook_input +' + +test_expect_success 'git rebase with implicit use of interactive backend' ' + git reset --hard D && + clear_hook_input && + test_must_fail git rebase --keep --onto A B && + echo C > foo && + git add foo && + git rebase --continue && + echo rebase >expected.args && + cat >expected.data <<-EOF && + $(git rev-parse C) $(git rev-parse HEAD^) + $(git rev-parse D) $(git rev-parse HEAD) + EOF + verify_hook_input +' + +test_expect_success 'git rebase --skip with implicit use of interactive backend' ' + git reset --hard D && + clear_hook_input && + test_must_fail git rebase --keep --onto A B && + test_must_fail git rebase --skip && + echo D > foo && + git add foo && + git rebase --continue && + echo rebase >expected.args && + cat >expected.data <<-EOF && + $(git rev-parse C) $(git rev-parse HEAD^) $(git rev-parse D) $(git rev-parse HEAD) EOF verify_hook_input diff --git a/t/t5537-fetch-shallow.sh b/t/t5537-fetch-shallow.sh index 6faf17e..6caf628 100755 --- a/t/t5537-fetch-shallow.sh +++ b/t/t5537-fetch-shallow.sh @@ -243,7 +243,8 @@ test_expect_success 'shallow fetches check connectivity before writing shallow f "$(git -C "$REPO" rev-parse HEAD)" \ "$(git -C "$REPO" rev-parse HEAD^)" \ >"$HTTPD_ROOT_PATH/one-time-sed" && - test_must_fail git -C client fetch --depth=1 "$HTTPD_URL/one_time_sed/repo" \ + test_must_fail env GIT_TEST_SIDEBAND_ALL=0 git -C client \ + fetch --depth=1 "$HTTPD_URL/one_time_sed/repo" \ master:a_branch && # Ensure that the one-time-sed script was used. diff --git a/t/t5580-clone-push-unc.sh b/t/t5580-clone-push-unc.sh index ba548df..217adf3 100755 --- a/t/t5580-clone-push-unc.sh +++ b/t/t5580-clone-push-unc.sh @@ -40,6 +40,11 @@ test_expect_success clone ' git clone "file://$UNCPATH" clone ' +test_expect_success 'clone with backslashed path' ' + BACKSLASHED="$(echo "$UNCPATH" | tr / \\\\)" && + git clone "$BACKSLASHED" backslashed +' + test_expect_success push ' ( cd clone && diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh index ae79c6b..fe45bf8 100755 --- a/t/t5701-git-serve.sh +++ b/t/t5701-git-serve.sh @@ -14,7 +14,7 @@ test_expect_success 'test capability advertisement' ' 0000 EOF - git serve --advertise-capabilities >out && + GIT_TEST_SIDEBAND_ALL=0 git serve --advertise-capabilities >out && test-tool pkt-line unpack <out >actual && test_cmp expect actual ' diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index a738c0c..db4ae09 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -561,6 +561,27 @@ test_expect_success 'fetch with http:// using protocol v2' ' grep "git< version 2" log ' +test_expect_success 'fetch from namespaced repo respects namespaces' ' + test_when_finished "rm -f log" && + + git init "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" && + test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" one && + test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" two && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" \ + update-ref refs/namespaces/ns/refs/heads/master one && + + GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \ + fetch "$HTTPD_URL/smart_namespace/nsrepo" \ + refs/heads/master:refs/heads/theirs && + + # Server responded using protocol v2 + grep "fetch< version 2" log && + + git -C "$HTTPD_DOCUMENT_ROOT_PATH/nsrepo" rev-parse one >expect && + git -C http_child rev-parse theirs >actual && + test_cmp expect actual +' + 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 @@ -630,8 +651,8 @@ test_expect_success 'when server does not send "ready", expect FLUSH' ' test_must_fail env GIT_TRACE_PACKET="$(pwd)/log" git -C http_child \ -c protocol.version=2 \ fetch "$HTTPD_URL/one_time_sed/http_parent" 2> err && - grep "fetch< acknowledgments" log && - ! grep "fetch< ready" log && + grep "fetch< .*acknowledgments" log && + ! grep "fetch< .*ready" log && test_i18ngrep "expected no other sections to be sent after no .ready." err ' diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index 7053899..f87b2f6 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -208,7 +208,7 @@ test_expect_success 'server is initially ahead - no ref in want' ' cp -r "$LOCAL_PRISTINE" local && inconsistency master 1234567890123456789012345678901234567890 && test_must_fail git -C local fetch 2>err && - test_i18ngrep "ERR upload-pack: not our ref" err + test_i18ngrep "fatal: remote error: upload-pack: not our ref" err ' test_expect_success 'server is initially ahead - ref in want' ' @@ -254,7 +254,7 @@ test_expect_success 'server loses a ref - ref in want' ' echo "s/master/raster/" >"$HTTPD_ROOT_PATH/one-time-sed" && test_must_fail git -C local fetch 2>err && - test_i18ngrep "ERR unknown ref refs/heads/raster" err + test_i18ngrep "fatal: remote error: unknown ref refs/heads/raster" err ' stop_httpd diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index f84ff94..55835ee 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -802,7 +802,7 @@ test_expect_success 'bisect terms needs 0 or 1 argument' ' test_must_fail git bisect terms only-one && test_must_fail git bisect terms 1 2 && test_must_fail git bisect terms 2>actual && - echo "no terms defined" >expected && + echo "error: no terms defined" >expected && test_i18ncmp expected actual ' diff --git a/t/t6042-merge-rename-corner-cases.sh b/t/t6042-merge-rename-corner-cases.sh index 7cc34e7..09dfa8b 100755 --- a/t/t6042-merge-rename-corner-cases.sh +++ b/t/t6042-merge-rename-corner-cases.sh @@ -1175,7 +1175,7 @@ test_expect_success 'setup nested conflicts from rename/rename(2to1)' ' # Handle the left side git checkout L && - git mv one three && + git rm one two && mv -f file_v2 three && mv -f file_v5 two && git add two three && @@ -1183,7 +1183,7 @@ test_expect_success 'setup nested conflicts from rename/rename(2to1)' ' # Handle the right side git checkout R && - git mv two three && + git rm one two && mv -f file_v3 one && mv -f file_v6 three && git add one three && diff --git a/t/t6112-rev-list-filters-objects.sh b/t/t6112-rev-list-filters-objects.sh index eb32505..9c11427 100755 --- a/t/t6112-rev-list-filters-objects.sh +++ b/t/t6112-rev-list-filters-objects.sh @@ -283,7 +283,7 @@ test_expect_success 'verify tree:0 includes trees in "filtered" output' ' # Make sure tree:0 does not iterate through any trees. -test_expect_success 'filter a GIANT tree through tree:0' ' +test_expect_success 'verify skipping tree iteration when not collecting omits' ' GIT_TRACE=1 git -C r3 rev-list \ --objects --filter=tree:0 HEAD 2>filter_trace && grep "Skipping contents of tree [.][.][.]" filter_trace >actual && @@ -294,6 +294,126 @@ test_expect_success 'filter a GIANT tree through tree:0' ' ! grep "Skipping contents of tree [^.]" filter_trace ' +# Test tree:# filters. + +expect_has () { + commit=$1 && + name=$2 && + + hash=$(git -C r3 rev-parse $commit:$name) && + grep "^$hash $name$" actual +} + +test_expect_success 'verify tree:1 includes root trees' ' + git -C r3 rev-list --objects --filter=tree:1 HEAD >actual && + + # We should get two root directories and two commits. + expect_has HEAD "" && + expect_has HEAD~1 "" && + test_line_count = 4 actual +' + +test_expect_success 'verify tree:2 includes root trees and immediate children' ' + git -C r3 rev-list --objects --filter=tree:2 HEAD >actual && + + expect_has HEAD "" && + expect_has HEAD~1 "" && + expect_has HEAD dir1 && + expect_has HEAD pattern && + expect_has HEAD sparse1 && + expect_has HEAD sparse2 && + + # There are also 2 commit objects + test_line_count = 8 actual +' + +test_expect_success 'verify tree:3 includes everything expected' ' + git -C r3 rev-list --objects --filter=tree:3 HEAD >actual && + + expect_has HEAD "" && + expect_has HEAD~1 "" && + expect_has HEAD dir1 && + expect_has HEAD dir1/sparse1 && + expect_has HEAD dir1/sparse2 && + expect_has HEAD pattern && + expect_has HEAD sparse1 && + expect_has HEAD sparse2 && + + # There are also 2 commit objects + test_line_count = 10 actual +' + +# Test provisional omit collection logic with a repo that has objects appearing +# at multiple depths - first deeper than the filter's threshold, then shallow. + +test_expect_success 'setup r4' ' + git init r4 && + + echo foo > r4/foo && + mkdir r4/subdir && + echo bar > r4/subdir/bar && + + mkdir r4/filt && + cp -r r4/foo r4/subdir r4/filt && + + git -C r4 add foo subdir filt && + git -C r4 commit -m "commit msg" +' + +expect_has_with_different_name () { + repo=$1 && + name=$2 && + + hash=$(git -C $repo rev-parse HEAD:$name) && + ! grep "^$hash $name$" actual && + grep "^$hash " actual && + ! grep "~$hash" actual +} + +test_expect_success 'test tree:# filter provisional omit for blob and tree' ' + git -C r4 rev-list --objects --filter-print-omitted --filter=tree:2 \ + HEAD >actual && + expect_has_with_different_name r4 filt/foo && + expect_has_with_different_name r4 filt/subdir +' + +test_expect_success 'verify skipping tree iteration when collecting omits' ' + GIT_TRACE=1 git -C r4 rev-list --filter-print-omitted \ + --objects --filter=tree:0 HEAD 2>filter_trace && + grep "^Skipping contents of tree " filter_trace >actual && + + echo "Skipping contents of tree subdir/..." >expect && + test_cmp expect actual +' + +# Test tree:<depth> where a tree is iterated to twice - once where a subentry is +# too deep to be included, and again where the blob inside it is shallow enough +# to be included. This makes sure we don't use LOFR_MARK_SEEN incorrectly (we +# can't use it because a tree can be iterated over again at a lower depth). + +test_expect_success 'tree:<depth> where we iterate over tree at two levels' ' + git init r5 && + + mkdir -p r5/a/subdir/b && + echo foo > r5/a/subdir/b/foo && + + mkdir -p r5/subdir/b && + echo foo > r5/subdir/b/foo && + + git -C r5 add a subdir && + git -C r5 commit -m "commit msg" && + + git -C r5 rev-list --objects --filter=tree:4 HEAD >actual && + expect_has_with_different_name r5 a/subdir/b/foo +' + +test_expect_success 'tree:<depth> which filters out blob but given as arg' ' + blob_hash=$(git -C r4 rev-parse HEAD:subdir/bar) && + + git -C r4 rev-list --objects --filter=tree:1 HEAD $blob_hash >actual && + grep ^$blob_hash actual +' + # Delete some loose objects and use rev-list, but WITHOUT any filtering. # This models previously omitted objects that we did not receive. @@ -324,4 +444,21 @@ test_expect_success 'rev-list W/ missing=allow-any' ' git -C r1 rev-list --quiet --missing=allow-any --objects HEAD ' +# Test expansion of filter specs. + +test_expect_success 'expand blob limit in protocol' ' + git -C r2 config --local uploadpack.allowfilter 1 && + GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 clone \ + --filter=blob:limit=1k "file://$(pwd)/r2" limit && + ! grep "blob:limit=1k" trace && + grep "blob:limit=1024" trace +' + +test_expect_success 'expand tree depth limit in protocol' ' + GIT_TRACE_PACKET="$(pwd)/tree_trace" git -c protocol.version=2 clone \ + --filter=tree:0k "file://$(pwd)/r2" tree && + ! grep "tree:0k" tree_trace && + grep "tree:0" tree_trace +' + test_done diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index d639d94..ee5b03e 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -143,16 +143,46 @@ test_expect_success 'rename tag Q back to A' ' test_expect_success 'pack tag refs' 'git pack-refs' check_describe A-* HEAD +test_expect_success 'describe works from outside repo using --git-dir' ' + git clone --bare "$TRASH_DIRECTORY" "$TRASH_DIRECTORY/bare" && + git --git-dir "$TRASH_DIRECTORY/bare" describe >out && + grep "^A-[1-9][0-9]\?-g[0-9a-f]\+$" out +' + check_describe "A-*[0-9a-f]" --dirty +test_expect_success 'describe --dirty with --work-tree' ' + ( + cd "$TEST_DIRECTORY" && + git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty >"$TRASH_DIRECTORY/out" + ) && + grep "^A-[1-9][0-9]\?-g[0-9a-f]\+$" out +' + test_expect_success 'set-up dirty work tree' ' echo >>file ' check_describe "A-*[0-9a-f]-dirty" --dirty +test_expect_success 'describe --dirty with --work-tree (dirty)' ' + ( + cd "$TEST_DIRECTORY" && + git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty >"$TRASH_DIRECTORY/out" + ) && + grep "^A-[1-9][0-9]\?-g[0-9a-f]\+-dirty$" out +' + check_describe "A-*[0-9a-f].mod" --dirty=.mod +test_expect_success 'describe --dirty=.mod with --work-tree (dirty)' ' + ( + cd "$TEST_DIRECTORY" && + git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --dirty=.mod >"$TRASH_DIRECTORY/out" + ) && + grep "^A-[1-9][0-9]\?-g[0-9a-f]\+.mod$" out +' + test_expect_success 'describe --dirty HEAD' ' test_must_fail git describe --dirty HEAD ' @@ -303,8 +333,17 @@ test_expect_success 'describe chokes on severely broken submodules' ' mv .git/modules/sub1/ .git/modules/sub_moved && test_must_fail git describe --dirty ' + test_expect_success 'describe ignoring a broken submodule' ' git describe --broken >out && + grep broken out +' + +test_expect_success 'describe with --work-tree ignoring a broken submodule' ' + ( + cd "$TEST_DIRECTORY" && + git --git-dir "$TRASH_DIRECTORY/.git" --work-tree "$TRASH_DIRECTORY" describe --broken >"$TRASH_DIRECTORY/out" + ) && test_when_finished "mv .git/modules/sub_moved .git/modules/sub1" && grep broken out ' diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh index ebfcad9..ba8bd1b 100755 --- a/t/t7505-prepare-commit-msg-hook.sh +++ b/t/t7505-prepare-commit-msg-hook.sh @@ -215,7 +215,7 @@ test_expect_success 'with hook and editor (merge)' ' test_rebase () { expect=$1 && mode=$2 && - test_expect_$expect C_LOCALE_OUTPUT "with hook (rebase $mode)" ' + test_expect_$expect C_LOCALE_OUTPUT "with hook (rebase ${mode:--i})" ' test_when_finished "\ git rebase --abort git checkout -f master @@ -225,7 +225,7 @@ test_rebase () { GIT_EDITOR="\"$FAKE_EDITOR\"" && ( export GIT_SEQUENCE_EDITOR GIT_EDITOR && - test_must_fail git rebase $mode b && + test_must_fail git rebase -i $mode b && echo x >a && git add a && test_must_fail git rebase --continue && @@ -241,18 +241,18 @@ test_rebase () { git add b && git rebase --continue ) && - if test $mode = -p # reword amended after pick + if test "$mode" = -p # reword amended after pick then n=18 else n=17 fi && git log --pretty=%s -g -n$n HEAD@{1} >actual && - test_cmp "$TEST_DIRECTORY/t7505/expected-rebase$mode" actual + test_cmp "$TEST_DIRECTORY/t7505/expected-rebase${mode:--i}" actual ' } -test_rebase success -i +test_rebase success test_have_prereq !REBASE_P || test_rebase success -p test_expect_success 'with hook (cherry-pick)' ' diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 86d3f93..682b23a 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -49,15 +49,28 @@ test_expect_success GPG 'create signed commits' ' git tag eighth-signed-alt && # commit.gpgsign is still on but this must not be signed - git tag ninth-unsigned $(echo 9 | git commit-tree HEAD^{tree}) && + echo 9 | git commit-tree HEAD^{tree} >oid && + test_line_count = 1 oid && + git tag ninth-unsigned $(cat oid) && # explicit -S of course must sign. - git tag tenth-signed $(echo 9 | git commit-tree -S HEAD^{tree}) + echo 10 | git commit-tree -S HEAD^{tree} >oid && + test_line_count = 1 oid && + git tag tenth-signed $(cat oid) && + + # --gpg-sign[=<key-id>] must sign. + echo 11 | git commit-tree --gpg-sign HEAD^{tree} >oid && + test_line_count = 1 oid && + git tag eleventh-signed $(cat oid) && + echo 12 | git commit-tree --gpg-sign=B7227189 HEAD^{tree} >oid && + test_line_count = 1 oid && + git tag twelfth-signed-alt $(cat oid) ' test_expect_success GPG 'verify and show signatures' ' ( for commit in initial second merge fourth-signed \ - fifth-signed sixth-signed seventh-signed tenth-signed + fifth-signed sixth-signed seventh-signed tenth-signed \ + eleventh-signed do git verify-commit $commit && git show --pretty=short --show-signature $commit >actual && @@ -78,7 +91,7 @@ test_expect_success GPG 'verify and show signatures' ' done ) && ( - for commit in eighth-signed-alt + for commit in eighth-signed-alt twelfth-signed-alt do git show --pretty=short --show-signature $commit >actual && grep "Good signature from" actual && diff --git a/t/t9303-fast-import-compression.sh b/t/t9303-fast-import-compression.sh index 856219f..5045f02 100755 --- a/t/t9303-fast-import-compression.sh +++ b/t/t9303-fast-import-compression.sh @@ -6,7 +6,7 @@ test_description='compression setting of fast-import utility' # This should be moved to test-lib.sh together with the # copy in t0021 after both topics have graduated to 'master'. file_size () { - perl -e 'print -s $ARGV[0]' "$1" + test-tool path-utils file-size "$1" } import_large () { diff --git a/t/t9807-git-p4-submit.sh b/t/t9807-git-p4-submit.sh index 2325599..850d979 100755 --- a/t/t9807-git-p4-submit.sh +++ b/t/t9807-git-p4-submit.sh @@ -500,6 +500,10 @@ test_expect_success 'submit --shelve' ' ) ' +last_shelve () { + p4 -G changes -s shelved -m 1 //depot/... | marshal_dump change +} + make_shelved_cl() { test_commit "$1" >/dev/null && git p4 submit --origin HEAD^ --shelve >/dev/null && @@ -533,12 +537,59 @@ test_expect_success 'submit --update-shelve' ' ) && ( cd "$cli" && - change=$(p4 -G changes -s shelved -m 1 //depot/... | \ - marshal_dump change) && + change=$(last_shelve) && p4 unshelve -c $change -s $change && grep -q updated-line shelf.t && p4 describe -S $change | grep added-file.t && - test_path_is_missing shelved-change-1.t + test_path_is_missing shelved-change-1.t && + p4 revert ... + ) +' + +test_expect_success 'update a shelve involving moved and copied files' ' + test_when_finished cleanup_git && + ( + cd "$cli" && + : >file_to_move && + p4 add file_to_move && + p4 submit -d "change1" && + p4 edit file_to_move && + echo change >>file_to_move && + p4 submit -d "change2" && + p4 opened + ) && + git p4 clone --dest="$git" //depot && + ( + cd "$git" && + git config git-p4.detectCopies true && + git config git-p4.detectRenames true && + git config git-p4.skipSubmitEdit true && + mkdir moved && + cp file_to_move copy_of_file && + git add copy_of_file && + git mv file_to_move moved/ && + git commit -m "rename a file" && + git p4 submit -M --shelve --origin HEAD^ && + : >new_file && + git add new_file && + git commit --amend && + git show --stat HEAD && + change=$(last_shelve) && + git p4 submit -M --update-shelve $change --commit HEAD + ) && + ( + cd "$cli" && + change=$(last_shelve) && + echo change=$change && + p4 unshelve -s $change && + p4 submit -d "Testing update-shelve" && + test_path_is_file copy_of_file && + test_path_is_file moved/file_to_move && + test_path_is_missing file_to_move && + test_path_is_file new_file && + echo "unshelved and submitted change $change" && + p4 changes moved/file_to_move | grep "Testing update-shelve" && + p4 changes copy_of_file | grep "Testing update-shelve" ) ' diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 81a5179..5cadedb 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -180,7 +180,7 @@ test_expect_success 'prompt - interactive rebase' ' ' test_expect_success 'prompt - rebase merge' ' - printf " (b2|REBASE-m 1/3)" >expected && + printf " (b2|REBASE-i 1/3)" >expected && git checkout b2 && test_when_finished "git checkout master" && test_must_fail git rebase --merge b1 b2 && diff --git a/t/test-lib.sh b/t/test-lib.sh index a1abb11..42b1a0a 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -111,6 +111,8 @@ do test -z "$HARNESS_ACTIVE" && quiet=t ;; --with-dashes) with_dashes=t ;; + --no-bin-wrappers) + no_bin_wrappers=t ;; --no-color) color= ;; --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind) @@ -139,6 +141,9 @@ do verbose_log=t tee=t ;; + --write-junit-xml) + write_junit_xml=t + ;; --stress) stress=t ;; --stress=*) @@ -622,11 +627,35 @@ trap 'exit $?' INT TERM HUP # the test_expect_* functions instead. test_ok_ () { + if test -n "$write_junit_xml" + then + write_junit_xml_testcase "$*" + fi test_success=$(($test_success + 1)) say_color "" "ok $test_count - $@" } test_failure_ () { + if test -n "$write_junit_xml" + then + junit_insert="<failure message=\"not ok $test_count -" + junit_insert="$junit_insert $(xml_attr_encode "$1")\">" + junit_insert="$junit_insert $(xml_attr_encode \ + "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + test-tool path-utils skip-n-bytes \ + "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET + else + printf '%s\n' "$@" | sed 1d + fi)")" + junit_insert="$junit_insert</failure>" + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + junit_insert="$junit_insert<system-err>$(xml_attr_encode \ + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>" + fi + write_junit_xml_testcase "$1" " $junit_insert" + fi test_failure=$(($test_failure + 1)) say_color error "not ok $test_count - $1" shift @@ -635,11 +664,19 @@ test_failure_ () { } test_known_broken_ok_ () { + if test -n "$write_junit_xml" + then + write_junit_xml_testcase "$* (breakage fixed)" + fi test_fixed=$(($test_fixed+1)) say_color error "ok $test_count - $@ # TODO known breakage vanished" } test_known_broken_failure_ () { + if test -n "$write_junit_xml" + then + write_junit_xml_testcase "$* (known breakage)" + fi test_broken=$(($test_broken+1)) say_color warn "not ok $test_count - $@ # TODO known breakage" } @@ -897,12 +934,21 @@ test_start_ () { test_count=$(($test_count+1)) maybe_setup_verbose maybe_setup_valgrind + if test -n "$write_junit_xml" + then + junit_start=$(test-tool date getnanos) + fi } test_finish_ () { echo >&3 "" maybe_teardown_valgrind maybe_teardown_verbose + if test -n "$GIT_TEST_TEE_OFFSET" + then + GIT_TEST_TEE_OFFSET=$(test-tool path-utils file-size \ + "$GIT_TEST_TEE_OUTPUT_FILE") + fi } test_skip () { @@ -934,6 +980,13 @@ test_skip () { case "$to_skip" in t) + if test -n "$write_junit_xml" + then + message="$(xml_attr_encode "$skipped_reason")" + write_junit_xml_testcase "$1" \ + " <skipped message=\"$message\" />" + fi + say_color skip >&3 "skipping test: $@" say_color skip "ok $test_count # skip $1 ($skipped_reason)" : true @@ -949,9 +1002,51 @@ test_at_end_hook_ () { : } +write_junit_xml () { + case "$1" in + --truncate) + >"$junit_xml_path" + junit_have_testcase= + shift + ;; + esac + printf '%s\n' "$@" >>"$junit_xml_path" +} + +xml_attr_encode () { + printf '%s\n' "$@" | test-tool xml-encode +} + +write_junit_xml_testcase () { + junit_attrs="name=\"$(xml_attr_encode "$this_test.$test_count $1")\"" + shift + junit_attrs="$junit_attrs classname=\"$this_test\"" + junit_attrs="$junit_attrs time=\"$(test-tool \ + date getnanos $junit_start)\"" + write_junit_xml "$(printf '%s\n' \ + " <testcase $junit_attrs>" "$@" " </testcase>")" + junit_have_testcase=t +} + test_done () { GIT_EXIT_OK=t + if test -n "$write_junit_xml" && test -n "$junit_xml_path" + then + test -n "$junit_have_testcase" || { + junit_start=$(test-tool date getnanos) + write_junit_xml_testcase "all tests skipped" + } + + # adjust the overall time + junit_time=$(test-tool date getnanos $junit_suite_start) + sed "s/<testsuite [^>]*/& time=\"$junit_time\"/" \ + <"$junit_xml_path" >"$junit_xml_path.new" + mv "$junit_xml_path.new" "$junit_xml_path" + + write_junit_xml " </testsuite>" "</testsuites>" + fi + if test -z "$HARNESS_ACTIVE" then mkdir -p "$TEST_RESULTS_DIR" @@ -1011,7 +1106,11 @@ test_done () { error "Tests passed but trash directory already removed before test cleanup; aborting" cd "$TRASH_DIRECTORY/.." && - rm -fr "$TRASH_DIRECTORY" || + rm -fr "$TRASH_DIRECTORY" || { + # try again in a bit + sleep 5; + rm -fr "$TRASH_DIRECTORY" + } || error "Tests passed but test cleanup failed; aborting" fi test_at_end_hook_ @@ -1117,20 +1216,25 @@ then PATH=$GIT_TEST_INSTALLED:$GIT_BUILD_DIR/t/helper:$PATH GIT_EXEC_PATH=${GIT_TEST_EXEC_PATH:-$GIT_EXEC_PATH} else # normal case, use ../bin-wrappers only unless $with_dashes: - git_bin_dir="$GIT_BUILD_DIR/bin-wrappers" - if ! test -x "$git_bin_dir/git" + if test -n "$no_bin_wrappers" then - if test -z "$with_dashes" + with_dashes=t + else + git_bin_dir="$GIT_BUILD_DIR/bin-wrappers" + if ! test -x "$git_bin_dir/git" then - say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH" + if test -z "$with_dashes" + then + say "$git_bin_dir/git is not executable; using GIT_EXEC_PATH" + fi + with_dashes=t fi - with_dashes=t + PATH="$git_bin_dir:$PATH" fi - PATH="$git_bin_dir:$PATH" GIT_EXEC_PATH=$GIT_BUILD_DIR if test -n "$with_dashes" then - PATH="$GIT_BUILD_DIR:$PATH" + PATH="$GIT_BUILD_DIR:$GIT_BUILD_DIR/t/helper:$PATH" fi fi GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt @@ -1154,7 +1258,7 @@ test -d "$GIT_BUILD_DIR"/templates/blt || { error "You haven't built things yet, have you?" } -if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool +if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool$X then echo >&2 'You need to build test-tool:' echo >&2 'Run "make t/helper/test-tool" in the source (toplevel) directory' @@ -1178,6 +1282,7 @@ then else mkdir -p "$TRASH_DIRECTORY" fi + # Use -P to resolve symlinks in our working directory so that the cwd # in subprocesses like git equals our $PWD (for pathname comparisons). cd -P "$TRASH_DIRECTORY" || exit 1 @@ -1191,6 +1296,23 @@ then test_done fi +if test -n "$write_junit_xml" +then + junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out" + mkdir -p "$junit_xml_dir" + junit_xml_base=${0##*/} + junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml" + junit_attrs="name=\"${junit_xml_base%.sh}\"" + junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \ + date +%Y-%m-%dT%H:%M:%S)\"" + write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>" + junit_suite_start=$(test-tool date getnanos) + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + GIT_TEST_TEE_OFFSET=0 + fi +fi + # Provide an implementation of the 'yes' utility yes () { if test $# = 0 |