diff options
Diffstat (limited to 't')
29 files changed, 1051 insertions, 113 deletions
@@ -479,6 +479,9 @@ GIT_TEST_DEFAULT_HASH=<hash-algo> specifies which hash algorithm to use in the test scripts. Recognized values for <hash-algo> are "sha1" and "sha256". +GIT_TEST_DEFAULT_REF_FORMAT=<format> specifies which ref storage format +to use in the test scripts. Recognized values for <format> are "files". + GIT_TEST_NO_WRITE_REV_INDEX=<boolean>, when true disables the 'pack.writeReverseIndex' setting. diff --git a/t/helper/test-ctype.c b/t/helper/test-ctype.c deleted file mode 100644 index e5659df40b..0000000000 --- a/t/helper/test-ctype.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "test-tool.h" - -static int rc; - -static void report_error(const char *class, int ch) -{ - printf("%s classifies char %d (0x%02x) wrongly\n", class, ch, ch); - rc = 1; -} - -static int is_in(const char *s, int ch) -{ - /* - * We can't find NUL using strchr. Accept it as the first - * character in the spec -- there are no empty classes. - */ - if (ch == '\0') - return ch == *s; - if (*s == '\0') - s++; - return !!strchr(s, ch); -} - -#define TEST_CLASS(t,s) { \ - int i; \ - for (i = 0; i < 256; i++) { \ - if (is_in(s, i) != t(i)) \ - report_error(#t, i); \ - } \ - if (t(EOF)) \ - report_error(#t, EOF); \ -} - -#define DIGIT "0123456789" -#define LOWER "abcdefghijklmnopqrstuvwxyz" -#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" -#define PUNCT "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" -#define ASCII \ - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ - "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ - "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ - "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ - "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ - "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ - "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" -#define CNTRL \ - "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ - "\x7f" - -int cmd__ctype(int argc UNUSED, const char **argv UNUSED) -{ - TEST_CLASS(isdigit, DIGIT); - TEST_CLASS(isspace, " \n\r\t"); - TEST_CLASS(isalpha, LOWER UPPER); - TEST_CLASS(isalnum, LOWER UPPER DIGIT); - TEST_CLASS(is_glob_special, "*?[\\"); - TEST_CLASS(is_regex_special, "$()*+.?[\\^{|"); - TEST_CLASS(is_pathspec_magic, "!\"#%&',-/:;<=>@_`~"); - TEST_CLASS(isascii, ASCII); - TEST_CLASS(islower, LOWER); - TEST_CLASS(isupper, UPPER); - TEST_CLASS(iscntrl, CNTRL); - TEST_CLASS(ispunct, PUNCT); - TEST_CLASS(isxdigit, DIGIT "abcdefABCDEF"); - TEST_CLASS(isprint, LOWER UPPER DIGIT PUNCT " "); - - return rc; -} diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c index 77e99c37df..4daa82f00f 100644 --- a/t/helper/test-pkt-line.c +++ b/t/helper/test-pkt-line.c @@ -3,6 +3,7 @@ #include "pkt-line.h" #include "sideband.h" #include "write-or-die.h" +#include "parse-options.h" static void pack_line(const char *line) { @@ -65,12 +66,33 @@ static void unpack(void) } } -static void unpack_sideband(void) +static void unpack_sideband(int argc, const char **argv) { struct packet_reader reader; - packet_reader_init(&reader, 0, NULL, 0, - PACKET_READ_GENTLE_ON_EOF | - PACKET_READ_CHOMP_NEWLINE); + int options = PACKET_READ_GENTLE_ON_EOF; + int chomp_newline = 1; + int reader_use_sideband = 0; + const char *const unpack_sideband_usage[] = { + "test_tool unpack_sideband [options...]", NULL + }; + struct option cmd_options[] = { + OPT_BOOL(0, "reader-use-sideband", &reader_use_sideband, + "set use_sideband bit for packet reader (Default: off)"), + OPT_BOOL(0, "chomp-newline", &chomp_newline, + "chomp newline in packet (Default: on)"), + OPT_END() + }; + + argc = parse_options(argc, argv, "", cmd_options, unpack_sideband_usage, + 0); + if (argc > 0) + usage_msg_opt(_("too many arguments"), unpack_sideband_usage, + cmd_options); + + if (chomp_newline) + options |= PACKET_READ_CHOMP_NEWLINE; + packet_reader_init(&reader, 0, NULL, 0, options); + reader.use_sideband = reader_use_sideband; while (packet_reader_read(&reader) != PACKET_READ_EOF) { int band; @@ -80,6 +102,17 @@ static void unpack_sideband(void) case PACKET_READ_EOF: break; case PACKET_READ_NORMAL: + /* + * When the "use_sideband" field of the reader is turned + * on, sideband packets other than the payload have been + * parsed and consumed in packet_reader_read(), and only + * the payload arrives here. + */ + if (reader.use_sideband) { + write_or_die(1, reader.line, reader.pktlen - 1); + break; + } + band = reader.line[0] & 0xff; if (band < 1 || band > 2) continue; /* skip non-sideband packets */ @@ -98,15 +131,31 @@ static void unpack_sideband(void) static int send_split_sideband(void) { + const char *foo = "Foo.\n"; + const char *bar = "Bar.\n"; const char *part1 = "Hello,"; const char *primary = "\001primary: regular output\n"; const char *part2 = " world!\n"; + /* Each sideband message has a trailing newline character. */ + send_sideband(1, 2, foo, strlen(foo), LARGE_PACKET_MAX); + send_sideband(1, 2, bar, strlen(bar), LARGE_PACKET_MAX); + + /* + * One sideband message is divided into part1 and part2 + * by the primary message. + */ send_sideband(1, 2, part1, strlen(part1), LARGE_PACKET_MAX); packet_write(1, primary, strlen(primary)); send_sideband(1, 2, part2, strlen(part2), LARGE_PACKET_MAX); packet_response_end(1); + /* + * We use unpack_sideband() to consume packets. A flush packet + * is required to end parsing. + */ + packet_flush(1); + return 0; } @@ -127,7 +176,7 @@ int cmd__pkt_line(int argc, const char **argv) else if (!strcmp(argv[1], "unpack")) unpack(); else if (!strcmp(argv[1], "unpack-sideband")) - unpack_sideband(); + unpack_sideband(argc - 1, argv + 1); else if (!strcmp(argv[1], "send-split-sideband")) send_split_sideband(); else if (!strcmp(argv[1], "receive-sideband")) diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index e9a444ddba..4acae41bb9 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -6,6 +6,7 @@ #include "pack-bitmap.h" #include "packfile.h" #include "setup.h" +#include "gettext.h" static int read_midx_file(const char *object_dir, int show_objects) { @@ -79,7 +80,7 @@ static int read_midx_checksum(const char *object_dir) static int read_midx_preferred_pack(const char *object_dir) { struct multi_pack_index *midx = NULL; - struct bitmap_index *bitmap = NULL; + uint32_t preferred_pack; setup_git_directory(); @@ -87,23 +88,45 @@ static int read_midx_preferred_pack(const char *object_dir) if (!midx) return 1; - bitmap = prepare_bitmap_git(the_repository); - if (!bitmap) + if (midx_preferred_pack(midx, &preferred_pack) < 0) { + warning(_("could not determine MIDX preferred pack")); return 1; - if (!bitmap_is_midx(bitmap)) { - free_bitmap_index(bitmap); + } + + printf("%s\n", midx->pack_names[preferred_pack]); + return 0; +} + +static int read_midx_bitmapped_packs(const char *object_dir) +{ + struct multi_pack_index *midx = NULL; + struct bitmapped_pack pack; + uint32_t i; + + setup_git_directory(); + + midx = load_multi_pack_index(object_dir, 1); + if (!midx) return 1; + + for (i = 0; i < midx->num_packs; i++) { + if (nth_bitmapped_pack(the_repository, midx, &pack, i) < 0) + return 1; + + printf("%s\n", pack_basename(pack.p)); + printf(" bitmap_pos: %"PRIuMAX"\n", (uintmax_t)pack.bitmap_pos); + printf(" bitmap_nr: %"PRIuMAX"\n", (uintmax_t)pack.bitmap_nr); } - printf("%s\n", midx->pack_names[midx_preferred_pack(bitmap)]); - free_bitmap_index(bitmap); + close_midx(midx); + return 0; } int cmd__read_midx(int argc, const char **argv) { if (!(argc == 2 || argc == 3)) - usage("read-midx [--show-objects|--checksum|--preferred-pack] <object-dir>"); + usage("read-midx [--show-objects|--checksum|--preferred-pack|--bitmap] <object-dir>"); if (!strcmp(argv[1], "--show-objects")) return read_midx_file(argv[2], 1); @@ -111,5 +134,7 @@ int cmd__read_midx(int argc, const char **argv) return read_midx_checksum(argv[2]); else if (!strcmp(argv[1], "--preferred-pack")) return read_midx_preferred_pack(argv[2]); + else if (!strcmp(argv[1], "--bitmap")) + return read_midx_bitmapped_packs(argv[2]); return read_midx_file(argv[1], 0); } diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 37ba996539..33b9501c21 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -19,7 +19,6 @@ static struct test_cmd cmds[] = { { "config", cmd__config }, { "crontab", cmd__crontab }, { "csprng", cmd__csprng }, - { "ctype", cmd__ctype }, { "date", cmd__date }, { "delta", cmd__delta }, { "dir-iterator", cmd__dir_iterator }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 8a1a7c63da..b72f07ded9 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -12,7 +12,6 @@ int cmd__chmtime(int argc, const char **argv); int cmd__config(int argc, const char **argv); int cmd__crontab(int argc, const char **argv); int cmd__csprng(int argc, const char **argv); -int cmd__ctype(int argc, const char **argv); int cmd__date(int argc, const char **argv); int cmd__delta(int argc, const char **argv); int cmd__dir_iterator(int argc, const char **argv); diff --git a/t/perf/p5332-multi-pack-reuse.sh b/t/perf/p5332-multi-pack-reuse.sh new file mode 100755 index 0000000000..5c6c575d62 --- /dev/null +++ b/t/perf/p5332-multi-pack-reuse.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +test_description='tests pack performance with multi-pack reuse' + +. ./perf-lib.sh +. "${TEST_DIRECTORY}/perf/lib-pack.sh" + +packdir=.git/objects/pack + +test_perf_large_repo + +find_pack () { + for idx in $packdir/pack-*.idx + do + if git show-index <$idx | grep -q "$1" + then + basename $idx + fi || return 1 + done +} + +repack_into_n_chunks () { + git repack -adk && + + test "$1" -eq 1 && return || + + find $packdir -type f | sort >packs.before && + + # partition the repository into $1 chunks of consecutive commits, and + # then create $1 packs with the objects reachable from each chunk + # (excluding any objects reachable from the previous chunks) + sz="$(($(git rev-list --count --all) / $1))" + for rev in $(git rev-list --all | awk "NR % $sz == 0" | tac) + do + pack="$(echo "$rev" | git pack-objects --revs \ + --honor-pack-keep --delta-base-offset $packdir/pack)" && + touch $packdir/pack-$pack.keep || return 1 + done + + # grab any remaining objects not packed by the previous step(s) + git pack-objects --revs --all --honor-pack-keep --delta-base-offset \ + $packdir/pack && + + find $packdir -type f | sort >packs.after && + + # and install the whole thing + for f in $(comm -12 packs.before packs.after) + do + rm -f "$f" || return 1 + done + rm -fr $packdir/*.keep +} + +for nr_packs in 1 10 100 +do + test_expect_success "create $nr_packs-pack scenario" ' + repack_into_n_chunks $nr_packs + ' + + test_expect_success "setup bitmaps for $nr_packs-pack scenario" ' + find $packdir -type f -name "*.idx" | sed -e "s/.*\/\(.*\)$/+\1/g" | + git multi-pack-index write --stdin-packs --bitmap \ + --preferred-pack="$(find_pack $(git rev-parse HEAD))" + ' + + for reuse in single multi + do + test_perf "clone for $nr_packs-pack scenario ($reuse-pack reuse)" " + git for-each-ref --format='%(objectname)' refs/heads refs/tags >in && + git -c pack.allowPackReuse=$reuse pack-objects \ + --revs --delta-base-offset --use-bitmap-index \ + --stdout <in >result + " + + test_size "clone size for $nr_packs-pack scenario ($reuse-pack reuse)" ' + wc -c <result + ' + done +done + +test_done diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 2b78e3be47..b131d665db 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -532,6 +532,76 @@ test_expect_success 'init rejects attempts to initialize with different hash' ' test_must_fail git -C sha256 init --object-format=sha1 ' +test_expect_success DEFAULT_REPO_FORMAT 'extensions.refStorage is not allowed with repo version 0' ' + test_when_finished "rm -rf refstorage" && + git init refstorage && + git -C refstorage config extensions.refStorage files && + test_must_fail git -C refstorage rev-parse 2>err && + grep "repo version is 0, but v1-only extension found" err +' + +test_expect_success DEFAULT_REPO_FORMAT 'extensions.refStorage with files backend' ' + test_when_finished "rm -rf refstorage" && + git init refstorage && + git -C refstorage config core.repositoryformatversion 1 && + git -C refstorage config extensions.refStorage files && + test_commit -C refstorage A && + git -C refstorage rev-parse --verify HEAD +' + +test_expect_success DEFAULT_REPO_FORMAT 'extensions.refStorage with unknown backend' ' + test_when_finished "rm -rf refstorage" && + git init refstorage && + git -C refstorage config core.repositoryformatversion 1 && + git -C refstorage config extensions.refStorage garbage && + test_must_fail git -C refstorage rev-parse 2>err && + grep "invalid value for ${SQ}extensions.refstorage${SQ}: ${SQ}garbage${SQ}" err +' + +test_expect_success DEFAULT_REPO_FORMAT 'init with GIT_DEFAULT_REF_FORMAT=files' ' + test_when_finished "rm -rf refformat" && + GIT_DEFAULT_REF_FORMAT=files git init refformat && + echo 0 >expect && + git -C refformat config core.repositoryformatversion >actual && + test_cmp expect actual && + test_must_fail git -C refformat config extensions.refstorage +' + +test_expect_success 'init with GIT_DEFAULT_REF_FORMAT=garbage' ' + test_when_finished "rm -rf refformat" && + cat >expect <<-EOF && + fatal: unknown ref storage format ${SQ}garbage${SQ} + EOF + test_must_fail env GIT_DEFAULT_REF_FORMAT=garbage git init refformat 2>err && + test_cmp expect err +' + +test_expect_success 'init with --ref-format=files' ' + test_when_finished "rm -rf refformat" && + git init --ref-format=files refformat && + echo files >expect && + git -C refformat rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 're-init with same format' ' + test_when_finished "rm -rf refformat" && + git init --ref-format=files refformat && + git init --ref-format=files refformat && + echo files >expect && + git -C refformat rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'init with --ref-format=garbage' ' + test_when_finished "rm -rf refformat" && + cat >expect <<-EOF && + fatal: unknown ref storage format ${SQ}garbage${SQ} + EOF + test_must_fail git init --ref-format=garbage refformat 2>err && + test_cmp expect err +' + test_expect_success MINGW 'core.hidedotfiles = false' ' git config --global core.hidedotfiles false && rm -rf newdir && diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index aee2298f01..774b52c298 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -19,6 +19,20 @@ attr_check () { test_must_be_empty err } +attr_check_object_mode_basic () { + path="$1" && + expect="$2" && + check_opts="$3" && + git check-attr $check_opts builtin_objectmode -- "$path" >actual 2>err && + echo "$path: builtin_objectmode: $expect" >expect && + test_cmp expect actual +} + +attr_check_object_mode () { + attr_check_object_mode_basic "$@" && + test_must_be_empty err +} + attr_check_quote () { path="$1" quoted_path="$2" expect="$3" && @@ -558,4 +572,66 @@ test_expect_success EXPENSIVE 'large attributes file ignored in index' ' test_cmp expect err ' +test_expect_success 'builtin object mode attributes work (dir and regular paths)' ' + >normal && + attr_check_object_mode normal 100644 && + mkdir dir && + attr_check_object_mode dir 040000 +' + +test_expect_success POSIXPERM 'builtin object mode attributes work (executable)' ' + >exec && + chmod +x exec && + attr_check_object_mode exec 100755 +' + +test_expect_success SYMLINKS 'builtin object mode attributes work (symlinks)' ' + ln -s to_sym sym && + attr_check_object_mode sym 120000 +' + +test_expect_success 'native object mode attributes work with --cached' ' + >normal && + git add normal && + empty_blob=$(git rev-parse :normal) && + git update-index --index-info <<-EOF && + 100755 $empty_blob 0 exec + 120000 $empty_blob 0 symlink + EOF + attr_check_object_mode normal 100644 --cached && + attr_check_object_mode exec 100755 --cached && + attr_check_object_mode symlink 120000 --cached +' + +test_expect_success 'check object mode attributes work for submodules' ' + mkdir sub && + ( + cd sub && + git init && + mv .git .real && + echo "gitdir: .real" >.git && + test_commit first + ) && + attr_check_object_mode sub 160000 && + attr_check_object_mode sub unspecified --cached && + git add sub && + attr_check_object_mode sub 160000 --cached +' + +test_expect_success 'we do not allow user defined builtin_* attributes' ' + echo "foo* builtin_foo" >.gitattributes && + git add .gitattributes 2>actual && + echo "builtin_foo is not a valid attribute name: .gitattributes:1" >expect && + test_cmp expect actual +' + +test_expect_success 'user defined builtin_objectmode values are ignored' ' + echo "foo* builtin_objectmode=12345" >.gitattributes && + git add .gitattributes && + >foo_1 && + attr_check_object_mode_basic foo_1 100644 && + echo "builtin_objectmode is not a valid attribute name: .gitattributes:1" >expect && + test_cmp expect err +' + test_done diff --git a/t/t0070-fundamental.sh b/t/t0070-fundamental.sh index 487bc8d905..0ecec2ba71 100755 --- a/t/t0070-fundamental.sh +++ b/t/t0070-fundamental.sh @@ -9,10 +9,6 @@ Verify wrappers and compatibility functions. TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -test_expect_success 'character classes (isspace, isalpha etc.)' ' - test-tool ctype -' - test_expect_success 'mktemp to nonexistent directory prints filename' ' test_must_fail test-tool mktemp doesnotexist/testXXXXXX 2>err && grep "doesnotexist/test" err @@ -53,4 +49,62 @@ test_expect_success 'missing sideband designator is reported' ' test_grep "missing sideband" err ' +test_expect_success 'unpack-sideband: --no-chomp-newline' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --no-chomp-newline <split-sideband >out 2>err && + cat >expect-out <<-EOF && + primary: regular output + EOF + cat >expect-err <<-EOF && + Foo. + Bar. + Hello, world! + EOF + test_cmp expect-out out && + test_cmp expect-err err +' + +test_expect_success 'unpack-sideband: --chomp-newline (default)' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --chomp-newline <split-sideband >out 2>err && + printf "primary: regular output" >expect-out && + printf "Foo.Bar.Hello, world!" >expect-err && + test_cmp expect-out out && + test_cmp expect-err err +' + +test_expect_success 'unpack-sideband: packet_reader_read() consumes sideband, no chomp payload' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --reader-use-sideband \ + --no-chomp-newline <split-sideband >out 2>err && + cat >expect-out <<-EOF && + primary: regular output + EOF + printf "remote: Foo. \n" >expect-err && + printf "remote: Bar. \n" >>expect-err && + printf "remote: Hello, world! \n" >>expect-err && + test_cmp expect-out out && + test_cmp expect-err err +' + +test_expect_success 'unpack-sideband: packet_reader_read() consumes sideband, chomp payload' ' + test_when_finished "rm -f expect-out expect-err" && + test-tool pkt-line send-split-sideband >split-sideband && + test-tool pkt-line unpack-sideband \ + --reader-use-sideband \ + --chomp-newline <split-sideband >out 2>err && + printf "primary: regular output" >expect-out && + printf "remote: Foo. \n" >expect-err && + printf "remote: Bar. \n" >>expect-err && + printf "remote: Hello, world! \n" >>expect-err && + test_cmp expect-out out && + test_cmp expect-err err +' + test_done diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index 271c5e4fd3..e0c6482797 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -1100,6 +1100,42 @@ test_expect_success 'cat-file --batch="batman" with --batch-all-objects will wor cmp expect actual ' +test_expect_success 'cat-file %(objectsize:disk) with --batch-all-objects' ' + # our state has both loose and packed objects, + # so find both for our expected output + { + find .git/objects/?? -type f | + awk -F/ "{ print \$0, \$3\$4 }" | + while read path oid + do + size=$(test_file_size "$path") && + echo "$oid $size" || + return 1 + done && + rawsz=$(test_oid rawsz) && + find .git/objects/pack -name "*.idx" | + while read idx + do + git show-index <"$idx" >idx.raw && + sort -nr <idx.raw >idx.sorted && + packsz=$(test_file_size "${idx%.idx}.pack") && + end=$((packsz - rawsz)) && + while read start oid rest + do + size=$((end - start)) && + end=$start && + echo "$oid $size" || + return 1 + done <idx.sorted || + return 1 + done + } >expect.raw && + sort <expect.raw >expect && + git cat-file --batch-all-objects \ + --batch-check="%(objectname) %(objectsize:disk)" >actual && + test_cmp expect actual +' + test_expect_success 'set up replacement object' ' orig=$(git rev-parse HEAD) && git cat-file commit $orig >orig && diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 3241d35917..5c60d6f812 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -106,9 +106,8 @@ test_expect_success LONG_REF 'we can parse long symbolic ref' ' ' test_expect_success 'symbolic-ref reports failure in exit code' ' - test_when_finished "rm -f .git/HEAD.lock" && - >.git/HEAD.lock && - test_must_fail git symbolic-ref HEAD refs/heads/whatever + # Create d/f conflict to simulate failure. + test_must_fail git symbolic-ref refs/heads refs/heads/foo ' test_expect_success 'symbolic-ref writes reflog entry' ' diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 3f9e7f62e4..a669e592f1 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -208,6 +208,23 @@ test_expect_success 'rev-parse --show-object-format in repo' ' grep "unknown mode for --show-object-format: squeamish-ossifrage" err ' +test_expect_success 'rev-parse --show-ref-format' ' + test_detect_ref_format >expect && + git rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'rev-parse --show-ref-format with invalid storage' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + git config extensions.refstorage broken && + test_must_fail git rev-parse --show-ref-format 2>err && + grep "error: invalid value for ${SQ}extensions.refstorage${SQ}: ${SQ}broken${SQ}" err + ) +' + test_expect_success '--show-toplevel from subdir of working tree' ' pwd >expect && git -C sub/dir rev-parse --show-toplevel >actual && diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 6a316f081e..de7d3014e4 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -519,7 +519,7 @@ EOF mv .git/config .git/config-saved -test_expect_success SHA1 'git branch -m q q2 without config should succeed' ' +test_expect_success DEFAULT_REPO_FORMAT 'git branch -m q q2 without config should succeed' ' git branch -m q q2 && git branch -m q2 q ' diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index e7a7295f1b..2775bfadd8 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -41,7 +41,8 @@ test_expect_success FILEMODE 'same mode (index only)' ' chmod +x file && git add file && git apply --cached patch-0.txt && - git ls-files -s file | grep "^100755" + git ls-files -s file >ls-files-output && + test_grep "^100755" ls-files-output ' test_expect_success FILEMODE 'mode update (no index)' ' @@ -60,7 +61,8 @@ test_expect_success FILEMODE 'mode update (with index)' ' test_expect_success FILEMODE 'mode update (index only)' ' git reset --hard && git apply --cached patch-1.txt && - git ls-files -s file | grep "^100755" + git ls-files -s file >ls-files-output && + test_grep "^100755" ls-files-output ' test_expect_success FILEMODE 'empty mode is rejected' ' diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index c20aafe99a..dd09134db0 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -1171,4 +1171,39 @@ test_expect_success 'reader notices out-of-bounds fanout' ' test_cmp expect err ' +test_expect_success 'bitmapped packs are stored via the BTMP chunk' ' + test_when_finished "rm -fr repo" && + git init repo && + ( + cd repo && + + for i in 1 2 3 4 5 + do + test_commit "$i" && + git repack -d || return 1 + done && + + find $objdir/pack -type f -name "*.idx" | xargs -n 1 basename | + sort >packs && + + git multi-pack-index write --stdin-packs <packs && + test_must_fail test-tool read-midx --bitmap $objdir 2>err && + cat >expect <<-\EOF && + error: MIDX does not contain the BTMP chunk + EOF + test_cmp expect err && + + git multi-pack-index write --stdin-packs --bitmap \ + --preferred-pack="$(head -n1 <packs)" <packs && + test-tool read-midx --bitmap $objdir >actual && + for i in $(test_seq $(wc -l <packs)) + do + sed -ne "${i}s/\.idx$/\.pack/p" packs && + echo " bitmap_pos: $((($i - 1) * 3))" && + echo " bitmap_nr: 3" || return 1 + done >expect && + test_cmp expect actual + ) +' + test_done diff --git a/t/t5332-multi-pack-reuse.sh b/t/t5332-multi-pack-reuse.sh new file mode 100755 index 0000000000..2ba788b042 --- /dev/null +++ b/t/t5332-multi-pack-reuse.sh @@ -0,0 +1,203 @@ +#!/bin/sh + +test_description='pack-objects multi-pack reuse' + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-bitmap.sh + +objdir=.git/objects +packdir=$objdir/pack + +test_pack_reused () { + test_trace2_data pack-objects pack-reused "$1" +} + +test_packs_reused () { + test_trace2_data pack-objects packs-reused "$1" +} + + +# pack_position <object> </path/to/pack.idx +pack_position () { + git show-index >objects && + grep "$1" objects | cut -d" " -f1 +} + +test_expect_success 'preferred pack is reused for single-pack reuse' ' + test_config pack.allowPackReuse single && + + for i in A B + do + test_commit "$i" && + git repack -d || return 1 + done && + + git multi-pack-index write --bitmap && + + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --revs --all >/dev/null && + + test_pack_reused 3 <trace2.txt && + test_packs_reused 1 <trace2.txt +' + +test_expect_success 'enable multi-pack reuse' ' + git config pack.allowPackReuse multi +' + +test_expect_success 'reuse all objects from subset of bitmapped packs' ' + test_commit C && + git repack -d && + + git multi-pack-index write --bitmap && + + cat >in <<-EOF && + $(git rev-parse C) + ^$(git rev-parse A) + EOF + + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --revs <in >/dev/null && + + test_pack_reused 6 <trace2.txt && + test_packs_reused 2 <trace2.txt +' + +test_expect_success 'reuse all objects from all packs' ' + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --revs --all >/dev/null && + + test_pack_reused 9 <trace2.txt && + test_packs_reused 3 <trace2.txt +' + +test_expect_success 'reuse objects from first pack with middle gap' ' + for i in D E F + do + test_commit "$i" || return 1 + done && + + # Set "pack.window" to zero to ensure that we do not create any + # deltas, which could alter the amount of pack reuse we perform + # (if, for e.g., we are not sending one or more bases). + D="$(git -c pack.window=0 pack-objects --all --unpacked $packdir/pack)" && + + d_pos="$(pack_position $(git rev-parse D) <$packdir/pack-$D.idx)" && + e_pos="$(pack_position $(git rev-parse E) <$packdir/pack-$D.idx)" && + f_pos="$(pack_position $(git rev-parse F) <$packdir/pack-$D.idx)" && + + # commits F, E, and D, should appear in that order at the + # beginning of the pack + test $f_pos -lt $e_pos && + test $e_pos -lt $d_pos && + + # Ensure that the pack we are constructing sorts ahead of any + # other packs in lexical/bitmap order by choosing it as the + # preferred pack. + git multi-pack-index write --bitmap --preferred-pack="pack-$D.idx" && + + cat >in <<-EOF && + $(git rev-parse E) + ^$(git rev-parse D) + EOF + + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --delta-base-offset --revs <in >/dev/null && + + test_pack_reused 3 <trace2.txt && + test_packs_reused 1 <trace2.txt +' + +test_expect_success 'reuse objects from middle pack with middle gap' ' + rm -fr $packdir/multi-pack-index* && + + # Ensure that the pack we are constructing sort into any + # position *but* the first one, by choosing a different pack as + # the preferred one. + git multi-pack-index write --bitmap --preferred-pack="pack-$A.idx" && + + cat >in <<-EOF && + $(git rev-parse E) + ^$(git rev-parse D) + EOF + + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --delta-base-offset --revs <in >/dev/null && + + test_pack_reused 3 <trace2.txt && + test_packs_reused 1 <trace2.txt +' + +test_expect_success 'omit delta with uninteresting base (same pack)' ' + git repack -adk && + + test_seq 32 >f && + git add f && + test_tick && + git commit -m "delta" && + delta="$(git rev-parse HEAD)" && + + test_seq 64 >f && + test_tick && + git commit -a -m "base" && + base="$(git rev-parse HEAD)" && + + test_commit other && + + git repack -d && + + have_delta "$(git rev-parse $delta:f)" "$(git rev-parse $base:f)" && + + git multi-pack-index write --bitmap && + + cat >in <<-EOF && + $(git rev-parse other) + ^$base + EOF + + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --delta-base-offset --revs <in >/dev/null && + + # We can only reuse the 3 objects corresponding to "other" from + # the latest pack. + # + # This is because even though we want "delta", we do not want + # "base", meaning that we have to inflate the delta/base-pair + # corresponding to the blob in commit "delta", which bypasses + # the pack-reuse mechanism. + # + # The remaining objects from the other pack are similarly not + # reused because their objects are on the uninteresting side of + # the query. + test_pack_reused 3 <trace2.txt && + test_packs_reused 1 <trace2.txt +' + +test_expect_success 'omit delta from uninteresting base (cross pack)' ' + cat >in <<-EOF && + $(git rev-parse $base) + ^$(git rev-parse $delta) + EOF + + P="$(git pack-objects --revs $packdir/pack <in)" && + + git multi-pack-index write --bitmap --preferred-pack="pack-$P.idx" && + + : >trace2.txt && + GIT_TRACE2_EVENT="$PWD/trace2.txt" \ + git pack-objects --stdout --delta-base-offset --all >/dev/null && + + packs_nr="$(find $packdir -type f -name "pack-*.pack" | wc -l)" && + objects_nr="$(git rev-list --count --all --objects)" && + + test_pack_reused $(($objects_nr - 1)) <trace2.txt && + test_packs_reused $packs_nr <trace2.txt +' + +test_done diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 79592a3b0a..33d34d5ae9 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -803,7 +803,8 @@ test_expect_success 'fetch.writeCommitGraph with submodules' ' cd super-clone && rm -rf .git/objects/info && git -c fetch.writeCommitGraph=true fetch origin && - test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain + test_path_is_file .git/objects/info/commit-graphs/commit-graph-chain && + git -c fetch.writeCommitGraph=true fetch --recurse-submodules origin ) ' diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh index a95841dc36..25772c85c5 100755 --- a/t/t5514-fetch-multiple.sh +++ b/t/t5514-fetch-multiple.sh @@ -24,6 +24,15 @@ setup_repository () { ) } +setup_test_clone () { + test_dir="$1" && + git clone one "$test_dir" && + for r in one two three + do + git -C "$test_dir" remote add "$r" "../$r" || return 1 + done +} + test_expect_success setup ' setup_repository one && setup_repository two && @@ -209,4 +218,156 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' ' git fetch --multiple --jobs=0) ' +create_fetch_all_expect () { + cat >expect <<-\EOF + one/main + one/side + origin/HEAD -> origin/main + origin/main + origin/side + three/another + three/main + three/side + two/another + two/main + two/side + EOF +} + +for fetch_all in true false +do + test_expect_success "git fetch --all (works with fetch.all = $fetch_all)" ' + test_dir="test_fetch_all_$fetch_all" && + setup_test_clone "$test_dir" && + ( + cd "$test_dir" && + git config fetch.all $fetch_all && + git fetch --all && + create_fetch_all_expect && + git branch -r >actual && + test_cmp expect actual + ) + ' +done + +test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' ' + setup_test_clone test9 && + ( + cd test9 && + git config fetch.all true && + git fetch && + git branch -r >actual && + create_fetch_all_expect && + test_cmp expect actual + ) +' + +create_fetch_one_expect () { + cat >expect <<-\EOF + one/main + one/side + origin/HEAD -> origin/main + origin/main + origin/side + EOF +} + +test_expect_success 'git fetch one (explicit remote overrides fetch.all)' ' + setup_test_clone test10 && + ( + cd test10 && + git config fetch.all true && + git fetch one && + create_fetch_one_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +create_fetch_two_as_origin_expect () { + cat >expect <<-\EOF + origin/HEAD -> origin/main + origin/another + origin/main + origin/side + EOF +} + +test_expect_success 'git config fetch.all false (fetch only default remote)' ' + setup_test_clone test11 && + ( + cd test11 && + git config fetch.all false && + git remote set-url origin ../two && + git fetch && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +for fetch_all in true false +do + test_expect_success "git fetch --no-all (fetch only default remote with fetch.all = $fetch_all)" ' + test_dir="test_no_all_fetch_all_$fetch_all" && + setup_test_clone "$test_dir" && + ( + cd "$test_dir" && + git config fetch.all $fetch_all && + git remote set-url origin ../two && + git fetch --no-all && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) + ' +done + +test_expect_success 'git fetch --no-all (fetch only default remote without fetch.all)' ' + setup_test_clone test12 && + ( + cd test12 && + git config --unset-all fetch.all || true && + git remote set-url origin ../two && + git fetch --no-all && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +test_expect_success 'git fetch --all --no-all (fetch only default remote)' ' + setup_test_clone test13 && + ( + cd test13 && + git remote set-url origin ../two && + git fetch --all --no-all && + create_fetch_two_as_origin_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +test_expect_success 'git fetch --no-all one (fetch only explicit remote)' ' + setup_test_clone test14 && + ( + cd test14 && + git fetch --no-all one && + create_fetch_one_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + +test_expect_success 'git fetch --no-all --all (fetch all remotes)' ' + setup_test_clone test15 && + ( + cd test15 && + git fetch --no-all --all && + create_fetch_all_expect && + git branch -r >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index df758e187d..71428f3d5c 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -232,8 +232,9 @@ test_expect_success 'push --atomic fails on server-side errors' ' test_config -C "$d" http.receivepack true && up="$HTTPD_URL"/smart/atomic-branches.git && - # break ref updates for other on the remote site - mkdir "$d/refs/heads/other.lock" && + # Create d/f conflict to break ref updates for other on the remote site. + git -C "$d" update-ref -d refs/heads/other && + git -C "$d" update-ref refs/heads/other/conflict HEAD && # add the new commit to other git branch -f other collateral && @@ -241,18 +242,9 @@ test_expect_success 'push --atomic fails on server-side errors' ' # --atomic should cause entire push to be rejected test_must_fail git push --atomic "$up" atomic other 2>output && - # the new branch should not have been created upstream - test_must_fail git -C "$d" show-ref --verify refs/heads/atomic && - - # upstream should still reflect atomic2, the last thing we pushed - # successfully - git rev-parse atomic2 >expected && - # ...to other. - git -C "$d" rev-parse refs/heads/other >actual && - test_cmp expected actual && - - # the new branch should not have been created upstream + # The atomic and other branches should not be created upstream. test_must_fail git -C "$d" show-ref --verify refs/heads/atomic && + test_must_fail git -C "$d" show-ref --verify refs/heads/other && # the failed refs should be indicated to the user grep "^ ! .*rejected.* other -> other .*atomic transaction failed" output && diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 47eae641f0..fb1b9c686d 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -157,6 +157,23 @@ test_expect_success 'clone --mirror does not repeat tags' ' ' +test_expect_success 'clone with files ref format' ' + test_when_finished "rm -rf ref-storage" && + git clone --ref-format=files --mirror src ref-storage && + echo files >expect && + git -C ref-storage rev-parse --show-ref-format >actual && + test_cmp expect actual +' + +test_expect_success 'clone with garbage ref format' ' + cat >expect <<-EOF && + fatal: unknown ref storage format ${SQ}garbage${SQ} + EOF + test_must_fail git clone --ref-format=garbage --mirror src ref-storage 2>err && + test_cmp expect err && + test_path_is_missing ref-storage +' + test_expect_success 'clone to destination with trailing /' ' git clone src target-1/ && diff --git a/t/t6113-rev-list-bitmap-filters.sh b/t/t6113-rev-list-bitmap-filters.sh index 86c70521f1..459f0d7412 100755 --- a/t/t6113-rev-list-bitmap-filters.sh +++ b/t/t6113-rev-list-bitmap-filters.sh @@ -4,6 +4,8 @@ test_description='rev-list combining bitmaps and filters' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bitmap.sh +TEST_PASSES_SANITIZE_LEAK=true + test_expect_success 'set up bitmapped repo' ' # one commit will have bitmaps, the other will not test_commit one && diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh index 00b84ecba6..120dcd74a5 100755 --- a/t/t6135-pathspec-with-attrs.sh +++ b/t/t6135-pathspec-with-attrs.sh @@ -393,4 +393,31 @@ test_expect_success 'reading from .gitattributes in a subdirectory (3)' ' test_cmp expect actual ' +test_expect_success POSIXPERM 'pathspec with builtin_objectmode attr can be used' ' + >mode_exec_file_1 && + + git status -s ":(attr:builtin_objectmode=100644)mode_exec_*" >actual && + echo ?? mode_exec_file_1 >expect && + test_cmp expect actual && + + git add mode_exec_file_1 && + chmod +x mode_exec_file_1 && + git status -s ":(attr:builtin_objectmode=100755)mode_exec_*" >actual && + echo AM mode_exec_file_1 >expect && + test_cmp expect actual +' + +test_expect_success POSIXPERM 'builtin_objectmode attr can be excluded' ' + >mode_1_regular && + >mode_1_exec && + chmod +x mode_1_exec && + git status -s ":(exclude,attr:builtin_objectmode=100644)" "mode_1_*" >actual && + echo ?? mode_1_exec >expect && + test_cmp expect actual && + + git status -s ":(exclude,attr:builtin_objectmode=100755)" "mode_1_*" >actual && + echo ?? mode_1_regular >expect && + test_cmp expect actual +' + test_done diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh index 78503158fd..363f9dc0e4 100755 --- a/t/t7527-builtin-fsmonitor.sh +++ b/t/t7527-builtin-fsmonitor.sh @@ -978,7 +978,7 @@ test_expect_success !UNICODE_COMPOSITION_SENSITIVE 'Unicode nfc/nfd' ' mkdir test_unicode/nfd && mkdir test_unicode/nfd/d_${utf8_nfd} && - git -C test_unicode fsmonitor--daemon stop && + test-tool -C test_unicode fsmonitor-client query --token 0 && if test_have_prereq UNICODE_NFC_PRESERVED then diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 0333065d4d..7679780fb8 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -627,6 +627,7 @@ test_expect_success \ test_expect_success 'setup' ' version=$(git config core.repositoryformatversion) && algo=$(test_might_fail git config extensions.objectformat) && + refstorage=$(test_might_fail git config extensions.refstorage) && cat >.git/config <<-\EOF && # testing noval and alternate separator [gitweb] @@ -637,6 +638,10 @@ test_expect_success 'setup' ' if test -n "$algo" then git config extensions.objectformat "$algo" + fi && + if test -n "$refstorage" + then + git config extensions.refstorage "$refstorage" fi ' diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index aa9a614de3..35eb534fdd 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -5,6 +5,12 @@ test_description='test bash completion' +# The Bash completion scripts must not print anything to either stdout or +# stderr, which we try to verify. When tracing is enabled without support for +# BASH_XTRACEFD this assertion will fail, so we have to mark the test as +# untraceable with such ancient Bash versions. +test_untraceable=UnfortunatelyYes + . ./lib-bash.sh complete () @@ -87,9 +93,11 @@ test_completion () else sed -e 's/Z$//' |sort >expected fi && - run_completion "$1" && + run_completion "$1" >"$TRASH_DIRECTORY"/bash-completion-output 2>&1 && sort out >out_sorted && - test_cmp expected out_sorted + test_cmp expected out_sorted && + test_must_be_empty "$TRASH_DIRECTORY"/bash-completion-output && + rm "$TRASH_DIRECTORY"/bash-completion-output } # Test __gitcomp. @@ -1925,6 +1933,14 @@ test_expect_success 'git checkout - --orphan with branch already provided comple EOF ' +test_expect_success 'git restore completes modified files' ' + test_commit A a.file && + echo B >a.file && + test_completion "git restore a." <<-\EOF + a.file + EOF +' + test_expect_success 'teardown after ref completion' ' git branch -d matching-branch && git tag -d matching-tag && @@ -2720,4 +2736,31 @@ test_expect_success '__git_complete' ' test_must_fail __git_complete ga missing ' +test_expect_success '__git_pseudoref_exists' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + sane_unset __git_repo_path && + + # HEAD should exist, even if it points to an unborn branch. + __git_pseudoref_exists HEAD >output 2>&1 && + test_must_be_empty output && + + # HEAD points to an existing branch, so it should exist. + test_commit A && + __git_pseudoref_exists HEAD >output 2>&1 && + test_must_be_empty output && + + # CHERRY_PICK_HEAD does not exist, so the existence check should fail. + ! __git_pseudoref_exists CHERRY_PICK_HEAD >output 2>&1 && + test_must_be_empty output && + + # CHERRY_PICK_HEAD points to a commit, so it should exist. + git update-ref CHERRY_PICK_HEAD A && + __git_pseudoref_exists CHERRY_PICK_HEAD >output 2>&1 && + test_must_be_empty output + ) +' + test_done diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 5eb57914ab..b5eaf7fdc1 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -1659,6 +1659,11 @@ test_detect_hash () { test_hash_algo="${GIT_TEST_DEFAULT_HASH:-sha1}" } +# Detect the hash algorithm in use. +test_detect_ref_format () { + echo "${GIT_TEST_DEFAULT_REF_FORMAT:-files}" +} + # Load common hash metadata and common placeholder object IDs for use with # test_oid. test_oid_init () { @@ -1874,6 +1879,20 @@ test_region () { return 0 } +# Check that the given data fragment was included as part of the +# trace2-format trace on stdin. +# +# test_trace2_data <category> <key> <value> +# +# For example, to look for trace2_data_intmax("pack-objects", repo, +# "reused", N) in an invocation of "git pack-objects", run: +# +# GIT_TRACE2_EVENT="$(pwd)/trace.txt" git pack-objects ... && +# test_trace2_data pack-objects reused N <trace2.txt +test_trace2_data () { + grep -e '"category":"'"$1"'","key":"'"$2"'","value":"'"$3"'"' +} + # Given a GIT_TRACE2_EVENT log over stdin, writes to stdout a list of URLs # sent to git-remote-https child processes. test_remote_https_urls() { diff --git a/t/test-lib.sh b/t/test-lib.sh index 876b99562a..fc93aa57e6 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -542,6 +542,8 @@ export EDITOR GIT_DEFAULT_HASH="${GIT_TEST_DEFAULT_HASH:-sha1}" export GIT_DEFAULT_HASH +GIT_DEFAULT_REF_FORMAT="${GIT_TEST_DEFAULT_REF_FORMAT:-files}" +export GIT_DEFAULT_REF_FORMAT GIT_TEST_MERGE_ALGORITHM="${GIT_TEST_MERGE_ALGORITHM:-ort}" export GIT_TEST_MERGE_ALGORITHM @@ -1745,7 +1747,14 @@ parisc* | hppa*) ;; esac -test_set_prereq REFFILES +case "$GIT_DEFAULT_REF_FORMAT" in +files) + test_set_prereq REFFILES;; +*) + echo 2>&1 "error: unknown ref format $GIT_DEFAULT_REF_FORMAT" + exit 1 + ;; +esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_CURL" && test_set_prereq LIBCURL @@ -1936,6 +1945,10 @@ test_lazy_prereq SHA1 ' esac ' +test_lazy_prereq DEFAULT_REPO_FORMAT ' + test_have_prereq SHA1,REFFILES +' + # Ensure that no test accidentally triggers a Git command # that runs the actual maintenance scheduler, affecting a user's # system permanently. diff --git a/t/unit-tests/t-ctype.c b/t/unit-tests/t-ctype.c new file mode 100644 index 0000000000..f315489984 --- /dev/null +++ b/t/unit-tests/t-ctype.c @@ -0,0 +1,80 @@ +#include "test-lib.h" + +static int is_in(const char *s, int ch) +{ + /* + * We can't find NUL using strchr. Accept it as the first + * character in the spec -- there are no empty classes. + */ + if (ch == '\0') + return ch == *s; + if (*s == '\0') + s++; + return !!strchr(s, ch); +} + +/* Macro to test a character type */ +#define TEST_CTYPE_FUNC(func, string) \ +static void test_ctype_##func(void) { \ + for (int i = 0; i < 256; i++) { \ + if (!check_int(func(i), ==, is_in(string, i))) \ + test_msg(" i: 0x%02x", i); \ + } \ + if (!check(!func(EOF))) \ + test_msg(" i: 0x%02x (EOF)", EOF); \ +} + +#define TEST_CHAR_CLASS(class) TEST(test_ctype_##class(), #class " works") + +#define DIGIT "0123456789" +#define LOWER "abcdefghijklmnopqrstuvwxyz" +#define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define PUNCT "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" +#define ASCII \ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ + "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f" \ + "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f" \ + "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f" \ + "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f" \ + "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f" \ + "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f" +#define CNTRL \ + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" \ + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" \ + "\x7f" + +TEST_CTYPE_FUNC(isdigit, DIGIT) +TEST_CTYPE_FUNC(isspace, " \n\r\t") +TEST_CTYPE_FUNC(isalpha, LOWER UPPER) +TEST_CTYPE_FUNC(isalnum, LOWER UPPER DIGIT) +TEST_CTYPE_FUNC(is_glob_special, "*?[\\") +TEST_CTYPE_FUNC(is_regex_special, "$()*+.?[\\^{|") +TEST_CTYPE_FUNC(is_pathspec_magic, "!\"#%&',-/:;<=>@_`~") +TEST_CTYPE_FUNC(isascii, ASCII) +TEST_CTYPE_FUNC(islower, LOWER) +TEST_CTYPE_FUNC(isupper, UPPER) +TEST_CTYPE_FUNC(iscntrl, CNTRL) +TEST_CTYPE_FUNC(ispunct, PUNCT) +TEST_CTYPE_FUNC(isxdigit, DIGIT "abcdefABCDEF") +TEST_CTYPE_FUNC(isprint, LOWER UPPER DIGIT PUNCT " ") + +int cmd_main(int argc, const char **argv) { + /* Run all character type tests */ + TEST_CHAR_CLASS(isspace); + TEST_CHAR_CLASS(isdigit); + TEST_CHAR_CLASS(isalpha); + TEST_CHAR_CLASS(isalnum); + TEST_CHAR_CLASS(is_glob_special); + TEST_CHAR_CLASS(is_regex_special); + TEST_CHAR_CLASS(is_pathspec_magic); + TEST_CHAR_CLASS(isascii); + TEST_CHAR_CLASS(islower); + TEST_CHAR_CLASS(isupper); + TEST_CHAR_CLASS(iscntrl); + TEST_CHAR_CLASS(ispunct); + TEST_CHAR_CLASS(isxdigit); + TEST_CHAR_CLASS(isprint); + + return test_done(); +} |
