diff options
Diffstat (limited to 't')
347 files changed, 3965 insertions, 1648 deletions
diff --git a/t/.gitattributes b/t/.gitattributes index dafa17c3e6..9930e28351 100644 --- a/t/.gitattributes +++ b/t/.gitattributes @@ -1,6 +1,5 @@ t[0-9][0-9][0-9][0-9]/* -whitespace /chainlint/*.expect eol=lf -/lib-diff/* eol=lf /t0110/url-* binary /t3206/* eol=lf /t3900/*.txt eol=lf @@ -463,11 +463,14 @@ GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=<boolean>, when true, makes registering submodule ODBs as alternates a fatal action. Support for this environment variable can be removed once the migration to explicitly providing repositories when accessing submodule objects is -complete (in which case we might want to replace this with a trace2 -call so that users can make it visible if accessing submodule objects -without an explicit repository still happens) or needs to be abandoned -for whatever reason (in which case the migrated codepaths still retain -their performance benefits). +complete or needs to be abandoned for whatever reason (in which case the +migrated codepaths still retain their performance benefits). + +GIT_TEST_REQUIRE_PREREQ=<list> allows specifying a space speparated list of +prereqs that are required to succeed. If a prereq in this list is triggered by +a test and then fails then the whole test run will abort. This can help to make +sure the expected tests are executed and not silently skipped when their +dependency breaks or is simply not present in a new environment. Naming Tests ------------ diff --git a/t/aggregate-results.sh b/t/aggregate-results.sh index 7913e206ed..7f2b83bdc8 100755 --- a/t/aggregate-results.sh +++ b/t/aggregate-results.sh @@ -6,6 +6,7 @@ success=0 failed=0 broken=0 total=0 +missing_prereq= while read file do @@ -30,10 +31,26 @@ do broken=$(($broken + $value)) ;; total) total=$(($total + $value)) ;; + missing_prereq) + missing_prereq="$missing_prereq,$value" ;; esac done <"$file" done +if test -n "$missing_prereq" +then + unique_missing_prereq=$( + echo $missing_prereq | + tr -s "," "\n" | + grep -v '^$' | + sort -u | + paste -s -d ' ') + if test -n "$unique_missing_prereq" + then + printf "\nmissing prereq: $unique_missing_prereq\n\n" + fi +fi + if test -n "$failed_tests" then printf "\nfailed test(s):$failed_tests\n\n" diff --git a/t/helper/test-genzeros.c b/t/helper/test-genzeros.c index 9532f5bac9..8ca988d621 100644 --- a/t/helper/test-genzeros.c +++ b/t/helper/test-genzeros.c @@ -3,18 +3,31 @@ int cmd__genzeros(int argc, const char **argv) { - long count; + /* static, so that it is NUL-initialized */ + static const char zeros[256 * 1024]; + intmax_t count; + ssize_t n; if (argc > 2) { fprintf(stderr, "usage: %s [<count>]\n", argv[0]); return 1; } - count = argc > 1 ? strtol(argv[1], NULL, 0) : -1L; + count = argc > 1 ? strtoimax(argv[1], NULL, 0) : -1; - while (count < 0 || count--) { - if (putchar(0) == EOF) + /* Writing out individual NUL bytes is slow... */ + while (count < 0) + if (write(1, zeros, ARRAY_SIZE(zeros)) < 0) return -1; + + while (count > 0) { + n = write(1, zeros, count < ARRAY_SIZE(zeros) ? + count : ARRAY_SIZE(zeros)); + + if (n < 0) + return -1; + + count -= n; } return 0; diff --git a/t/helper/test-mergesort.c b/t/helper/test-mergesort.c index c5cffaa4b7..ebf68f7de8 100644 --- a/t/helper/test-mergesort.c +++ b/t/helper/test-mergesort.c @@ -2,6 +2,12 @@ #include "cache.h" #include "mergesort.h" +static uint32_t minstd_rand(uint32_t *state) +{ + *state = (uint64_t)*state * 48271 % 2147483647; + return *state; +} + struct line { char *text; struct line *next; @@ -23,14 +29,12 @@ static int compare_strings(const void *a, const void *b) return strcmp(x->text, y->text); } -int cmd__mergesort(int argc, const char **argv) +static int sort_stdin(void) { struct line *line, *p = NULL, *lines = NULL; struct strbuf sb = STRBUF_INIT; - for (;;) { - if (strbuf_getwholeline(&sb, stdin, '\n')) - break; + while (!strbuf_getline(&sb, stdin)) { line = xmalloc(sizeof(struct line)); line->text = strbuf_detach(&sb, NULL); if (p) { @@ -46,8 +50,362 @@ int cmd__mergesort(int argc, const char **argv) lines = llist_mergesort(lines, get_next, set_next, compare_strings); while (lines) { - printf("%s", lines->text); + puts(lines->text); lines = lines->next; } return 0; } + +static void dist_sawtooth(int *arr, int n, int m) +{ + int i; + for (i = 0; i < n; i++) + arr[i] = i % m; +} + +static void dist_rand(int *arr, int n, int m) +{ + int i; + uint32_t seed = 1; + for (i = 0; i < n; i++) + arr[i] = minstd_rand(&seed) % m; +} + +static void dist_stagger(int *arr, int n, int m) +{ + int i; + for (i = 0; i < n; i++) + arr[i] = (i * m + i) % n; +} + +static void dist_plateau(int *arr, int n, int m) +{ + int i; + for (i = 0; i < n; i++) + arr[i] = (i < m) ? i : m; +} + +static void dist_shuffle(int *arr, int n, int m) +{ + int i, j, k; + uint32_t seed = 1; + for (i = j = 0, k = 1; i < n; i++) + arr[i] = minstd_rand(&seed) % m ? (j += 2) : (k += 2); +} + +#define DIST(name) { #name, dist_##name } + +static struct dist { + const char *name; + void (*fn)(int *arr, int n, int m); +} dist[] = { + DIST(sawtooth), + DIST(rand), + DIST(stagger), + DIST(plateau), + DIST(shuffle), +}; + +static const struct dist *get_dist_by_name(const char *name) +{ + int i; + for (i = 0; i < ARRAY_SIZE(dist); i++) { + if (!strcmp(dist[i].name, name)) + return &dist[i]; + } + return NULL; +} + +static void mode_copy(int *arr, int n) +{ + /* nothing */ +} + +static void mode_reverse(int *arr, int n) +{ + int i, j; + for (i = 0, j = n - 1; i < j; i++, j--) + SWAP(arr[i], arr[j]); +} + +static void mode_reverse_1st_half(int *arr, int n) +{ + mode_reverse(arr, n / 2); +} + +static void mode_reverse_2nd_half(int *arr, int n) +{ + int half = n / 2; + mode_reverse(arr + half, n - half); +} + +static int compare_ints(const void *av, const void *bv) +{ + const int *ap = av, *bp = bv; + int a = *ap, b = *bp; + return (a > b) - (a < b); +} + +static void mode_sort(int *arr, int n) +{ + QSORT(arr, n, compare_ints); +} + +static void mode_dither(int *arr, int n) +{ + int i; + for (i = 0; i < n; i++) + arr[i] += i % 5; +} + +static void unriffle(int *arr, int n, int *tmp) +{ + int i, j; + COPY_ARRAY(tmp, arr, n); + for (i = j = 0; i < n; i += 2) + arr[j++] = tmp[i]; + for (i = 1; i < n; i += 2) + arr[j++] = tmp[i]; +} + +static void unriffle_recursively(int *arr, int n, int *tmp) +{ + if (n > 1) { + int half = n / 2; + unriffle(arr, n, tmp); + unriffle_recursively(arr, half, tmp); + unriffle_recursively(arr + half, n - half, tmp); + } +} + +static void mode_unriffle(int *arr, int n) +{ + int *tmp; + ALLOC_ARRAY(tmp, n); + unriffle_recursively(arr, n, tmp); + free(tmp); +} + +static unsigned int prev_pow2(unsigned int n) +{ + unsigned int pow2 = 1; + while (pow2 * 2 < n) + pow2 *= 2; + return pow2; +} + +static void unriffle_recursively_skewed(int *arr, int n, int *tmp) +{ + if (n > 1) { + int pow2 = prev_pow2(n); + int rest = n - pow2; + unriffle(arr + pow2 - rest, rest * 2, tmp); + unriffle_recursively_skewed(arr, pow2, tmp); + unriffle_recursively_skewed(arr + pow2, rest, tmp); + } +} + +static void mode_unriffle_skewed(int *arr, int n) +{ + int *tmp; + ALLOC_ARRAY(tmp, n); + unriffle_recursively_skewed(arr, n, tmp); + free(tmp); +} + +#define MODE(name) { #name, mode_##name } + +static struct mode { + const char *name; + void (*fn)(int *arr, int n); +} mode[] = { + MODE(copy), + MODE(reverse), + MODE(reverse_1st_half), + MODE(reverse_2nd_half), + MODE(sort), + MODE(dither), + MODE(unriffle), + MODE(unriffle_skewed), +}; + +static const struct mode *get_mode_by_name(const char *name) +{ + int i; + for (i = 0; i < ARRAY_SIZE(mode); i++) { + if (!strcmp(mode[i].name, name)) + return &mode[i]; + } + return NULL; +} + +static int generate(int argc, const char **argv) +{ + const struct dist *dist = NULL; + const struct mode *mode = NULL; + int i, n, m, *arr; + + if (argc != 4) + return 1; + + dist = get_dist_by_name(argv[0]); + mode = get_mode_by_name(argv[1]); + n = strtol(argv[2], NULL, 10); + m = strtol(argv[3], NULL, 10); + if (!dist || !mode) + return 1; + + ALLOC_ARRAY(arr, n); + dist->fn(arr, n, m); + mode->fn(arr, n); + for (i = 0; i < n; i++) + printf("%08x\n", arr[i]); + free(arr); + return 0; +} + +static struct stats { + int get_next, set_next, compare; +} stats; + +struct number { + int value, rank; + struct number *next; +}; + +static void *get_next_number(const void *a) +{ + stats.get_next++; + return ((const struct number *)a)->next; +} + +static void set_next_number(void *a, void *b) +{ + stats.set_next++; + ((struct number *)a)->next = b; +} + +static int compare_numbers(const void *av, const void *bv) +{ + const struct number *an = av, *bn = bv; + int a = an->value, b = bn->value; + stats.compare++; + return (a > b) - (a < b); +} + +static void clear_numbers(struct number *list) +{ + while (list) { + struct number *next = list->next; + free(list); + list = next; + } +} + +static int test(const struct dist *dist, const struct mode *mode, int n, int m) +{ + int *arr; + size_t i; + struct number *curr, *list, **tail; + int is_sorted = 1; + int is_stable = 1; + const char *verdict; + int result = -1; + + ALLOC_ARRAY(arr, n); + dist->fn(arr, n, m); + mode->fn(arr, n); + for (i = 0, tail = &list; i < n; i++) { + curr = xmalloc(sizeof(*curr)); + curr->value = arr[i]; + curr->rank = i; + *tail = curr; + tail = &curr->next; + } + *tail = NULL; + + stats.get_next = stats.set_next = stats.compare = 0; + list = llist_mergesort(list, get_next_number, set_next_number, + compare_numbers); + + QSORT(arr, n, compare_ints); + for (i = 0, curr = list; i < n && curr; i++, curr = curr->next) { + if (arr[i] != curr->value) + is_sorted = 0; + if (curr->next && curr->value == curr->next->value && + curr->rank >= curr->next->rank) + is_stable = 0; + } + if (i < n) { + verdict = "too short"; + } else if (curr) { + verdict = "too long"; + } else if (!is_sorted) { + verdict = "not sorted"; + } else if (!is_stable) { + verdict = "unstable"; + } else { + verdict = "OK"; + result = 0; + } + + printf("%-9s %-16s %8d %8d %8d %8d %8d %s\n", + dist->name, mode->name, n, m, stats.get_next, stats.set_next, + stats.compare, verdict); + + clear_numbers(list); + free(arr); + + return result; +} + +/* + * A version of the qsort certification program from "Engineering a Sort + * Function" by Bentley and McIlroy, Software—Practice and Experience, + * Volume 23, Issue 11, 1249–1265 (November 1993). + */ +static int run_tests(int argc, const char **argv) +{ + const char *argv_default[] = { "100", "1023", "1024", "1025" }; + if (!argc) + return run_tests(ARRAY_SIZE(argv_default), argv_default); + printf("%-9s %-16s %8s %8s %8s %8s %8s %s\n", + "distribut", "mode", "n", "m", "get_next", "set_next", + "compare", "verdict"); + while (argc--) { + int i, j, m, n = strtol(*argv++, NULL, 10); + for (i = 0; i < ARRAY_SIZE(dist); i++) { + for (j = 0; j < ARRAY_SIZE(mode); j++) { + for (m = 1; m < 2 * n; m *= 2) { + if (test(&dist[i], &mode[j], n, m)) + return 1; + } + } + } + } + return 0; +} + +int cmd__mergesort(int argc, const char **argv) +{ + int i; + const char *sep; + + if (argc == 6 && !strcmp(argv[1], "generate")) + return generate(argc - 2, argv + 2); + if (argc == 2 && !strcmp(argv[1], "sort")) + return sort_stdin(); + if (argc > 1 && !strcmp(argv[1], "test")) + return run_tests(argc - 2, argv + 2); + fprintf(stderr, "usage: test-tool mergesort generate <distribution> <mode> <n> <m>\n"); + fprintf(stderr, " or: test-tool mergesort sort\n"); + fprintf(stderr, " or: test-tool mergesort test [<n>...]\n"); + fprintf(stderr, "\n"); + for (i = 0, sep = "distributions: "; i < ARRAY_SIZE(dist); i++, sep = ", ") + fprintf(stderr, "%s%s", sep, dist[i].name); + fprintf(stderr, "\n"); + for (i = 0, sep = "modes: "; i < ARRAY_SIZE(mode); i++, sep = ", ") + fprintf(stderr, "%s%s", sep, mode[i].name); + fprintf(stderr, "\n"); + return 129; +} diff --git a/t/helper/test-oid-array.c b/t/helper/test-oid-array.c index b16cd0b11b..d1324d086a 100644 --- a/t/helper/test-oid-array.c +++ b/t/helper/test-oid-array.c @@ -35,5 +35,9 @@ int cmd__oid_array(int argc, const char **argv) else die("unknown command: %s", line.buf); } + + strbuf_release(&line); + oid_array_clear(&array); + return 0; } diff --git a/t/helper/test-oidtree.c b/t/helper/test-oidtree.c index 180ee28dd9..d48a409f4e 100644 --- a/t/helper/test-oidtree.c +++ b/t/helper/test-oidtree.c @@ -45,5 +45,8 @@ int cmd__oidtree(int argc, const char **argv) die("unknown command: %s", line.buf); } } + + strbuf_release(&line); + return 0; } diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c index a282b6ff13..48d3cf6692 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -14,7 +14,6 @@ static int dry_run = 0, quiet = 0; static char *string = NULL; static char *file = NULL; static int ambiguous; -static struct string_list list = STRING_LIST_INIT_NODUP; static struct { int called; @@ -107,6 +106,8 @@ int cmd__parse_options(int argc, const char **argv) NULL }; struct string_list expect = STRING_LIST_INIT_NODUP; + struct string_list list = STRING_LIST_INIT_NODUP; + struct option options[] = { OPT_BOOL(0, "yes", &boolean, "get a boolean"), OPT_BOOL('D', "no-doubt", &boolean, "begins with 'no-'"), @@ -185,5 +186,9 @@ int cmd__parse_options(int argc, const char **argv) for (i = 0; i < argc; i++) show(&expect, &ret, "arg %02d: %s", i, argv[i]); + expect.strdup_strings = 1; + string_list_clear(&expect, 0); + string_list_clear(&list, 0); + return ret; } diff --git a/t/helper/test-prio-queue.c b/t/helper/test-prio-queue.c index f4028442e3..133b5e6f4a 100644 --- a/t/helper/test-prio-queue.c +++ b/t/helper/test-prio-queue.c @@ -46,5 +46,7 @@ int cmd__prio_queue(int argc, const char **argv) } } + clear_prio_queue(&pq); + return 0; } diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index cb0d27049a..27072ba94d 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -3,6 +3,7 @@ #include "midx.h" #include "repository.h" #include "object-store.h" +#include "pack-bitmap.h" static int read_midx_file(const char *object_dir, int show_objects) { @@ -54,9 +55,10 @@ static int read_midx_file(const char *object_dir, int show_objects) printf("%s %"PRIu64"\t%s\n", oid_to_hex(&oid), e.offset, e.p->pack_name); } - return 0; } + close_midx(m); + return 0; } @@ -72,14 +74,40 @@ static int read_midx_checksum(const char *object_dir) return 0; } +static int read_midx_preferred_pack(const char *object_dir) +{ + struct multi_pack_index *midx = NULL; + struct bitmap_index *bitmap = NULL; + + setup_git_directory(); + + midx = load_multi_pack_index(object_dir, 1); + if (!midx) + return 1; + + bitmap = prepare_bitmap_git(the_repository); + if (!bitmap) + return 1; + if (!bitmap_is_midx(bitmap)) { + free_bitmap_index(bitmap); + return 1; + } + + printf("%s\n", midx->pack_names[midx_preferred_pack(bitmap)]); + free_bitmap_index(bitmap); + return 0; +} + int cmd__read_midx(int argc, const char **argv) { if (!(argc == 2 || argc == 3)) - usage("read-midx [--show-objects|--checksum] <object-dir>"); + usage("read-midx [--show-objects|--checksum|--preferred-pack] <object-dir>"); if (!strcmp(argv[1], "--show-objects")) return read_midx_file(argv[2], 1); else if (!strcmp(argv[1], "--checksum")) return read_midx_checksum(argv[2]); + else if (!strcmp(argv[1], "--preferred-pack")) + return read_midx_preferred_pack(argv[2]); return read_midx_file(argv[1], 0); } diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index b314b81a45..24dd4bec08 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -5,6 +5,48 @@ #include "object-store.h" #include "repository.h" +struct flag_definition { + const char *name; + uint64_t mask; +}; + +#define FLAG_DEF(x) \ + { \ +#x, (x) \ + } + +static unsigned int parse_flags(const char *str, struct flag_definition *defs) +{ + struct string_list masks = STRING_LIST_INIT_DUP; + int i = 0; + unsigned int result = 0; + + if (!strcmp(str, "0")) + return 0; + + string_list_split(&masks, str, ',', 64); + for (; i < masks.nr; i++) { + const char *name = masks.items[i].string; + struct flag_definition *def = defs; + int found = 0; + while (def->name) { + if (!strcmp(def->name, name)) { + result |= def->mask; + found = 1; + break; + } + def++; + } + if (!found) + die("unknown flag \"%s\"", name); + } + + string_list_clear(&masks, 0); + return result; +} + +static struct flag_definition empty_flags[] = { { NULL, 0 } }; + static const char *notnull(const char *arg, const char *name) { if (!arg) @@ -12,9 +54,10 @@ static const char *notnull(const char *arg, const char *name) return arg; } -static unsigned int arg_flags(const char *arg, const char *name) +static unsigned int arg_flags(const char *arg, const char *name, + struct flag_definition *defs) { - return atoi(notnull(arg, name)); + return parse_flags(notnull(arg, name), defs); } static const char **get_store(const char **argv, struct ref_store **refs) @@ -64,10 +107,13 @@ static const char **get_store(const char **argv, struct ref_store **refs) return argv + 1; } +static struct flag_definition pack_flags[] = { FLAG_DEF(PACK_REFS_PRUNE), + FLAG_DEF(PACK_REFS_ALL), + { NULL, 0 } }; static int cmd_pack_refs(struct ref_store *refs, const char **argv) { - unsigned int flags = arg_flags(*argv++, "flags"); + unsigned int flags = arg_flags(*argv++, "flags", pack_flags); return refs_pack_refs(refs, flags); } @@ -81,16 +127,27 @@ static int cmd_create_symref(struct ref_store *refs, const char **argv) return refs_create_symref(refs, refname, target, logmsg); } +static struct flag_definition transaction_flags[] = { + FLAG_DEF(REF_NO_DEREF), + FLAG_DEF(REF_FORCE_CREATE_REFLOG), + FLAG_DEF(REF_SKIP_OID_VERIFICATION), + FLAG_DEF(REF_SKIP_REFNAME_VERIFICATION), + { NULL, 0 } +}; + static int cmd_delete_refs(struct ref_store *refs, const char **argv) { - unsigned int flags = arg_flags(*argv++, "flags"); + unsigned int flags = arg_flags(*argv++, "flags", transaction_flags); const char *msg = *argv++; struct string_list refnames = STRING_LIST_INIT_NODUP; + int result; while (*argv) string_list_append(&refnames, *argv++); - return refs_delete_refs(refs, msg, &refnames, flags); + result = refs_delete_refs(refs, msg, &refnames, flags); + string_list_clear(&refnames, 0); + return result; } static int cmd_rename_ref(struct ref_store *refs, const char **argv) @@ -120,12 +177,13 @@ static int cmd_resolve_ref(struct ref_store *refs, const char **argv) { struct object_id oid = *null_oid(); const char *refname = notnull(*argv++, "refname"); - int resolve_flags = arg_flags(*argv++, "resolve-flags"); + int resolve_flags = arg_flags(*argv++, "resolve-flags", empty_flags); int flags; const char *ref; + int ignore_errno; ref = refs_resolve_ref_unsafe(refs, refname, resolve_flags, - &oid, &flags); + &oid, &flags, &ignore_errno); printf("%s %s 0x%x\n", oid_to_hex(&oid), ref ? ref : "(null)", flags); return ref ? 0 : 1; } @@ -151,9 +209,9 @@ static int each_reflog(struct object_id *old_oid, struct object_id *new_oid, const char *committer, timestamp_t timestamp, int tz, const char *msg, void *cb_data) { - printf("%s %s %s %"PRItime" %d %s\n", - oid_to_hex(old_oid), oid_to_hex(new_oid), - committer, timestamp, tz, msg); + printf("%s %s %s %" PRItime " %+05d%s%s", oid_to_hex(old_oid), + oid_to_hex(new_oid), committer, timestamp, tz, + *msg == '\n' ? "" : "\t", msg); return 0; } @@ -181,11 +239,10 @@ static int cmd_reflog_exists(struct ref_store *refs, const char **argv) static int cmd_create_reflog(struct ref_store *refs, const char **argv) { const char *refname = notnull(*argv++, "refname"); - int force_create = arg_flags(*argv++, "force-create"); struct strbuf err = STRBUF_INIT; int ret; - ret = refs_create_reflog(refs, refname, force_create, &err); + ret = refs_create_reflog(refs, refname, &err); if (err.len) puts(err.buf); return ret; @@ -208,7 +265,7 @@ static int cmd_delete_ref(struct ref_store *refs, const char **argv) const char *msg = notnull(*argv++, "msg"); const char *refname = notnull(*argv++, "refname"); const char *sha1_buf = notnull(*argv++, "old-sha1"); - unsigned int flags = arg_flags(*argv++, "flags"); + unsigned int flags = arg_flags(*argv++, "flags", transaction_flags); struct object_id old_oid; if (get_oid_hex(sha1_buf, &old_oid)) @@ -223,7 +280,7 @@ static int cmd_update_ref(struct ref_store *refs, const char **argv) const char *refname = notnull(*argv++, "refname"); 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"); + unsigned int flags = arg_flags(*argv++, "flags", transaction_flags); struct object_id old_oid; struct object_id new_oid; diff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c new file mode 100644 index 0000000000..26b03d7b78 --- /dev/null +++ b/t/helper/test-reftable.c @@ -0,0 +1,21 @@ +#include "reftable/reftable-tests.h" +#include "test-tool.h" + +int cmd__reftable(int argc, const char **argv) +{ + basics_test_main(argc, argv); + block_test_main(argc, argv); + merged_test_main(argc, argv); + pq_test_main(argc, argv); + record_test_main(argc, argv); + refname_test_main(argc, argv); + readwrite_test_main(argc, argv); + stack_test_main(argc, argv); + tree_test_main(argc, argv); + return 0; +} + +int cmd__dump_reftable(int argc, const char **argv) +{ + return reftable_dump_main(argc, (char *const *)argv); +} diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index 3c4fb86223..913775a14b 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -31,7 +31,7 @@ static int parallel_next(struct child_process *cp, if (number_callbacks >= 4) return 0; - strvec_pushv(&cp->args, d->argv); + strvec_pushv(&cp->args, d->args.v); strbuf_addstr(err, "preloaded output of a child\n"); number_callbacks++; return 1; @@ -274,7 +274,7 @@ static int quote_stress_test(int argc, const char **argv) if (i < skip) continue; - cp.argv = args.v; + strvec_pushv(&cp.args, args.v); strbuf_reset(&out); if (pipe_command(&cp, NULL, 0, &out, 0, NULL, 0) < 0) return error("Failed to spawn child process"); @@ -396,7 +396,7 @@ int cmd__run_command(int argc, const char **argv) } if (argc < 3) return 1; - proc.argv = (const char **)argv + 2; + strvec_pushv(&proc.args, (const char **)argv + 2); if (!strcmp(argv[1], "start-command-ENOENT")) { if (start_command(&proc) < 0 && errno == ENOENT) @@ -408,7 +408,8 @@ int cmd__run_command(int argc, const char **argv) exit(run_command(&proc)); jobs = atoi(argv[2]); - proc.argv = (const char **)argv + 3; + strvec_clear(&proc.args); + strvec_pushv(&proc.args, (const char **)argv + 3); if (!strcmp(argv[1], "run-command-parallel")) exit(run_processes_parallel(jobs, parallel_next, diff --git a/t/helper/test-subprocess.c b/t/helper/test-subprocess.c index 92b69de635..ff22f2fa2c 100644 --- a/t/helper/test-subprocess.c +++ b/t/helper/test-subprocess.c @@ -15,6 +15,6 @@ int cmd__subprocess(int argc, const char **argv) argv++; } cp.git_cmd = 1; - cp.argv = (const char **)argv + 1; + strvec_pushv(&cp.args, (const char **)argv + 1); return run_command(&cp); } diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 3ce5585e53..338a57b104 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -53,13 +53,15 @@ static struct test_cmd cmds[] = { { "pcre2-config", cmd__pcre2_config }, { "pkt-line", cmd__pkt_line }, { "prio-queue", cmd__prio_queue }, - { "proc-receive", cmd__proc_receive}, + { "proc-receive", cmd__proc_receive }, { "progress", cmd__progress }, { "reach", cmd__reach }, { "read-cache", cmd__read_cache }, { "read-graph", cmd__read_graph }, { "read-midx", cmd__read_midx }, { "ref-store", cmd__ref_store }, + { "reftable", cmd__reftable }, + { "dump-reftable", cmd__dump_reftable }, { "regex", cmd__regex }, { "repository", cmd__repository }, { "revision-walking", cmd__revision_walking }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 9f0f522850..48cee1f4a2 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -19,6 +19,7 @@ int cmd__dump_cache_tree(int argc, const char **argv); int cmd__dump_fsmonitor(int argc, const char **argv); int cmd__dump_split_index(int argc, const char **argv); int cmd__dump_untracked_cache(int argc, const char **argv); +int cmd__dump_reftable(int argc, const char **argv); int cmd__example_decorate(int argc, const char **argv); int cmd__fast_rebase(int argc, const char **argv); int cmd__genrandom(int argc, const char **argv); @@ -49,6 +50,7 @@ int cmd__read_cache(int argc, const char **argv); int cmd__read_graph(int argc, const char **argv); int cmd__read_midx(int argc, const char **argv); int cmd__ref_store(int argc, const char **argv); +int cmd__reftable(int argc, const char **argv); int cmd__regex(int argc, const char **argv); int cmd__repository(int argc, const char **argv); int cmd__revision_walking(int argc, const char **argv); diff --git a/t/lib-diff-data.sh b/t/lib-diff-data.sh new file mode 100644 index 0000000000..c64ec18324 --- /dev/null +++ b/t/lib-diff-data.sh @@ -0,0 +1,22 @@ +COPYING_test_data () { + cat <<\EOF + + Note that the only valid version of the GPL as far as this project + is concerned is _this_ particular version of the license (ie v2, not + v2.2 or v3.x or whatever), unless explicitly otherwise stated. + + HOWEVER, in order to allow a migration to GPLv3 if that seems like + a good idea, I also ask that people involved with the project make + their preferences known. In particular, if you trust me to make that + decision, you might note so in your copyright message, ie something + like + + This file is licensed under the GPL v2, or a later version + at the discretion of Linus. + + might avoid issues. But we can also just decide to synchronize and + contact all copyright holders on record if/when the occasion arises. + + Linus Torvalds +EOF +} diff --git a/t/lib-diff.sh b/t/lib-diff.sh index 2de880f7a5..c4606bd4b7 100644 --- a/t/lib-diff.sh +++ b/t/lib-diff.sh @@ -1,3 +1,5 @@ +. "$TEST_DIRECTORY"/lib-diff-data.sh + : sanitize_diff_raw='/^:/s/ '"\($OID_REGEX\)"' '"\($OID_REGEX\)"' \([A-Z]\)[0-9]* / \1 \2 \3# /' diff --git a/t/lib-diff/COPYING b/t/lib-diff/COPYING deleted file mode 100644 index 6ff87c4664..0000000000 --- a/t/lib-diff/COPYING +++ /dev/null @@ -1,361 +0,0 @@ - - Note that the only valid version of the GPL as far as this project - is concerned is _this_ particular version of the license (ie v2, not - v2.2 or v3.x or whatever), unless explicitly otherwise stated. - - HOWEVER, in order to allow a migration to GPLv3 if that seems like - a good idea, I also ask that people involved with the project make - their preferences known. In particular, if you trust me to make that - decision, you might note so in your copyright message, ie something - like - - This file is licensed under the GPL v2, or a later version - at the discretion of Linus. - - might avoid issues. But we can also just decide to synchronize and - contact all copyright holders on record if/when the occasion arises. - - Linus Torvalds - ----------------------------------------- - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/t/lib-diff/README b/t/lib-diff/README deleted file mode 100644 index 548142c327..0000000000 --- a/t/lib-diff/README +++ /dev/null @@ -1,46 +0,0 @@ -//////////////////////////////////////////////////////////////// - - GIT - the stupid content tracker - -//////////////////////////////////////////////////////////////// - -"git" can mean anything, depending on your mood. - - - random three-letter combination that is pronounceable, and not - actually used by any common UNIX command. The fact that it is a - mispronunciation of "get" may or may not be relevant. - - stupid. contemptible and despicable. simple. Take your pick from the - dictionary of slang. - - "global information tracker": you're in a good mood, and it actually - works for you. Angels sing, and a light suddenly fills the room. - - "goddamn idiotic truckload of sh*t": when it breaks - -Git is a fast, scalable, distributed revision control system with an -unusually rich command set that provides both high-level operations -and full access to internals. - -Git is an Open Source project covered by the GNU General Public License. -It was originally written by Linus Torvalds with help of a group of -hackers around the net. It is currently maintained by Junio C Hamano. - -Please read the file INSTALL for installation instructions. -See Documentation/tutorial.txt to get started, then see -Documentation/everyday.txt for a useful minimum set of commands, -and "man git-commandname" for documentation of each command. -CVS users may also want to read Documentation/cvs-migration.txt. - -Many Git online resources are accessible from http://git.or.cz/ -including full documentation and Git related tools. - -The user discussion and development of Git take place on the Git -mailing list -- everyone is welcome to post bug reports, feature -requests, comments and patches to git@vger.kernel.org. To subscribe -to the list, send an email with just "subscribe git" in the body to -majordomo@vger.kernel.org. The mailing list archives are available at -http://marc.theaimsgroup.com/?l=git and other archival sites. - -The messages titled "A note from the maintainer", "What's in -git.git (stable)" and "What's cooking in git.git (topics)" and -the discussion following them on the mailing list give a good -reference for project status, development direction and -remaining tasks. diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh index 9fc5241228..3e7ee1386a 100644 --- a/t/lib-gpg.sh +++ b/t/lib-gpg.sh @@ -87,6 +87,88 @@ test_lazy_prereq RFC1991 ' echo | gpg --homedir "${GNUPGHOME}" -b --rfc1991 >/dev/null ' +GPGSSH_KEY_PRIMARY="${GNUPGHOME}/ed25519_ssh_signing_key" +GPGSSH_KEY_SECONDARY="${GNUPGHOME}/rsa_2048_ssh_signing_key" +GPGSSH_KEY_UNTRUSTED="${GNUPGHOME}/untrusted_ssh_signing_key" +GPGSSH_KEY_EXPIRED="${GNUPGHOME}/expired_ssh_signing_key" +GPGSSH_KEY_NOTYETVALID="${GNUPGHOME}/notyetvalid_ssh_signing_key" +GPGSSH_KEY_TIMEBOXEDVALID="${GNUPGHOME}/timeboxed_valid_ssh_signing_key" +GPGSSH_KEY_TIMEBOXEDINVALID="${GNUPGHOME}/timeboxed_invalid_ssh_signing_key" +GPGSSH_KEY_WITH_PASSPHRASE="${GNUPGHOME}/protected_ssh_signing_key" +GPGSSH_KEY_ECDSA="${GNUPGHOME}/ecdsa_ssh_signing_key" +GPGSSH_KEY_PASSPHRASE="super_secret" +GPGSSH_ALLOWED_SIGNERS="${GNUPGHOME}/ssh.all_valid.allowedSignersFile" + +GPGSSH_GOOD_SIGNATURE_TRUSTED='Good "git" signature for' +GPGSSH_GOOD_SIGNATURE_UNTRUSTED='Good "git" signature with' +GPGSSH_KEY_NOT_TRUSTED="No principal matched" +GPGSSH_BAD_SIGNATURE="Signature verification failed" + +test_lazy_prereq GPGSSH ' + ssh_version=$(ssh-keygen -Y find-principals -n "git" 2>&1) + test $? != 127 || exit 1 + echo $ssh_version | grep -q "find-principals:missing signature file" + test $? = 0 || exit 1; + + # Setup some keys and an allowed signers file + mkdir -p "${GNUPGHOME}" && + chmod 0700 "${GNUPGHOME}" && + (setfacl -k "${GNUPGHOME}" 2>/dev/null || true) && + ssh-keygen -t ed25519 -N "" -C "git ed25519 key" -f "${GPGSSH_KEY_PRIMARY}" >/dev/null && + ssh-keygen -t rsa -b 2048 -N "" -C "git rsa2048 key" -f "${GPGSSH_KEY_SECONDARY}" >/dev/null && + ssh-keygen -t ed25519 -N "${GPGSSH_KEY_PASSPHRASE}" -C "git ed25519 encrypted key" -f "${GPGSSH_KEY_WITH_PASSPHRASE}" >/dev/null && + ssh-keygen -t ecdsa -N "" -f "${GPGSSH_KEY_ECDSA}" >/dev/null && + ssh-keygen -t ed25519 -N "" -C "git ed25519 key" -f "${GPGSSH_KEY_UNTRUSTED}" >/dev/null && + + cat >"${GPGSSH_ALLOWED_SIGNERS}" <<-EOF && + "principal with number 1" $(cat "${GPGSSH_KEY_PRIMARY}.pub")" + "principal with number 2" $(cat "${GPGSSH_KEY_SECONDARY}.pub")" + "principal with number 3" $(cat "${GPGSSH_KEY_WITH_PASSPHRASE}.pub")" + "principal with number 4" $(cat "${GPGSSH_KEY_ECDSA}.pub")" + EOF + + # Verify if at least one key and ssh-keygen works as expected + echo "testpayload" | + ssh-keygen -Y sign -n "git" -f "${GPGSSH_KEY_PRIMARY}" >gpgssh_prereq.sig && + ssh-keygen -Y find-principals -f "${GPGSSH_ALLOWED_SIGNERS}" -s gpgssh_prereq.sig && + echo "testpayload" | + ssh-keygen -Y verify -n "git" -f "${GPGSSH_ALLOWED_SIGNERS}" -I "principal with number 1" -s gpgssh_prereq.sig +' + +test_lazy_prereq GPGSSH_VERIFYTIME ' + # Check if ssh-keygen has a verify-time option by passing an invalid date to it + ssh-keygen -Overify-time=INVALID -Y check-novalidate -s doesnotmatter 2>&1 | grep -q -F "Invalid \"verify-time\"" && + + # Set up keys with key lifetimes + ssh-keygen -t ed25519 -N "" -C "timeboxed valid key" -f "${GPGSSH_KEY_TIMEBOXEDVALID}" >/dev/null && + key_valid=$(cat "${GPGSSH_KEY_TIMEBOXEDVALID}.pub") && + ssh-keygen -t ed25519 -N "" -C "timeboxed invalid key" -f "${GPGSSH_KEY_TIMEBOXEDINVALID}" >/dev/null && + key_invalid=$(cat "${GPGSSH_KEY_TIMEBOXEDINVALID}.pub") && + ssh-keygen -t ed25519 -N "" -C "expired key" -f "${GPGSSH_KEY_EXPIRED}" >/dev/null && + key_expired=$(cat "${GPGSSH_KEY_EXPIRED}.pub") && + ssh-keygen -t ed25519 -N "" -C "not yet valid key" -f "${GPGSSH_KEY_NOTYETVALID}" >/dev/null && + key_notyetvalid=$(cat "${GPGSSH_KEY_NOTYETVALID}.pub") && + + # Timestamps outside of test_tick span + ts2005a=20050401000000 ts2005b=200504020000 && + # Timestamps within test_tick span + ts2005c=20050407000000 ts2005d=200504100000 && + # Definitely not yet valid / expired timestamps + ts2000=20000101000000 ts2999=29990101000000 && + + cat >>"${GPGSSH_ALLOWED_SIGNERS}" <<-EOF && + "timeboxed valid key" valid-after="$ts2005c",valid-before="$ts2005d" $key_valid" + "timeboxed invalid key" valid-after="$ts2005a",valid-before="$ts2005b" $key_invalid" + "principal with expired key" valid-before="$ts2000" $key_expired" + "principal with not yet valid key" valid-after="$ts2999" $key_notyetvalid" + EOF + + # and verify ssh-keygen verifies the key lifetime + echo "testpayload" | + ssh-keygen -Y sign -n "git" -f "${GPGSSH_KEY_EXPIRED}" >gpgssh_verifytime_prereq.sig && + ! (ssh-keygen -Y verify -n "git" -f "${GPGSSH_ALLOWED_SIGNERS}" -I "principal with expired key" -s gpgssh_verifytime_prereq.sig) +' + sanitize_pgp() { perl -ne ' /^-----END PGP/ and $in_pgp = 0; diff --git a/t/lib-httpd.sh b/t/lib-httpd.sh index d2edfa4c50..782891908d 100644 --- a/t/lib-httpd.sh +++ b/t/lib-httpd.sh @@ -131,6 +131,7 @@ prepare_httpd() { cp "$TEST_PATH"/passwd "$HTTPD_ROOT_PATH" install_script incomplete-length-upload-pack-v2-http.sh install_script incomplete-body-upload-pack-v2-http.sh + install_script error-no-report.sh install_script broken-smart-http.sh install_script error-smart-http.sh install_script error.sh diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 180a41fe96..497b9b9d92 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -122,6 +122,7 @@ Alias /auth/dumb/ www/auth/dumb/ </LocationMatch> ScriptAlias /smart/incomplete_length/git-upload-pack incomplete-length-upload-pack-v2-http.sh/ ScriptAlias /smart/incomplete_body/git-upload-pack incomplete-body-upload-pack-v2-http.sh/ +ScriptAlias /smart/no_report/git-receive-pack error-no-report.sh/ ScriptAliasMatch /error_git_upload_pack/(.*)/git-upload-pack error.sh/ ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 ScriptAlias /broken_smart/ broken-smart-http.sh/ @@ -137,6 +138,9 @@ ScriptAliasMatch /one_time_perl/(.*) apply-one-time-perl.sh/$1 <Files incomplete-body-upload-pack-v2-http.sh> Options ExecCGI </Files> +<Files error-no-report.sh> + Options ExecCGI +</Files> <Files broken-smart-http.sh> Options ExecCGI </Files> diff --git a/t/lib-httpd/error-no-report.sh b/t/lib-httpd/error-no-report.sh new file mode 100644 index 0000000000..39ff75bbc4 --- /dev/null +++ b/t/lib-httpd/error-no-report.sh @@ -0,0 +1,6 @@ +echo "Content-Type: application/x-git-receive-pack-result" +echo +printf '0013\001000eunpack ok\n' +printf '0015\002skipping report\n' +printf '0009\0010000' +printf '0000' diff --git a/t/lib-midx.sh b/t/lib-midx.sh new file mode 100644 index 0000000000..1261994744 --- /dev/null +++ b/t/lib-midx.sh @@ -0,0 +1,8 @@ +# test_midx_consistent <objdir> +test_midx_consistent () { + ls $1/pack/pack-*.idx | xargs -n 1 basename | sort >expect && + test-tool read-midx $1 | grep ^pack-.*\.idx$ | sort >actual && + + test_cmp expect actual && + git multi-pack-index --object-dir=$1 verify +} diff --git a/t/oid-info/oid b/t/oid-info/oid index a754970523..7547d2c790 100644 --- a/t/oid-info/oid +++ b/t/oid-info/oid @@ -27,3 +27,5 @@ numeric sha1:0123456789012345678901234567890123456789 numeric sha256:0123456789012345678901234567890123456789012345678901234567890123 deadbeef sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbeef deadbeef sha256:deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef +deadbeef_short sha1:deadbeefdeadbeefdeadbeefdeadbeefdeadbee +deadbeef_short sha256:deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbee diff --git a/t/perf/config b/t/perf/config new file mode 100644 index 0000000000..b92768b039 --- /dev/null +++ b/t/perf/config @@ -0,0 +1,2 @@ +[gc] + auto = 0 diff --git a/t/perf/p0071-sort.sh b/t/perf/p0071-sort.sh index 6e924f5fa3..ed366e2e12 100755 --- a/t/perf/p0071-sort.sh +++ b/t/perf/p0071-sort.sh @@ -11,16 +11,42 @@ test_expect_success 'setup' ' git cat-file --batch >unsorted ' -test_perf 'sort(1)' ' - sort <unsorted >expect +test_perf 'sort(1) unsorted' ' + sort <unsorted >sorted ' -test_perf 'string_list_sort()' ' - test-tool string-list sort <unsorted >actual +test_expect_success 'reverse' ' + sort -r <unsorted >reversed ' -test_expect_success 'string_list_sort() sorts like sort(1)' ' - test_cmp_bin expect actual -' +for file in sorted reversed +do + test_perf "sort(1) $file" " + sort <$file >actual + " +done + +for file in unsorted sorted reversed +do + + test_perf "string_list_sort() $file" " + test-tool string-list sort <$file >actual + " + + test_expect_success "string_list_sort() $file sorts like sort(1)" " + test_cmp_bin sorted actual + " +done + +for file in unsorted sorted reversed +do + test_perf "llist_mergesort() $file" " + test-tool mergesort sort <$file >actual + " + + test_expect_success "llist_mergesort() $file sorts like sort(1)" " + test_cmp_bin sorted actual + " +done test_done diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index f5ed092ee5..780a7402d5 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -27,6 +27,10 @@ TEST_NO_MALLOC_CHECK=t . ../test-lib.sh +unset GIT_CONFIG_NOSYSTEM +GIT_CONFIG_SYSTEM="$TEST_DIRECTORY/perf/config" +export GIT_CONFIG_SYSTEM + if test -n "$GIT_TEST_INSTALLED" -a -z "$PERF_SET_GIT_TEST_INSTALLED" then error "Do not use GIT_TEST_INSTALLED with the perf tests. @@ -230,6 +234,7 @@ test_perf_ () { test_ok_ "$1" fi "$TEST_DIRECTORY"/perf/min_time.perl test_time.* >"$base".result + rm test_time.* } test_perf () { diff --git a/t/t0001-init.sh b/t/t0001-init.sh index df544bb321..7603ad2f82 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -2,6 +2,7 @@ test_description='git init' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_config () { diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index 8440e6add1..76052cb562 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -7,6 +7,7 @@ Verify that plumbing commands work when .git is a file GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh objpath() { diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index 1e4c672b84..b9ed612af1 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -2,6 +2,7 @@ test_description=gitattributes +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh attr_check_basic () { diff --git a/t/t0004-unwritable.sh b/t/t0004-unwritable.sh index 37d68ef03b..2e9d652d82 100755 --- a/t/t0004-unwritable.sh +++ b/t/t0004-unwritable.sh @@ -19,27 +19,66 @@ test_expect_success setup ' test_expect_success POSIXPERM,SANITY 'write-tree should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && chmod a-w .git/objects .git/objects/?? && - test_must_fail git write-tree + test_must_fail git write-tree 2>out.write-tree +' + +test_lazy_prereq WRITE_TREE_OUT 'test -e "$TRASH_DIRECTORY"/out.write-tree' +test_expect_success WRITE_TREE_OUT 'write-tree output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + fatal: git-write-tree: error building trees + EOF + test_cmp expect out.write-tree ' test_expect_success POSIXPERM,SANITY,!SANITIZE_LEAK 'commit should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && chmod a-w .git/objects .git/objects/?? && - test_must_fail git commit -m second + test_must_fail git commit -m second 2>out.commit +' + +test_lazy_prereq COMMIT_OUT 'test -e "$TRASH_DIRECTORY"/out.commit' +test_expect_success COMMIT_OUT 'commit output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + error: Error building trees + EOF + test_cmp expect out.commit ' test_expect_success POSIXPERM,SANITY 'update-index should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && echo 6O >file && chmod a-w .git/objects .git/objects/?? && - test_must_fail git update-index file + test_must_fail git update-index file 2>out.update-index +' + +test_lazy_prereq UPDATE_INDEX_OUT 'test -e "$TRASH_DIRECTORY"/out.update-index' +test_expect_success UPDATE_INDEX_OUT 'update-index output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + error: file: failed to insert into database + fatal: Unable to process path file + EOF + test_cmp expect out.update-index ' test_expect_success POSIXPERM,SANITY 'add should notice unwritable repository' ' test_when_finished "chmod 775 .git/objects .git/objects/??" && echo b >file && chmod a-w .git/objects .git/objects/?? && - test_must_fail git add file + test_must_fail git add file 2>out.add +' + +test_lazy_prereq ADD_OUT 'test -e "$TRASH_DIRECTORY"/out.add' +test_expect_success ADD_OUT 'add output on unwritable repository' ' + cat >expect <<-\EOF && + error: insufficient permission for adding an object to repository database .git/objects + error: file: failed to insert into database + error: unable to index file '\''file'\'' + fatal: updating files failed + EOF + test_cmp expect out.add ' test_done diff --git a/t/t0005-signals.sh b/t/t0005-signals.sh index 4c214bd11c..a5ec6a0315 100755 --- a/t/t0005-signals.sh +++ b/t/t0005-signals.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='signals work as we expect' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect <<EOF diff --git a/t/t0006-date.sh b/t/t0006-date.sh index 6b757d7169..794186961e 100755 --- a/t/t0006-date.sh +++ b/t/t0006-date.sh @@ -63,6 +63,10 @@ check_show 'format-local:%%z' "$TIME" '%z' check_show 'format:%Y-%m-%d %H:%M:%S' "$TIME" '2016-06-15 16:13:20' check_show 'format-local:%Y-%m-%d %H:%M:%S' "$TIME" '2016-06-15 09:13:20' '' EST5 +check_show 'format:%s' '123456789 +1234' 123456789 +check_show 'format:%s' '123456789 -1234' 123456789 +check_show 'format-local:%s' '123456789 -1234' 123456789 + # arbitrary time absurdly far in the future FUTURE="5758122296 -0400" check_show iso "$FUTURE" "2152-06-19 18:24:56 -0400" TIME_IS_64BIT,TIME_T_IS_64BIT diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh index 88b9ae8158..e56f4b9ac5 100755 --- a/t/t0007-git-var.sh +++ b/t/t0007-git-var.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='basic sanity checks for git var' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'get GIT_AUTHOR_IDENT' ' @@ -25,6 +27,26 @@ test_expect_success !FAIL_PREREQS,!AUTOIDENT 'requested identities are strict' ' ) ' +test_expect_success 'get GIT_DEFAULT_BRANCH without configuration' ' + ( + sane_unset GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME && + git init defbranch && + git -C defbranch symbolic-ref --short HEAD >expect && + git var GIT_DEFAULT_BRANCH >actual && + test_cmp expect actual + ) +' + +test_expect_success 'get GIT_DEFAULT_BRANCH with configuration' ' + test_config init.defaultbranch foo && + ( + sane_unset GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME && + echo foo >expect && + git var GIT_DEFAULT_BRANCH >actual && + test_cmp expect actual + ) +' + # For git var -l, we check only a representative variable; # testing the whole output would make our test too brittle with # respect to unrelated changes in the test suite's environment. diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index a594b4aa7d..42d2314804 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -2,6 +2,7 @@ test_description=check-ignore +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh init_vars () { @@ -802,6 +803,49 @@ test_expect_success 'existing directory and file' ' grep top-level-dir actual ' +test_expect_success 'exact prefix matching (with root)' ' + test_when_finished rm -r a && + mkdir -p a/git a/git-foo && + touch a/git/foo a/git-foo/bar && + echo /git/ >a/.gitignore && + git check-ignore a/git a/git/foo a/git-foo a/git-foo/bar >actual && + cat >expect <<-\EOF && + a/git + a/git/foo + EOF + test_cmp expect actual +' + +test_expect_success 'exact prefix matching (without root)' ' + test_when_finished rm -r a && + mkdir -p a/git a/git-foo && + touch a/git/foo a/git-foo/bar && + echo git/ >a/.gitignore && + git check-ignore a/git a/git/foo a/git-foo a/git-foo/bar >actual && + cat >expect <<-\EOF && + a/git + a/git/foo + EOF + test_cmp expect actual +' + +test_expect_success 'directories and ** matches' ' + cat >.gitignore <<-\EOF && + data/** + !data/**/ + !data/**/*.txt + EOF + git check-ignore file \ + data/file data/data1/file1 data/data1/file1.txt \ + data/data2/file2 data/data2/file2.txt >actual && + cat >expect <<-\EOF && + data/file + data/data1/file1 + data/data2/file2 + EOF + test_cmp expect actual +' + ############################################################################ # # test whitespace handling diff --git a/t/t0009-prio-queue.sh b/t/t0009-prio-queue.sh index 3941ad2528..eea99107a4 100755 --- a/t/t0009-prio-queue.sh +++ b/t/t0009-prio-queue.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='basic tests for priority queue implementation' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect <<'EOF' diff --git a/t/t0010-racy-git.sh b/t/t0010-racy-git.sh index 5657c5a87b..837c8b7228 100755 --- a/t/t0010-racy-git.sh +++ b/t/t0010-racy-git.sh @@ -2,6 +2,7 @@ test_description='racy GIT' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test can give false success if your machine is sufficiently diff --git a/t/t0013-sha1dc.sh b/t/t0013-sha1dc.sh index 419f31a8f7..9ad76080aa 100755 --- a/t/t0013-sha1dc.sh +++ b/t/t0013-sha1dc.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test sha1 collision detection' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh TEST_DATA="$TEST_DIRECTORY/t0013" diff --git a/t/t0020-crlf.sh b/t/t0020-crlf.sh index f25ae8b5e1..4125ab8b88 100755 --- a/t/t0020-crlf.sh +++ b/t/t0020-crlf.sh @@ -5,6 +5,7 @@ test_description='CRLF conversion' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh has_cr() { diff --git a/t/t0022-crlf-rename.sh b/t/t0022-crlf-rename.sh index 7af3fbcc7b..c1a331e9e9 100755 --- a/t/t0022-crlf-rename.sh +++ b/t/t0022-crlf-rename.sh @@ -2,6 +2,7 @@ test_description='ignore CR in CRLF sequence while computing similiarity' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t0024-crlf-archive.sh b/t/t0024-crlf-archive.sh index 4e9fa3cd68..a34de56420 100755 --- a/t/t0024-crlf-archive.sh +++ b/t/t0024-crlf-archive.sh @@ -2,6 +2,7 @@ test_description='respect crlf in git archive' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t0025-crlf-renormalize.sh b/t/t0025-crlf-renormalize.sh index e13363ade5..81447978b7 100755 --- a/t/t0025-crlf-renormalize.sh +++ b/t/t0025-crlf-renormalize.sh @@ -2,6 +2,7 @@ test_description='CRLF renormalization' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t0026-eol-config.sh b/t/t0026-eol-config.sh index c5203e232c..cdcafcdff7 100755 --- a/t/t0026-eol-config.sh +++ b/t/t0026-eol-config.sh @@ -2,6 +2,7 @@ test_description='CRLF conversion' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh has_cr() { diff --git a/t/t0029-core-unsetenvvars.sh b/t/t0029-core-unsetenvvars.sh index 24ce46a6ea..b138e1d9cb 100755 --- a/t/t0029-core-unsetenvvars.sh +++ b/t/t0029-core-unsetenvvars.sh @@ -2,6 +2,7 @@ test_description='test the Windows-only core.unsetenvvars setting' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if ! test_have_prereq MINGW diff --git a/t/t0032-reftable-unittest.sh b/t/t0032-reftable-unittest.sh new file mode 100755 index 0000000000..0ed14971a5 --- /dev/null +++ b/t/t0032-reftable-unittest.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# +# Copyright (c) 2020 Google LLC +# + +test_description='reftable unittests' + +. ./test-lib.sh + +test_expect_success 'unittests' ' + TMPDIR=$(pwd) && export TMPDIR && + test-tool reftable +' + +test_done diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index da310ed29b..ed2fb620a9 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -5,6 +5,7 @@ test_description='our own option parser' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect <<\EOF @@ -168,9 +169,45 @@ test_expect_success 'long options' ' ' test_expect_success 'missing required value' ' - test_expect_code 129 test-tool parse-options -s && - test_expect_code 129 test-tool parse-options --string && - test_expect_code 129 test-tool parse-options --file + cat >expect <<-\EOF && + error: switch `s'\'' requires a value + EOF + test_expect_code 129 test-tool parse-options -s 2>actual && + test_cmp expect actual && + + cat >expect <<-\EOF && + error: option `string'\'' requires a value + EOF + test_expect_code 129 test-tool parse-options --string 2>actual && + test_cmp expect actual && + + cat >expect <<-\EOF && + error: option `file'\'' requires a value + EOF + test_expect_code 129 test-tool parse-options --file 2>actual && + test_cmp expect actual +' + +test_expect_success 'superfluous value provided: boolean' ' + cat >expect <<-\EOF && + error: option `yes'\'' takes no value + EOF + test_expect_code 129 test-tool parse-options --yes=hi 2>actual && + test_cmp expect actual && + + cat >expect <<-\EOF && + error: option `no-yes'\'' takes no value + EOF + test_expect_code 129 test-tool parse-options --no-yes=hi 2>actual && + test_cmp expect actual +' + +test_expect_success 'superfluous value provided: cmdmode' ' + cat >expect <<-\EOF && + error: option `mode1'\'' takes no value + EOF + test_expect_code 129 test-tool parse-options --mode1=hi 2>actual && + test_cmp expect actual ' cat >expect <<\EOF diff --git a/t/t0052-simple-ipc.sh b/t/t0052-simple-ipc.sh index ff98be31a5..1a36a53574 100755 --- a/t/t0052-simple-ipc.sh +++ b/t/t0052-simple-ipc.sh @@ -2,6 +2,7 @@ test_description='simple command server' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test-tool simple-ipc SUPPORTS_SIMPLE_IPC || { diff --git a/t/t0055-beyond-symlinks.sh b/t/t0055-beyond-symlinks.sh index 0c6ff567a1..6bada37022 100755 --- a/t/t0055-beyond-symlinks.sh +++ b/t/t0055-beyond-symlinks.sh @@ -2,6 +2,7 @@ test_description='update-index and add refuse to add beyond symlinks' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success SYMLINKS setup ' diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 7d599675e3..ee281909bc 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -5,6 +5,7 @@ test_description='Test run command' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >hello-script <<-EOF diff --git a/t/t0064-oid-array.sh b/t/t0064-oid-array.sh index 2e5438ccda..88c89e8f48 100755 --- a/t/t0064-oid-array.sh +++ b/t/t0064-oid-array.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='basic tests for the oid array implementation' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh echoid () { diff --git a/t/t0065-strcmp-offset.sh b/t/t0065-strcmp-offset.sh index 91fa639c4a..94e34c83ed 100755 --- a/t/t0065-strcmp-offset.sh +++ b/t/t0065-strcmp-offset.sh @@ -2,6 +2,7 @@ test_description='Test strcmp_offset functionality' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh while read s1 s2 expect diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh index 92910e4e6c..63a1a45cd3 100755 --- a/t/t0066-dir-iterator.sh +++ b/t/t0066-dir-iterator.sh @@ -2,6 +2,7 @@ test_description='Test the dir-iterator functionality' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t0067-parse_pathspec_file.sh b/t/t0067-parse_pathspec_file.sh index 7bab49f361..0188d0423a 100755 --- a/t/t0067-parse_pathspec_file.sh +++ b/t/t0067-parse_pathspec_file.sh @@ -2,6 +2,7 @@ test_description='Test parse_pathspec_file()' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'one item from stdin' ' diff --git a/t/t0069-oidtree.sh b/t/t0069-oidtree.sh index bfb1397d7b..74cc59bf8a 100755 --- a/t/t0069-oidtree.sh +++ b/t/t0069-oidtree.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='basic tests for the oidtree implementation' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh maxhexsz=$(test_oid hexsz) diff --git a/t/t0071-sort.sh b/t/t0071-sort.sh new file mode 100755 index 0000000000..6f9a501c72 --- /dev/null +++ b/t/t0071-sort.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +test_description='verify sort functions' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +test_expect_success 'llist_mergesort()' ' + test-tool mergesort test +' + +test_done diff --git a/t/t0110-urlmatch-normalization.sh b/t/t0110-urlmatch-normalization.sh index f99529d838..4dc9fecf72 100755 --- a/t/t0110-urlmatch-normalization.sh +++ b/t/t0110-urlmatch-normalization.sh @@ -47,7 +47,7 @@ test_expect_success 'url authority' ' test-tool urlmatch-normalization "scheme://@host" && test-tool urlmatch-normalization "scheme://%00@host" && ! test-tool urlmatch-normalization "scheme://%%@host" && - ! test-tool urlmatch-normalization "scheme://host_" && + test-tool urlmatch-normalization "scheme://host_" && test-tool urlmatch-normalization "scheme://user:pass@host/" && test-tool urlmatch-normalization "scheme://@host/" && test-tool urlmatch-normalization "scheme://host/" && diff --git a/t/t0200-gettext-basic.sh b/t/t0200-gettext-basic.sh index 8853d8afb9..522fb2ae69 100755 --- a/t/t0200-gettext-basic.sh +++ b/t/t0200-gettext-basic.sh @@ -5,6 +5,7 @@ test_description='Gettext support for Git' +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh test_expect_success "sanity: \$GIT_INTERNAL_GETTEXT_SH_SCHEME is set (to $GIT_INTERNAL_GETTEXT_SH_SCHEME)" ' diff --git a/t/t0201-gettext-fallbacks.sh b/t/t0201-gettext-fallbacks.sh index 6c74df0dc6..8724ce1052 100755 --- a/t/t0201-gettext-fallbacks.sh +++ b/t/t0201-gettext-fallbacks.sh @@ -8,6 +8,7 @@ test_description='Gettext Shell fallbacks' GIT_INTERNAL_GETTEXT_TEST_FALLBACKS=YesPlease export GIT_INTERNAL_GETTEXT_TEST_FALLBACKS +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh test_expect_success "sanity: \$GIT_INTERNAL_GETTEXT_SH_SCHEME is set (to $GIT_INTERNAL_GETTEXT_SH_SCHEME)" ' diff --git a/t/t0202-gettext-perl.sh b/t/t0202-gettext-perl.sh index a29d166e00..df2ea34932 100755 --- a/t/t0202-gettext-perl.sh +++ b/t/t0202-gettext-perl.sh @@ -5,6 +5,7 @@ test_description='Perl gettext interface (Git::I18N)' +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh if ! test_have_prereq PERL; then diff --git a/t/t0204-gettext-reencode-sanity.sh b/t/t0204-gettext-reencode-sanity.sh index 8437e51eb5..4f2e0dcb02 100755 --- a/t/t0204-gettext-reencode-sanity.sh +++ b/t/t0204-gettext-reencode-sanity.sh @@ -5,6 +5,7 @@ test_description="Gettext reencoding of our *.po/*.mo files works" +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh # The constants used in a tricky observation for undefined behaviour diff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh index 0cf3a63b75..37c359bd5a 100755 --- a/t/t0210-trace2-normal.sh +++ b/t/t0210-trace2-normal.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test trace2 facility (normal target)' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Turn off any inherited trace2 settings for this test. diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index 6ee8ee3b67..22d0845544 100755 --- a/t/t0211-trace2-perf.sh +++ b/t/t0211-trace2-perf.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test trace2 facility (perf target)' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Turn off any inherited trace2 settings for this test. diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh index 1529155cf0..6d3374ff77 100755 --- a/t/t0212-trace2-event.sh +++ b/t/t0212-trace2-event.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test trace2 facility' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Turn off any inherited trace2 settings for this test. diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index bba679685f..c76485b1b6 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -6,6 +6,10 @@ test_description='partial clone' # missing promisor objects cause repacks which write bitmaps to fail GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 +# When enabled, some commands will write commit-graphs. This causes fsck +# to fail when delete_object() is called because fsck will attempt to +# verify the out-of-sync commit graph. +GIT_TEST_COMMIT_GRAPH=0 delete_object () { rm $1/.git/objects/$(echo $2 | sed -e 's|^..|&/|') @@ -322,7 +326,7 @@ test_expect_success 'rev-list stops traversal at missing and promised commit' ' git -C repo config core.repositoryformatversion 1 && git -C repo config extensions.partialclone "arbitrary string" && - GIT_TEST_COMMIT_GRAPH=0 git -C repo -c core.commitGraph=false rev-list --exclude-promisor-objects --objects bar >out && + git -C repo rev-list --exclude-promisor-objects --objects bar >out && grep $(git -C repo rev-parse bar) out && ! grep $FOO out ' diff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh index 013c5a7bc3..0e8c0dfbbe 100755 --- a/t/t1000-read-tree-m-3way.sh +++ b/t/t1000-read-tree-m-3way.sh @@ -71,6 +71,8 @@ In addition: DF: a special case, where A makes a directory and B makes a file. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 1057a96b24..d1115528cb 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -20,6 +20,8 @@ In the test, these paths are used: rezrov - in H, deleted in M yomin - not in H or M ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index 9c05f5e1f5..ca5c5510c7 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -8,6 +8,8 @@ test_description='Two way merge with read-tree -m -u $H $M This is identical to t1001, but uses -u to update the work tree as well. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1003-read-tree-prefix.sh b/t/t1003-read-tree-prefix.sh index b6111cd150..e0db2066f3 100755 --- a/t/t1003-read-tree-prefix.sh +++ b/t/t1003-read-tree-prefix.sh @@ -6,6 +6,7 @@ test_description='git read-tree --prefix test. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1005-read-tree-reset.sh b/t/t1005-read-tree-reset.sh index 83b09e1310..12e30d77d0 100755 --- a/t/t1005-read-tree-reset.sh +++ b/t/t1005-read-tree-reset.sh @@ -2,6 +2,7 @@ test_description='read-tree -u --reset' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index 18b3779ccb..0d4c55f74e 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -315,39 +315,237 @@ test_expect_success '%(deltabase) reports packed delta bases' ' } ' -bogus_type="bogus" -bogus_content="bogus" -bogus_size=$(strlen "$bogus_content") -bogus_sha1=$(echo_without_newline "$bogus_content" | git hash-object -t $bogus_type --literally -w --stdin) +test_expect_success 'setup bogus data' ' + bogus_short_type="bogus" && + bogus_short_content="bogus" && + bogus_short_size=$(strlen "$bogus_short_content") && + bogus_short_sha1=$(echo_without_newline "$bogus_short_content" | git hash-object -t $bogus_short_type --literally -w --stdin) && + + bogus_long_type="abcdefghijklmnopqrstuvwxyz1234679" && + bogus_long_content="bogus" && + bogus_long_size=$(strlen "$bogus_long_content") && + bogus_long_sha1=$(echo_without_newline "$bogus_long_content" | git hash-object -t $bogus_long_type --literally -w --stdin) +' + +for arg1 in '' --allow-unknown-type +do + for arg2 in -s -t -p + do + if test "$arg1" = "--allow-unknown-type" && test "$arg2" = "-p" + then + continue + fi + + + test_expect_success "cat-file $arg1 $arg2 error on bogus short OID" ' + cat >expect <<-\EOF && + fatal: invalid object type + EOF + + if test "$arg1" = "--allow-unknown-type" + then + git cat-file $arg1 $arg2 $bogus_short_sha1 + else + test_must_fail git cat-file $arg1 $arg2 $bogus_short_sha1 >out 2>actual && + test_must_be_empty out && + test_cmp expect actual + fi + ' + + test_expect_success "cat-file $arg1 $arg2 error on bogus full OID" ' + if test "$arg2" = "-p" + then + cat >expect <<-EOF + error: header for $bogus_long_sha1 too long, exceeds 32 bytes + fatal: Not a valid object name $bogus_long_sha1 + EOF + else + cat >expect <<-EOF + error: header for $bogus_long_sha1 too long, exceeds 32 bytes + fatal: git cat-file: could not get object info + EOF + fi && + + if test "$arg1" = "--allow-unknown-type" + then + git cat-file $arg1 $arg2 $bogus_short_sha1 + else + test_must_fail git cat-file $arg1 $arg2 $bogus_long_sha1 >out 2>actual && + test_must_be_empty out && + test_cmp expect actual + fi + ' + + test_expect_success "cat-file $arg1 $arg2 error on missing short OID" ' + cat >expect.err <<-EOF && + fatal: Not a valid object name $(test_oid deadbeef_short) + EOF + test_must_fail git cat-file $arg1 $arg2 $(test_oid deadbeef_short) >out 2>err.actual && + test_must_be_empty out + ' + + test_expect_success "cat-file $arg1 $arg2 error on missing full OID" ' + if test "$arg2" = "-p" + then + cat >expect.err <<-EOF + fatal: Not a valid object name $(test_oid deadbeef) + EOF + else + cat >expect.err <<-\EOF + fatal: git cat-file: could not get object info + EOF + fi && + test_must_fail git cat-file $arg1 $arg2 $(test_oid deadbeef) >out 2>err.actual && + test_must_be_empty out && + test_cmp expect.err err.actual + ' + done +done + +test_expect_success '-e is OK with a broken object without --allow-unknown-type' ' + git cat-file -e $bogus_short_sha1 +' + +test_expect_success '-e can not be combined with --allow-unknown-type' ' + test_expect_code 128 git cat-file -e --allow-unknown-type $bogus_short_sha1 +' + +test_expect_success '-p cannot print a broken object even with --allow-unknown-type' ' + test_must_fail git cat-file -p $bogus_short_sha1 && + test_expect_code 128 git cat-file -p --allow-unknown-type $bogus_short_sha1 +' + +test_expect_success '<type> <hash> does not work with objects of broken types' ' + cat >err.expect <<-\EOF && + fatal: invalid object type "bogus" + EOF + test_must_fail git cat-file $bogus_short_type $bogus_short_sha1 2>err.actual && + test_cmp err.expect err.actual +' + +test_expect_success 'broken types combined with --batch and --batch-check' ' + echo $bogus_short_sha1 >bogus-oid && + + cat >err.expect <<-\EOF && + fatal: invalid object type + EOF + + test_must_fail git cat-file --batch <bogus-oid 2>err.actual && + test_cmp err.expect err.actual && + + test_must_fail git cat-file --batch-check <bogus-oid 2>err.actual && + test_cmp err.expect err.actual +' + +test_expect_success 'the --batch and --batch-check options do not combine with --allow-unknown-type' ' + test_expect_code 128 git cat-file --batch --allow-unknown-type <bogus-oid && + test_expect_code 128 git cat-file --batch-check --allow-unknown-type <bogus-oid +' + +test_expect_success 'the --allow-unknown-type option does not consider replacement refs' ' + cat >expect <<-EOF && + $bogus_short_type + EOF + git cat-file -t --allow-unknown-type $bogus_short_sha1 >actual && + test_cmp expect actual && + + # Create it manually, as "git replace" will die on bogus + # types. + head=$(git rev-parse --verify HEAD) && + test_when_finished "test-tool ref-store main delete-refs 0 msg refs/replace/$bogus_short_sha1" && + test-tool ref-store main update-ref msg "refs/replace/$bogus_short_sha1" $head $ZERO_OID REF_SKIP_OID_VERIFICATION && + + cat >expect <<-EOF && + commit + EOF + git cat-file -t --allow-unknown-type $bogus_short_sha1 >actual && + test_cmp expect actual +' test_expect_success "Type of broken object is correct" ' - echo $bogus_type >expect && - git cat-file -t --allow-unknown-type $bogus_sha1 >actual && + echo $bogus_short_type >expect && + git cat-file -t --allow-unknown-type $bogus_short_sha1 >actual && test_cmp expect actual ' test_expect_success "Size of broken object is correct" ' - echo $bogus_size >expect && - git cat-file -s --allow-unknown-type $bogus_sha1 >actual && + echo $bogus_short_size >expect && + git cat-file -s --allow-unknown-type $bogus_short_sha1 >actual && test_cmp expect actual ' -bogus_type="abcdefghijklmnopqrstuvwxyz1234679" -bogus_content="bogus" -bogus_size=$(strlen "$bogus_content") -bogus_sha1=$(echo_without_newline "$bogus_content" | git hash-object -t $bogus_type --literally -w --stdin) + +test_expect_success 'clean up broken object' ' + rm .git/objects/$(test_oid_to_path $bogus_short_sha1) +' test_expect_success "Type of broken object is correct when type is large" ' - echo $bogus_type >expect && - git cat-file -t --allow-unknown-type $bogus_sha1 >actual && + echo $bogus_long_type >expect && + git cat-file -t --allow-unknown-type $bogus_long_sha1 >actual && test_cmp expect actual ' test_expect_success "Size of large broken object is correct when type is large" ' - echo $bogus_size >expect && - git cat-file -s --allow-unknown-type $bogus_sha1 >actual && + echo $bogus_long_size >expect && + git cat-file -s --allow-unknown-type $bogus_long_sha1 >actual && test_cmp expect actual ' +test_expect_success 'clean up broken object' ' + rm .git/objects/$(test_oid_to_path $bogus_long_sha1) +' + +test_expect_success 'cat-file -t and -s on corrupt loose object' ' + git init --bare corrupt-loose.git && + ( + cd corrupt-loose.git && + + # Setup and create the empty blob and its path + empty_path=$(git rev-parse --git-path objects/$(test_oid_to_path "$EMPTY_BLOB")) && + git hash-object -w --stdin </dev/null && + + # Create another blob and its path + echo other >other.blob && + other_blob=$(git hash-object -w --stdin <other.blob) && + other_path=$(git rev-parse --git-path objects/$(test_oid_to_path "$other_blob")) && + + # Before the swap the size is 0 + cat >out.expect <<-EOF && + 0 + EOF + git cat-file -s "$EMPTY_BLOB" >out.actual 2>err.actual && + test_must_be_empty err.actual && + test_cmp out.expect out.actual && + + # Swap the two to corrupt the repository + mv -f "$other_path" "$empty_path" && + test_must_fail git fsck 2>err.fsck && + grep "hash-path mismatch" err.fsck && + + # confirm that cat-file is reading the new swapped-in + # blob... + cat >out.expect <<-EOF && + blob + EOF + git cat-file -t "$EMPTY_BLOB" >out.actual 2>err.actual && + test_must_be_empty err.actual && + test_cmp out.expect out.actual && + + # ... since it has a different size now. + cat >out.expect <<-EOF && + 6 + EOF + git cat-file -s "$EMPTY_BLOB" >out.actual 2>err.actual && + test_must_be_empty err.actual && + test_cmp out.expect out.actual && + + # So far "cat-file" has been happy to spew the found + # content out as-is. Try to make it zlib-invalid. + mv -f other.blob "$empty_path" && + test_must_fail git fsck 2>err.fsck && + grep "^error: inflate: data stream error (" err.fsck + ) +' + # Tests for git cat-file --follow-symlinks test_expect_success 'prep for symlink tests' ' echo_without_newline "$hello_content" >morx && @@ -608,4 +806,70 @@ test_expect_success 'cat-file --batch="batman" with --batch-all-objects will wor cmp expect actual ' +test_expect_success 'set up replacement object' ' + orig=$(git rev-parse HEAD) && + git cat-file commit $orig >orig && + { + cat orig && + echo extra + } >fake && + fake=$(git hash-object -t commit -w fake) && + orig_size=$(git cat-file -s $orig) && + fake_size=$(git cat-file -s $fake) && + git replace $orig $fake +' + +test_expect_success 'cat-file --batch respects replace objects' ' + git cat-file --batch >actual <<-EOF && + $orig + EOF + { + echo "$orig commit $fake_size" && + cat fake && + echo + } >expect && + test_cmp expect actual +' + +test_expect_success 'cat-file --batch-check respects replace objects' ' + git cat-file --batch-check >actual <<-EOF && + $orig + EOF + echo "$orig commit $fake_size" >expect && + test_cmp expect actual +' + +# Pull the entry for object with oid "$1" out of the output of +# "cat-file --batch", including its object content (which requires +# parsing and reading a set amount of bytes, hence perl). +extract_batch_output () { + perl -ne ' + BEGIN { $oid = shift } + if (/^$oid \S+ (\d+)$/) { + print; + read STDIN, my $buf, $1; + print $buf; + print "\n"; + } + ' "$@" +} + +test_expect_success 'cat-file --batch-all-objects --batch ignores replace' ' + git cat-file --batch-all-objects --batch >actual.raw && + extract_batch_output $orig <actual.raw >actual && + { + echo "$orig commit $orig_size" && + cat orig && + echo + } >expect && + test_cmp expect actual +' + +test_expect_success 'cat-file --batch-all-objects --batch-check ignores replace' ' + git cat-file --batch-all-objects --batch-check >actual.raw && + grep ^$orig actual.raw >actual && + echo "$orig commit $orig_size" >expect && + test_cmp expect actual +' + test_done diff --git a/t/t1008-read-tree-overlay.sh b/t/t1008-read-tree-overlay.sh index 4512fb0b6e..ad5936e54d 100755 --- a/t/t1008-read-tree-overlay.sh +++ b/t/t1008-read-tree-overlay.sh @@ -5,6 +5,7 @@ test_description='test multi-tree read-tree without merging' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1009-read-tree-new-index.sh b/t/t1009-read-tree-new-index.sh index 2935f68f8d..fc179ac5dd 100755 --- a/t/t1009-read-tree-new-index.sh +++ b/t/t1009-read-tree-new-index.sh @@ -5,6 +5,7 @@ test_description='test read-tree into a fresh index file' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh index b946f87686..48bfad07ab 100755 --- a/t/t1010-mktree.sh +++ b/t/t1010-mktree.sh @@ -2,6 +2,7 @@ test_description='git mktree' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1012-read-tree-df.sh b/t/t1012-read-tree-df.sh index 57f0770df1..cde93d22cd 100755 --- a/t/t1012-read-tree-df.sh +++ b/t/t1012-read-tree-df.sh @@ -2,6 +2,7 @@ test_description='read-tree D/F conflict corner cases' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1014-read-tree-confusing.sh b/t/t1014-read-tree-confusing.sh index da3376b3bb..8ea8d36818 100755 --- a/t/t1014-read-tree-confusing.sh +++ b/t/t1014-read-tree-confusing.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='check that read-tree rejects confusing paths' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create base tree' ' diff --git a/t/t1022-read-tree-partial-clone.sh b/t/t1022-read-tree-partial-clone.sh index a763e27c7d..a9953b6a71 100755 --- a/t/t1022-read-tree-partial-clone.sh +++ b/t/t1022-read-tree-partial-clone.sh @@ -4,9 +4,6 @@ test_description='git read-tree in partial clones' TEST_NO_CREATE_REPO=1 -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh test_expect_success 'read-tree in partial clone prefetches in one batch' ' diff --git a/t/t1050-large.sh b/t/t1050-large.sh index 4bab6a513c..6bc1d76fb1 100755 --- a/t/t1050-large.sh +++ b/t/t1050-large.sh @@ -17,6 +17,14 @@ test_expect_success setup ' export GIT_ALLOC_LIMIT ' +test_expect_success 'enter "large" codepath, with small core.bigFileThreshold' ' + test_when_finished "rm -rf repo" && + + git init --bare repo && + echo large | git -C repo hash-object -w --stdin && + git -C repo -c core.bigfilethreshold=4 fsck +' + # add a large file with different settings while read expect config do diff --git a/t/t1051-large-conversion.sh b/t/t1051-large-conversion.sh index 8b7640b3ba..042b0e4429 100755 --- a/t/t1051-large-conversion.sh +++ b/t/t1051-large-conversion.sh @@ -83,4 +83,30 @@ test_expect_success 'ident converts on output' ' test_cmp small.clean large.clean ' +# This smudge filter prepends 5GB of zeros to the file it checks out. This +# ensures that smudging doesn't mangle large files on 64-bit Windows. +test_expect_success EXPENSIVE,SIZE_T_IS_64BIT,!LONG_IS_64BIT \ + 'files over 4GB convert on output' ' + test_commit test small "a small file" && + small_size=$(test_file_size small) && + test_config filter.makelarge.smudge \ + "test-tool genzeros $((5*1024*1024*1024)) && cat" && + echo "small filter=makelarge" >.gitattributes && + rm small && + git checkout -- small && + size=$(test_file_size small) && + test "$size" -eq $((5 * 1024 * 1024 * 1024 + $small_size)) +' + +# This clean filter writes down the size of input it receives. By checking against +# the actual size, we ensure that cleaning doesn't mangle large files on 64-bit Windows. +test_expect_success EXPENSIVE,SIZE_T_IS_64BIT,!LONG_IS_64BIT \ + 'files over 4GB convert on input' ' + test-tool genzeros $((5*1024*1024*1024)) >big && + test_config filter.checklarge.clean "wc -c >big.size" && + echo "big filter=checklarge" >.gitattributes && + git add big && + test $(test_file_size big) -eq $(cat big.size) +' + test_done diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index f65bd7a92f..49f70a6569 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -19,6 +19,8 @@ test_expect_success 'setup' ' mkdir folder1 folder2 deep x && mkdir deep/deeper1 deep/deeper2 deep/before deep/later && mkdir deep/deeper1/deepest && + mkdir deep/deeper1/deepest2 && + mkdir deep/deeper1/deepest3 && echo "after deeper1" >deep/e && echo "after deepest" >deep/deeper1/e && cp a folder1 && @@ -30,7 +32,9 @@ test_expect_success 'setup' ' cp a deep/deeper2 && cp a deep/later && cp a deep/deeper1/deepest && - cp -r deep/deeper1/deepest deep/deeper2 && + cp a deep/deeper1/deepest2 && + cp a deep/deeper1/deepest3 && + cp -r deep/deeper1/ deep/deeper2 && mkdir deep/deeper1/0 && mkdir deep/deeper1/0/0 && touch deep/deeper1/0/1 && @@ -126,6 +130,8 @@ test_expect_success 'setup' ' git checkout -b deepest base && echo "updated deepest" >deep/deeper1/deepest/a && + echo "updated deepest2" >deep/deeper1/deepest2/a && + echo "updated deepest3" >deep/deeper1/deepest3/a && git commit -a -m "update deepest" && git checkout -f base && @@ -301,6 +307,14 @@ test_expect_success 'add, commit, checkout' ' test_all_match git checkout - ' +test_expect_success 'deep changes during checkout' ' + init_repos && + + test_sparse_match git sparse-checkout set deep/deeper1/deepest && + test_all_match git checkout deepest && + test_all_match git checkout base +' + test_expect_success 'add outside sparse cone' ' init_repos && @@ -621,7 +635,7 @@ test_expect_success 'reset with wildcard pathspec' ' test_expect_success 'merge, cherry-pick, and rebase' ' init_repos && - for OPERATION in "merge -m merge" cherry-pick rebase + for OPERATION in "merge -m merge" cherry-pick "rebase --apply" "rebase --merge" do test_all_match git checkout -B temp update-deep && test_all_match git $OPERATION update-folder1 && @@ -799,12 +813,43 @@ test_expect_success 'submodule handling' ' test_expect_success 'sparse-index is expanded and converted back' ' init_repos && - GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ git -C sparse-index reset -- folder1/a && test_region index convert_to_sparse trace2.txt && test_region index ensure_full_index trace2.txt ' +test_expect_success 'index.sparse disabled inline uses full index' ' + init_repos && + + # When index.sparse is disabled inline with `git status`, the + # index is expanded at the beginning of the execution then never + # converted back to sparse. It is then written to disk as a full index. + rm -f trace2.txt && + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + git -C sparse-index -c index.sparse=false status && + ! test_region index convert_to_sparse trace2.txt && + test_region index ensure_full_index trace2.txt && + + # Since index.sparse is set to true at a repo level, the index + # is converted from full to sparse when read, then never expanded + # over the course of `git status`. It is written to disk as a sparse + # index. + rm -f trace2.txt && + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + git -C sparse-index status && + test_region index convert_to_sparse trace2.txt && + ! test_region index ensure_full_index trace2.txt && + + # Now that the index has been written to disk as sparse, it is not + # converted to sparse (or expanded to full) when read by `git status`. + rm -f trace2.txt && + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + git -C sparse-index status && + ! test_region index convert_to_sparse trace2.txt && + ! test_region index ensure_full_index trace2.txt +' + ensure_not_expanded () { rm -f trace2.txt && echo >>sparse-index/untracked.txt && @@ -813,10 +858,10 @@ ensure_not_expanded () { then shift && test_must_fail env \ - GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ git -C sparse-index "$@" || return 1 else - GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ git -C sparse-index "$@" || return 1 fi && test_region ! index ensure_full_index trace2.txt diff --git a/t/t1100-commit-tree-options.sh b/t/t1100-commit-tree-options.sh index ae66ba5bab..0f37a43fd3 100755 --- a/t/t1100-commit-tree-options.sh +++ b/t/t1100-commit-tree-options.sh @@ -12,6 +12,7 @@ Also make sure that command line parser understands the normal "flags first and then non flag arguments" command line. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expected <<EOF diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 9ff46f3b04..f8031afaaf 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -8,6 +8,7 @@ test_description='Test git config in different settings' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'clear default config' ' diff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh index 0000e664e7..0506f3d6bb 100755 --- a/t/t1303-wacky-config.sh +++ b/t/t1303-wacky-config.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='Test wacky input to git config' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Leaving off the newline is intentional! diff --git a/t/t1305-config-include.sh b/t/t1305-config-include.sh index ccbb116c01..5cde79ef8c 100755 --- a/t/t1305-config-include.sh +++ b/t/t1305-config-include.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='test config file include directives' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Force setup_explicit_git_dir() to run until the end. This is needed diff --git a/t/t1307-config-blob.sh b/t/t1307-config-blob.sh index 930dce06f0..0a7099d6f5 100755 --- a/t/t1307-config-blob.sh +++ b/t/t1307-config-blob.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='support for reading config from a blob' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create config blob' ' diff --git a/t/t1308-config-set.sh b/t/t1308-config-set.sh index 88b119a0a3..b38e158d3b 100755 --- a/t/t1308-config-set.sh +++ b/t/t1308-config-set.sh @@ -2,6 +2,7 @@ test_description='Test git config-set API in different settings' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # 'check_config get_* section.key value' verifies that the entry for diff --git a/t/t1309-early-config.sh b/t/t1309-early-config.sh index b4a9158307..537435b90a 100755 --- a/t/t1309-early-config.sh +++ b/t/t1309-early-config.sh @@ -2,6 +2,7 @@ test_description='Test read_early_config()' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'read early config' ' diff --git a/t/t1310-config-default.sh b/t/t1310-config-default.sh index 6049d91708..09b10c144b 100755 --- a/t/t1310-config-default.sh +++ b/t/t1310-config-default.sh @@ -2,6 +2,7 @@ test_description='Test git config in different settings (with --default)' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'uses --default when entry missing' ' diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 0d4f73acaa..640659c9d7 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -4,9 +4,6 @@ # test_description='Test git update-ref and basic ref logging' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh Z=$ZERO_OID @@ -321,8 +318,9 @@ $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150260 +0000 Switch $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150860 +0000 EOF test_expect_success "verifying $m's log (logged by touch)" ' - test_when_finished "rm -rf .git/$m .git/logs expect" && - test_cmp expect .git/logs/$m + test_when_finished "git update-ref -d $m && rm -rf .git/logs actual expect" && + test-tool ref-store main for-each-reflog-ent $m >actual && + test_cmp actual expect ' test_expect_success "create $m (logged by config)" ' @@ -350,8 +348,9 @@ $A $B $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150380 +0000 Switch $B $A $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150980 +0000 EOF test_expect_success "verifying $m's log (logged by config)" ' - test_when_finished "rm -f .git/$m .git/logs/$m expect" && - test_cmp expect .git/logs/$m + test_when_finished "git update-ref -d $m && rm -rf .git/logs actual expect" && + test-tool ref-store main for-each-reflog-ent $m >actual && + test_cmp actual expect ' test_expect_success 'set up for querying the reflog' ' @@ -467,7 +466,8 @@ $h_OTHER $h_FIXED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151040 +0000 co $h_FIXED $h_MERGED $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117151100 +0000 commit (merge): Merged initial commit and a later commit. EOF test_expect_success 'git commit logged updates' ' - test_cmp expect .git/logs/$m + test-tool ref-store main for-each-reflog-ent $m >actual && + test_cmp expect actual ' unset h_TEST h_OTHER h_FIXED h_MERGED diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh index 17d3cc1405..4d261e80c6 100755 --- a/t/t1403-show-ref.sh +++ b/t/t1403-show-ref.sh @@ -4,6 +4,7 @@ test_description='show-ref' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1404-update-ref-errors.sh b/t/t1404-update-ref-errors.sh index b729c1f480..13c2b43bba 100755 --- a/t/t1404-update-ref-errors.sh +++ b/t/t1404-update-ref-errors.sh @@ -261,69 +261,69 @@ test_expect_success REFFILES 'empty directory should not fool 1-arg delete' ' git update-ref --stdin ' -test_expect_success 'D/F conflict prevents add long + delete short' ' +test_expect_success REFFILES 'D/F conflict prevents add long + delete short' ' df_test refs/df-al-ds --add-del foo/bar foo ' -test_expect_success 'D/F conflict prevents add short + delete long' ' +test_expect_success REFFILES 'D/F conflict prevents add short + delete long' ' df_test refs/df-as-dl --add-del foo foo/bar ' -test_expect_success 'D/F conflict prevents delete long + add short' ' +test_expect_success REFFILES 'D/F conflict prevents delete long + add short' ' df_test refs/df-dl-as --del-add foo/bar foo ' -test_expect_success 'D/F conflict prevents delete short + add long' ' +test_expect_success REFFILES 'D/F conflict prevents delete short + add long' ' df_test refs/df-ds-al --del-add foo foo/bar ' -test_expect_success 'D/F conflict prevents add long + delete short packed' ' +test_expect_success REFFILES 'D/F conflict prevents add long + delete short packed' ' df_test refs/df-al-dsp --pack --add-del foo/bar foo ' -test_expect_success 'D/F conflict prevents add short + delete long packed' ' +test_expect_success REFFILES 'D/F conflict prevents add short + delete long packed' ' df_test refs/df-as-dlp --pack --add-del foo foo/bar ' -test_expect_success 'D/F conflict prevents delete long packed + add short' ' +test_expect_success REFFILES 'D/F conflict prevents delete long packed + add short' ' df_test refs/df-dlp-as --pack --del-add foo/bar foo ' -test_expect_success 'D/F conflict prevents delete short packed + add long' ' +test_expect_success REFFILES 'D/F conflict prevents delete short packed + add long' ' df_test refs/df-dsp-al --pack --del-add foo foo/bar ' # Try some combinations involving symbolic refs... -test_expect_success 'D/F conflict prevents indirect add long + delete short' ' +test_expect_success REFFILES 'D/F conflict prevents indirect add long + delete short' ' df_test refs/df-ial-ds --sym-add --add-del foo/bar foo ' -test_expect_success 'D/F conflict prevents indirect add long + indirect delete short' ' +test_expect_success REFFILES 'D/F conflict prevents indirect add long + indirect delete short' ' df_test refs/df-ial-ids --sym-add --sym-del --add-del foo/bar foo ' -test_expect_success 'D/F conflict prevents indirect add short + indirect delete long' ' +test_expect_success REFFILES 'D/F conflict prevents indirect add short + indirect delete long' ' df_test refs/df-ias-idl --sym-add --sym-del --add-del foo foo/bar ' -test_expect_success 'D/F conflict prevents indirect delete long + indirect add short' ' +test_expect_success REFFILES 'D/F conflict prevents indirect delete long + indirect add short' ' df_test refs/df-idl-ias --sym-add --sym-del --del-add foo/bar foo ' -test_expect_success 'D/F conflict prevents indirect add long + delete short packed' ' +test_expect_success REFFILES 'D/F conflict prevents indirect add long + delete short packed' ' df_test refs/df-ial-dsp --sym-add --pack --add-del foo/bar foo ' -test_expect_success 'D/F conflict prevents indirect add long + indirect delete short packed' ' +test_expect_success REFFILES 'D/F conflict prevents indirect add long + indirect delete short packed' ' df_test refs/df-ial-idsp --sym-add --sym-del --pack --add-del foo/bar foo ' -test_expect_success 'D/F conflict prevents add long + indirect delete short packed' ' +test_expect_success REFFILES 'D/F conflict prevents add long + indirect delete short packed' ' df_test refs/df-al-idsp --sym-del --pack --add-del foo/bar foo ' -test_expect_success 'D/F conflict prevents indirect delete long packed + indirect add short' ' +test_expect_success REFFILES 'D/F conflict prevents indirect delete long packed + indirect add short' ' df_test refs/df-idlp-ias --sym-add --sym-del --pack --del-add foo/bar foo ' diff --git a/t/t1405-main-ref-store.sh b/t/t1405-main-ref-store.sh index 49718b7ea7..1a3ee8845d 100755 --- a/t/t1405-main-ref-store.sh +++ b/t/t1405-main-ref-store.sh @@ -17,8 +17,7 @@ test_expect_success 'setup' ' test_expect_success REFFILES 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' ' N=`find .git/refs -type f | wc -l` && test "$N" != 0 && - ALL_OR_PRUNE_FLAG=3 && - $RUN pack-refs ${ALL_OR_PRUNE_FLAG} && + $RUN pack-refs PACK_REFS_PRUNE,PACK_REFS_ALL && N=`find .git/refs -type f` && test -z "$N" ' @@ -35,8 +34,7 @@ test_expect_success 'delete_refs(FOO, refs/tags/new-tag)' ' git rev-parse FOO -- && git rev-parse refs/tags/new-tag -- && m=$(git rev-parse main) && - REF_NO_DEREF=1 && - $RUN delete-refs $REF_NO_DEREF nothing FOO refs/tags/new-tag && + $RUN delete-refs REF_NO_DEREF nothing FOO refs/tags/new-tag && test_must_fail git rev-parse --symbolic-full-name FOO && test_must_fail git rev-parse FOO -- && test_must_fail git rev-parse refs/tags/new-tag -- @@ -89,13 +87,13 @@ test_expect_success 'for_each_reflog()' ' test_expect_success 'for_each_reflog_ent()' ' $RUN for-each-reflog-ent HEAD >actual && head -n1 actual | grep one && - tail -n2 actual | head -n1 | grep recreate-main + tail -n1 actual | grep recreate-main ' test_expect_success 'for_each_reflog_ent_reverse()' ' $RUN for-each-reflog-ent-reverse HEAD >actual && head -n1 actual | grep recreate-main && - tail -n2 actual | head -n1 | grep one + tail -n1 actual | grep one ' test_expect_success 'reflog_exists(HEAD)' ' @@ -108,7 +106,7 @@ test_expect_success 'delete_reflog(HEAD)' ' ' test_expect_success 'create-reflog(HEAD)' ' - $RUN create-reflog HEAD 1 && + $RUN create-reflog HEAD && git reflog exists HEAD ' diff --git a/t/t1406-submodule-ref-store.sh b/t/t1406-submodule-ref-store.sh index 0a87058971..e6a7f7334b 100755 --- a/t/t1406-submodule-ref-store.sh +++ b/t/t1406-submodule-ref-store.sh @@ -5,6 +5,7 @@ test_description='test submodule ref store api' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh RUN="test-tool ref-store submodule:sub" @@ -74,13 +75,13 @@ test_expect_success 'for_each_reflog()' ' test_expect_success 'for_each_reflog_ent()' ' $RUN for-each-reflog-ent HEAD >actual && head -n1 actual | grep first && - tail -n2 actual | head -n1 | grep main.to.new + tail -n1 actual | grep main.to.new ' test_expect_success 'for_each_reflog_ent_reverse()' ' $RUN for-each-reflog-ent-reverse HEAD >actual && head -n1 actual | grep main.to.new && - tail -n2 actual | head -n1 | grep first + tail -n1 actual | grep first ' test_expect_success 'reflog_exists(HEAD)' ' @@ -92,7 +93,7 @@ test_expect_success 'delete_reflog() not allowed' ' ' test_expect_success 'create-reflog() not allowed' ' - test_must_fail $RUN create-reflog HEAD 1 + test_must_fail $RUN create-reflog HEAD ' test_done diff --git a/t/t1417-reflog-updateref.sh b/t/t1417-reflog-updateref.sh new file mode 100755 index 0000000000..14f13b57c6 --- /dev/null +++ b/t/t1417-reflog-updateref.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +test_description='git reflog --updateref' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +test_expect_success 'setup' ' + git init -b main repo && + ( + cd repo && + + test_commit A && + test_commit B && + test_commit C && + + cp .git/logs/HEAD HEAD.old && + git reset --hard HEAD~ && + cp HEAD.old .git/logs/HEAD + ) +' + +test_reflog_updateref () { + exp=$1 + shift + args="$@" + + test_expect_success REFFILES "get '$exp' with '$args'" ' + test_when_finished "rm -rf copy" && + cp -R repo copy && + + ( + cd copy && + + $args && + git rev-parse $exp >expect && + git rev-parse HEAD >actual && + + test_cmp expect actual + ) + ' +} + +test_reflog_updateref B git reflog delete --updateref HEAD@{0} +test_reflog_updateref B git reflog delete --updateref HEAD@{1} +test_reflog_updateref C git reflog delete --updateref main@{0} +test_reflog_updateref B git reflog delete --updateref main@{1} +test_reflog_updateref B git reflog delete --updateref --rewrite HEAD@{0} +test_reflog_updateref B git reflog delete --updateref --rewrite HEAD@{1} +test_reflog_updateref C git reflog delete --updateref --rewrite main@{0} +test_reflog_updateref B git reflog delete --updateref --rewrite main@{1} +test_reflog_updateref B test_must_fail git reflog expire HEAD@{0} +test_reflog_updateref B test_must_fail git reflog expire HEAD@{1} +test_reflog_updateref B test_must_fail git reflog expire main@{0} +test_reflog_updateref B test_must_fail git reflog expire main@{1} +test_reflog_updateref B test_must_fail git reflog expire --updateref HEAD@{0} +test_reflog_updateref B test_must_fail git reflog expire --updateref HEAD@{1} +test_reflog_updateref B test_must_fail git reflog expire --updateref main@{0} +test_reflog_updateref B test_must_fail git reflog expire --updateref main@{1} +test_reflog_updateref B test_must_fail git reflog expire --updateref --rewrite HEAD@{0} +test_reflog_updateref B test_must_fail git reflog expire --updateref --rewrite HEAD@{1} +test_reflog_updateref B test_must_fail git reflog expire --updateref --rewrite main@{0} +test_reflog_updateref B test_must_fail git reflog expire --updateref --rewrite main@{1} + +test_done diff --git a/t/t1420-lost-found.sh b/t/t1420-lost-found.sh index dc9e402c55..dbe15a0be1 100755 --- a/t/t1420-lost-found.sh +++ b/t/t1420-lost-found.sh @@ -4,6 +4,8 @@ # test_description='Test fsck --lost-found' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh index fa3aeb80f2..ff1c967d55 100755 --- a/t/t1430-bad-ref-name.sh +++ b/t/t1430-bad-ref-name.sh @@ -4,11 +4,13 @@ test_description='Test handling of ref names that check-ref-format rejects' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' test_commit one && - test_commit two + test_commit two && + main_sha1=$(git rev-parse refs/heads/main) ' test_expect_success 'fast-import: fail on invalid branch name ".badbranchname"' ' @@ -42,16 +44,16 @@ test_expect_success 'fast-import: fail on invalid branch name "bad[branch]name"' ' test_expect_success 'git branch shows badly named ref as warning' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && git branch >output 2>error && test_i18ngrep -e "ignoring ref with broken name refs/heads/broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' test_expect_success 'branch -d can delete badly named ref' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && git branch -d broken...ref && git branch >output 2>error && ! grep -e "broken\.\.\.ref" error && @@ -59,8 +61,8 @@ test_expect_success 'branch -d can delete badly named ref' ' ' test_expect_success 'branch -D can delete badly named ref' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && git branch -D broken...ref && git branch >output 2>error && ! grep -e "broken\.\.\.ref" error && @@ -89,7 +91,7 @@ test_expect_success 'branch -D cannot delete absolute path' ' ' test_expect_success 'git branch cannot create a badly named ref' ' - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && test_must_fail git branch broken...ref && git branch >output 2>error && ! grep -e "broken\.\.\.ref" error && @@ -97,7 +99,7 @@ test_expect_success 'git branch cannot create a badly named ref' ' ' test_expect_success 'branch -m cannot rename to a bad ref name' ' - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && test_might_fail git branch -D goodref && git branch goodref && test_must_fail git branch -m goodref broken...ref && @@ -108,8 +110,9 @@ test_expect_success 'branch -m cannot rename to a bad ref name' ' ' test_expect_failure 'branch -m can rename from a bad ref name' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && git branch -m broken...ref renamed && test_cmp_rev main renamed && git branch >output 2>error && @@ -118,7 +121,7 @@ test_expect_failure 'branch -m can rename from a bad ref name' ' ' test_expect_success 'push cannot create a badly named ref' ' - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && test_must_fail git push "file://$(pwd)" HEAD:refs/heads/broken...ref && git branch >output 2>error && ! grep -e "broken\.\.\.ref" error && @@ -138,7 +141,7 @@ test_expect_failure 'push --mirror can delete badly named ref' ' cd dest && test_commit two && git checkout --detach && - cp .git/refs/heads/main .git/refs/heads/broken...ref + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION ) && git -C src push --mirror "file://$top/dest" && git -C dest branch >output 2>error && @@ -147,11 +150,11 @@ test_expect_failure 'push --mirror can delete badly named ref' ' ' test_expect_success 'rev-parse skips symref pointing to broken name' ' - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && git branch shadow one && - cp .git/refs/heads/main .git/refs/heads/broken...ref && - printf "ref: refs/heads/broken...ref\n" >.git/refs/tags/shadow && - test_when_finished "rm -f .git/refs/tags/shadow" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test-tool ref-store main create-symref refs/tags/shadow refs/heads/broken...ref msg && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/tags/shadow" && git rev-parse --verify one >expect && git rev-parse --verify shadow >actual 2>err && test_cmp expect actual && @@ -159,12 +162,12 @@ test_expect_success 'rev-parse skips symref pointing to broken name' ' ' test_expect_success 'for-each-ref emits warnings for broken names' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && - test_when_finished "rm -f .git/refs/heads/badname" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && - test_when_finished "rm -f .git/refs/heads/broken...symref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && git for-each-ref >output 2>error && ! grep -e "broken\.\.\.ref" output && ! grep -e "badname" output && @@ -175,8 +178,8 @@ test_expect_success 'for-each-ref emits warnings for broken names' ' ' test_expect_success 'update-ref -d can delete broken name' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && git update-ref -d refs/heads/broken...ref >output 2>error && test_must_be_empty output && test_must_be_empty error && @@ -186,8 +189,8 @@ test_expect_success 'update-ref -d can delete broken name' ' ' test_expect_success 'branch -d can delete broken name' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && git branch -d broken...ref >output 2>error && test_i18ngrep "Deleted branch broken...ref (was broken)" output && test_must_be_empty error && @@ -197,10 +200,11 @@ test_expect_success 'branch -d can delete broken name' ' ' test_expect_success 'update-ref --no-deref -d can delete symref to broken name' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && - printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && - test_when_finished "rm -f .git/refs/heads/badname" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && + test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && git update-ref --no-deref -d refs/heads/badname >output 2>error && test_path_is_missing .git/refs/heads/badname && test_must_be_empty output && @@ -208,10 +212,10 @@ test_expect_success 'update-ref --no-deref -d can delete symref to broken name' ' test_expect_success 'branch -d can delete symref to broken name' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && - printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && - test_when_finished "rm -f .git/refs/heads/badname" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && + test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && git branch -d badname >output 2>error && test_path_is_missing .git/refs/heads/badname && test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output && @@ -219,8 +223,8 @@ test_expect_success 'branch -d can delete symref to broken name' ' ' test_expect_success 'update-ref --no-deref -d can delete dangling symref to broken name' ' - printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && - test_when_finished "rm -f .git/refs/heads/badname" && + test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && git update-ref --no-deref -d refs/heads/badname >output 2>error && test_path_is_missing .git/refs/heads/badname && test_must_be_empty output && @@ -228,8 +232,8 @@ test_expect_success 'update-ref --no-deref -d can delete dangling symref to brok ' test_expect_success 'branch -d can delete dangling symref to broken name' ' - printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && - test_when_finished "rm -f .git/refs/heads/badname" && + test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && git branch -d badname >output 2>error && test_path_is_missing .git/refs/heads/badname && test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output && @@ -237,10 +241,10 @@ test_expect_success 'branch -d can delete dangling symref to broken name' ' ' test_expect_success 'update-ref -d can delete broken name through symref' ' - cp .git/refs/heads/main .git/refs/heads/broken...ref && - test_when_finished "rm -f .git/refs/heads/broken...ref" && - printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && - test_when_finished "rm -f .git/refs/heads/badname" && + test-tool ref-store main update-ref msg "refs/heads/broken...ref" $main_sha1 $ZERO_OID REF_SKIP_REFNAME_VERIFICATION && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...ref" && + test-tool ref-store main create-symref refs/heads/badname refs/heads/broken...ref msg && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/badname" && git update-ref -d refs/heads/badname >output 2>error && test_path_is_missing .git/refs/heads/broken...ref && test_must_be_empty output && @@ -249,7 +253,7 @@ test_expect_success 'update-ref -d can delete broken name through symref' ' test_expect_success 'update-ref --no-deref -d can delete symref with broken name' ' printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && - test_when_finished "rm -f .git/refs/heads/broken...symref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && test_path_is_missing .git/refs/heads/broken...symref && test_must_be_empty output && @@ -258,7 +262,7 @@ test_expect_success 'update-ref --no-deref -d can delete symref with broken name test_expect_success 'branch -d can delete symref with broken name' ' printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref && - test_when_finished "rm -f .git/refs/heads/broken...symref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && git branch -d broken...symref >output 2>error && test_path_is_missing .git/refs/heads/broken...symref && test_i18ngrep "Deleted branch broken...symref (was refs/heads/main)" output && @@ -267,7 +271,7 @@ test_expect_success 'branch -d can delete symref with broken name' ' test_expect_success 'update-ref --no-deref -d can delete dangling symref with broken name' ' printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && - test_when_finished "rm -f .git/refs/heads/broken...symref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && test_path_is_missing .git/refs/heads/broken...symref && test_must_be_empty output && @@ -276,7 +280,7 @@ test_expect_success 'update-ref --no-deref -d can delete dangling symref with br test_expect_success 'branch -d can delete dangling symref with broken name' ' printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && - test_when_finished "rm -f .git/refs/heads/broken...symref" && + test_when_finished "test-tool ref-store main delete-refs REF_NO_DEREF msg refs/heads/broken...symref" && git branch -d broken...symref >output 2>error && test_path_is_missing .git/refs/heads/broken...symref && test_i18ngrep "Deleted branch broken...symref (was refs/heads/idonotexist)" output && diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 5071ac63a5..6337236fd8 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -48,24 +48,70 @@ remove_object () { rm "$(sha1_file "$1")" } -test_expect_success 'object with bad sha1' ' - sha=$(echo blob | git hash-object -w --stdin) && - old=$(test_oid_to_path "$sha") && - new=$(dirname $old)/$(test_oid ff_2) && - sha="$(dirname $new)$(basename $new)" && - mv .git/objects/$old .git/objects/$new && - test_when_finished "remove_object $sha" && - git update-index --add --cacheinfo 100644 $sha foo && - test_when_finished "git read-tree -u --reset HEAD" && - tree=$(git write-tree) && - test_when_finished "remove_object $tree" && - cmt=$(echo bogus | git commit-tree $tree) && - test_when_finished "remove_object $cmt" && - git update-ref refs/heads/bogus $cmt && - test_when_finished "git update-ref -d refs/heads/bogus" && +test_expect_success 'object with hash mismatch' ' + git init --bare hash-mismatch && + ( + cd hash-mismatch && - test_must_fail git fsck 2>out && - test_i18ngrep "$sha.*corrupt" out + oid=$(echo blob | git hash-object -w --stdin) && + oldoid=$oid && + old=$(test_oid_to_path "$oid") && + new=$(dirname $old)/$(test_oid ff_2) && + oid="$(dirname $new)$(basename $new)" && + + mv objects/$old objects/$new && + git update-index --add --cacheinfo 100644 $oid foo && + tree=$(git write-tree) && + cmt=$(echo bogus | git commit-tree $tree) && + git update-ref refs/heads/bogus $cmt && + + test_must_fail git fsck 2>out && + grep "$oldoid: hash-path mismatch, found at: .*$new" out + ) +' + +test_expect_success 'object with hash and type mismatch' ' + git init --bare hash-type-mismatch && + ( + cd hash-type-mismatch && + + oid=$(echo blob | git hash-object -w --stdin -t garbage --literally) && + oldoid=$oid && + old=$(test_oid_to_path "$oid") && + new=$(dirname $old)/$(test_oid ff_2) && + oid="$(dirname $new)$(basename $new)" && + + mv objects/$old objects/$new && + git update-index --add --cacheinfo 100644 $oid foo && + tree=$(git write-tree) && + cmt=$(echo bogus | git commit-tree $tree) && + git update-ref refs/heads/bogus $cmt && + + + test_must_fail git fsck 2>out && + grep "^error: $oldoid: hash-path mismatch, found at: .*$new" out && + grep "^error: $oldoid: object is of unknown type '"'"'garbage'"'"'" out + ) +' + +test_expect_success POSIXPERM 'zlib corrupt loose object output ' ' + git init --bare corrupt-loose-output && + ( + cd corrupt-loose-output && + oid=$(git hash-object -w --stdin --literally </dev/null) && + oidf=objects/$(test_oid_to_path "$oid") && + chmod 755 $oidf && + echo extra garbage >>$oidf && + + cat >expect.error <<-EOF && + error: garbage at end of loose object '\''$oid'\'' + error: unable to unpack contents of ./$oidf + error: $oid: object corrupt or missing: ./$oidf + EOF + test_must_fail git fsck 2>actual && + grep ^error: actual >error && + test_cmp expect.error error + ) ' test_expect_success 'branch pointing to non-commit' ' @@ -865,4 +911,21 @@ test_expect_success 'detect corrupt index file in fsck' ' test_i18ngrep "bad index file" errors ' +test_expect_success 'fsck error and recovery on invalid object type' ' + git init --bare garbage-type && + ( + cd garbage-type && + + garbage_blob=$(git hash-object --stdin -w -t garbage --literally </dev/null) && + + cat >err.expect <<-\EOF && + fatal: invalid object type + EOF + test_must_fail git fsck >out 2>err && + grep -e "^error" -e "^fatal" err >errors && + test_line_count = 1 errors && + grep "$garbage_blob: object is of unknown type '"'"'garbage'"'"':" err + ) +' + test_done diff --git a/t/t1503-rev-parse-verify.sh b/t/t1503-rev-parse-verify.sh index 40958615eb..94fe413ee3 100755 --- a/t/t1503-rev-parse-verify.sh +++ b/t/t1503-rev-parse-verify.sh @@ -9,6 +9,7 @@ exec </dev/null GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh add_line_into_file() diff --git a/t/t1504-ceiling-dirs.sh b/t/t1504-ceiling-dirs.sh index 3d51615e42..0fafcf9dde 100755 --- a/t/t1504-ceiling-dirs.sh +++ b/t/t1504-ceiling-dirs.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test GIT_CEILING_DIRECTORIES' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_prefix() { diff --git a/t/t1505-rev-parse-last.sh b/t/t1505-rev-parse-last.sh index 2803ca9489..4a5758f08a 100755 --- a/t/t1505-rev-parse-last.sh +++ b/t/t1505-rev-parse-last.sh @@ -5,6 +5,7 @@ test_description='test @{-N} syntax' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t1506-rev-parse-diagnosis.sh b/t/t1506-rev-parse-diagnosis.sh index 65a154a8a2..18688cae17 100755 --- a/t/t1506-rev-parse-diagnosis.sh +++ b/t/t1506-rev-parse-diagnosis.sh @@ -7,6 +7,7 @@ exec </dev/null GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_did_you_mean () diff --git a/t/t1510-repo-setup.sh b/t/t1510-repo-setup.sh index bbfe05b8e4..591505a39c 100755 --- a/t/t1510-repo-setup.sh +++ b/t/t1510-repo-setup.sh @@ -43,6 +43,7 @@ A few rules for repo setup: # This test heavily relies on the standard error of nested function calls. test_untraceable=UnfortunatelyYes +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh here=$(pwd) diff --git a/t/t1513-rev-parse-prefix.sh b/t/t1513-rev-parse-prefix.sh index 5f437be8c9..ba43387bf1 100755 --- a/t/t1513-rev-parse-prefix.sh +++ b/t/t1513-rev-parse-prefix.sh @@ -5,6 +5,7 @@ test_description='Tests for rev-parse --prefix' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1515-rev-parse-outside-repo.sh b/t/t1515-rev-parse-outside-repo.sh index 3ec2971ee5..cdb26a30d7 100755 --- a/t/t1515-rev-parse-outside-repo.sh +++ b/t/t1515-rev-parse-outside-repo.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='check that certain rev-parse options work outside repo' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up non-repo directory' ' diff --git a/t/t1600-index.sh b/t/t1600-index.sh index 46329c488b..010989f90e 100755 --- a/t/t1600-index.sh +++ b/t/t1600-index.sh @@ -2,6 +2,7 @@ test_description='index file specific tests' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh sane_unset GIT_TEST_SPLIT_INDEX diff --git a/t/t2000-conflict-when-checking-files-out.sh b/t/t2000-conflict-when-checking-files-out.sh index f18616ad2b..79fc97f1d7 100755 --- a/t/t2000-conflict-when-checking-files-out.sh +++ b/t/t2000-conflict-when-checking-files-out.sh @@ -21,6 +21,7 @@ test_description='git conflicts when checking files out test.' # path1 is occupied by a non-directory. With "-f" flag, it should remove # the conflicting paths and succeed. +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh show_files() { diff --git a/t/t2002-checkout-cache-u.sh b/t/t2002-checkout-cache-u.sh index 70361c806e..fc95cf9048 100755 --- a/t/t2002-checkout-cache-u.sh +++ b/t/t2002-checkout-cache-u.sh @@ -8,6 +8,7 @@ test_description='git checkout-index -u test. With -u flag, git checkout-index internally runs the equivalent of git update-index --refresh on the checked out entry.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t2003-checkout-cache-mkdir.sh b/t/t2003-checkout-cache-mkdir.sh index ff163cf675..f0fd441d81 100755 --- a/t/t2003-checkout-cache-mkdir.sh +++ b/t/t2003-checkout-cache-mkdir.sh @@ -10,6 +10,7 @@ also verifies that such leading path may contain symlinks, unlike the GIT controlled paths. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2004-checkout-cache-temp.sh b/t/t2004-checkout-cache-temp.sh index a9352b08a8..9bb503a975 100755 --- a/t/t2004-checkout-cache-temp.sh +++ b/t/t2004-checkout-cache-temp.sh @@ -8,6 +8,7 @@ test_description='git checkout-index --temp test. With --temp flag, git checkout-index writes to temporary merge files rather than the tracked path.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2005-checkout-index-symlinks.sh b/t/t2005-checkout-index-symlinks.sh index 9fa5610474..112682a45a 100755 --- a/t/t2005-checkout-index-symlinks.sh +++ b/t/t2005-checkout-index-symlinks.sh @@ -8,6 +8,7 @@ test_description='git checkout-index on filesystem w/o symlinks test. This tests that git checkout-index creates a symbolic link as a plain file if core.symlinks is false.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t2007-checkout-symlink.sh b/t/t2007-checkout-symlink.sh index 6f0b90ce12..bd9e9e7530 100755 --- a/t/t2007-checkout-symlink.sh +++ b/t/t2007-checkout-symlink.sh @@ -7,6 +7,7 @@ test_description='git checkout to switch between branches with symlink<->dir' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2008-checkout-subdir.sh b/t/t2008-checkout-subdir.sh index eadb9434ae..8a518a44ea 100755 --- a/t/t2008-checkout-subdir.sh +++ b/t/t2008-checkout-subdir.sh @@ -4,6 +4,7 @@ test_description='git checkout from subdirectories' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2009-checkout-statinfo.sh b/t/t2009-checkout-statinfo.sh index b0540636ae..71195dd28f 100755 --- a/t/t2009-checkout-statinfo.sh +++ b/t/t2009-checkout-statinfo.sh @@ -5,6 +5,7 @@ test_description='checkout should leave clean stat info' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2010-checkout-ambiguous.sh b/t/t2010-checkout-ambiguous.sh index 6e8757387d..9d4b37526a 100755 --- a/t/t2010-checkout-ambiguous.sh +++ b/t/t2010-checkout-ambiguous.sh @@ -5,6 +5,7 @@ test_description='checkout and pathspecs/refspecs ambiguities' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2011-checkout-invalid-head.sh b/t/t2011-checkout-invalid-head.sh index e52022e152..d9997e7b6b 100755 --- a/t/t2011-checkout-invalid-head.sh +++ b/t/t2011-checkout-invalid-head.sh @@ -5,6 +5,7 @@ test_description='checkout switching away from an invalid branch' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2014-checkout-switch.sh b/t/t2014-checkout-switch.sh index ccfb147113..c138bdde4f 100755 --- a/t/t2014-checkout-switch.sh +++ b/t/t2014-checkout-switch.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='Peter MacMillan' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2017-checkout-orphan.sh b/t/t2017-checkout-orphan.sh index 88d6992a5e..f3371e2646 100755 --- a/t/t2017-checkout-orphan.sh +++ b/t/t2017-checkout-orphan.sh @@ -10,6 +10,7 @@ Main Tests for --orphan functionality.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh TEST_FILE=foo diff --git a/t/t2018-checkout-branch.sh b/t/t2018-checkout-branch.sh index 93be1c0eae..3e93506c04 100755 --- a/t/t2018-checkout-branch.sh +++ b/t/t2018-checkout-branch.sh @@ -148,7 +148,7 @@ test_expect_success 'checkout -b to an existing branch fails' ' test_expect_success 'checkout -b to @{-1} fails with the right branch name' ' git checkout branch1 && git checkout branch2 && - echo >expect "fatal: A branch named '\''branch1'\'' already exists." && + echo >expect "fatal: a branch named '\''branch1'\'' already exists" && test_must_fail git checkout -b @{-1} 2>actual && test_cmp expect actual ' diff --git a/t/t2019-checkout-ambiguous-ref.sh b/t/t2019-checkout-ambiguous-ref.sh index b99d5192a9..2c8c926b4d 100755 --- a/t/t2019-checkout-ambiguous-ref.sh +++ b/t/t2019-checkout-ambiguous-ref.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='checkout handling of ambiguous (branch/tag) refs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup ambiguous refs' ' diff --git a/t/t2021-checkout-overwrite.sh b/t/t2021-checkout-overwrite.sh index 660132ff8d..713c3fa603 100755 --- a/t/t2021-checkout-overwrite.sh +++ b/t/t2021-checkout-overwrite.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='checkout must not overwrite an untracked objects' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh index c49ba7f9bd..f1b709d58b 100755 --- a/t/t2022-checkout-paths.sh +++ b/t/t2022-checkout-paths.sh @@ -4,6 +4,7 @@ test_description='checkout $tree -- $paths' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2026-checkout-pathspec-file.sh b/t/t2026-checkout-pathspec-file.sh index 43d31d7948..9db11f86dd 100755 --- a/t/t2026-checkout-pathspec-file.sh +++ b/t/t2026-checkout-pathspec-file.sh @@ -2,6 +2,7 @@ test_description='checkout --pathspec-from-file' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t2050-git-dir-relative.sh b/t/t2050-git-dir-relative.sh index 21f4659a9d..1f193cde96 100755 --- a/t/t2050-git-dir-relative.sh +++ b/t/t2050-git-dir-relative.sh @@ -12,6 +12,7 @@ into the subdir while keeping the worktree location, and tries commits from the top and the subdir, checking that the commit-hook still gets called.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh COMMIT_FILE="$(pwd)/output" diff --git a/t/t2081-parallel-checkout-collisions.sh b/t/t2081-parallel-checkout-collisions.sh index f6fcfc0c1e..6acdb89d12 100755 --- a/t/t2081-parallel-checkout-collisions.sh +++ b/t/t2081-parallel-checkout-collisions.sh @@ -11,6 +11,7 @@ The tests in this file exercise parallel checkout's collision detection code in both these mechanics. " +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-parallel-checkout.sh" diff --git a/t/t2100-update-cache-badpath.sh b/t/t2100-update-cache-badpath.sh index 2df3fdde8b..7915e7b821 100755 --- a/t/t2100-update-cache-badpath.sh +++ b/t/t2100-update-cache-badpath.sh @@ -22,6 +22,7 @@ and tries to git update-index --add the following: All of the attempts should fail. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh mkdir path2 path3 diff --git a/t/t2101-update-index-reupdate.sh b/t/t2101-update-index-reupdate.sh index 6c32d42c8c..e3c7acdbf9 100755 --- a/t/t2101-update-index-reupdate.sh +++ b/t/t2101-update-index-reupdate.sh @@ -6,6 +6,7 @@ test_description='git update-index --again test. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'update-index --add' ' diff --git a/t/t2102-update-index-symlinks.sh b/t/t2102-update-index-symlinks.sh index 22f2c730ae..d7a3485582 100755 --- a/t/t2102-update-index-symlinks.sh +++ b/t/t2102-update-index-symlinks.sh @@ -8,6 +8,7 @@ test_description='git update-index on filesystem w/o symlinks test. This tests that git update-index keeps the symbolic link property even if a plain file is in the working tree if core.symlinks is false.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t2103-update-index-ignore-missing.sh b/t/t2103-update-index-ignore-missing.sh index 0114f05228..b304714fdb 100755 --- a/t/t2103-update-index-ignore-missing.sh +++ b/t/t2103-update-index-ignore-missing.sh @@ -2,6 +2,7 @@ test_description='update-index with options' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success basics ' diff --git a/t/t2104-update-index-skip-worktree.sh b/t/t2104-update-index-skip-worktree.sh index 30666fc70d..b8686aabd3 100755 --- a/t/t2104-update-index-skip-worktree.sh +++ b/t/t2104-update-index-skip-worktree.sh @@ -5,6 +5,7 @@ test_description='skip-worktree bit test' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh sane_unset GIT_TEST_SPLIT_INDEX diff --git a/t/t2105-update-index-gitfile.sh b/t/t2105-update-index-gitfile.sh index a7f3d47aec..963ebe77eb 100755 --- a/t/t2105-update-index-gitfile.sh +++ b/t/t2105-update-index-gitfile.sh @@ -6,6 +6,7 @@ test_description='git update-index for gitlink to .git file. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'submodule with absolute .git file' ' diff --git a/t/t2106-update-index-assume-unchanged.sh b/t/t2106-update-index-assume-unchanged.sh index 2d450daf5c..d943ddf47e 100755 --- a/t/t2106-update-index-assume-unchanged.sh +++ b/t/t2106-update-index-assume-unchanged.sh @@ -3,6 +3,7 @@ test_description='git update-index --assume-unchanged test. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 45ca35d60a..a8297c2943 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -14,6 +14,7 @@ only the updates to dir/sub. Also tested are "git add -u" without limiting, and "git add -u" without contents changes, and other conditions' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' @@ -129,12 +130,15 @@ test_expect_success 'add -n -u should not add but just report' ' echo "remove '\''top'\''" ) >expect && before=$(git ls-files -s check top) && + git count-objects -v >objects_before && echo changed >>check && rm -f top && git add -n -u >actual && after=$(git ls-files -s check top) && + git count-objects -v >objects_after && test "$before" = "$after" && + test_cmp objects_before objects_after && test_cmp expect actual ' diff --git a/t/t2201-add-update-typechange.sh b/t/t2201-add-update-typechange.sh index a4eec0a346..c6876b120f 100755 --- a/t/t2201-add-update-typechange.sh +++ b/t/t2201-add-update-typechange.sh @@ -2,6 +2,7 @@ test_description='more git add -u' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2202-add-addremove.sh b/t/t2202-add-addremove.sh index 9ee659098c..24c60bfd79 100755 --- a/t/t2202-add-addremove.sh +++ b/t/t2202-add-addremove.sh @@ -2,6 +2,7 @@ test_description='git add --all' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2204-add-ignored.sh b/t/t2204-add-ignored.sh index 2e07365bbb..89424abccd 100755 --- a/t/t2204-add-ignored.sh +++ b/t/t2204-add-ignored.sh @@ -2,6 +2,7 @@ test_description='giving ignored paths to git add' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2300-cd-to-toplevel.sh b/t/t2300-cd-to-toplevel.sh index c8de6d8a19..b40eeb263f 100755 --- a/t/t2300-cd-to-toplevel.sh +++ b/t/t2300-cd-to-toplevel.sh @@ -2,6 +2,7 @@ test_description='cd_to_toplevel' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh EXEC_PATH="$(git --exec-path)" diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh index a615d3b483..3d28c7f06b 100755 --- a/t/t2401-worktree-prune.sh +++ b/t/t2401-worktree-prune.sh @@ -19,7 +19,7 @@ test_expect_success 'worktree prune on normal repo' ' test_expect_success 'prune files inside $GIT_DIR/worktrees' ' mkdir .git/worktrees && : >.git/worktrees/abc && - git worktree prune --verbose >actual && + git worktree prune --verbose 2>actual && cat >expect <<EOF && Removing worktrees/abc: not a valid directory EOF @@ -34,7 +34,7 @@ test_expect_success 'prune directories without gitdir' ' cat >expect <<EOF && Removing worktrees/def: gitdir file does not exist EOF - git worktree prune --verbose >actual && + git worktree prune --verbose 2>actual && test_cmp expect actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -45,7 +45,7 @@ test_expect_success SANITY 'prune directories with unreadable gitdir' ' : >.git/worktrees/def/def && : >.git/worktrees/def/gitdir && chmod u-r .git/worktrees/def/gitdir && - git worktree prune --verbose >actual && + git worktree prune --verbose 2>actual && test_i18ngrep "Removing worktrees/def: unable to read gitdir file" actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -55,7 +55,7 @@ test_expect_success 'prune directories with invalid gitdir' ' mkdir -p .git/worktrees/def/abc && : >.git/worktrees/def/def && : >.git/worktrees/def/gitdir && - git worktree prune --verbose >actual && + git worktree prune --verbose 2>actual && test_i18ngrep "Removing worktrees/def: invalid gitdir file" actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -65,7 +65,7 @@ test_expect_success 'prune directories with gitdir pointing to nowhere' ' mkdir -p .git/worktrees/def/abc && : >.git/worktrees/def/def && echo "$(pwd)"/nowhere >.git/worktrees/def/gitdir && - git worktree prune --verbose >actual && + git worktree prune --verbose 2>actual && test_i18ngrep "Removing worktrees/def: gitdir file points to non-existent location" actual && ! test -d .git/worktrees/def && ! test -d .git/worktrees @@ -101,7 +101,7 @@ test_expect_success 'prune duplicate (linked/linked)' ' git worktree add --detach w2 && sed "s/w2/w1/" .git/worktrees/w2/gitdir >.git/worktrees/w2/gitdir.new && mv .git/worktrees/w2/gitdir.new .git/worktrees/w2/gitdir && - git worktree prune --verbose >actual && + git worktree prune --verbose 2>actual && test_i18ngrep "duplicate entry" actual && test -d .git/worktrees/w1 && ! test -d .git/worktrees/w2 @@ -114,7 +114,7 @@ test_expect_success 'prune duplicate (main/linked)' ' git -C repo worktree add --detach ../wt && rm -fr wt && mv repo wt && - git -C wt worktree prune --verbose >actual && + git -C wt worktree prune --verbose 2>actual && test_i18ngrep "duplicate entry" actual && ! test -d .git/worktrees/wt ' diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index 4012bd67b0..c8a5a0aac6 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -134,7 +134,7 @@ test_expect_success '"list" all worktrees with prunable consistent with "prune"' git worktree list >out && grep "/prunable *[0-9a-f].* prunable$" out && ! grep "/unprunable *[0-9a-f].* unprunable$" out && - git worktree prune --verbose >out && + git worktree prune --verbose 2>out && test_i18ngrep "^Removing worktrees/prunable" out && test_i18ngrep ! "^Removing worktrees/unprunable" out ' diff --git a/t/t2404-worktree-config.sh b/t/t2404-worktree-config.sh index 9536d10919..842937bfb9 100755 --- a/t/t2404-worktree-config.sh +++ b/t/t2404-worktree-config.sh @@ -2,6 +2,7 @@ test_description="config file in multi worktree" +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh index f73741886b..5c44453e1c 100755 --- a/t/t2406-worktree-repair.sh +++ b/t/t2406-worktree-repair.sh @@ -45,9 +45,8 @@ test_corrupt_gitfile () { git worktree add --detach corrupt && git -C corrupt rev-parse --absolute-git-dir >expect && eval "$butcher" && - git -C "$repairdir" worktree repair >out 2>err && - test_i18ngrep "$problem" out && - test_must_be_empty err && + git -C "$repairdir" worktree repair 2>err && + test_i18ngrep "$problem" err && git -C corrupt rev-parse --absolute-git-dir >actual && test_cmp expect actual } @@ -130,10 +129,9 @@ test_expect_success 'repair broken gitdir' ' sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect && rm .git/worktrees/orig/gitdir && mv orig moved && - git worktree repair moved >out 2>err && + git worktree repair moved 2>err && test_cmp expect .git/worktrees/orig/gitdir && - test_i18ngrep "gitdir unreadable" out && - test_must_be_empty err + test_i18ngrep "gitdir unreadable" err ' test_expect_success 'repair incorrect gitdir' ' @@ -141,10 +139,9 @@ test_expect_success 'repair incorrect gitdir' ' git worktree add --detach orig && sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect && mv orig moved && - git worktree repair moved >out 2>err && + git worktree repair moved 2>err && test_cmp expect .git/worktrees/orig/gitdir && - test_i18ngrep "gitdir incorrect" out && - test_must_be_empty err + test_i18ngrep "gitdir incorrect" err ' test_expect_success 'repair gitdir (implicit) from linked worktree' ' @@ -152,10 +149,9 @@ test_expect_success 'repair gitdir (implicit) from linked worktree' ' git worktree add --detach orig && sed s,orig/\.git$,moved/.git, .git/worktrees/orig/gitdir >expect && mv orig moved && - git -C moved worktree repair >out 2>err && + git -C moved worktree repair 2>err && test_cmp expect .git/worktrees/orig/gitdir && - test_i18ngrep "gitdir incorrect" out && - test_must_be_empty err + test_i18ngrep "gitdir incorrect" err ' test_expect_success 'unable to repair gitdir (implicit) from main worktree' ' @@ -163,9 +159,8 @@ test_expect_success 'unable to repair gitdir (implicit) from main worktree' ' git worktree add --detach orig && cat .git/worktrees/orig/gitdir >expect && mv orig moved && - git worktree repair >out 2>err && + git worktree repair 2>err && test_cmp expect .git/worktrees/orig/gitdir && - test_must_be_empty out && test_must_be_empty err ' @@ -178,12 +173,11 @@ test_expect_success 'repair multiple gitdir files' ' sed s,orig2/\.git$,moved2/.git, .git/worktrees/orig2/gitdir >expect2 && mv orig1 moved1 && mv orig2 moved2 && - git worktree repair moved1 moved2 >out 2>err && + git worktree repair moved1 moved2 2>err && test_cmp expect1 .git/worktrees/orig1/gitdir && test_cmp expect2 .git/worktrees/orig2/gitdir && - test_i18ngrep "gitdir incorrect:.*orig1/gitdir$" out && - test_i18ngrep "gitdir incorrect:.*orig2/gitdir$" out && - test_must_be_empty err + test_i18ngrep "gitdir incorrect:.*orig1/gitdir$" err && + test_i18ngrep "gitdir incorrect:.*orig2/gitdir$" err ' test_expect_success 'repair moved main and linked worktrees' ' diff --git a/t/t3000-ls-files-others.sh b/t/t3000-ls-files-others.sh index 740ce56eab..11af4552f7 100755 --- a/t/t3000-ls-files-others.sh +++ b/t/t3000-ls-files-others.sh @@ -15,6 +15,8 @@ filesystem. path3/file3 - a file in a directory path4 - an empty directory ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup ' ' diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index 516c95ea0e..48cec4e5f8 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -8,6 +8,7 @@ test_description='git ls-files --others --exclude This test runs git ls-files --others and tests --exclude patterns. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh rm -fr one three @@ -102,7 +103,7 @@ test_expect_success \ >output && test_cmp expect output' -test_expect_success 'restore gitignore' ' +test_expect_success !SANITIZE_LEAK 'restore gitignore' ' git checkout --ignore-skip-worktree-bits $allignores && rm .git/index ' @@ -125,7 +126,7 @@ cat > expect << EOF # three/ EOF -test_expect_success 'git status honors core.excludesfile' \ +test_expect_success !SANITIZE_LEAK 'git status honors core.excludesfile' \ 'test_cmp expect output' test_expect_success 'trailing slash in exclude allows directory match(1)' ' diff --git a/t/t3002-ls-files-dashpath.sh b/t/t3002-ls-files-dashpath.sh index 8704b04e1b..54d22a45df 100755 --- a/t/t3002-ls-files-dashpath.sh +++ b/t/t3002-ls-files-dashpath.sh @@ -12,6 +12,8 @@ filesystem. -foo - a file with a funny name. -- - another file with a funny name. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t3003-ls-files-exclude.sh b/t/t3003-ls-files-exclude.sh index c41c4f046a..7933dff9b3 100755 --- a/t/t3003-ls-files-exclude.sh +++ b/t/t3003-ls-files-exclude.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='ls-files --exclude does not affect index files' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create repo with file' ' diff --git a/t/t3004-ls-files-basic.sh b/t/t3004-ls-files-basic.sh index 9fd5a1f188..a16e25c79b 100755 --- a/t/t3004-ls-files-basic.sh +++ b/t/t3004-ls-files-basic.sh @@ -6,6 +6,7 @@ This test runs git ls-files with various unusual or malformed command-line arguments. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'ls-files in empty repository' ' diff --git a/t/t3005-ls-files-relative.sh b/t/t3005-ls-files-relative.sh index 727e9ae1a4..6ba8b589cd 100755 --- a/t/t3005-ls-files-relative.sh +++ b/t/t3005-ls-files-relative.sh @@ -5,6 +5,7 @@ test_description='ls-files tests with relative paths This test runs git ls-files with various relative path arguments. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'prepare' ' diff --git a/t/t3006-ls-files-long.sh b/t/t3006-ls-files-long.sh index e109c3fbfb..2aaf91ebc8 100755 --- a/t/t3006-ls-files-long.sh +++ b/t/t3006-ls-files-long.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='overly long paths' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3008-ls-files-lazy-init-name-hash.sh b/t/t3008-ls-files-lazy-init-name-hash.sh index 85f3704958..51d3dffaa6 100755 --- a/t/t3008-ls-files-lazy-init-name-hash.sh +++ b/t/t3008-ls-files-lazy-init-name-hash.sh @@ -2,6 +2,7 @@ test_description='Test the lazy init name hash with various folder structures' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if test 1 -eq $(test-tool online-cpus) diff --git a/t/t3020-ls-files-error-unmatch.sh b/t/t3020-ls-files-error-unmatch.sh index 124e73b8e6..2cbcbc0721 100755 --- a/t/t3020-ls-files-error-unmatch.sh +++ b/t/t3020-ls-files-error-unmatch.sh @@ -9,6 +9,8 @@ This test runs git ls-files --error-unmatch to ensure it correctly returns an error when a non-existent path is provided on the command line. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3040-subprojects-basic.sh b/t/t3040-subprojects-basic.sh index 6abdcbbc94..bd65dfcffc 100755 --- a/t/t3040-subprojects-basic.sh +++ b/t/t3040-subprojects-basic.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='Basic subproject functionality' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup: create superproject' ' diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh index 56ea4bda13..72d5b014d8 100755 --- a/t/t3070-wildmatch.sh +++ b/t/t3070-wildmatch.sh @@ -2,6 +2,7 @@ test_description='wildmatch tests' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Disable expensive chain-lint tests; all of the tests in this script diff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh index 18baf49a49..436de44971 100755 --- a/t/t3100-ls-tree-restrict.sh +++ b/t/t3100-ls-tree-restrict.sh @@ -16,6 +16,8 @@ This test runs git ls-tree with the following in a tree. The new path restriction code should do the right thing for path2 and path2/baz. Also path0/ should snow nothing. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh index 12bf31022a..05fde64225 100755 --- a/t/t3101-ls-tree-dirname.sh +++ b/t/t3101-ls-tree-dirname.sh @@ -19,6 +19,8 @@ This test runs git ls-tree with the following in a tree. Test the handling of multiple directories which have matching file entries. Also test odd filename and missing entries handling. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3102-ls-tree-wildcards.sh b/t/t3102-ls-tree-wildcards.sh index 1e16c6b8ea..3942db2290 100755 --- a/t/t3102-ls-tree-wildcards.sh +++ b/t/t3102-ls-tree-wildcards.sh @@ -2,6 +2,7 @@ test_description='ls-tree with(out) globs' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3103-ls-tree-misc.sh b/t/t3103-ls-tree-misc.sh index 14520913af..d18ba1bd84 100755 --- a/t/t3103-ls-tree-misc.sh +++ b/t/t3103-ls-tree-misc.sh @@ -7,6 +7,7 @@ Miscellaneous tests for git ls-tree. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index e575ffb4ff..8a619d785e 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -168,6 +168,13 @@ test_expect_success 'git branch -M foo bar should fail when bar is checked out' test_must_fail git branch -M bar foo ' +test_expect_success 'git branch -M foo bar should fail when bar is checked out in worktree' ' + git branch -f bar && + test_when_finished "git worktree remove wt && git branch -D wt" && + git worktree add wt && + test_must_fail git branch -M bar wt +' + test_expect_success 'git branch -M baz bam should succeed when baz is checked out' ' git checkout -b baz && git branch bam && @@ -731,6 +738,28 @@ test_expect_success SYMLINKS 'git branch -m u v should fail when the reflog for test_must_fail git branch -m u v ' +test_expect_success SYMLINKS 'git branch -m with symlinked .git/refs' ' + test_when_finished "rm -rf subdir" && + git init --bare subdir && + + rm -rfv subdir/refs subdir/objects subdir/packed-refs && + ln -s ../.git/refs subdir/refs && + ln -s ../.git/objects subdir/objects && + ln -s ../.git/packed-refs subdir/packed-refs && + + git -C subdir rev-parse --absolute-git-dir >subdir.dir && + git rev-parse --absolute-git-dir >our.dir && + ! test_cmp subdir.dir our.dir && + + git -C subdir log && + git -C subdir branch rename-src && + git rev-parse rename-src >expect && + git -C subdir branch -m rename-src rename-dest && + git rev-parse rename-dest >actual && + test_cmp expect actual && + git branch -D rename-dest +' + test_expect_success 'test tracking setup via --track' ' git config remote.local.url . && git config remote.local.fetch refs/heads/*:refs/remotes/local/* && @@ -866,7 +895,7 @@ test_expect_success '--set-upstream-to fails on a missing src branch' ' ' test_expect_success '--set-upstream-to fails on a non-ref' ' - echo "fatal: Cannot setup tracking information; starting point '"'"'HEAD^{}'"'"' is not a branch." >expect && + echo "fatal: cannot set up tracking information; starting point '"'"'HEAD^{}'"'"' is not a branch" >expect && test_must_fail git branch --set-upstream-to HEAD^{} 2>err && test_cmp expect err ' @@ -953,7 +982,7 @@ test_expect_success 'disabled option --set-upstream fails' ' test_expect_success '--set-upstream-to notices an error to set branch as own upstream' ' git branch --set-upstream-to refs/heads/my13 my13 2>actual && cat >expect <<-\EOF && - warning: Not setting branch my13 as its own upstream. + warning: not setting branch my13 as its own upstream EOF test_expect_code 1 git config branch.my13.remote && test_expect_code 1 git config branch.my13.merge && @@ -1418,7 +1447,17 @@ test_expect_success 'invalid sort parameter in configuration' ' ( cd sort && git config branch.sort "v:notvalid" && - test_must_fail git branch + + # this works in the "listing" mode, so bad sort key + # is a dying offence. + test_must_fail git branch && + + # these do not need to use sorting, and should all + # succeed + git branch newone main && + git branch -c newone newerone && + git branch -m newone newestone && + git branch -d newerone newestone ) ' diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh index 349a810cee..800fc33165 100755 --- a/t/t3201-branch-contains.sh +++ b/t/t3201-branch-contains.sh @@ -2,9 +2,6 @@ test_description='branch --contains <commit>, --no-contains <commit> --merged, and --no-merged' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh index ad9902a06b..d4d64401e4 100755 --- a/t/t3202-show-branch.sh +++ b/t/t3202-show-branch.sh @@ -4,6 +4,9 @@ test_description='test show-branch' . ./test-lib.sh +# arbitrary reference time: 2009-08-30 19:20:00 +GIT_TEST_DATE_NOW=1251660000; export GIT_TEST_DATE_NOW + test_expect_success 'setup' ' test_commit initial && for i in $(test_seq 1 10) @@ -146,4 +149,16 @@ test_expect_success 'show branch --merge-base with N arguments' ' test_cmp expect actual ' +test_expect_success 'show branch --reflog=2' ' + sed "s/^> //" >expect <<-\EOF && + > ! [refs/heads/branch10@{0}] (4 years, 5 months ago) commit: branch10 + > ! [refs/heads/branch10@{1}] (4 years, 5 months ago) commit: branch10 + > -- + > + [refs/heads/branch10@{0}] branch10 + > ++ [refs/heads/branch10@{1}] initial + EOF + git show-branch --reflog=2 >actual && + test_cmp actual expect +' + test_done diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 6e94c6db7b..d34d77f893 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -1,9 +1,6 @@ #!/bin/sh test_description='git branch display tests' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t3205-branch-color.sh b/t/t3205-branch-color.sh index 08bd906173..0b61da92b3 100755 --- a/t/t3205-branch-color.sh +++ b/t/t3205-branch-color.sh @@ -1,9 +1,7 @@ #!/bin/sh test_description='basic branch output coloring' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up some sample branches' ' diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh index 37b9d26f4b..9cbc34fc58 100755 --- a/t/t3211-peel-ref.sh +++ b/t/t3211-peel-ref.sh @@ -4,6 +4,7 @@ test_description='tests for the peel_ref optimization of packed-refs' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create annotated tag in refs/tags' ' diff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh index f5bf16abcd..d3ac826283 100755 --- a/t/t3300-funny-names.sh +++ b/t/t3300-funny-names.sh @@ -9,6 +9,7 @@ This test tries pathnames with funny characters in the working tree, index, and tree objects. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh HT=' ' diff --git a/t/t3302-notes-index-expensive.sh b/t/t3302-notes-index-expensive.sh index ef8b63952e..bc9d8ee1e6 100755 --- a/t/t3302-notes-index-expensive.sh +++ b/t/t3302-notes-index-expensive.sh @@ -8,6 +8,7 @@ test_description='Test commit notes index (expensive!)' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_repo () { diff --git a/t/t3303-notes-subtrees.sh b/t/t3303-notes-subtrees.sh index d47ce00f69..f5fd80d4d3 100755 --- a/t/t3303-notes-subtrees.sh +++ b/t/t3303-notes-subtrees.sh @@ -5,6 +5,7 @@ test_description='Test commit notes organized in subtrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh number_of_commits=100 diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh index 94c1b02251..960d0587e1 100755 --- a/t/t3305-notes-fanout.sh +++ b/t/t3305-notes-fanout.sh @@ -2,6 +2,7 @@ test_description='Test that adding/removing many notes triggers automatic fanout restructuring' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh path_has_fanout() { diff --git a/t/t3320-notes-merge-worktrees.sh b/t/t3320-notes-merge-worktrees.sh index 6b2d507f3e..bff0aea550 100755 --- a/t/t3320-notes-merge-worktrees.sh +++ b/t/t3320-notes-merge-worktrees.sh @@ -8,6 +8,7 @@ test_description='Test merging of notes trees in multiple worktrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup commit' ' diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 972ce026bb..0baa68e9b4 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -25,8 +25,6 @@ Initial setup: where A, B, D and G all touch file1, and one, two, three, four all touch file "conflict". ' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh @@ -352,82 +350,6 @@ test_expect_success 'retain authorship when squashing' ' git show HEAD | grep "^Author: Twerp Snog" ' -test_expect_success REBASE_P '-p handles "no changes" gracefully' ' - HEAD=$(git rev-parse HEAD) && - git rebase -i -p HEAD^ && - git update-index --refresh && - git diff-files --quiet && - git diff-index --quiet --cached HEAD -- && - test $HEAD = $(git rev-parse HEAD) -' - -test_expect_failure REBASE_P 'exchange two commits with -p' ' - git checkout H && - ( - set_fake_editor && - FAKE_LINES="2 1" git rebase -i -p HEAD~2 - ) && - test H = $(git cat-file commit HEAD^ | sed -ne \$p) && - test G = $(git cat-file commit HEAD | sed -ne \$p) -' - -test_expect_success REBASE_P 'preserve merges with -p' ' - git checkout -b to-be-preserved primary^ && - : > unrelated-file && - git add unrelated-file && - test_tick && - git commit -m "unrelated" && - git checkout -b another-branch primary && - echo B > file1 && - test_tick && - git commit -m J file1 && - test_tick && - git merge to-be-preserved && - echo C > file1 && - test_tick && - git commit -m K file1 && - echo D > file1 && - test_tick && - git commit -m L1 file1 && - git checkout HEAD^ && - echo 1 > unrelated-file && - test_tick && - git commit -m L2 unrelated-file && - test_tick && - git merge another-branch && - echo E > file1 && - test_tick && - git commit -m M file1 && - git checkout -b to-be-rebased && - test_tick && - git rebase -i -p --onto branch1 primary && - git update-index --refresh && - git diff-files --quiet && - git diff-index --quiet --cached HEAD -- && - test_cmp_rev HEAD~6 branch1 && - test_cmp_rev HEAD~4^2 to-be-preserved && - test_cmp_rev HEAD^^2^ HEAD^^^ && - test $(git show HEAD~5:file1) = B && - test $(git show HEAD~3:file1) = C && - test $(git show HEAD:file1) = E && - test $(git show HEAD:unrelated-file) = 1 -' - -test_expect_success REBASE_P 'edit ancestor with -p' ' - ( - set_fake_editor && - FAKE_LINES="1 2 edit 3 4" git rebase -i -p HEAD~3 - ) && - echo 2 > unrelated-file && - test_tick && - git commit -m L2-modified --amend unrelated-file && - git rebase --continue && - git update-index --refresh && - git diff-files --quiet && - git diff-index --quiet --cached HEAD -- && - test $(git show HEAD:unrelated-file) = 2 -' - test_expect_success '--continue tries to commit' ' git reset --hard D && test_tick && diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh index ab0960e6d9..cde3562e3a 100755 --- a/t/t3408-rebase-multi-line.sh +++ b/t/t3408-rebase-multi-line.sh @@ -55,14 +55,4 @@ test_expect_success rebase ' test_cmp expect actual ' -test_expect_success REBASE_P rebasep ' - - git checkout side-merge && - git rebase -p side && - git cat-file commit HEAD | sed -e "1,/^\$/d" >actual && - git cat-file commit side-merge-original | sed -e "1,/^\$/d" >expect && - test_cmp expect actual - -' - test_done diff --git a/t/t3409-rebase-environ.sh b/t/t3409-rebase-environ.sh new file mode 100755 index 0000000000..83ffb39d9f --- /dev/null +++ b/t/t3409-rebase-environ.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +test_description='git rebase interactive environment' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit one && + test_commit two && + test_commit three +' + +test_expect_success 'rebase --exec does not muck with GIT_DIR' ' + git rebase --exec "printf %s \$GIT_DIR >environ" HEAD~1 && + test_must_be_empty environ +' + +test_expect_success 'rebase --exec does not muck with GIT_WORK_TREE' ' + git rebase --exec "printf %s \$GIT_WORK_TREE >environ" HEAD~1 && + test_must_be_empty environ +' + +test_done diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh deleted file mode 100755 index ec8062a66a..0000000000 --- a/t/t3409-rebase-preserve-merges.sh +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/sh -# -# Copyright(C) 2008 Stephen Habermann & Andreas Ericsson -# -test_description='git rebase -p should preserve merges - -Run "git rebase -p" and check that merges are properly carried along -' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - -. ./test-lib.sh - -if ! test_have_prereq REBASE_P; then - skip_all='skipping git rebase -p tests, as asked for' - test_done -fi - -GIT_AUTHOR_EMAIL=bogus_email_address -export GIT_AUTHOR_EMAIL - -# Clone 2 (conflicting merge): -# -# A1--A2--B3 <-- origin/main -# \ \ -# B1------M <-- topic -# \ -# B2 <-- origin/topic -# -# Clone 3 (no-ff merge): -# -# A1--A2--B3 <-- origin/main -# \ -# B1------M <-- topic -# \ / -# \--A3 <-- topic2 -# \ -# B2 <-- origin/topic -# -# Clone 4 (same as Clone 3) - -test_expect_success 'setup for merge-preserving rebase' \ - 'echo First > A && - git add A && - git commit -m "Add A1" && - git checkout -b topic && - echo Second > B && - git add B && - git commit -m "Add B1" && - git checkout -f main && - echo Third >> A && - git commit -a -m "Modify A2" && - echo Fifth > B && - git add B && - git commit -m "Add different B" && - - git clone ./. clone2 && - ( - cd clone2 && - git checkout -b topic origin/topic && - test_must_fail git merge origin/main && - echo Resolved >B && - git add B && - git commit -m "Merge origin/main into topic" - ) && - - git clone ./. clone3 && - ( - cd clone3 && - git checkout -b topic2 origin/topic && - echo Sixth > A && - git commit -a -m "Modify A3" && - git checkout -b topic origin/topic && - git merge --no-ff topic2 - ) && - - git clone ./. clone4 && - ( - cd clone4 && - git checkout -b topic2 origin/topic && - echo Sixth > A && - git commit -a -m "Modify A3" && - git checkout -b topic origin/topic && - git merge --no-ff topic2 - ) && - - git checkout topic && - echo Fourth >> B && - git commit -a -m "Modify B2" -' - -test_expect_success '--continue works after a conflict' ' - ( - cd clone2 && - git fetch && - test_must_fail git rebase -p origin/topic && - test 2 = $(git ls-files B | wc -l) && - echo Resolved again > B && - test_must_fail git rebase --continue && - grep "^@@@ " .git/rebase-merge/patch && - git add B && - git rebase --continue && - test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && - test 1 = $(git rev-list --all --pretty=oneline | grep "Add different" | wc -l) && - test 1 = $(git rev-list --all --pretty=oneline | grep "Merge origin" | wc -l) - ) -' - -test_expect_success 'rebase -p preserves no-ff merges' ' - ( - cd clone3 && - git fetch && - git rebase -p origin/topic && - test 3 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) && - test 1 = $(git rev-list --all --pretty=oneline | grep "Merge branch" | wc -l) - ) -' - -test_expect_success 'rebase -p ignores merge.log config' ' - ( - cd clone4 && - git fetch && - git -c merge.log=1 rebase -p origin/topic && - echo >expected && - git log --format="%b" -1 >current && - test_cmp expected current - ) -' - -test_done diff --git a/t/t3410-rebase-preserve-dropped-merges.sh b/t/t3410-rebase-preserve-dropped-merges.sh deleted file mode 100755 index 2e29866993..0000000000 --- a/t/t3410-rebase-preserve-dropped-merges.sh +++ /dev/null @@ -1,90 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2008 Stephen Haberman -# - -test_description='git rebase preserve merges - -This test runs git rebase with preserve merges and ensures commits -dropped by the --cherry-pick flag have their childrens parents -rewritten. -' -. ./test-lib.sh - -if ! test_have_prereq REBASE_P; then - skip_all='skipping git rebase -p tests, as asked for' - test_done -fi - -# set up two branches like this: -# -# A - B - C - D - E -# \ -# F - G - H -# \ -# I -# -# where B, D and G touch the same file. - -test_expect_success 'setup' ' - test_commit A file1 && - test_commit B file1 1 && - test_commit C file2 && - test_commit D file1 2 && - test_commit E file3 && - git checkout A && - test_commit F file4 && - test_commit G file1 3 && - test_commit H file5 && - git checkout F && - test_commit I file6 -' - -# A - B - C - D - E -# \ \ \ -# F - G - H -- L \ --> L -# \ | \ -# I -- G2 -- J -- K I -- K -# G2 = same changes as G -test_expect_success 'skip same-resolution merges with -p' ' - git checkout H && - test_must_fail git merge E && - test_commit L file1 23 && - git checkout I && - test_commit G2 file1 3 && - test_must_fail git merge E && - test_commit J file1 23 && - test_commit K file7 file7 && - git rebase -i -p L && - test $(git rev-parse HEAD^^) = $(git rev-parse L) && - test "23" = "$(cat file1)" && - test "I" = "$(cat file6)" && - test "file7" = "$(cat file7)" -' - -# A - B - C - D - E -# \ \ \ -# F - G - H -- L2 \ --> L2 -# \ | \ -# I -- G3 --- J2 -- K2 I -- G3 -- K2 -# G2 = different changes as G -test_expect_success 'keep different-resolution merges with -p' ' - git checkout H && - test_must_fail git merge E && - test_commit L2 file1 23 && - git checkout I && - test_commit G3 file1 4 && - test_must_fail git merge E && - test_commit J2 file1 24 && - test_commit K2 file7 file7 && - test_must_fail git rebase -i -p L2 && - echo 234 > file1 && - git add file1 && - git rebase --continue && - test $(git rev-parse HEAD^^^) = $(git rev-parse L2) && - test "234" = "$(cat file1)" && - test "I" = "$(cat file6)" && - test "file7" = "$(cat file7)" -' - -test_done diff --git a/t/t3411-rebase-preserve-around-merges.sh b/t/t3411-rebase-preserve-around-merges.sh deleted file mode 100755 index fb45e7bf7b..0000000000 --- a/t/t3411-rebase-preserve-around-merges.sh +++ /dev/null @@ -1,80 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2008 Stephen Haberman -# - -test_description='git rebase preserve merges - -This test runs git rebase with -p and tries to squash a commit from after -a merge to before the merge. -' -. ./test-lib.sh - -if ! test_have_prereq REBASE_P; then - skip_all='skipping git rebase -p tests, as asked for' - test_done -fi - -. "$TEST_DIRECTORY"/lib-rebase.sh - -set_fake_editor - -# set up two branches like this: -# -# A1 - B1 - D1 - E1 - F1 -# \ / -# -- C1 -- - -test_expect_success 'setup' ' - test_commit A1 && - test_commit B1 && - test_commit C1 && - git reset --hard B1 && - test_commit D1 && - test_merge E1 C1 && - test_commit F1 -' - -# Should result in: -# -# A1 - B1 - D2 - E2 -# \ / -# -- C1 -- -# -test_expect_success 'squash F1 into D1' ' - FAKE_LINES="1 squash 4 2 3" git rebase -i -p B1 && - test "$(git rev-parse HEAD^2)" = "$(git rev-parse C1)" && - test "$(git rev-parse HEAD~2)" = "$(git rev-parse B1)" && - git tag E2 -' - -# Start with: -# -# A1 - B1 - D2 - E2 -# \ -# G1 ---- L1 ---- M1 -# \ / -# H1 -- J1 -- K1 -# \ / -# -- I1 -- -# -# And rebase G1..M1 onto E2 - -test_expect_success 'rebase two levels of merge' ' - git checkout A1 && - test_commit G1 && - test_commit H1 && - test_commit I1 && - git checkout -b branch3 H1 && - test_commit J1 && - test_merge K1 I1 && - git checkout -b branch2 G1 && - test_commit L1 && - test_merge M1 K1 && - GIT_EDITOR=: git rebase -i -p E2 && - test "$(git rev-parse HEAD~3)" = "$(git rev-parse E2)" && - test "$(git rev-parse HEAD~2)" = "$(git rev-parse HEAD^2^2~2)" && - test "$(git rev-parse HEAD^2^1^1)" = "$(git rev-parse HEAD^2^2^1)" -' - -test_done diff --git a/t/t3412-rebase-root.sh b/t/t3412-rebase-root.sh index fda62c65bd..19c6f4acbf 100755 --- a/t/t3412-rebase-root.sh +++ b/t/t3412-rebase-root.sh @@ -89,17 +89,6 @@ test_expect_success 'pre-rebase got correct input (4)' ' test "z$(cat .git/PRE-REBASE-INPUT)" = z--root,work4 ' -test_expect_success REBASE_P 'rebase -i -p with linear history' ' - git checkout -b work5 other && - git rebase -i -p --root --onto main && - git log --pretty=tformat:"%s" > rebased5 && - test_cmp expect rebased5 -' - -test_expect_success REBASE_P 'pre-rebase got correct input (5)' ' - test "z$(cat .git/PRE-REBASE-INPUT)" = z--root, -' - test_expect_success 'set up merge history' ' git checkout other^ && git checkout -b side && @@ -123,13 +112,6 @@ commit work6~4 1 EOF -test_expect_success REBASE_P 'rebase -i -p with merge' ' - git checkout -b work6 other && - git rebase -i -p --root --onto main && - log_with_names work6 > rebased6 && - test_cmp expect-side rebased6 -' - test_expect_success 'set up second root and merge' ' git symbolic-ref HEAD refs/heads/third && rm .git/index && @@ -158,13 +140,6 @@ commit work7~5 1 EOF -test_expect_success REBASE_P 'rebase -i -p with two roots' ' - git checkout -b work7 other && - git rebase -i -p --root --onto main && - log_with_names work7 > rebased7 && - test_cmp expect-third rebased7 -' - test_expect_success 'setup pre-rebase hook that fails' ' mkdir -p .git/hooks && cat >.git/hooks/pre-rebase <<EOF && @@ -264,21 +239,9 @@ commit conflict3~6 1 EOF -test_expect_success REBASE_P 'rebase -i -p --root with conflict (first part)' ' - git checkout -b conflict3 other && - test_must_fail git rebase -i -p --root --onto main && - git ls-files -u | grep "B$" -' - test_expect_success 'fix the conflict' ' echo 3 > B && git add B ' -test_expect_success REBASE_P 'rebase -i -p --root with conflict (second part)' ' - git rebase --continue && - log_with_names conflict3 >out && - test_cmp expect-conflict-p out -' - test_done diff --git a/t/t3414-rebase-preserve-onto.sh b/t/t3414-rebase-preserve-onto.sh deleted file mode 100755 index 72e04b5386..0000000000 --- a/t/t3414-rebase-preserve-onto.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2009 Greg Price -# - -test_description='git rebase -p should respect --onto - -In a rebase with --onto, we should rewrite all the commits that -aren'"'"'t on top of $ONTO, even if they are on top of $UPSTREAM. -' -. ./test-lib.sh - -if ! test_have_prereq REBASE_P; then - skip_all='skipping git rebase -p tests, as asked for' - test_done -fi - -. "$TEST_DIRECTORY"/lib-rebase.sh - -# Set up branches like this: -# A1---B1---E1---F1---G1 -# \ \ / -# \ \--C1---D1--/ -# H1 - -test_expect_success 'setup' ' - test_commit A1 && - test_commit B1 && - test_commit C1 && - test_commit D1 && - git reset --hard B1 && - test_commit E1 && - test_commit F1 && - test_merge G1 D1 && - git reset --hard A1 && - test_commit H1 -' - -# Now rebase merge G1 from both branches' base B1, both should move: -# A1---B1---E1---F1---G1 -# \ \ / -# \ \--C1---D1--/ -# \ -# H1---E2---F2---G2 -# \ / -# \--C2---D2--/ - -test_expect_success 'rebase from B1 onto H1' ' - git checkout G1 && - git rebase -p --onto H1 B1 && - test "$(git rev-parse HEAD^1^1^1)" = "$(git rev-parse H1)" && - test "$(git rev-parse HEAD^2^1^1)" = "$(git rev-parse H1)" -' - -# On the other hand if rebase from E1 which is within one branch, -# then the other branch stays: -# A1---B1---E1---F1---G1 -# \ \ / -# \ \--C1---D1--/ -# \ \ -# H1-----F3-----G3 - -test_expect_success 'rebase from E1 onto H1' ' - git checkout G1 && - git rebase -p --onto H1 E1 && - test "$(git rev-parse HEAD^1^1)" = "$(git rev-parse H1)" && - test "$(git rev-parse HEAD^2)" = "$(git rev-parse D1)" -' - -# And the same if we rebase from a commit in the second-parent branch. -# A1---B1---E1---F1----G1 -# \ \ \ / -# \ \--C1---D1-\-/ -# \ \ -# H1------D3------G4 - -test_expect_success 'rebase from C1 onto H1' ' - git checkout G1 && - git rev-list --first-parent --pretty=oneline C1..G1 && - git rebase -p --onto H1 C1 && - test "$(git rev-parse HEAD^2^1)" = "$(git rev-parse H1)" && - test "$(git rev-parse HEAD^1)" = "$(git rev-parse F1)" -' - -test_done diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index 738fbae9b2..22eca73aa3 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -119,20 +119,6 @@ test_expect_success 'rebase -i --continue handles merge strategy and options' ' test -f funny.was.run ' -test_expect_success REBASE_P 'rebase passes merge strategy options correctly' ' - rm -fr .git/rebase-* && - git reset --hard commit-new-file-F3-on-topic-branch && - test_commit theirs-to-merge && - git reset --hard HEAD^ && - test_commit some-commit && - test_tick && - git merge --no-ff theirs-to-merge && - FAKE_LINES="1 edit 2 3" git rebase -i -f -p -m \ - -s recursive --strategy-option=theirs HEAD~2 && - test_commit force-change && - git rebase --continue -' - test_expect_success 'rebase -r passes merge strategy options correctly' ' rm -fr .git/rebase-* && git reset --hard commit-new-file-F3-on-topic-branch && @@ -268,7 +254,6 @@ test_rerere_autoupdate --apply test_rerere_autoupdate -m GIT_SEQUENCE_EDITOR=: && export GIT_SEQUENCE_EDITOR test_rerere_autoupdate -i -test_have_prereq !REBASE_P || test_rerere_autoupdate --preserve-merges unset GIT_SEQUENCE_EDITOR test_expect_success 'the todo command "break" works' ' diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh index 4a9204b4b6..62d86d557d 100755 --- a/t/t3421-rebase-topology-linear.sh +++ b/t/t3421-rebase-topology-linear.sh @@ -29,7 +29,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_expect_success 'setup branches and remote tracking' ' git tag -l >tags && @@ -53,7 +52,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -70,7 +68,6 @@ test_run_rebase success --apply test_run_rebase success --fork-point test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p test_run_rebase () { result=$1 @@ -87,7 +84,6 @@ test_run_rebase success --apply test_run_rebase success --fork-point test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -102,7 +98,6 @@ test_run_rebase success --apply test_run_rebase success --fork-point test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p # f # / @@ -142,7 +137,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -157,7 +151,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -172,7 +165,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -187,7 +179,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p # a---b---c---j! # \ @@ -215,7 +206,6 @@ test_run_rebase () { test_run_rebase failure --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p test_run_rebase () { result=$1 @@ -229,7 +219,6 @@ test_run_rebase () { } test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -243,7 +232,6 @@ test_run_rebase () { } test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase success --rebase-merges # m @@ -283,7 +271,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -298,7 +285,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p test_run_rebase () { result=$1 @@ -313,7 +299,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_run_rebase () { result=$1 @@ -329,7 +314,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p test_run_rebase () { result=$1 @@ -344,7 +328,6 @@ test_run_rebase () { test_run_rebase success --apply test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p test_run_rebase () { result=$1 @@ -358,7 +341,6 @@ test_run_rebase () { test_run_rebase success '' test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase failure -p test_run_rebase () { result=$1 @@ -373,6 +355,5 @@ test_run_rebase () { test_run_rebase success '' test_run_rebase success -m test_run_rebase success -i -test_have_prereq !REBASE_P || test_run_rebase success -p test_done diff --git a/t/t3422-rebase-incompatible-options.sh b/t/t3422-rebase-incompatible-options.sh index c8234062c6..6dabb05a2a 100755 --- a/t/t3422-rebase-incompatible-options.sh +++ b/t/t3422-rebase-incompatible-options.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test if rebase detects and aborts on incompatible options' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' @@ -63,15 +65,4 @@ test_rebase_am_only () { test_rebase_am_only --whitespace=fix test_rebase_am_only -C4 -test_expect_success REBASE_P '--preserve-merges incompatible with --signoff' ' - git checkout B^0 && - test_must_fail git rebase --preserve-merges --signoff A -' - -test_expect_success REBASE_P \ - '--preserve-merges incompatible with --rebase-merges' ' - git checkout B^0 && - test_must_fail git rebase --preserve-merges --rebase-merges A -' - test_done diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh index e42faa44e7..63acc1ea4d 100755 --- a/t/t3425-rebase-topology-merges.sh +++ b/t/t3425-rebase-topology-merges.sh @@ -106,155 +106,4 @@ test_run_rebase success 'd n o e' --apply test_run_rebase success 'd n o e' -m test_run_rebase success 'd n o e' -i -if ! test_have_prereq REBASE_P; then - skip_all='skipping git rebase -p tests, as asked for' - test_done -fi - -test_expect_success "rebase -p is no-op in non-linear history" " - reset_rebase && - git rebase -p d w && - test_cmp_rev w HEAD -" - -test_expect_success "rebase -p is no-op when base inside second parent" " - reset_rebase && - git rebase -p e w && - test_cmp_rev w HEAD -" - -test_expect_failure "rebase -p --root on non-linear history is a no-op" " - reset_rebase && - git rebase -p --root w && - test_cmp_rev w HEAD -" - -test_expect_success "rebase -p re-creates merge from side branch" " - reset_rebase && - git rebase -p z w && - test_cmp_rev z HEAD^ && - test_cmp_rev w^2 HEAD^2 -" - -test_expect_success "rebase -p re-creates internal merge" " - reset_rebase && - git rebase -p c w && - test_cmp_rev c HEAD~4 && - test_cmp_rev HEAD^2^ HEAD~3 && - test_revision_subjects 'd n e o w' HEAD~3 HEAD~2 HEAD^2 HEAD^ HEAD -" - -test_expect_success "rebase -p can re-create two branches on onto" " - reset_rebase && - git rebase -p --onto c d w && - test_cmp_rev c HEAD~3 && - test_cmp_rev c HEAD^2^ && - test_revision_subjects 'n e o w' HEAD~2 HEAD^2 HEAD^ HEAD -" - -# f -# / -# a---b---c---g---h -# \ -# d---gp--i -# \ \ -# e-------u -# -# gp = cherry-picked g -# h = reverted g -test_expect_success 'setup of non-linear-history for patch-equivalence tests' ' - git checkout e && - test_merge u i -' - -test_expect_success "rebase -p re-creates history around dropped commit matching upstream" " - reset_rebase && - git rebase -p h u && - test_cmp_rev h HEAD~3 && - test_cmp_rev HEAD^2^ HEAD~2 && - test_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD -" - -test_expect_success "rebase -p --onto in merged history drops patches in upstream" " - reset_rebase && - git rebase -p --onto f h u && - test_cmp_rev f HEAD~3 && - test_cmp_rev HEAD^2^ HEAD~2 && - test_revision_subjects 'd i e u' HEAD~2 HEAD^2 HEAD^ HEAD -" - -test_expect_success "rebase -p --onto in merged history does not drop patches in onto" " - reset_rebase && - git rebase -p --onto h f u && - test_cmp_rev h HEAD~3 && - test_cmp_rev HEAD^2~2 HEAD~2 && - test_revision_subjects 'd gp i e u' HEAD~2 HEAD^2^ HEAD^2 HEAD^ HEAD -" - -# a---b---c---g---h -# \ -# d---gp--s -# \ \ / -# \ X -# \ / \ -# e---t -# -# gp = cherry-picked g -# h = reverted g -test_expect_success 'setup of non-linear-history for dropping whole side' ' - git checkout gp && - test_merge s e && - git checkout e && - test_merge t gp -' - -test_expect_failure "rebase -p drops merge commit when entire first-parent side is dropped" " - reset_rebase && - git rebase -p h s && - test_cmp_rev h HEAD~2 && - test_linear_range 'd e' h.. -" - -test_expect_success "rebase -p drops merge commit when entire second-parent side is dropped" " - reset_rebase && - git rebase -p h t && - test_cmp_rev h HEAD~2 && - test_linear_range 'd e' h.. -" - -# a---b---c -# \ -# d---e -# \ \ -# n---r -# \ -# o -# -# r = tree-same with n -test_expect_success 'setup of non-linear-history for empty commits' ' - git checkout n && - git merge --no-commit e && - git reset n . && - git commit -m r && - git reset --hard && - git clean -f && - git tag r -' - -test_expect_success "rebase -p re-creates empty internal merge commit" " - reset_rebase && - git rebase -p c r && - test_cmp_rev c HEAD~3 && - test_cmp_rev HEAD^2^ HEAD~2 && - test_revision_subjects 'd e n r' HEAD~2 HEAD^2 HEAD^ HEAD -" - -test_expect_success "rebase -p re-creates empty merge commit" " - reset_rebase && - git rebase -p o r && - test_cmp_rev e HEAD^2 && - test_cmp_rev o HEAD^ && - test_revision_subjects 'r' HEAD -" - test_done diff --git a/t/t3427-rebase-subtree.sh b/t/t3427-rebase-subtree.sh index e78c7e3796..48b76f8232 100755 --- a/t/t3427-rebase-subtree.sh +++ b/t/t3427-rebase-subtree.sh @@ -36,11 +36,10 @@ commit_message() { # where the root commit adds three files: topic_1.t, topic_2.t and topic_3.t. # # This commit history is then rebased onto `topic_3` with the -# `-Xsubtree=files_subtree` option in three different ways: +# `-Xsubtree=files_subtree` option in two different ways: # -# 1. using `--preserve-merges` -# 2. using `--preserve-merges` and --keep-empty -# 3. without specifying a rebase backend +# 1. without specifying a rebase backend +# 2. using the `--rebase-merges` backend test_expect_success 'setup' ' test_commit README && @@ -69,25 +68,6 @@ test_expect_success 'setup' ' git commit -m "Empty commit" --allow-empty ' -# FAILURE: Does not preserve topic_4. -test_expect_failure REBASE_P 'Rebase -Xsubtree --preserve-merges --onto commit' ' - reset_rebase && - git checkout -b rebase-preserve-merges to-rebase && - git rebase -Xsubtree=files_subtree --preserve-merges --onto files-main main && - verbose test "$(commit_message HEAD~)" = "topic_4" && - verbose test "$(commit_message HEAD)" = "files_subtree/topic_5" -' - -# FAILURE: Does not preserve topic_4. -test_expect_failure REBASE_P 'Rebase -Xsubtree --keep-empty --preserve-merges --onto commit' ' - reset_rebase && - git checkout -b rebase-keep-empty to-rebase && - git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-main main && - verbose test "$(commit_message HEAD~2)" = "topic_4" && - verbose test "$(commit_message HEAD~)" = "files_subtree/topic_5" && - verbose test "$(commit_message HEAD)" = "Empty commit" -' - test_expect_success 'Rebase -Xsubtree --empty=ask --onto commit' ' reset_rebase && git checkout -b rebase-onto to-rebase && diff --git a/t/t3429-rebase-edit-todo.sh b/t/t3429-rebase-edit-todo.sh index 7024d49ae7..abd66f3602 100755 --- a/t/t3429-rebase-edit-todo.sh +++ b/t/t3429-rebase-edit-todo.sh @@ -13,10 +13,15 @@ test_expect_success 'setup' ' test_expect_success 'rebase exec modifies rebase-todo' ' todo=.git/rebase-merge/git-rebase-todo && - git rebase HEAD -x "echo exec touch F >>$todo" && + git rebase HEAD~1 -x "echo exec touch F >>$todo" && test -e F ' +test_expect_success 'rebase exec with an empty list does not exec anything' ' + git rebase HEAD -x "true" 2>output && + ! grep "Executing: true" output +' + test_expect_success 'loose object cache vs re-reading todo list' ' GIT_REBASE_TODO=.git/rebase-merge/git-rebase-todo && export GIT_REBASE_TODO && diff --git a/t/t3436-rebase-more-options.sh b/t/t3436-rebase-more-options.sh index 4d106642ba..94671d3c46 100755 --- a/t/t3436-rebase-more-options.sh +++ b/t/t3436-rebase-more-options.sh @@ -82,6 +82,20 @@ test_expect_success '--committer-date-is-author-date works with merge backend' ' test_ctime_is_atime -1 ' +test_expect_success '--committer-date-is-author-date works when rewording' ' + GIT_AUTHOR_DATE="@1234 +0300" git commit --amend --reset-author && + ( + set_fake_editor && + FAKE_COMMIT_MESSAGE=edited \ + FAKE_LINES="reword 1" \ + git rebase -i --committer-date-is-author-date HEAD^ + ) && + test_write_lines edited "" >expect && + git log --format="%B" -1 >actual && + test_cmp expect actual && + test_ctime_is_atime -1 +' + test_expect_success '--committer-date-is-author-date works with rebase -r' ' git checkout side && GIT_AUTHOR_DATE="@1234 +0300" git merge --no-ff commit3 && @@ -155,6 +169,21 @@ test_expect_success '--reset-author-date with --committer-date-is-author-date wo test_atime_is_ignored -2 ' +test_expect_success 'reset-author-date with --committer-date-is-author-date works when rewording' ' + GIT_AUTHOR_DATE="@1234 +0300" git commit --amend --reset-author && + ( + set_fake_editor && + FAKE_COMMIT_MESSAGE=edited \ + FAKE_LINES="reword 1" \ + git rebase -i --committer-date-is-author-date \ + --reset-author-date HEAD^ + ) && + test_write_lines edited "" >expect && + git log --format="%B" -1 >actual && + test_cmp expect actual && + test_atime_is_ignored -1 +' + test_expect_success '--reset-author-date --committer-date-is-author-date works when forking merge' ' GIT_SEQUENCE_EDITOR="echo \"merge -C $(git rev-parse HEAD) commit3\">" \ PATH="./test-bin:$PATH" git rebase -i --strategy=test \ diff --git a/t/t3601-rm-pathspec-file.sh b/t/t3601-rm-pathspec-file.sh index 7de21f8bcf..b2a8db69af 100755 --- a/t/t3601-rm-pathspec-file.sh +++ b/t/t3601-rm-pathspec-file.sh @@ -2,6 +2,7 @@ test_description='rm --pathspec-from-file' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t3602-rm-sparse-checkout.sh b/t/t3602-rm-sparse-checkout.sh index ecce497a9c..034ec01091 100755 --- a/t/t3602-rm-sparse-checkout.sh +++ b/t/t3602-rm-sparse-checkout.sh @@ -40,14 +40,20 @@ done test_expect_success 'recursive rm does not remove sparse entries' ' git reset --hard && git sparse-checkout set sub/dir && - test_must_fail git rm -r sub && - git rm --sparse -r sub && + git rm -r sub && git status --porcelain -uno >actual && cat >expected <<-\EOF && + D sub/dir/e + EOF + test_cmp expected actual && + + git rm --sparse -r sub && + git status --porcelain -uno >actual2 && + cat >expected2 <<-\EOF && D sub/d D sub/dir/e EOF - test_cmp expected actual + test_cmp expected2 actual2 ' test_expect_success 'recursive rm --sparse removes sparse entries' ' @@ -105,4 +111,29 @@ test_expect_success 'refuse to rm a non-skip-worktree path outside sparse cone' test_path_is_missing b ' +test_expect_success 'can remove files from non-sparse dir' ' + git reset --hard && + git sparse-checkout disable && + mkdir -p w x/y && + test_commit w/f && + test_commit x/y/f && + + git sparse-checkout set w !/x y/ && + git rm w/f.t x/y/f.t 2>stderr && + test_must_be_empty stderr +' + +test_expect_success 'refuse to remove non-skip-worktree file from sparse dir' ' + git reset --hard && + git sparse-checkout disable && + mkdir -p x/y/z && + test_commit x/y/z/f && + git sparse-checkout set !/x y/ !x/y/z && + + git update-index --no-skip-worktree x/y/z/f.t && + test_must_fail git rm x/y/z/f.t 2>stderr && + echo x/y/z/f.t | cat sparse_error_header - sparse_hint >expect && + test_cmp expect stderr +' + test_done diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 4086e1ebbc..283a66955d 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -5,6 +5,7 @@ test_description='Test of git add, including the -- option.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Test the file mode "$1" of the file "$2" in the index. diff --git a/t/t3702-add-edit.sh b/t/t3702-add-edit.sh index 6c676645d8..a1801a8cbd 100755 --- a/t/t3702-add-edit.sh +++ b/t/t3702-add-edit.sh @@ -4,6 +4,8 @@ # test_description='add -e basic tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t3703-add-magic-pathspec.sh b/t/t3703-add-magic-pathspec.sh index 3ef525a559..d84071038e 100755 --- a/t/t3703-add-magic-pathspec.sh +++ b/t/t3703-add-magic-pathspec.sh @@ -2,6 +2,7 @@ test_description='magic pathspec tests using git-add' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3704-add-pathspec-file.sh b/t/t3704-add-pathspec-file.sh index 9e35c1fbca..5d5164d1fc 100755 --- a/t/t3704-add-pathspec-file.sh +++ b/t/t3704-add-pathspec-file.sh @@ -2,6 +2,7 @@ test_description='add --pathspec-from-file' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t3705-add-sparse-checkout.sh b/t/t3705-add-sparse-checkout.sh index 5b904988d4..f3143c9290 100755 --- a/t/t3705-add-sparse-checkout.sh +++ b/t/t3705-add-sparse-checkout.sh @@ -214,4 +214,21 @@ test_expect_success 'add allows sparse entries with --sparse' ' test_must_be_empty stderr ' +test_expect_success 'can add files from non-sparse dir' ' + git sparse-checkout set w !/x y/ && + mkdir -p w x/y && + touch w/f x/y/f && + git add w/f x/y/f 2>stderr && + test_must_be_empty stderr +' + +test_expect_success 'refuse to add non-skip-worktree file from sparse dir' ' + git sparse-checkout set !/x y/ !x/y/z && + mkdir -p x/y/z && + touch x/y/z/f && + test_must_fail git add x/y/z/f 2>stderr && + echo x/y/z/f | cat sparse_error_header - sparse_hint >expect && + test_cmp expect stderr +' + test_done diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh index 0544d58a6e..e3cf0ffbe5 100755 --- a/t/t3800-mktag.sh +++ b/t/t3800-mktag.sh @@ -72,7 +72,8 @@ check_verify_failure () { # Manually create the broken, we cannot do it with # update-ref - echo "$bad_tag" >"bad-tag/$tag_ref" && + test-tool -C bad-tag ref-store main delete-refs 0 msg "$tag_ref" && + test-tool -C bad-tag ref-store main update-ref msg "$tag_ref" $bad_tag $ZERO_OID REF_SKIP_OID_VERIFICATION && # Unlike fsck-ing unreachable content above, this # will always fail. @@ -83,7 +84,8 @@ check_verify_failure () { # Make sure the earlier test created it for us git rev-parse "$bad_tag" && - echo "$bad_tag" >"bad-tag/$tag_ref" && + test-tool -C bad-tag ref-store main delete-refs 0 msg "$tag_ref" && + test-tool -C bad-tag ref-store main update-ref msg "$tag_ref" $bad_tag $ZERO_OID REF_SKIP_OID_VERIFICATION && printf "%s tag\t%s\n" "$bad_tag" "$tag_ref" >expected && git -C bad-tag for-each-ref "$tag_ref" >actual && diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh index f528008c36..72a5a565e9 100755 --- a/t/t3902-quoted.sh +++ b/t/t3902-quoted.sh @@ -5,6 +5,7 @@ test_description='quoted output' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh FN='濱野' diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index f0a82be9de..2c66cfbc3b 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -288,6 +288,17 @@ test_expect_success 'stash --no-keep-index' ' test bar,bar2 = $(cat file),$(cat file2) ' +test_expect_success 'stash --staged' ' + echo bar3 >file && + echo bar4 >file2 && + git add file2 && + git stash --staged && + test bar3,bar2 = $(cat file),$(cat file2) && + git reset --hard && + git stash pop && + test bar,bar4 = $(cat file),$(cat file2) +' + test_expect_success 'dont assume push with non-option args' ' test_must_fail git stash -q drop 2>err && test_i18ngrep -e "subcommand wasn'\''t specified; '\''push'\'' can'\''t be assumed due to unexpected token '\''drop'\''" err diff --git a/t/t3905-stash-include-untracked.sh b/t/t3905-stash-include-untracked.sh index dd2cdcc114..5390eec4e3 100755 --- a/t/t3905-stash-include-untracked.sh +++ b/t/t3905-stash-include-untracked.sh @@ -422,4 +422,10 @@ test_expect_success 'stash show --{include,only}-untracked on stashes without un test_must_be_empty actual ' +test_expect_success 'stash -u ignores sub-repository' ' + test_when_finished "rm -rf sub-repo" && + git init sub-repo && + git stash -u +' + test_done diff --git a/t/t3908-stash-in-worktree.sh b/t/t3908-stash-in-worktree.sh index 2b2b366ef9..347a89b030 100755 --- a/t/t3908-stash-in-worktree.sh +++ b/t/t3908-stash-in-worktree.sh @@ -5,6 +5,7 @@ test_description='Test git stash in a worktree' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh index cce334981e..bfcaae390f 100755 --- a/t/t4000-diff-format.sh +++ b/t/t4000-diff-format.sh @@ -6,6 +6,8 @@ test_description='Test built-in diff output engine. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index 6a9f010197..ea52e5b91b 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -6,6 +6,8 @@ test_description='Test diff raw-output. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree-m-3way.sh diff --git a/t/t4003-diff-rename-1.sh b/t/t4003-diff-rename-1.sh index db07ff3eb1..181e9683a7 100755 --- a/t/t4003-diff-rename-1.sh +++ b/t/t4003-diff-rename-1.sh @@ -6,12 +6,14 @@ test_description='More rename detection ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash test_expect_success \ 'prepare reference tree' \ - 'cat "$TEST_DIRECTORY"/lib-diff/COPYING >COPYING && + 'COPYING_test_data >COPYING && echo frotz >rezrov && git update-index --add COPYING rezrov && tree=$(git write-tree) && @@ -99,7 +101,7 @@ test_expect_success \ test_expect_success \ 'prepare work tree once again' \ - 'cat "$TEST_DIRECTORY"/lib-diff/COPYING >COPYING && + 'COPYING_test_data >COPYING && git update-index --add --remove COPYING COPYING.1' # tree has COPYING and rezrov. work tree has COPYING and COPYING.1, diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh index 3d495e37bb..8def4d4aee 100755 --- a/t/t4004-diff-rename-symlink.sh +++ b/t/t4004-diff-rename-symlink.sh @@ -9,6 +9,8 @@ The rename detection logic should be able to detect pure rename or copy of symbolic links, but should not produce rename/copy followed by an edit for them. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4005-diff-rename-2.sh b/t/t4005-diff-rename-2.sh index 8647906132..5c756dc243 100755 --- a/t/t4005-diff-rename-2.sh +++ b/t/t4005-diff-rename-2.sh @@ -5,11 +5,13 @@ test_description='Same rename detection as t4003 but testing diff-raw.' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash test_expect_success 'setup reference tree' ' - cat "$TEST_DIRECTORY"/lib-diff/COPYING >COPYING && + COPYING_test_data >COPYING && echo frotz >rezrov && git update-index --add COPYING rezrov && tree=$(git write-tree) && @@ -64,7 +66,7 @@ test_expect_success 'validate output from rename/copy detection (#2)' ' # nows how to say Copy. test_expect_success 'validate output from rename/copy detection (#3)' ' - cat "$TEST_DIRECTORY"/lib-diff/COPYING >COPYING && + COPYING_test_data >COPYING && git update-index --add --remove COPYING COPYING.1 && cat <<-EOF >expected && diff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh index 6cdee2a216..dbd4c0da21 100755 --- a/t/t4006-diff-mode.sh +++ b/t/t4006-diff-mode.sh @@ -6,6 +6,8 @@ test_description='Test mode change diffs. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh sed_script='s/\(:100644 100755\) \('"$OID_REGEX"'\) \2 /\1 X X /' diff --git a/t/t4007-rename-3.sh b/t/t4007-rename-3.sh index cbb9c62f53..b86165cbac 100755 --- a/t/t4007-rename-3.sh +++ b/t/t4007-rename-3.sh @@ -6,18 +6,19 @@ test_description='Rename interaction with pathspec. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash test_expect_success 'prepare reference tree' ' mkdir path0 path1 && - cp "$TEST_DIRECTORY"/lib-diff/COPYING path0/COPYING && + COPYING_test_data >path0/COPYING && git update-index --add path0/COPYING && tree=$(git write-tree) && - echo $tree + blob=$(git rev-parse :path0/COPYING) ' -blob=$(git hash-object "$TEST_DIRECTORY/lib-diff/COPYING") test_expect_success 'prepare work tree' ' cp path0/COPYING path1/COPYING && git update-index --add --remove path0/COPYING path1/COPYING diff --git a/t/t4008-diff-break-rewrite.sh b/t/t4008-diff-break-rewrite.sh index 2299f27511..562aaf3a2a 100755 --- a/t/t4008-diff-break-rewrite.sh +++ b/t/t4008-diff-break-rewrite.sh @@ -25,8 +25,8 @@ Further, with -B and -M together, these should turn into two renames. . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash test_expect_success setup ' - cat "$TEST_DIRECTORY"/lib-diff/README >file0 && - cat "$TEST_DIRECTORY"/lib-diff/COPYING >file1 && + echo some dissimilar content >file0 && + COPYING_test_data >file1 && blob0_id=$(git hash-object file0) && blob1_id=$(git hash-object file1) && git update-index --add file0 file1 && diff --git a/t/t4009-diff-rename-4.sh b/t/t4009-diff-rename-4.sh index b1da807f16..3480781dab 100755 --- a/t/t4009-diff-rename-4.sh +++ b/t/t4009-diff-rename-4.sh @@ -6,12 +6,14 @@ test_description='Same rename detection as t4003 but testing diff-raw -z. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash test_expect_success \ 'prepare reference tree' \ - 'cat "$TEST_DIRECTORY"/lib-diff/COPYING >COPYING && + 'COPYING_test_data >COPYING && echo frotz >rezrov && git update-index --add COPYING rezrov && orig=$(git hash-object COPYING) && @@ -81,7 +83,7 @@ test_expect_success \ test_expect_success \ 'prepare work tree once again' \ - 'cat "$TEST_DIRECTORY"/lib-diff/COPYING >COPYING && + 'COPYING_test_data >COPYING && git update-index --add --remove COPYING COPYING.1' git diff-index -z -C --find-copies-harder $tree >current diff --git a/t/t4010-diff-pathspec.sh b/t/t4010-diff-pathspec.sh index 1bbced79ec..9d9650eba7 100755 --- a/t/t4010-diff-pathspec.sh +++ b/t/t4010-diff-pathspec.sh @@ -9,6 +9,8 @@ Prepare: file0 path1/file1 ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh ;# test-lib chdir's into trash diff --git a/t/t4011-diff-symlink.sh b/t/t4011-diff-symlink.sh index 5a25c259fe..d7a5f7ae78 100755 --- a/t/t4011-diff-symlink.sh +++ b/t/t4011-diff-symlink.sh @@ -6,6 +6,8 @@ test_description='Test diff of symlinks. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4012-diff-binary.sh b/t/t4012-diff-binary.sh index 33ff588ebc..00eeafb2ac 100755 --- a/t/t4012-diff-binary.sh +++ b/t/t4012-diff-binary.sh @@ -6,6 +6,7 @@ test_description='Binary diff and apply ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect.binary-numstat <<\EOF diff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh index 876271d682..5a8d887683 100755 --- a/t/t4016-diff-quote.sh +++ b/t/t4016-diff-quote.sh @@ -6,6 +6,7 @@ test_description='Quoting paths in diff output. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh P0='pathname' diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh index c6135c7548..c68729ac09 100755 --- a/t/t4019-diff-wserror.sh +++ b/t/t4019-diff-wserror.sh @@ -2,6 +2,7 @@ test_description='diff whitespace error detection' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4020-diff-external.sh b/t/t4020-diff-external.sh index e009826fcb..54bb8ef27e 100755 --- a/t/t4020-diff-external.sh +++ b/t/t4020-diff-external.sh @@ -2,6 +2,7 @@ test_description='external diff interface test' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4022-diff-rewrite.sh b/t/t4022-diff-rewrite.sh index 6d1c3d949c..1c89050a97 100755 --- a/t/t4022-diff-rewrite.sh +++ b/t/t4022-diff-rewrite.sh @@ -3,15 +3,17 @@ test_description='rewrite diff' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-diff-data.sh test_expect_success setup ' - cat "$TEST_DIRECTORY"/../COPYING >test && + COPYING_test_data >test.data && + cp test.data test && git add test && tr \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" \ "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM" \ - <"$TEST_DIRECTORY"/../COPYING >test && + <test.data >test && echo "to be deleted" >test2 && blob=$(git hash-object test2) && blob=$(git rev-parse --short $blob) && diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh index 8c9823765e..47d6f35dcc 100755 --- a/t/t4023-diff-rename-typechange.sh +++ b/t/t4023-diff-rename-typechange.sh @@ -3,25 +3,26 @@ test_description='typechange rename detection' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-diff.sh test_expect_success setup ' rm -f foo bar && - cat "$TEST_DIRECTORY"/../COPYING >foo && + COPYING_test_data >foo && test_ln_s_add linklink bar && git add foo && git commit -a -m Initial && git tag one && git rm -f foo bar && - cat "$TEST_DIRECTORY"/../COPYING >bar && + COPYING_test_data >bar && test_ln_s_add linklink foo && git add bar && git commit -a -m Second && git tag two && git rm -f foo bar && - cat "$TEST_DIRECTORY"/../COPYING >foo && + COPYING_test_data >foo && git add foo && git commit -a -m Third && git tag three && @@ -35,7 +36,7 @@ test_expect_success setup ' # This is purely for sanity check git rm -f foo bar && - cat "$TEST_DIRECTORY"/../COPYING >foo && + COPYING_test_data >foo && cat "$TEST_DIRECTORY"/../Makefile >bar && git add foo bar && git commit -a -m Fifth && @@ -43,7 +44,7 @@ test_expect_success setup ' git rm -f foo bar && cat "$TEST_DIRECTORY"/../Makefile >foo && - cat "$TEST_DIRECTORY"/../COPYING >bar && + COPYING_test_data >bar && git add foo bar && git commit -a -m Sixth && git tag six diff --git a/t/t4024-diff-optimize-common.sh b/t/t4024-diff-optimize-common.sh index 6b44ce1493..540f93715e 100755 --- a/t/t4024-diff-optimize-common.sh +++ b/t/t4024-diff-optimize-common.sh @@ -2,6 +2,7 @@ test_description='common tail optimization' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh z=zzzzzzzz ;# 8 diff --git a/t/t4025-hunk-header.sh b/t/t4025-hunk-header.sh index 35578f2bb9..6356961de4 100755 --- a/t/t4025-hunk-header.sh +++ b/t/t4025-hunk-header.sh @@ -2,6 +2,7 @@ test_description='diff hunk header truncation' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh N='日本語' diff --git a/t/t4026-color.sh b/t/t4026-color.sh index c0b642c1ab..cc3f60d468 100755 --- a/t/t4026-color.sh +++ b/t/t4026-color.sh @@ -4,6 +4,8 @@ # test_description='Test diff/status color escape codes' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh ESC=$(printf '\033') @@ -58,6 +60,10 @@ test_expect_success 'fg bg attr...' ' color "blue bold dim ul blink reverse" "[1;2;4;5;7;34m" ' +test_expect_success 'reset fg bg attr...' ' + color "reset blue bold dim ul blink reverse" "[;1;2;4;5;7;34m" +' + # note that nobold and nodim are the same code (22) test_expect_success 'attr negation' ' color "nobold nodim noul noblink noreverse" "[22;24;25;27m" @@ -94,6 +100,18 @@ test_expect_success '24-bit colors' ' color "#ff00ff black" "[38;2;255;0;255;40m" ' +test_expect_success '"default" foreground' ' + color "default" "[39m" +' + +test_expect_success '"normal default" to clear background' ' + color "normal default" "[49m" +' + +test_expect_success '"default" can be combined with attributes' ' + color "default default no-reverse bold" "[1;27;39;49m" +' + test_expect_success '"normal" yields no color at all"' ' color "normal black" "[40m" ' diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 94ef77e1df..6cef0da982 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -2,6 +2,7 @@ test_description='difference in submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4029-diff-trailing-space.sh b/t/t4029-diff-trailing-space.sh index 32b6e9a4e7..5f8ffef74b 100755 --- a/t/t4029-diff-trailing-space.sh +++ b/t/t4029-diff-trailing-space.sh @@ -4,6 +4,7 @@ # test_description='diff honors config option, diff.suppressBlankEmpty' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat <<\EOF >expected || diff --git a/t/t4032-diff-inter-hunk-context.sh b/t/t4032-diff-inter-hunk-context.sh index bada0cbd32..7db92d0d9f 100755 --- a/t/t4032-diff-inter-hunk-context.sh +++ b/t/t4032-diff-inter-hunk-context.sh @@ -2,6 +2,7 @@ test_description='diff hunk fusing' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh f() { diff --git a/t/t4033-diff-patience.sh b/t/t4033-diff-patience.sh index 113304dc59..f7be7f5ef0 100755 --- a/t/t4033-diff-patience.sh +++ b/t/t4033-diff-patience.sh @@ -2,6 +2,7 @@ test_description='patience diff algorithm' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-alternative.sh diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 561c582d16..d5abcf4b4c 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -2,6 +2,7 @@ test_description='word diff colors' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4034/cpp/expect b/t/t4034/cpp/expect index 37d1ea2587..dc500ae092 100644 --- a/t/t4034/cpp/expect +++ b/t/t4034/cpp/expect @@ -1,36 +1,35 @@ <BOLD>diff --git a/pre b/post<RESET> -<BOLD>index 23d5c8a..7e8c026 100644<RESET> +<BOLD>index a1a09b7..f1b6f3c 100644<RESET> <BOLD>--- a/pre<RESET> <BOLD>+++ b/post<RESET> -<CYAN>@@ -1,19 +1,19 @@<RESET> -Foo() : x(0<RED>&&1<RESET><GREEN>&42<RESET>) { <GREEN>bar(x);<RESET> } +<CYAN>@@ -1,30 +1,30 @@<RESET> +Foo() : x(0<RED>&&1<RESET><GREEN>&42<RESET>) { <RED>foo0<RESET><GREEN>bar<RESET>(x.<RED>find<RESET><GREEN>Find<RESET>); } cout<<"Hello World<RED>!<RESET><GREEN>?<RESET>\n"<<endl; -<GREEN>(<RESET>1<GREEN>) (<RESET>-1e10<GREEN>) (<RESET>0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>y<RESET>' -[<RED>a<RESET><GREEN>x<RESET>] <RED>a<RESET><GREEN>x<RESET>-><RED>b a<RESET><GREEN>y x<RESET>.<RED>b<RESET><GREEN>y<RESET> -!<RED>a<RESET><GREEN>x<RESET> ~<RED>a a<RESET><GREEN>x x<RESET>++ <RED>a<RESET><GREEN>x<RESET>-- <RED>a<RESET><GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>&<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>*<RED>b a<RESET><GREEN>y x<RESET>/<RED>b a<RESET><GREEN>y x<RESET>%<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>+<RED>b a<RESET><GREEN>y x<RESET>-<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET><<<RED>b a<RESET><GREEN>y x<RESET>>><RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET><<RED>b a<RESET><GREEN>y x<RESET><=<RED>b a<RESET><GREEN>y x<RESET>><RED>b a<RESET><GREEN>y x<RESET>>=<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>==<RED>b a<RESET><GREEN>y x<RESET>!=<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>&<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>^<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>|<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>&&<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>||<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>?<RED>b<RESET><GREEN>y<RESET>:z -<RED>a<RESET><GREEN>x<RESET>=<RED>b a<RESET><GREEN>y x<RESET>+=<RED>b a<RESET><GREEN>y x<RESET>-=<RED>b a<RESET><GREEN>y x<RESET>*=<RED>b a<RESET><GREEN>y x<RESET>/=<RED>b a<RESET><GREEN>y x<RESET>%=<RED>b a<RESET><GREEN>y x<RESET><<=<RED>b a<RESET><GREEN>y x<RESET>>>=<RED>b a<RESET><GREEN>y x<RESET>&=<RED>b a<RESET><GREEN>y x<RESET>^=<RED>b a<RESET><GREEN>y x<RESET>|=<RED>b<RESET> -<RED>a<RESET><GREEN>y<RESET> -<GREEN>x<RESET>,y -<RED>a<RESET><GREEN>x<RESET>::<RED>b<RESET><GREEN>y<RESET> +<GREEN>(<RESET>1 <RED>-<RESET><GREEN>+<RESET>1e10 0xabcdef<GREEN>)<RESET> '<RED>x<RESET><GREEN>2<RESET>' +// long double<RESET> +<RED>3.141592653e-10l<RESET><GREEN>3.141592654e+10l<RESET> +// float<RESET> +<RED>120E5f<RESET><GREEN>120E6f<RESET> +// hex<RESET> +<RED>0xdead<RESET><GREEN>0xdeaf<RESET>'1<RED>eaF<RESET><GREEN>eaf<RESET>+<RED>8ULL<RESET><GREEN>7ULL<RESET> +// octal<RESET> +<RED>01234567<RESET><GREEN>01234560<RESET> +// binary<RESET> +<RED>0b1000<RESET><GREEN>0b1100<RESET>+e1 +// expression<RESET> +1.5-e+<RED>2<RESET><GREEN>3<RESET>+f +// another one<RESET> +str.e+<RED>65<RESET><GREEN>75<RESET> +[a] b<RED>-><RESET><GREEN>->*<RESET>v d<RED>.<RESET><GREEN>.*<RESET>e +<GREEN>~<RESET>!a <GREEN>!<RESET>~b c<RED>++<RESET><GREEN>+<RESET> d<RED>--<RESET><GREEN>-<RESET> e*<GREEN>*<RESET>f g<RED>&<RESET><GREEN>&&<RESET>h +a<RED>*<RESET><GREEN>*=<RESET>b c<RED>/<RESET><GREEN>/=<RESET>d e<RED>%<RESET><GREEN>%=<RESET>f +a<RED>+<RESET><GREEN>++<RESET>b c<RED>-<RESET><GREEN>--<RESET>d +a<RED><<<RESET><GREEN><<=<RESET>b c<RED>>><RESET><GREEN>>>=<RESET>d +a<RED><<RESET><GREEN><=<RESET>b c<RED><=<RESET><GREEN><<RESET>d e<RED>><RESET><GREEN>>=<RESET>f g<RED>>=<RESET><GREEN>><RESET>h i<RED><=<RESET><GREEN><=><RESET>j +a<RED>==<RESET><GREEN>!=<RESET>b c<RED>!=<RESET><GREEN>=<RESET>d +a<RED>^<RESET><GREEN>^=<RESET>b c<RED>|<RESET><GREEN>|=<RESET>d e<RED>&&<RESET><GREEN>&=<RESET>f +a<RED>||<RESET><GREEN>|<RESET>b +a?<GREEN>:<RESET>b +a<RED>=<RESET><GREEN>==<RESET>b c<RED>+=<RESET><GREEN>+<RESET>d e<RED>-=<RESET><GREEN>-<RESET>f g<RED>*=<RESET><GREEN>*<RESET>h i<RED>/=<RESET><GREEN>/<RESET>j k<RED>%=<RESET><GREEN>%<RESET>l m<RED><<=<RESET><GREEN><<<RESET>n o<RED>>>=<RESET><GREEN>>><RESET>p q<RED>&=<RESET><GREEN>&<RESET>r s<RED>^=<RESET><GREEN>^<RESET>t u<RED>|=<RESET><GREEN>|<RESET>v +a,b<RESET> +a<RED>::<RESET><GREEN>:<RESET>b diff --git a/t/t4034/cpp/post b/t/t4034/cpp/post index 7e8c026cef..f1b6f3c228 100644 --- a/t/t4034/cpp/post +++ b/t/t4034/cpp/post @@ -1,19 +1,30 @@ -Foo() : x(0&42) { bar(x); } +Foo() : x(0&42) { bar(x.Find); } cout<<"Hello World?\n"<<endl; -(1) (-1e10) (0xabcdef) 'y' -[x] x->y x.y -!x ~x x++ x-- x*y x&y -x*y x/y x%y -x+y x-y -x<<y x>>y -x<y x<=y x>y x>=y -x==y x!=y -x&y -x^y -x|y -x&&y -x||y -x?y:z -x=y x+=y x-=y x*=y x/=y x%=y x<<=y x>>=y x&=y x^=y x|=y -x,y -x::y +(1 +1e10 0xabcdef) '2' +// long double +3.141592654e+10l +// float +120E6f +// hex +0xdeaf'1eaf+7ULL +// octal +01234560 +// binary +0b1100+e1 +// expression +1.5-e+3+f +// another one +str.e+75 +[a] b->*v d.*e +~!a !~b c+ d- e**f g&&h +a*=b c/=d e%=f +a++b c--d +a<<=b c>>=d +a<=b c<d e>=f g>h i<=>j +a!=b c=d +a^=b c|=d e&=f +a|b +a?:b +a==b c+d e-f g*h i/j k%l m<<n o>>p q&r s^t u|v +a,b +a:b diff --git a/t/t4034/cpp/pre b/t/t4034/cpp/pre index 23d5c8adf5..a1a09b7712 100644 --- a/t/t4034/cpp/pre +++ b/t/t4034/cpp/pre @@ -1,19 +1,30 @@ -Foo():x(0&&1){} +Foo():x(0&&1){ foo0( x.find); } cout<<"Hello World!\n"<<endl; 1 -1e10 0xabcdef 'x' -[a] a->b a.b -!a ~a a++ a-- a*b a&b -a*b a/b a%b -a+b a-b -a<<b a>>b -a<b a<=b a>b a>=b -a==b a!=b -a&b -a^b -a|b -a&&b +// long double +3.141592653e-10l +// float +120E5f +// hex +0xdead'1eaF+8ULL +// octal +01234567 +// binary +0b1000+e1 +// expression +1.5-e+2+f +// another one +str.e+65 +[a] b->v d.e +!a ~b c++ d-- e*f g&h +a*b c/d e%f +a+b c-d +a<<b c>>d +a<b c<=d e>f g>=h i<=j +a==b c!=d +a^b c|d e&&f a||b -a?b:z -a=b a+=b a-=b a*=b a/=b a%=b a<<=b a>>=b a&=b a^=b a|=b -a,y +a?b +a=b c+=d e-=f g*=h i/=j k%=l m<<=n o>>=p q&=r s^=t u|=v +a,b a::b diff --git a/t/t4035-diff-quiet.sh b/t/t4035-diff-quiet.sh index 0352bf81a9..76f8034c60 100755 --- a/t/t4035-diff-quiet.sh +++ b/t/t4035-diff-quiet.sh @@ -2,6 +2,7 @@ test_description='Return value of diffs' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4037-diff-r-t-dirs.sh b/t/t4037-diff-r-t-dirs.sh index f5ce3b29a2..b5f96fe23b 100755 --- a/t/t4037-diff-r-t-dirs.sh +++ b/t/t4037-diff-r-t-dirs.sh @@ -2,6 +2,7 @@ test_description='diff -r -t shows directory additions and deletions' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4040-whitespace-status.sh b/t/t4040-whitespace-status.sh index 3c728a3ebf..e70e020ae9 100755 --- a/t/t4040-whitespace-status.sh +++ b/t/t4040-whitespace-status.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='diff --exit-code with whitespace' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4046-diff-unmerged.sh b/t/t4046-diff-unmerged.sh index ff7cfd884a..fd3f3a7260 100755 --- a/t/t4046-diff-unmerged.sh +++ b/t/t4046-diff-unmerged.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='diff with unmerged index entries' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4049-diff-stat-count.sh b/t/t4049-diff-stat-count.sh index 53061b104e..f5b35e7860 100755 --- a/t/t4049-diff-stat-count.sh +++ b/t/t4049-diff-stat-count.sh @@ -2,6 +2,8 @@ # Copyright (c) 2011, Google Inc. test_description='diff --stat-count' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4050-diff-histogram.sh b/t/t4050-diff-histogram.sh index fd3e86a74f..c61b30f96d 100755 --- a/t/t4050-diff-histogram.sh +++ b/t/t4050-diff-histogram.sh @@ -2,6 +2,7 @@ test_description='histogram diff algorithm' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-alternative.sh diff --git a/t/t4054-diff-bogus-tree.sh b/t/t4054-diff-bogus-tree.sh index 8c95f152b2..294fb55313 100755 --- a/t/t4054-diff-bogus-tree.sh +++ b/t/t4054-diff-bogus-tree.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test diff with a bogus tree containing the null sha1' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create bogus tree' ' diff --git a/t/t4062-diff-pickaxe.sh b/t/t4062-diff-pickaxe.sh index 1130c8019b..9aaa068ed9 100755 --- a/t/t4062-diff-pickaxe.sh +++ b/t/t4062-diff-pickaxe.sh @@ -5,6 +5,7 @@ test_description='Pickaxe options' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4063-diff-blobs.sh b/t/t4063-diff-blobs.sh index bc69e26c52..7e6c9d6384 100755 --- a/t/t4063-diff-blobs.sh +++ b/t/t4063-diff-blobs.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test direct comparison of blobs via git-diff' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh run_diff () { diff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh index 9b433de836..d503547732 100755 --- a/t/t4100-apply-stat.sh +++ b/t/t4100-apply-stat.sh @@ -6,6 +6,8 @@ test_description='git apply --stat --summary test, with --recount ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh UNC='s/^\(@@ -[1-9][0-9]*\),[0-9]* \(+[1-9][0-9]*\),[0-9]* @@/\1,999 \2,999 @@/' diff --git a/t/t4101-apply-nonl.sh b/t/t4101-apply-nonl.sh index e3443d004d..b1169193ef 100755 --- a/t/t4101-apply-nonl.sh +++ b/t/t4101-apply-nonl.sh @@ -6,6 +6,8 @@ test_description='git apply should handle files with incomplete lines. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # setup diff --git a/t/t4102-apply-rename.sh b/t/t4102-apply-rename.sh index fae305979a..d1e06fc1ac 100755 --- a/t/t4102-apply-rename.sh +++ b/t/t4102-apply-rename.sh @@ -6,6 +6,8 @@ test_description='git apply handling copy/rename patch. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # setup diff --git a/t/t4105-apply-fuzz.sh b/t/t4105-apply-fuzz.sh index 3266e39400..76e2c01b0f 100755 --- a/t/t4105-apply-fuzz.sh +++ b/t/t4105-apply-fuzz.sh @@ -2,6 +2,8 @@ test_description='apply with fuzz and offset' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh dotest () { diff --git a/t/t4106-apply-stdin.sh b/t/t4106-apply-stdin.sh index 72467a1e8e..a57a318699 100755 --- a/t/t4106-apply-stdin.sh +++ b/t/t4106-apply-stdin.sh @@ -2,6 +2,8 @@ test_description='git apply --numstat - <patch' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4109-apply-multifrag.sh b/t/t4109-apply-multifrag.sh index ac58083fe2..4dc6d8e7d3 100755 --- a/t/t4109-apply-multifrag.sh +++ b/t/t4109-apply-multifrag.sh @@ -6,6 +6,8 @@ test_description='git apply test patches with multiple fragments.' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cp "$TEST_DIRECTORY/t4109/patch1.patch" . diff --git a/t/t4110-apply-scan.sh b/t/t4110-apply-scan.sh index 09f58112e0..266302a182 100755 --- a/t/t4110-apply-scan.sh +++ b/t/t4110-apply-scan.sh @@ -7,6 +7,8 @@ test_description='git apply test for patches which require scanning forwards and backwards. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'git apply scan' ' diff --git a/t/t4112-apply-renames.sh b/t/t4112-apply-renames.sh index f9ad183758..d53aa4222e 100755 --- a/t/t4112-apply-renames.sh +++ b/t/t4112-apply-renames.sh @@ -7,6 +7,8 @@ test_description='git apply should not get confused with rename/copy. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # setup diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh index 872fcda6cb..d0f3edef54 100755 --- a/t/t4115-apply-symlink.sh +++ b/t/t4115-apply-symlink.sh @@ -7,6 +7,7 @@ test_description='git apply symlinks and partial files ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh index b99e65c086..f3b635475a 100755 --- a/t/t4116-apply-reverse.sh +++ b/t/t4116-apply-reverse.sh @@ -7,6 +7,8 @@ test_description='git apply in reverse ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh index 65f2e4c3ef..5fc6d3e4e7 100755 --- a/t/t4118-apply-empty-context.sh +++ b/t/t4118-apply-empty-context.sh @@ -7,6 +7,8 @@ test_description='git apply with new style GNU diff with empty context ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4119-apply-config.sh b/t/t4119-apply-config.sh index a9a0583811..208c961d37 100755 --- a/t/t4119-apply-config.sh +++ b/t/t4119-apply-config.sh @@ -7,6 +7,8 @@ test_description='git apply --whitespace=strip and configuration file. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4121-apply-diffs.sh b/t/t4121-apply-diffs.sh index b45454aaf4..a80cec9d11 100755 --- a/t/t4121-apply-diffs.sh +++ b/t/t4121-apply-diffs.sh @@ -4,6 +4,7 @@ test_description='git apply for contextually independent diffs' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh echo '1 diff --git a/t/t4123-apply-shrink.sh b/t/t4123-apply-shrink.sh index 984157f03b..ef57cd3aeb 100755 --- a/t/t4123-apply-shrink.sh +++ b/t/t4123-apply-shrink.sh @@ -2,6 +2,8 @@ test_description='apply a patch that is larger than the preimage' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >F <<\EOF diff --git a/t/t4126-apply-empty.sh b/t/t4126-apply-empty.sh index ceb6a79fe0..a361e79a81 100755 --- a/t/t4126-apply-empty.sh +++ b/t/t4126-apply-empty.sh @@ -2,6 +2,8 @@ test_description='apply empty' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4127-apply-same-fn.sh b/t/t4127-apply-same-fn.sh index 305b7e649e..c27e9aec57 100755 --- a/t/t4127-apply-same-fn.sh +++ b/t/t4127-apply-same-fn.sh @@ -2,6 +2,8 @@ test_description='apply same filename' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh modify () { diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh index 6cc741a634..cb3181e8b7 100755 --- a/t/t4128-apply-root.sh +++ b/t/t4128-apply-root.sh @@ -2,6 +2,8 @@ test_description='apply same filename' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4129-apply-samemode.sh b/t/t4129-apply-samemode.sh index 576632f868..a1c7686519 100755 --- a/t/t4129-apply-samemode.sh +++ b/t/t4129-apply-samemode.sh @@ -2,6 +2,8 @@ test_description='applying patch with mode bits' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4130-apply-criss-cross-rename.sh b/t/t4130-apply-criss-cross-rename.sh index f8a313bcb9..f3ea632742 100755 --- a/t/t4130-apply-criss-cross-rename.sh +++ b/t/t4130-apply-criss-cross-rename.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git apply handling criss-cross rename patch.' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_file() { diff --git a/t/t4132-apply-removal.sh b/t/t4132-apply-removal.sh index fec1d6fa51..c1e3049c04 100755 --- a/t/t4132-apply-removal.sh +++ b/t/t4132-apply-removal.sh @@ -4,6 +4,8 @@ test_description='git-apply notices removal patches generated by GNU diff' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4133-apply-filenames.sh b/t/t4133-apply-filenames.sh index c5ed3b17c4..35f1060bc8 100755 --- a/t/t4133-apply-filenames.sh +++ b/t/t4133-apply-filenames.sh @@ -5,6 +5,8 @@ test_description='git apply filename consistency check' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4134-apply-submodule.sh b/t/t4134-apply-submodule.sh index d1c16ba33c..aceb4c42b0 100755 --- a/t/t4134-apply-submodule.sh +++ b/t/t4134-apply-submodule.sh @@ -5,6 +5,8 @@ test_description='git apply submodule tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4136-apply-check.sh b/t/t4136-apply-check.sh index 4c3f264a63..dfec1c5f0f 100755 --- a/t/t4136-apply-check.sh +++ b/t/t4136-apply-check.sh @@ -2,6 +2,8 @@ test_description='git apply should exit non-zero with unrecognized input.' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4139-apply-escape.sh b/t/t4139-apply-escape.sh index 45b5660a47..e5c7439df1 100755 --- a/t/t4139-apply-escape.sh +++ b/t/t4139-apply-escape.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='paths written by git-apply cannot escape the working tree' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # tests will try to write to ../foo, and we do not diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 9dfead936b..2ced7e9d81 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -449,6 +449,57 @@ test_expect_success !FAIL_PREREQS 'log with various grep.patternType configurati ) ' +test_expect_success 'log --author' ' + cat >expect <<-\EOF && + Author: <BOLD;RED>A U<RESET> Thor <author@example.com> + EOF + git log -1 --color=always --author="A U" >log && + grep Author log >actual.raw && + test_decode_color <actual.raw >actual && + test_cmp expect actual +' + +test_expect_success 'log --committer' ' + cat >expect <<-\EOF && + Commit: C O Mitter <committer@<BOLD;RED>example<RESET>.com> + EOF + git log -1 --color=always --pretty=fuller --committer="example" >log && + grep "Commit:" log >actual.raw && + test_decode_color <actual.raw >actual && + test_cmp expect actual +' + +test_expect_success 'log -i --grep with color' ' + cat >expect <<-\EOF && + <BOLD;RED>Sec<RESET>ond + <BOLD;RED>sec<RESET>ond + EOF + git log --color=always -i --grep=^sec >log && + grep -i sec log >actual.raw && + test_decode_color <actual.raw >actual && + test_cmp expect actual +' + +test_expect_success '-c color.grep.selected log --grep' ' + cat >expect <<-\EOF && + <GREEN>th<RESET><BOLD;RED>ir<RESET><GREEN>d<RESET> + EOF + git -c color.grep.selected="green" log --color=always --grep=ir >log && + grep ir log >actual.raw && + test_decode_color <actual.raw >actual && + test_cmp expect actual +' + +test_expect_success '-c color.grep.matchSelected log --grep' ' + cat >expect <<-\EOF && + <BLUE>i<RESET>n<BLUE>i<RESET>t<BLUE>i<RESET>al + EOF + git -c color.grep.matchSelected="blue" log --color=always --grep=i >log && + grep al log >actual.raw && + test_decode_color <actual.raw >actual && + test_cmp expect actual +' + cat > expect <<EOF * Second * sixth @@ -901,6 +952,43 @@ test_expect_success 'decorate-refs-exclude and simplify-by-decoration' ' test_cmp expect.decorate actual ' +test_expect_success 'decorate-refs with implied decorate from format' ' + cat >expect <<-\EOF && + side-2 (tag: side-2) + side-1 + EOF + git log --no-walk --format="%s%d" \ + --decorate-refs="*side-2" side-1 side-2 \ + >actual && + test_cmp expect actual +' + +test_expect_success 'implied decorate does not override option' ' + cat >expect <<-\EOF && + side-2 (tag: refs/tags/side-2, refs/heads/side) + side-1 (tag: refs/tags/side-1) + EOF + git log --no-walk --format="%s%d" \ + --decorate=full side-1 side-2 \ + >actual && + test_cmp expect actual +' + +test_expect_success 'decorate-refs and simplify-by-decoration without output' ' + cat >expect <<-\EOF && + side-2 + initial + EOF + # Do not just use a --format without %d here; we want to + # make sure that we did not accidentally turn on displaying + # the decorations, too. And that requires one of the regular + # formats. + git log --decorate-refs="*side-2" --oneline \ + --simplify-by-decoration >actual.raw && + sed "s/^[0-9a-f]* //" <actual.raw >actual && + test_cmp expect actual +' + test_expect_success 'log.decorate config parsing' ' git log --oneline --decorate=full >expect.full && git log --oneline --decorate=short >expect.short && @@ -1616,6 +1704,34 @@ test_expect_success GPGSM 'setup signed branch x509' ' git commit -S -m signed_commit ' +test_expect_success GPGSSH 'setup sshkey signed branch' ' + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + test_when_finished "git reset --hard && git checkout main" && + git checkout -b signed-ssh main && + echo foo >foo && + git add foo && + git commit -S -m signed_commit +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'create signed commits with keys having defined lifetimes' ' + test_config gpg.format ssh && + touch file && + git add file && + + echo expired >file && test_tick && git commit -a -m expired -S"${GPGSSH_KEY_EXPIRED}" && + git tag expired-signed && + + echo notyetvalid >file && test_tick && git commit -a -m notyetvalid -S"${GPGSSH_KEY_NOTYETVALID}" && + git tag notyetvalid-signed && + + echo timeboxedvalid >file && test_tick && git commit -a -m timeboxedvalid -S"${GPGSSH_KEY_TIMEBOXEDVALID}" && + git tag timeboxedvalid-signed && + + echo timeboxedinvalid >file && test_tick && git commit -a -m timeboxedinvalid -S"${GPGSSH_KEY_TIMEBOXEDINVALID}" && + git tag timeboxedinvalid-signed +' + test_expect_success GPGSM 'log x509 fingerprint' ' echo "F8BF62E0693D0694816377099909C779FA23FD65 | " >expect && git log -n1 --format="%GF | %GP" signed-x509 >actual && @@ -1628,6 +1744,13 @@ test_expect_success GPGSM 'log OpenPGP fingerprint' ' test_cmp expect actual ' +test_expect_success GPGSSH 'log ssh key fingerprint' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2\" | \"}" >expect && + git log -n1 --format="%GF | %GP" signed-ssh >actual && + test_cmp expect actual +' + test_expect_success GPG 'log --graph --show-signature' ' git log --graph --show-signature -n1 signed >actual && grep "^| gpg: Signature made" actual && @@ -1640,6 +1763,37 @@ test_expect_success GPGSM 'log --graph --show-signature x509' ' grep "^| gpgsm: Good signature" actual ' +test_expect_success GPGSSH 'log --graph --show-signature ssh' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git log --graph --show-signature -n1 signed-ssh >actual && + grep "${GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'log shows failure on expired signature key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git log --graph --show-signature -n1 expired-signed >actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'log shows failure on not yet valid signature key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git log --graph --show-signature -n1 notyetvalid-signed >actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'log show success with commit date and key validity matching' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git log --graph --show-signature -n1 timeboxedvalid-signed >actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'log shows failure with commit date outside of key validity' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git log --graph --show-signature -n1 timeboxedinvalid-signed >actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + test_expect_success GPG 'log --graph --show-signature for merged tag' ' test_when_finished "git reset --hard && git checkout main" && git checkout -b plain main && diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh index f120857c20..e78d8097f3 100755 --- a/t/t4204-patch-id.sh +++ b/t/t4204-patch-id.sh @@ -5,6 +5,7 @@ test_description='git patch-id' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index 5865daa8f8..35eef4c865 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -1002,4 +1002,20 @@ test_expect_success '%(describe:exclude=...) vs git describe --exclude ...' ' test_cmp expect actual ' +test_expect_success '%(describe:tags) vs git describe --tags' ' + test_when_finished "git tag -d tagname" && + git tag tagname && + git describe --tags >expect && + git log -1 --format="%(describe:tags)" >actual && + test_cmp expect actual +' + +test_expect_success '%(describe:abbrev=...) vs git describe --abbrev=...' ' + test_when_finished "git tag -d tagname" && + git tag -a -m tagged tagname && + git describe --abbrev=15 >expect && + git log -1 --format="%(describe:abbrev=15)" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index 0141f36e33..d2dfcf164e 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -131,11 +131,4 @@ do fi done -test_expect_success 'log shows warning when conversion fails' ' - enc=this-encoding-does-not-exist && - git log -1 --encoding=$enc 2>err && - echo "warning: unable to reencode commit to ${SQ}${enc}${SQ}" >expect && - test_cmp expect err -' - test_done diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh index 50f206db55..8018c12a6a 100755 --- a/t/t4216-log-bloom.sh +++ b/t/t4216-log-bloom.sh @@ -175,13 +175,11 @@ test_expect_success 'persist filter settings' ' test_when_finished rm -rf .git/objects/info/commit-graph* && rm -rf .git/objects/info/commit-graph* && GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ - GIT_TRACE2_EVENT_NESTING=5 \ GIT_TEST_BLOOM_SETTINGS_NUM_HASHES=9 \ GIT_TEST_BLOOM_SETTINGS_BITS_PER_ENTRY=15 \ git commit-graph write --reachable --changed-paths && grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2.txt && GIT_TRACE2_EVENT="$(pwd)/trace2-auto.txt" \ - GIT_TRACE2_EVENT_NESTING=5 \ git commit-graph write --reachable --changed-paths && grep "{\"hash_version\":1,\"num_hashes\":9,\"bits_per_entry\":15,\"max_changed_paths\":512" trace2-auto.txt ' diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh index e59601e5fe..c52c8a21fa 100755 --- a/t/t4300-merge-tree.sh +++ b/t/t4300-merge-tree.sh @@ -4,6 +4,8 @@ # test_description='git merge-tree' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5002-archive-attr-pattern.sh b/t/t5002-archive-attr-pattern.sh index bda6d7d7e9..a66b5ba27e 100755 --- a/t/t5002-archive-attr-pattern.sh +++ b/t/t5002-archive-attr-pattern.sh @@ -2,6 +2,7 @@ test_description='git archive attribute pattern tests' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_exists() { diff --git a/t/t5200-update-server-info.sh b/t/t5200-update-server-info.sh index 21a58eecb9..ed9dfd624c 100755 --- a/t/t5200-update-server-info.sh +++ b/t/t5200-update-server-info.sh @@ -2,6 +2,7 @@ test_description='Test git update-server-info' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' 'test_commit file' diff --git a/t/t5307-pack-missing-commit.sh b/t/t5307-pack-missing-commit.sh index f4338abb78..d3482ab279 100755 --- a/t/t5307-pack-missing-commit.sh +++ b/t/t5307-pack-missing-commit.sh @@ -2,6 +2,7 @@ test_description='pack should notice missing commit objects' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index 673baa5c3c..cbd33d5bde 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -1,11 +1,8 @@ #!/bin/sh test_description='exercise basic bitmap functionality' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh -. "$TEST_DIRECTORY"/lib-bundle.sh . "$TEST_DIRECTORY"/lib-bitmap.sh # t5310 deals only with single-pack bitmaps, so don't write MIDX bitmaps in @@ -36,7 +33,7 @@ test_expect_success 'setup writing bitmaps during repack' ' ' test_expect_success 'full repack creates bitmaps' ' - GIT_TRACE2_EVENT_NESTING=4 GIT_TRACE2_EVENT="$(pwd)/trace" \ + GIT_TRACE2_EVENT="$(pwd)/trace" \ git repack -ad && ls .git/objects/pack/ | grep bitmap >output && test_line_count = 1 output && diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index 295c5bd94d..f516fda7cc 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -70,8 +70,8 @@ test_expect_success 'create commits and repack' ' ' graph_git_two_modes() { - git -c core.commitGraph=true $1 >output - git -c core.commitGraph=false $1 >expect + git -c core.commitGraph=true $1 >output && + git -c core.commitGraph=false $1 >expect && test_cmp expect output } @@ -385,6 +385,7 @@ test_expect_success 'replace-objects invalidates commit-graph' ' git commit-graph write --reachable && test_path_is_file .git/objects/info/commit-graph && git replace HEAD~1 HEAD~2 && + graph_git_two_modes "commit-graph verify" && git -c core.commitGraph=false log >expect && git -c core.commitGraph=true log >actual && test_cmp expect actual && @@ -693,12 +694,33 @@ test_expect_success 'detect incorrect chunk count' ' $GRAPH_CHUNK_LOOKUP_OFFSET ' -test_expect_success 'git fsck (checks commit-graph)' ' +test_expect_success 'git fsck (checks commit-graph when config set to true)' ' cd "$TRASH_DIRECTORY/full" && git fsck && corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ "incorrect checksum" && cp commit-graph-pre-write-test $objdir/info/commit-graph && + test_must_fail git -c core.commitGraph=true fsck +' + +test_expect_success 'git fsck (ignores commit-graph when config set to false)' ' + cd "$TRASH_DIRECTORY/full" && + git fsck && + corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ + "incorrect checksum" && + cp commit-graph-pre-write-test $objdir/info/commit-graph && + git -c core.commitGraph=false fsck +' + +test_expect_success 'git fsck (checks commit-graph when config unset)' ' + cd "$TRASH_DIRECTORY/full" && + test_when_finished "git config core.commitGraph true" && + + git fsck && + corrupt_graph_and_verify $GRAPH_BYTE_FOOTER "\00" \ + "incorrect checksum" && + test_unconfig core.commitGraph && + cp commit-graph-pre-write-test $objdir/info/commit-graph && test_must_fail git fsck ' diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index bd17f308b3..a612e44547 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -168,6 +168,21 @@ test_expect_success 'write midx with two packs' ' compare_results_with_midx "two packs" +test_expect_success 'write midx with --stdin-packs' ' + rm -fr $objdir/pack/multi-pack-index && + + idx="$(find $objdir/pack -name "test-2-*.idx")" && + basename "$idx" >in && + + git multi-pack-index write --stdin-packs <in && + + test-tool read-midx $objdir | grep "\.idx$" >packs && + + test_cmp packs in +' + +compare_results_with_midx "mixed mode (one pack + extra)" + test_expect_success 'write progress off for redirected stderr' ' git multi-pack-index --object-dir=$objdir write 2>err && test_line_count = 0 err @@ -452,7 +467,10 @@ test_expect_success 'verify incorrect offset' ' test_expect_success 'git-fsck incorrect offset' ' corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\377" $objdir \ "incorrect object offset" \ - "git -c core.multipackindex=true fsck" + "git -c core.multiPackIndex=true fsck" && + test_unconfig core.multiPackIndex && + test_must_fail git fsck && + git -c core.multiPackIndex=false fsck ' test_expect_success 'corrupt MIDX is not reused' ' @@ -464,8 +482,10 @@ test_expect_success 'corrupt MIDX is not reused' ' ' test_expect_success 'verify incorrect checksum' ' - pos=$(($(wc -c <$objdir/pack/multi-pack-index) - 1)) && - corrupt_midx_and_verify $pos "\377" $objdir "incorrect checksum" + pos=$(($(wc -c <$objdir/pack/multi-pack-index) - 10)) && + corrupt_midx_and_verify $pos \ + "\377\377\377\377\377\377\377\377\377\377" \ + $objdir "incorrect checksum" ' test_expect_success 'repack progress off for redirected stderr' ' diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index 587226ed10..847b809710 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -55,8 +55,8 @@ test_expect_success 'create commits and write commit-graph' ' ' graph_git_two_modes() { - git -c core.commitGraph=true $1 >output - git -c core.commitGraph=false $1 >expect + git ${2:+ -C "$2"} -c core.commitGraph=true $1 >output && + git ${2:+ -C "$2"} -c core.commitGraph=false $1 >expect && test_cmp expect output } @@ -64,12 +64,13 @@ graph_git_behavior() { MSG=$1 BRANCH=$2 COMPARE=$3 + DIR=$4 test_expect_success "check normal git operations: $MSG" ' - graph_git_two_modes "log --oneline $BRANCH" && - graph_git_two_modes "log --topo-order $BRANCH" && - graph_git_two_modes "log --graph $COMPARE..$BRANCH" && - graph_git_two_modes "branch -vv" && - graph_git_two_modes "merge-base -a $BRANCH $COMPARE" + graph_git_two_modes "log --oneline $BRANCH" "$DIR" && + graph_git_two_modes "log --topo-order $BRANCH" "$DIR" && + graph_git_two_modes "log --graph $COMPARE..$BRANCH" "$DIR" && + graph_git_two_modes "branch -vv" "$DIR" && + graph_git_two_modes "merge-base -a $BRANCH $COMPARE" "$DIR" ' } @@ -187,7 +188,10 @@ test_expect_success 'create fork and chain across alternate' ' ) ' -graph_git_behavior 'alternate: commit 13 vs 6' commits/13 commits/6 +if test -d fork +then + graph_git_behavior 'alternate: commit 13 vs 6' commits/13 origin/commits/6 "fork" +fi test_expect_success 'test merge stragety constants' ' git clone . merge-2 && diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh index ec4aa89f63..e187f90f29 100755 --- a/t/t5326-multi-pack-bitmaps.sh +++ b/t/t5326-multi-pack-bitmaps.sh @@ -283,6 +283,88 @@ test_expect_success 'pack.preferBitmapTips' ' ) ' +test_expect_success 'writing a bitmap with --refs-snapshot' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit one && + test_commit two && + + git rev-parse one >snapshot && + + git repack -ad && + + # First, write a MIDX which see both refs/tags/one and + # refs/tags/two (causing both of those commits to receive + # bitmaps). + git multi-pack-index write --bitmap && + + test_path_is_file $midx && + test_path_is_file $midx-$(midx_checksum $objdir).bitmap && + + test-tool bitmap list-commits | sort >bitmaps && + grep "$(git rev-parse one)" bitmaps && + grep "$(git rev-parse two)" bitmaps && + + rm -fr $midx-$(midx_checksum $objdir).bitmap && + rm -fr $midx-$(midx_checksum $objdir).rev && + rm -fr $midx && + + # Then again, but with a refs snapshot which only sees + # refs/tags/one. + git multi-pack-index write --bitmap --refs-snapshot=snapshot && + + test_path_is_file $midx && + test_path_is_file $midx-$(midx_checksum $objdir).bitmap && + + test-tool bitmap list-commits | sort >bitmaps && + grep "$(git rev-parse one)" bitmaps && + ! grep "$(git rev-parse two)" bitmaps + ) +' + +test_expect_success 'write a bitmap with --refs-snapshot (preferred tips)' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit_bulk --message="%s" 103 && + + git log --format="%H" >commits.raw && + sort <commits.raw >commits && + + git log --format="create refs/tags/%s %H" HEAD >refs && + git update-ref --stdin <refs && + + git multi-pack-index write --bitmap && + test_path_is_file $midx && + test_path_is_file $midx-$(midx_checksum $objdir).bitmap && + + test-tool bitmap list-commits | sort >bitmaps && + comm -13 bitmaps commits >before && + test_line_count = 1 before && + + ( + grep -vf before commits.raw && + # mark missing commits as preferred + sed "s/^/+/" before + ) >snapshot && + + rm -fr $midx-$(midx_checksum $objdir).bitmap && + rm -fr $midx-$(midx_checksum $objdir).rev && + rm -fr $midx && + + git multi-pack-index write --bitmap --refs-snapshot=snapshot && + test-tool bitmap list-commits | sort >bitmaps && + comm -13 bitmaps commits >after && + + ! test_cmp before after + ) +' + test_expect_success 'hash-cache values are propagated from pack bitmaps' ' rm -fr repo && git init repo && diff --git a/t/t5410-receive-pack-alternates.sh b/t/t5410-receive-pack-alternates.sh index 0b28e4e452..7a45d4c311 100755 --- a/t/t5410-receive-pack-alternates.sh +++ b/t/t5410-receive-pack-alternates.sh @@ -5,6 +5,7 @@ test_description='git receive-pack with alternate ref filtering' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index 6e5a9c20e7..b0b795aca9 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -292,7 +292,7 @@ test_expect_success 'push with receive.fsck.missingEmail=warn' ' receive.fsck.missingEmail warn && git push --porcelain dst bogus >act 2>&1 && grep "missingEmail" act && - test_i18ngrep "Skipping unknown msg id.*whatever" act && + test_i18ngrep "skipping unknown msg id.*whatever" act && git --git-dir=dst/.git branch -D bogus && git --git-dir=dst/.git config --add \ receive.fsck.missingEmail ignore && diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index e6e3c8f552..7ce1a28ef6 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -2,9 +2,6 @@ test_description='git remote porcelain-ish' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh setup_repository () { diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index a0faf0dd94..8c33755c26 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -5,9 +5,6 @@ test_description='Per branch config variables affects "git fetch". ' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bundle.sh diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 8212ca56dc..837a49642a 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -541,6 +541,15 @@ do done +test_expect_success "push to remote with no explicit refspec and config remote.*.push = src:dest" ' + mk_test testrepo heads/main && + git checkout $the_first_commit && + test_config remote.there.url testrepo && + test_config remote.there.push refs/heads/main:refs/heads/main && + git push there && + check_push_result testrepo $the_commit heads/main +' + test_expect_success 'push with remote.pushdefault' ' mk_test up_repo heads/main && mk_test down_repo heads/main && @@ -1769,6 +1778,38 @@ test_expect_success 'denyCurrentBranch and worktrees' ' test_must_fail git -C cloned push origin HEAD:new-wt && test_config receive.denyCurrentBranch updateInstead && git -C cloned push origin HEAD:new-wt && + test_path_exists new-wt/first.t && test_must_fail git -C cloned push --delete origin new-wt ' + +test_expect_success 'denyCurrentBranch and bare repository worktrees' ' + test_when_finished "rm -fr bare.git" && + git clone --bare . bare.git && + git -C bare.git worktree add wt && + test_commit grape && + git -C bare.git config receive.denyCurrentBranch refuse && + test_must_fail git push bare.git HEAD:wt && + git -C bare.git config receive.denyCurrentBranch updateInstead && + git push bare.git HEAD:wt && + test_path_exists bare.git/wt/grape.t && + test_must_fail git push --delete bare.git wt +' + +test_expect_success 'refuse fetch to current branch of worktree' ' + test_when_finished "git worktree remove --force wt && git branch -D wt" && + git worktree add wt && + test_commit apple && + test_must_fail git fetch . HEAD:wt && + git fetch -u . HEAD:wt +' + +test_expect_success 'refuse fetch to current branch of bare repository worktree' ' + test_when_finished "rm -fr bare.git" && + git clone --bare . bare.git && + git -C bare.git worktree add wt && + test_commit banana && + test_must_fail git -C bare.git fetch .. HEAD:wt && + git -C bare.git fetch -u .. HEAD:wt +' + test_done diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 672001a18b..93ecfcdd24 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -546,15 +546,6 @@ test_expect_success 'pull.rebase=1 is treated as true and flattens keep-merge' ' test_cmp expect actual ' -test_expect_success REBASE_P \ - 'pull.rebase=preserve rebases and merges keep-merge' ' - git reset --hard before-preserve-rebase && - test_config pull.rebase preserve && - git pull . copy && - test_cmp_rev HEAD^^ copy && - test_cmp_rev HEAD^2 keep-merge -' - test_expect_success 'pull.rebase=interactive' ' write_script "$TRASH_DIRECTORY/fake-editor" <<-\EOF && echo I was here >fake.out && @@ -598,7 +589,7 @@ test_expect_success '--rebase=false create a new merge commit' ' test_expect_success '--rebase=true rebases and flattens keep-merge' ' git reset --hard before-preserve-rebase && - test_config pull.rebase preserve && + test_config pull.rebase merges && git pull --rebase=true . copy && test_cmp_rev HEAD^^ copy && echo file3 >expect && @@ -606,23 +597,14 @@ test_expect_success '--rebase=true rebases and flattens keep-merge' ' test_cmp expect actual ' -test_expect_success REBASE_P \ - '--rebase=preserve rebases and merges keep-merge' ' - git reset --hard before-preserve-rebase && - test_config pull.rebase true && - git pull --rebase=preserve . copy && - test_cmp_rev HEAD^^ copy && - test_cmp_rev HEAD^2 keep-merge -' - test_expect_success '--rebase=invalid fails' ' git reset --hard before-preserve-rebase && test_must_fail git pull --rebase=invalid . copy ' -test_expect_success '--rebase overrides pull.rebase=preserve and flattens keep-merge' ' +test_expect_success '--rebase overrides pull.rebase=merges and flattens keep-merge' ' git reset --hard before-preserve-rebase && - test_config pull.rebase preserve && + test_config pull.rebase merges && git pull --rebase . copy && test_cmp_rev HEAD^^ copy && echo file3 >expect && diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 7601c919fd..66cfcb09c5 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -228,4 +228,28 @@ test_expect_success 'git pull --no-signoff flag cancels --signoff flag' ' test_must_be_empty actual ' +test_expect_success 'git pull --no-verify flag passed to merge' ' + test_when_finished "rm -fr src dst actual" && + git init src && + test_commit -C src one && + git clone src dst && + write_script dst/.git/hooks/commit-msg <<-\EOF && + false + EOF + test_commit -C src two && + git -C dst pull --no-ff --no-verify +' + +test_expect_success 'git pull --no-verify --verify passed to merge' ' + test_when_finished "rm -fr src dst actual" && + git init src && + test_commit -C src one && + git clone src dst && + write_script dst/.git/hooks/commit-msg <<-\EOF && + false + EOF + test_commit -C src two && + test_must_fail git -C dst pull --no-ff --no-verify --verify +' + test_done diff --git a/t/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index ed11569d8d..840c89cc8b 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -3,8 +3,8 @@ test_description='Recursive "git fetch" for submodules' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 +export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB . ./test-lib.sh diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index d573ca496a..3f58b515ce 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -5,6 +5,9 @@ test_description='test push with submodules' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 +export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB + . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5534-push-signed.sh b/t/t5534-push-signed.sh index bba768f5de..24d374adba 100755 --- a/t/t5534-push-signed.sh +++ b/t/t5534-push-signed.sh @@ -137,6 +137,53 @@ test_expect_success GPG 'signed push sends push certificate' ' test_cmp expect dst/push-cert-status ' +test_expect_success GPGSSH 'ssh signed push sends push certificate' ' + prepare_dst && + mkdir -p dst/.git/hooks && + git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git -C dst config receive.certnonceseed sekrit && + write_script dst/.git/hooks/post-receive <<-\EOF && + # discard the update list + cat >/dev/null + # record the push certificate + if test -n "${GIT_PUSH_CERT-}" + then + git cat-file blob $GIT_PUSH_CERT >../push-cert + fi && + + cat >../push-cert-status <<E_O_F + SIGNER=${GIT_PUSH_CERT_SIGNER-nobody} + KEY=${GIT_PUSH_CERT_KEY-nokey} + STATUS=${GIT_PUSH_CERT_STATUS-nostatus} + NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus} + NONCE=${GIT_PUSH_CERT_NONCE-nononce} + E_O_F + + EOF + + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && + git push --signed dst noop ff +noff && + + ( + cat <<-\EOF && + SIGNER=principal with number 1 + KEY=FINGERPRINT + STATUS=G + NONCE_STATUS=OK + EOF + sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert + ) | sed -e "s|FINGERPRINT|$FINGERPRINT|" >expect && + + noop=$(git rev-parse noop) && + ff=$(git rev-parse ff) && + noff=$(git rev-parse noff) && + grep "$noop $ff refs/heads/ff" dst/push-cert && + grep "$noop $noff refs/heads/noff" dst/push-cert && + test_cmp expect dst/push-cert-status +' + test_expect_success GPG 'inconsistent push options in signed push not allowed' ' # First, invoke receive-pack with dummy input to obtain its preamble. prepare_dst && @@ -276,6 +323,60 @@ test_expect_success GPGSM 'fail without key and heed user.signingkey x509' ' test_cmp expect dst/push-cert-status ' +test_expect_success GPGSSH 'fail without key and heed user.signingkey ssh' ' + test_config gpg.format ssh && + prepare_dst && + mkdir -p dst/.git/hooks && + git -C dst config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git -C dst config receive.certnonceseed sekrit && + write_script dst/.git/hooks/post-receive <<-\EOF && + # discard the update list + cat >/dev/null + # record the push certificate + if test -n "${GIT_PUSH_CERT-}" + then + git cat-file blob $GIT_PUSH_CERT >../push-cert + fi && + + cat >../push-cert-status <<E_O_F + SIGNER=${GIT_PUSH_CERT_SIGNER-nobody} + KEY=${GIT_PUSH_CERT_KEY-nokey} + STATUS=${GIT_PUSH_CERT_STATUS-nostatus} + NONCE_STATUS=${GIT_PUSH_CERT_NONCE_STATUS-nononcestatus} + NONCE=${GIT_PUSH_CERT_NONCE-nononce} + E_O_F + + EOF + + test_config user.email hasnokey@nowhere.com && + test_config gpg.format ssh && + test_config user.signingkey "" && + ( + sane_unset GIT_COMMITTER_EMAIL && + test_must_fail git push --signed dst noop ff +noff + ) && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && + git push --signed dst noop ff +noff && + + ( + cat <<-\EOF && + SIGNER=principal with number 1 + KEY=FINGERPRINT + STATUS=G + NONCE_STATUS=OK + EOF + sed -n -e "s/^nonce /NONCE=/p" -e "/^$/q" dst/push-cert + ) | sed -e "s|FINGERPRINT|$FINGERPRINT|" >expect && + + noop=$(git rev-parse noop) && + ff=$(git rev-parse ff) && + noff=$(git rev-parse noff) && + grep "$noop $ff refs/heads/ff" dst/push-cert && + grep "$noop $noff refs/heads/noff" dst/push-cert && + test_cmp expect dst/push-cert-status +' + test_expect_success GPG 'failed atomic push does not execute GPG' ' prepare_dst && git -C dst config receive.certnonceseed sekrit && diff --git a/t/t5541-http-push-smart.sh b/t/t5541-http-push-smart.sh index c024fa2818..8ca50f8b18 100755 --- a/t/t5541-http-push-smart.sh +++ b/t/t5541-http-push-smart.sh @@ -509,4 +509,20 @@ test_expect_success 'colorize errors/hints' ' test_i18ngrep ! "^hint: " decoded ' +test_expect_success 'report error server does not provide ref status' ' + git init "$HTTPD_DOCUMENT_ROOT_PATH/no_report" && + git -C "$HTTPD_DOCUMENT_ROOT_PATH/no_report" config http.receivepack true && + test_must_fail git push --porcelain \ + $HTTPD_URL_USER_PASS/smart/no_report \ + HEAD:refs/tags/will-fail >actual && + test_must_fail git -C "$HTTPD_DOCUMENT_ROOT_PATH/no_report" \ + rev-parse --verify refs/tags/will-fail && + cat >expect <<-EOF && + To $HTTPD_URL/smart/no_report + ! HEAD:refs/tags/will-fail [remote failure] (remote failed to report status) + Done + EOF + test_cmp expect actual +' + test_done diff --git a/t/t5545-push-options.sh b/t/t5545-push-options.sh index 58c7add7ee..214228349a 100755 --- a/t/t5545-push-options.sh +++ b/t/t5545-push-options.sh @@ -5,6 +5,9 @@ test_description='pushing to a repository using push options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 +export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB + . ./test-lib.sh mk_repo_pair () { diff --git a/t/t5555-http-smart-common.sh b/t/t5555-http-smart-common.sh index 49faf5e283..b1cfe8b7db 100755 --- a/t/t5555-http-smart-common.sh +++ b/t/t5555-http-smart-common.sh @@ -2,6 +2,7 @@ test_description='test functionality common to smart fetch & push' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5572-pull-submodule.sh b/t/t5572-pull-submodule.sh index 4f92a116e1..fa6b4cca65 100755 --- a/t/t5572-pull-submodule.sh +++ b/t/t5572-pull-submodule.sh @@ -2,6 +2,9 @@ test_description='pull can handle submodules' +GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 +export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB + . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t5580-unc-paths.sh b/t/t5580-unc-paths.sh index cd803ae8bf..cd7604fff9 100755 --- a/t/t5580-unc-paths.sh +++ b/t/t5580-unc-paths.sh @@ -4,6 +4,7 @@ test_description='various Windows-only path tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if test_have_prereq CYGWIN diff --git a/t/t5602-clone-remote-exec.sh b/t/t5602-clone-remote-exec.sh index cbcceab9d5..56329aa160 100755 --- a/t/t5602-clone-remote-exec.sh +++ b/t/t5602-clone-remote-exec.sh @@ -2,6 +2,7 @@ test_description=clone +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5603-clone-dirname.sh b/t/t5603-clone-dirname.sh index 13b5e5eb9b..8ca1f09423 100755 --- a/t/t5603-clone-dirname.sh +++ b/t/t5603-clone-dirname.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='check output directory names used by git-clone' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # we use a fake ssh wrapper that ignores the arguments diff --git a/t/t5609-clone-branch.sh b/t/t5609-clone-branch.sh index f86a674a03..252e1f7c20 100755 --- a/t/t5609-clone-branch.sh +++ b/t/t5609-clone-branch.sh @@ -4,6 +4,7 @@ test_description='clone --branch option' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_HEAD() { diff --git a/t/t5615-alternate-env.sh b/t/t5615-alternate-env.sh index b4905b822c..83513e46a3 100755 --- a/t/t5615-alternate-env.sh +++ b/t/t5615-alternate-env.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='handling of alternates in environment variables' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check_obj () { diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh index aa1827d841..1896f671cb 100755 --- a/t/t5701-git-serve.sh +++ b/t/t5701-git-serve.sh @@ -5,6 +5,7 @@ test_description='test protocol v2 server commands' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'test capability advertisement' ' diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index d527cf6c49..78f85b0714 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -1107,6 +1107,57 @@ test_expect_success 'packfile-uri with transfer.fsckobjects fails when .gitmodul test_i18ngrep "disallowed submodule name" err ' +test_expect_success 'packfile-uri path redacted in trace' ' + P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && + rm -rf "$P" http_child log && + + git init "$P" && + git -C "$P" config "uploadpack.allowsidebandall" "true" && + + echo my-blob >"$P/my-blob" && + git -C "$P" add my-blob && + git -C "$P" commit -m x && + + git -C "$P" hash-object my-blob >objh && + git -C "$P" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && + git -C "$P" config --add \ + "uploadpack.blobpackfileuri" \ + "$(cat objh) $(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && + + GIT_TRACE_PACKET="$(pwd)/log" \ + git -c protocol.version=2 \ + -c fetch.uriprotocols=http,https \ + clone "$HTTPD_URL/smart/http_parent" http_child && + + grep -F "clone< \\1$(cat packh) $HTTPD_URL/<redacted>" log +' + +test_expect_success 'packfile-uri path not redacted in trace when GIT_TRACE_REDACT=0' ' + P="$HTTPD_DOCUMENT_ROOT_PATH/http_parent" && + rm -rf "$P" http_child log && + + git init "$P" && + git -C "$P" config "uploadpack.allowsidebandall" "true" && + + echo my-blob >"$P/my-blob" && + git -C "$P" add my-blob && + git -C "$P" commit -m x && + + git -C "$P" hash-object my-blob >objh && + git -C "$P" pack-objects "$HTTPD_DOCUMENT_ROOT_PATH/mypack" <objh >packh && + git -C "$P" config --add \ + "uploadpack.blobpackfileuri" \ + "$(cat objh) $(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" && + + GIT_TRACE_PACKET="$(pwd)/log" \ + GIT_TRACE_REDACT=0 \ + git -c protocol.version=2 \ + -c fetch.uriprotocols=http,https \ + clone "$HTTPD_URL/smart/http_parent" http_child && + + grep -F "clone< \\1$(cat packh) $HTTPD_URL/dumb/mypack-$(cat packh).pack" log +' + test_expect_success 'http:// --negotiate-only' ' SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" && URI="$HTTPD_URL/smart/server" && diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh index 220098523a..9d6cd7d986 100755 --- a/t/t5703-upload-pack-ref-in-want.sh +++ b/t/t5703-upload-pack-ref-in-want.sh @@ -2,9 +2,6 @@ test_description='upload-pack ref-in-want' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh get_actual_refs () { diff --git a/t/t5704-protocol-violations.sh b/t/t5704-protocol-violations.sh index bc393d7c31..ae1a00afb0 100755 --- a/t/t5704-protocol-violations.sh +++ b/t/t5704-protocol-violations.sh @@ -4,6 +4,8 @@ test_description='Test responses to violations of the network protocol. In most of these cases it will generally be acceptable for one side to break off communications if the other side says something unexpected. We are mostly making sure that we do not segfault or otherwise behave badly.' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'extra delim packet in v2 ls-refs args' ' diff --git a/t/t5705-session-id-in-capabilities.sh b/t/t5705-session-id-in-capabilities.sh index eb8c79aafd..ed38c76c29 100755 --- a/t/t5705-session-id-in-capabilities.sh +++ b/t/t5705-session-id-in-capabilities.sh @@ -32,7 +32,6 @@ do test_when_finished "git -C local push --delete origin new-branch" && cp -r "$LOCAL_PRISTINE" local && git -C local pull --no-rebase origin && - GIT_TRACE2_EVENT_NESTING=5 \ GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \ git -c protocol.version=$PROTO -C local push \ --receive-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-receive-pack" \ @@ -65,7 +64,6 @@ do test_when_finished "git -C local push --delete origin new-branch" && cp -r "$LOCAL_PRISTINE" local && git -C local pull --no-rebase origin && - GIT_TRACE2_EVENT_NESTING=5 \ GIT_TRACE2_EVENT="$(pwd)/tr2-client-events" \ git -c protocol.version=$PROTO -C local push \ --receive-pack "GIT_TRACE2_EVENT=\"$(pwd)/tr2-server-events\" git-receive-pack" \ diff --git a/t/t6000-rev-list-misc.sh b/t/t6000-rev-list-misc.sh index ef849e5bc8..12def7bcbf 100755 --- a/t/t6000-rev-list-misc.sh +++ b/t/t6000-rev-list-misc.sh @@ -169,35 +169,4 @@ test_expect_success 'rev-list --count --objects' ' test_line_count = $count actual ' -test_expect_success 'rev-list --unsorted-input results in different sorting' ' - git rev-list --unsorted-input HEAD HEAD~ >first && - git rev-list --unsorted-input HEAD~ HEAD >second && - ! test_cmp first second && - sort first >first.sorted && - sort second >second.sorted && - test_cmp first.sorted second.sorted -' - -test_expect_success 'rev-list --unsorted-input incompatible with --no-walk' ' - cat >expect <<-EOF && - fatal: --no-walk is incompatible with --unsorted-input - EOF - test_must_fail git rev-list --unsorted-input --no-walk HEAD 2>error && - test_cmp expect error && - test_must_fail git rev-list --unsorted-input --no-walk=sorted HEAD 2>error && - test_cmp expect error && - test_must_fail git rev-list --unsorted-input --no-walk=unsorted HEAD 2>error && - test_cmp expect error && - - cat >expect <<-EOF && - fatal: --unsorted-input is incompatible with --no-walk - EOF - test_must_fail git rev-list --no-walk --unsorted-input HEAD 2>error && - test_cmp expect error && - test_must_fail git rev-list --no-walk=sorted --unsorted-input HEAD 2>error && - test_cmp expect error && - test_must_fail git rev-list --no-walk=unsorted --unsorted-input HEAD 2>error && - test_cmp expect error -' - test_done diff --git a/t/t6005-rev-list-count.sh b/t/t6005-rev-list-count.sh index 0b64822bf6..d763de0041 100755 --- a/t/t6005-rev-list-count.sh +++ b/t/t6005-rev-list-count.sh @@ -2,6 +2,7 @@ test_description='git rev-list --max-count and --skip test' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6102-rev-list-unexpected-objects.sh b/t/t6102-rev-list-unexpected-objects.sh index 52cde097dd..6f0902b863 100755 --- a/t/t6102-rev-list-unexpected-objects.sh +++ b/t/t6102-rev-list-unexpected-objects.sh @@ -2,6 +2,7 @@ test_description='git rev-list should handle unexpected object types' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup well-formed objects' ' diff --git a/t/t6136-pathspec-in-bare.sh b/t/t6136-pathspec-in-bare.sh index b117251366..ae8b5379e2 100755 --- a/t/t6136-pathspec-in-bare.sh +++ b/t/t6136-pathspec-in-bare.sh @@ -2,6 +2,7 @@ test_description='diagnosing out-of-scope pathspec' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a bare and non-bare repository' ' diff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh index 44f55d93fe..6e10a539ce 100755 --- a/t/t6200-fmt-merge-msg.sh +++ b/t/t6200-fmt-merge-msg.sh @@ -81,6 +81,36 @@ test_expect_success GPG 'set up a signed tag' ' git tag -s -m signed-tag-msg signed-good-tag left ' +test_expect_success GPGSSH 'created ssh signed commit and tag' ' + test_config gpg.format ssh && + git checkout -b signed-ssh && + touch file && + git add file && + git commit -m "ssh signed" -S"${GPGSSH_KEY_PRIMARY}" && + git tag -s -u"${GPGSSH_KEY_PRIMARY}" -m signed-ssh-tag-msg signed-good-ssh-tag left && + git tag -s -u"${GPGSSH_KEY_UNTRUSTED}" -m signed-ssh-tag-msg-untrusted signed-untrusted-ssh-tag left +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'create signed tags with keys having defined lifetimes' ' + test_when_finished "test_unconfig commit.gpgsign" && + test_config gpg.format ssh && + git checkout -b signed-expiry-ssh && + touch file && + git add file && + + echo expired >file && test_tick && git commit -a -m expired -S"${GPGSSH_KEY_EXPIRED}" && + git tag -s -u "${GPGSSH_KEY_EXPIRED}" -m expired-signed expired-signed && + + echo notyetvalid >file && test_tick && git commit -a -m notyetvalid -S"${GPGSSH_KEY_NOTYETVALID}" && + git tag -s -u "${GPGSSH_KEY_NOTYETVALID}" -m notyetvalid-signed notyetvalid-signed && + + echo timeboxedvalid >file && test_tick && git commit -a -m timeboxedvalid -S"${GPGSSH_KEY_TIMEBOXEDVALID}" && + git tag -s -u "${GPGSSH_KEY_TIMEBOXEDVALID}" -m timeboxedvalid-signed timeboxedvalid-signed && + + echo timeboxedinvalid >file && test_tick && git commit -a -m timeboxedinvalid -S"${GPGSSH_KEY_TIMEBOXEDINVALID}" && + git tag -s -u "${GPGSSH_KEY_TIMEBOXEDINVALID}" -m timeboxedinvalid-signed timeboxedinvalid-signed +' + test_expect_success 'message for merging local branch' ' echo "Merge branch ${apos}left${apos}" >expected && @@ -94,7 +124,7 @@ test_expect_success 'message for merging local branch' ' test_expect_success GPG 'message for merging local tag signed by good key' ' git checkout main && git fetch . signed-good-tag && - git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 && + git fmt-merge-msg <.git/FETCH_HEAD >actual && grep "^Merge tag ${apos}signed-good-tag${apos}" actual && grep "^# gpg: Signature made" actual && grep "^# gpg: Good signature from" actual @@ -103,12 +133,70 @@ test_expect_success GPG 'message for merging local tag signed by good key' ' test_expect_success GPG 'message for merging local tag signed by unknown key' ' git checkout main && git fetch . signed-good-tag && - GNUPGHOME=. git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 && + GNUPGHOME=. git fmt-merge-msg <.git/FETCH_HEAD >actual && grep "^Merge tag ${apos}signed-good-tag${apos}" actual && grep "^# gpg: Signature made" actual && grep -E "^# gpg: Can${apos}t check signature: (public key not found|No public key)" actual ' +test_expect_success GPGSSH 'message for merging local tag signed by good ssh key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git checkout main && + git fetch . signed-good-ssh-tag && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + grep "^Merge tag ${apos}signed-good-ssh-tag${apos}" actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual +' + +test_expect_success GPGSSH 'message for merging local tag signed by unknown ssh key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git checkout main && + git fetch . signed-untrusted-ssh-tag && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + grep "^Merge tag ${apos}signed-untrusted-ssh-tag${apos}" actual && + grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + grep "${GPGSSH_KEY_NOT_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'message for merging local tag signed by expired ssh key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git checkout main && + git fetch . expired-signed && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + grep "^Merge tag ${apos}expired-signed${apos}" actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'message for merging local tag signed by not yet valid ssh key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git checkout main && + git fetch . notyetvalid-signed && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + grep "^Merge tag ${apos}notyetvalid-signed${apos}" actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'message for merging local tag signed by valid timeboxed ssh key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git checkout main && + git fetch . timeboxedvalid-signed && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + grep "^Merge tag ${apos}timeboxedvalid-signed${apos}" actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'message for merging local tag signed by invalid timeboxed ssh key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git checkout main && + git fetch . timeboxedinvalid-signed && + git fmt-merge-msg <.git/FETCH_HEAD >actual && + grep "^Merge tag ${apos}timeboxedinvalid-signed${apos}" actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + test_expect_success 'message for merging external branch' ' echo "Merge branch ${apos}left${apos} of $(pwd)" >expected && diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 80679d5e12..6aa9fb17ea 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -5,9 +5,6 @@ test_description='for-each-ref test' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -419,6 +416,11 @@ test_expect_success 'Verify descending sort' ' test_cmp expected actual ' +test_expect_success 'Give help even with invalid sort atoms' ' + test_expect_code 129 git for-each-ref --sort=bogus -h >actual 2>&1 && + grep "^usage: git for-each-ref" actual +' + cat >expected <<\EOF refs/tags/testtag refs/tags/testtag-2 @@ -1019,6 +1021,27 @@ test_expect_success 'equivalent sorts fall back on refname' ' test_cmp expected actual ' +test_expect_success '--no-sort cancels the previous sort keys' ' + cat >expected <<-\EOF && + 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 + 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 + 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 + 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 + 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 + 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 + 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 + 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 + EOF + git for-each-ref \ + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ + --sort=-refname \ + --sort=taggeremail \ + --no-sort \ + --sort=taggerdate \ + "refs/tags/multi-*" >actual && + test_cmp expected actual +' + test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' test_when_finished "git checkout main" && git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index 1537aa2179..1ce5f490e9 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -2,9 +2,6 @@ test_description='test for-each-refs usage of ref-filter APIs' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh diff --git a/t/t6407-merge-binary.sh b/t/t6407-merge-binary.sh index d4273f2575..e34676c204 100755 --- a/t/t6407-merge-binary.sh +++ b/t/t6407-merge-binary.sh @@ -5,6 +5,7 @@ test_description='ask merge-recursive to merge binary files' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6414-merge-rename-nocruft.sh b/t/t6414-merge-rename-nocruft.sh index d7e3c1fa6e..69fc1c9e69 100755 --- a/t/t6414-merge-rename-nocruft.sh +++ b/t/t6414-merge-rename-nocruft.sh @@ -4,6 +4,7 @@ test_description='Merge-recursive merging renames' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6427-diff3-conflict-markers.sh b/t/t6427-diff3-conflict-markers.sh index 25c4b720e7..a9ee4cb207 100755 --- a/t/t6427-diff3-conflict-markers.sh +++ b/t/t6427-diff3-conflict-markers.sh @@ -211,4 +211,94 @@ test_expect_success 'rebase --apply describes fake ancestor base' ' ) ' +test_setup_zdiff3 () { + test_create_repo zdiff3 && + ( + cd zdiff3 && + + test_write_lines 1 2 3 4 5 6 7 8 9 >basic && + test_write_lines 1 2 3 AA 4 5 BB 6 7 8 >middle-common && + test_write_lines 1 2 3 4 5 6 7 8 9 >interesting && + test_write_lines 1 2 3 4 5 6 7 8 9 >evil && + + git add basic middle-common interesting evil && + git commit -m base && + + git branch left && + git branch right && + + git checkout left && + test_write_lines 1 2 3 4 A B C D E 7 8 9 >basic && + test_write_lines 1 2 3 CC 4 5 DD 6 7 8 >middle-common && + test_write_lines 1 2 3 4 A B C D E F G H I J 7 8 9 >interesting && + test_write_lines 1 2 3 4 X A B C 7 8 9 >evil && + git add -u && + git commit -m letters && + + git checkout right && + test_write_lines 1 2 3 4 A X C Y E 7 8 9 >basic && + test_write_lines 1 2 3 EE 4 5 FF 6 7 8 >middle-common && + test_write_lines 1 2 3 4 A B C 5 6 G H I J 7 8 9 >interesting && + test_write_lines 1 2 3 4 Y A B C B C 7 8 9 >evil && + git add -u && + git commit -m permuted + ) +} + +test_expect_success 'check zdiff3 markers' ' + test_setup_zdiff3 && + ( + cd zdiff3 && + + git checkout left^0 && + + base=$(git rev-parse --short HEAD^1) && + test_must_fail git -c merge.conflictstyle=zdiff3 merge -s recursive right^0 && + + test_write_lines 1 2 3 4 A \ + "<<<<<<< HEAD" B C D \ + "||||||| $base" 5 6 \ + ======= X C Y \ + ">>>>>>> right^0" \ + E 7 8 9 \ + >expect && + test_cmp expect basic && + + test_write_lines 1 2 3 \ + "<<<<<<< HEAD" CC \ + "||||||| $base" AA \ + ======= EE \ + ">>>>>>> right^0" \ + 4 5 \ + "<<<<<<< HEAD" DD \ + "||||||| $base" BB \ + ======= FF \ + ">>>>>>> right^0" \ + 6 7 8 \ + >expect && + test_cmp expect middle-common && + + test_write_lines 1 2 3 4 A B C \ + "<<<<<<< HEAD" D E F \ + "||||||| $base" 5 6 \ + ======= 5 6 \ + ">>>>>>> right^0" \ + G H I J 7 8 9 \ + >expect && + test_cmp expect interesting && + + # Not passing this one yet; the common "B C" lines is still + # being left in the conflict blocks on the left and right + # sides. + test_write_lines 1 2 3 4 \ + "<<<<<<< HEAD" X A \ + "||||||| $base" 5 6 \ + ======= Y A B C \ + ">>>>>>> right^0" \ + B C 7 8 9 \ + >expect && + test_cmp expect evil + ) +' + test_done diff --git a/t/t6437-submodule-merge.sh b/t/t6437-submodule-merge.sh index e5e89c2045..178413c22f 100755 --- a/t/t6437-submodule-merge.sh +++ b/t/t6437-submodule-merge.sh @@ -5,6 +5,9 @@ test_description='merging with submodules' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 +export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB + . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 25bb9bbb89..963356ba5f 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -2,10 +2,11 @@ test_description='git mv in subdirs' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-diff-data.sh test_expect_success 'prepare reference tree' ' mkdir path0 path1 && - cp "$TEST_DIRECTORY"/../COPYING path0/COPYING && + COPYING_test_data >path0/COPYING && git add path0/COPYING && git commit -m add -a ' @@ -107,7 +108,7 @@ test_expect_success 'clean up' ' ' test_expect_success 'adding another file' ' - cp "$TEST_DIRECTORY"/../README.md path0/README && + COPYING_test_data | tr A-Za-z N-ZA-Mn-za-m >path0/README && git add path0/README && git commit -m add2 -a ' diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh index 545748949a..1d3d2aca21 100755 --- a/t/t7002-mv-sparse-checkout.sh +++ b/t/t7002-mv-sparse-checkout.sh @@ -143,8 +143,6 @@ test_expect_success 'recursive mv refuses to move (possible) sparse' ' cat >>expect <<-\EOF && sub/d sub2/d - sub/dir/e - sub2/dir/e sub/dir2/e sub2/dir2/e EOF @@ -186,4 +184,26 @@ test_expect_success 'recursive mv refuses to move sparse' ' git reset --hard HEAD~1 ' +test_expect_success 'can move files to non-sparse dir' ' + git reset --hard && + git sparse-checkout init --no-cone && + git sparse-checkout set a b c w !/x y/ && + mkdir -p w x/y && + + git mv a w/new-a 2>stderr && + git mv b x/y/new-b 2>stderr && + test_must_be_empty stderr +' + +test_expect_success 'refuse to move file to non-skip-worktree sparse path' ' + git reset --hard && + git sparse-checkout init --no-cone && + git sparse-checkout set a !/x y/ !x/y/z && + mkdir -p x/y/z && + + test_must_fail git mv a x/y/z/new-a 2>stderr && + echo x/y/z/new-a | cat sparse_error_header - sparse_hint >expect && + test_cmp expect stderr +' + test_done diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh index 0e7cf75435..e56ca5b0fa 100755 --- a/t/t7006-pager.sh +++ b/t/t7006-pager.sh @@ -661,6 +661,13 @@ test_expect_success 'setup trace2' ' export GIT_TRACE2_BRIEF ' +test_expect_success 'setup large log output' ' + perl -e " + print \"this is a long commit message\" x 50000 + " >commit-msg && + git commit --allow-empty -F commit-msg +' + test_expect_success TTY 'git returns SIGPIPE on early pager exit' ' test_when_finished "rm pager-used trace.normal" && test_config core.pager ">pager-used; head -n 1; exit 0" && @@ -670,7 +677,7 @@ test_expect_success TTY 'git returns SIGPIPE on early pager exit' ' if test_have_prereq !MINGW then - OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) && + { test_terminal git log >/dev/null; OUT=$?; } && test_match_signal 13 "$OUT" else test_terminal git log @@ -691,7 +698,7 @@ test_expect_success TTY 'git returns SIGPIPE on early pager non-zero exit' ' if test_have_prereq !MINGW then - OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) && + { test_terminal git log >/dev/null; OUT=$?; } && test_match_signal 13 "$OUT" else test_terminal git log @@ -710,13 +717,7 @@ test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' ' export GIT_TRACE2 && test_when_finished "unset GIT_TRACE2" && - if test_have_prereq !MINGW - then - OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) && - test "$OUT" -eq 0 - else - test_terminal git log - fi && + test_terminal git log && grep child_exit trace.normal >child-exits && test_line_count = 1 child-exits && @@ -724,41 +725,14 @@ test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' ' test_path_is_file pager-used ' -test_expect_success TTY 'git discards nonexisting pager without SIGPIPE' ' - test_when_finished "rm pager-used trace.normal" && - test_config core.pager "wc >pager-used; does-not-exist" && - GIT_TRACE2="$(pwd)/trace.normal" && - export GIT_TRACE2 && - test_when_finished "unset GIT_TRACE2" && - - if test_have_prereq !MINGW - then - OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) && - test "$OUT" -eq 0 - else - test_terminal git log - fi && - - grep child_exit trace.normal >child-exits && - test_line_count = 1 child-exits && - grep " code:127 " child-exits && - test_path_is_file pager-used -' - -test_expect_success TTY 'git attempts to page to nonexisting pager command, gets SIGPIPE' ' +test_expect_success TTY 'git skips paging nonexisting command' ' test_when_finished "rm trace.normal" && test_config core.pager "does-not-exist" && GIT_TRACE2="$(pwd)/trace.normal" && export GIT_TRACE2 && test_when_finished "unset GIT_TRACE2" && - if test_have_prereq !MINGW - then - OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) && - test_match_signal 13 "$OUT" - else - test_terminal git log - fi && + test_terminal git log && grep child_exit trace.normal >child-exits && test_line_count = 1 child-exits && @@ -767,14 +741,14 @@ test_expect_success TTY 'git attempts to page to nonexisting pager command, gets test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' ' test_when_finished "rm pager-used trace.normal" && - test_config core.pager ">pager-used; test-tool sigchain" && + test_config core.pager ">pager-used; exec test-tool sigchain" && GIT_TRACE2="$(pwd)/trace.normal" && export GIT_TRACE2 && test_when_finished "unset GIT_TRACE2" && if test_have_prereq !MINGW then - OUT=$( ((test_terminal git log; echo $? 1>&3) | :) 3>&1 ) && + { test_terminal git log >/dev/null; OUT=$?; } && test_match_signal 13 "$OUT" else test_terminal git log @@ -786,4 +760,9 @@ test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' ' test_path_is_file pager-used ' +test_expect_success TTY 'non-existent pager doesnt cause crash' ' + test_config pager.show invalid-pager && + test_terminal git show +' + test_done diff --git a/t/t7031-verify-tag-signed-ssh.sh b/t/t7031-verify-tag-signed-ssh.sh new file mode 100755 index 0000000000..1cb36b9ab8 --- /dev/null +++ b/t/t7031-verify-tag-signed-ssh.sh @@ -0,0 +1,203 @@ +#!/bin/sh + +test_description='signed tag tests' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh +. "$TEST_DIRECTORY/lib-gpg.sh" + +test_expect_success GPGSSH 'create signed tags ssh' ' + test_when_finished "test_unconfig commit.gpgsign" && + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + + echo 1 >file && git add file && + test_tick && git commit -m initial && + git tag -s -m initial initial && + git branch side && + + echo 2 >file && test_tick && git commit -a -m second && + git tag -s -m second second && + + git checkout side && + echo 3 >elif && git add elif && + test_tick && git commit -m "third on side" && + + git checkout main && + test_tick && git merge -S side && + git tag -s -m merge merge && + + echo 4 >file && test_tick && git commit -a -S -m "fourth unsigned" && + git tag -a -m fourth-unsigned fourth-unsigned && + + test_tick && git commit --amend -S -m "fourth signed" && + git tag -s -m fourth fourth-signed && + + echo 5 >file && test_tick && git commit -a -m "fifth" && + git tag fifth-unsigned && + + git config commit.gpgsign true && + echo 6 >file && test_tick && git commit -a -m "sixth" && + git tag -a -m sixth sixth-unsigned && + + test_tick && git rebase -f HEAD^^ && git tag -s -m 6th sixth-signed HEAD^ && + git tag -m seventh -s seventh-signed && + + echo 8 >file && test_tick && git commit -a -m eighth && + git tag -u"${GPGSSH_KEY_UNTRUSTED}" -m eighth eighth-signed-alt +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'create signed tags with keys having defined lifetimes' ' + test_when_finished "test_unconfig commit.gpgsign" && + test_config gpg.format ssh && + + echo expired >file && test_tick && git commit -a -m expired -S"${GPGSSH_KEY_EXPIRED}" && + git tag -s -u "${GPGSSH_KEY_EXPIRED}" -m expired-signed expired-signed && + + echo notyetvalid >file && test_tick && git commit -a -m notyetvalid -S"${GPGSSH_KEY_NOTYETVALID}" && + git tag -s -u "${GPGSSH_KEY_NOTYETVALID}" -m notyetvalid-signed notyetvalid-signed && + + echo timeboxedvalid >file && test_tick && git commit -a -m timeboxedvalid -S"${GPGSSH_KEY_TIMEBOXEDVALID}" && + git tag -s -u "${GPGSSH_KEY_TIMEBOXEDVALID}" -m timeboxedvalid-signed timeboxedvalid-signed && + + echo timeboxedinvalid >file && test_tick && git commit -a -m timeboxedinvalid -S"${GPGSSH_KEY_TIMEBOXEDINVALID}" && + git tag -s -u "${GPGSSH_KEY_TIMEBOXEDINVALID}" -m timeboxedinvalid-signed timeboxedinvalid-signed +' + +test_expect_success GPGSSH 'verify and show ssh signatures' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + ( + for tag in initial second merge fourth-signed sixth-signed seventh-signed + do + git verify-tag $tag 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in fourth-unsigned fifth-unsigned sixth-unsigned + do + test_must_fail git verify-tag $tag 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in eighth-signed-alt + do + test_must_fail git verify-tag $tag 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + grep "${GPGSSH_KEY_NOT_TRUSTED}" actual && + echo $tag OK || exit 1 + done + ) +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-tag exits failure on expired signature key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_must_fail git verify-tag expired-signed 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-tag exits failure on not yet valid signature key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_must_fail git verify-tag notyetvalid-signed 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-tag succeeds with tag date and key validity matching' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git verify-tag timeboxedvalid-signed 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-tag failes with tag date outside of key validity' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_must_fail git verify-tag timeboxedinvalid-signed 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH 'detect fudged ssh signature' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git cat-file tag seventh-signed >raw && + sed -e "/^tag / s/seventh/7th forged/" raw >forged1 && + git hash-object -w -t tag forged1 >forged1.tag && + test_must_fail git verify-tag $(cat forged1.tag) 2>actual1 && + grep "${GPGSSH_BAD_SIGNATURE}" actual1 && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual1 && + ! grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual1 +' + +test_expect_success GPGSSH 'verify ssh signatures with --raw' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + ( + for tag in initial second merge fourth-signed sixth-signed seventh-signed + do + git verify-tag --raw $tag 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in fourth-unsigned fifth-unsigned sixth-unsigned + do + test_must_fail git verify-tag --raw $tag 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $tag OK || exit 1 + done + ) && + ( + for tag in eighth-signed-alt + do + test_must_fail git verify-tag --raw $tag 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $tag OK || exit 1 + done + ) +' + +test_expect_success GPGSSH 'verify signatures with --raw ssh' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git verify-tag --raw sixth-signed 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo sixth-signed OK +' + +test_expect_success GPGSSH 'verify multiple tags ssh' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + tags="seventh-signed sixth-signed" && + for i in $tags + do + git verify-tag -v --raw $i || return 1 + done >expect.stdout 2>expect.stderr.1 && + grep "^${GPGSSH_GOOD_SIGNATURE_TRUSTED}" <expect.stderr.1 >expect.stderr && + git verify-tag -v --raw $tags >actual.stdout 2>actual.stderr.1 && + grep "^${GPGSSH_GOOD_SIGNATURE_TRUSTED}" <actual.stderr.1 >actual.stderr && + test_cmp expect.stdout actual.stdout && + test_cmp expect.stderr actual.stderr +' + +test_expect_success GPGSSH 'verifying tag with --format - ssh' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + cat >expect <<-\EOF && + tagname : fourth-signed + EOF + git verify-tag --format="tagname : %(tag)" "fourth-signed" >actual && + test_cmp expect actual +' + +test_expect_success GPGSSH 'verifying a forged tag with --format should fail silently - ssh' ' + test_must_fail git verify-tag --format="tagname : %(tag)" $(cat forged1.tag) >actual-forged && + test_must_be_empty actual-forged +' + +test_done diff --git a/t/t7064-wtstatus-pv2.sh b/t/t7064-wtstatus-pv2.sh index eeb0534163..20a0d2afc2 100755 --- a/t/t7064-wtstatus-pv2.sh +++ b/t/t7064-wtstatus-pv2.sh @@ -4,10 +4,6 @@ test_description='git status --porcelain=v2 This test exercises porcelain V2 output for git status.' - -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./test-lib.sh @@ -113,6 +109,21 @@ test_expect_success 'after first commit, create unstaged changes' ' test_cmp expect actual ' +test_expect_success 'after first commit, stash existing changes' ' + cat >expect <<-EOF && + # branch.oid $H0 + # branch.head initial-branch + # stash 2 + EOF + + test_when_finished "git stash pop && git stash pop" && + + git stash -- file_x && + git stash && + git status --porcelain=v2 --branch --show-stash --untracked-files=no >actual && + test_cmp expect actual +' + test_expect_success 'after first commit but omit untracked files and branch' ' cat >expect <<-EOF && 1 .M N... 100644 100644 100644 $OID_X $OID_X file_x diff --git a/t/t7101-reset-empty-subdirs.sh b/t/t7101-reset-empty-subdirs.sh index bfce05ac5d..638bb04e21 100755 --- a/t/t7101-reset-empty-subdirs.sh +++ b/t/t7101-reset-empty-subdirs.sh @@ -4,11 +4,14 @@ # test_description='git reset should cull empty subdirs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-diff-data.sh test_expect_success 'creating initial files' ' mkdir path0 && - cp "$TEST_DIRECTORY"/../COPYING path0/COPYING && + COPYING_test_data >path0/COPYING && git add path0/COPYING && git commit -m add -a ' @@ -16,10 +19,10 @@ test_expect_success 'creating initial files' ' test_expect_success 'creating second files' ' mkdir path1 && mkdir path1/path2 && - cp "$TEST_DIRECTORY"/../COPYING path1/path2/COPYING && - cp "$TEST_DIRECTORY"/../COPYING path1/COPYING && - cp "$TEST_DIRECTORY"/../COPYING COPYING && - cp "$TEST_DIRECTORY"/../COPYING path0/COPYING-TOO && + COPYING_test_data >path1/path2/COPYING && + COPYING_test_data >path1/COPYING && + COPYING_test_data >COPYING && + COPYING_test_data >path0/COPYING-TOO && git add path1/path2/COPYING && git add path1/COPYING && git add COPYING && diff --git a/t/t7103-reset-bare.sh b/t/t7103-reset-bare.sh index afe36a533c..0de83e3619 100755 --- a/t/t7103-reset-bare.sh +++ b/t/t7103-reset-bare.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git reset in a bare repository' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup non-bare' ' diff --git a/t/t7104-reset-hard.sh b/t/t7104-reset-hard.sh index 7948ec392b..cf9697eba9 100755 --- a/t/t7104-reset-hard.sh +++ b/t/t7104-reset-hard.sh @@ -2,6 +2,7 @@ test_description='reset --hard unmerged' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7113-post-index-change-hook.sh b/t/t7113-post-index-change-hook.sh index 688fa995c9..a21781d68a 100755 --- a/t/t7113-post-index-change-hook.sh +++ b/t/t7113-post-index-change-hook.sh @@ -5,6 +5,7 @@ test_description='post index change hook' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index cb1b8e35db..e7cec2e457 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1182,18 +1182,17 @@ test_expect_success 'submodule deinit is silent when used on an uninitialized su rmdir init example2 ' -test_expect_success 'submodule deinit fails when submodule has a .git directory even when forced' ' +test_expect_success 'submodule deinit absorbs .git directory if .git is a directory' ' git submodule update --init && ( cd init && rm .git && - cp -R ../.git/modules/example .git && + mv ../.git/modules/example .git && GIT_WORK_TREE=. git config --unset core.worktree ) && - test_must_fail git submodule deinit init && - test_must_fail git submodule deinit -f init && - test -d init/.git && - test -n "$(git config --get-regexp "submodule\.example\.")" + git submodule deinit init && + test_path_is_missing init/.git && + test -z "$(git config --get-regexp "submodule\.example\.")" ' test_expect_success 'submodule with UTF-8 name' ' diff --git a/t/t7418-submodule-sparse-gitmodules.sh b/t/t7418-submodule-sparse-gitmodules.sh index 3f7f271883..f87e524d6d 100755 --- a/t/t7418-submodule-sparse-gitmodules.sh +++ b/t/t7418-submodule-sparse-gitmodules.sh @@ -12,6 +12,9 @@ The test setup uses a sparse checkout, however the same scenario can be set up also by committing .gitmodules and then just removing it from the filesystem. ' +GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 +export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB + . ./test-lib.sh test_expect_success 'sparse checkout setup which hides .gitmodules' ' diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh index 4e7592522a..bba58f0480 100755 --- a/t/t7504-commit-msg-hook.sh +++ b/t/t7504-commit-msg-hook.sh @@ -133,6 +133,14 @@ test_expect_success '--no-verify with failing hook' ' ' +test_expect_success '-n followed by --verify with failing hook' ' + + echo "even more" >> file && + git add file && + test_must_fail git commit -n --verify -m "even more" + +' + test_expect_success '--no-verify with failing hook (editor)' ' echo "more stuff" >> file && diff --git a/t/t7505-prepare-commit-msg-hook.sh b/t/t7505-prepare-commit-msg-hook.sh index 7a8194ce72..2a07c70867 100755 --- a/t/t7505-prepare-commit-msg-hook.sh +++ b/t/t7505-prepare-commit-msg-hook.sh @@ -250,7 +250,6 @@ test_rebase () { } test_rebase success -test_have_prereq !REBASE_P || test_rebase success -p test_expect_success 'with hook (cherry-pick)' ' test_when_finished "git checkout -f main" && diff --git a/t/t7509-commit-authorship.sh b/t/t7509-commit-authorship.sh index d568593382..21c668f75e 100755 --- a/t/t7509-commit-authorship.sh +++ b/t/t7509-commit-authorship.sh @@ -5,6 +5,7 @@ test_description='commit tests of various authorhip options. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh author_header () { diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 8df5a74f1d..9882b69ae2 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -71,7 +71,25 @@ test_expect_success GPG 'create signed commits' ' 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) + git tag twelfth-signed-alt $(cat oid) && + + cat >keydetails <<-\EOF && + Key-Type: RSA + Key-Length: 2048 + Subkey-Type: RSA + Subkey-Length: 2048 + Name-Real: Unknown User + Name-Email: unknown@git.com + Expire-Date: 0 + %no-ask-passphrase + %no-protection + EOF + gpg --batch --gen-key keydetails && + echo 13 >file && git commit -a -S"unknown@git.com" -m thirteenth && + git tag thirteenth-signed && + DELETE_FINGERPRINT=$(gpg -K --with-colons --fingerprint --batch unknown@git.com | grep "^fpr" | head -n 1 | awk -F ":" "{print \$10;}") && + gpg --batch --yes --delete-secret-keys $DELETE_FINGERPRINT && + gpg --batch --yes --delete-keys unknown@git.com ' test_expect_success GPG 'verify and show signatures' ' @@ -110,6 +128,13 @@ test_expect_success GPG 'verify and show signatures' ' ) ' +test_expect_success GPG 'verify-commit exits failure on unknown signature' ' + test_must_fail git verify-commit thirteenth-signed 2>actual && + ! grep "Good signature from" actual && + ! grep "BAD signature from" actual && + grep -q -F -e "No public key" -e "public key not found" actual +' + test_expect_success GPG 'verify-commit exits success on untrusted signature' ' git verify-commit eighth-signed-alt 2>actual && grep "Good signature from" actual && @@ -203,7 +228,7 @@ test_expect_success GPG 'detect fudged signature with NUL' ' ' test_expect_success GPG 'amending already signed commit' ' - git checkout fourth-signed^0 && + git checkout -f fourth-signed^0 && git commit --amend -S --no-edit && git verify-commit HEAD && git show -s --show-signature HEAD >actual && @@ -338,6 +363,8 @@ test_expect_success GPG 'show double signature with custom format' ' ' +# NEEDSWORK: This test relies on the test_tick commit/author dates from the first +# 'create signed commits' test even though it creates its own test_expect_success GPG 'verify-commit verifies multiply signed commits' ' git init multiply-signed && cd multiply-signed && diff --git a/t/t7511-status-index.sh b/t/t7511-status-index.sh index b5fdc048a5..4ffa45a7bf 100755 --- a/t/t7511-status-index.sh +++ b/t/t7511-status-index.sh @@ -2,6 +2,7 @@ test_description='git status with certain file name lengths' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh files="0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z" diff --git a/t/t7515-status-symlinks.sh b/t/t7515-status-symlinks.sh index 9f989be01b..e3d6bb67bf 100755 --- a/t/t7515-status-symlinks.sh +++ b/t/t7515-status-symlinks.sh @@ -2,6 +2,7 @@ test_description='git status and symlinks' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh index 405420ae4d..163ae80468 100755 --- a/t/t7517-per-repo-email.sh +++ b/t/t7517-per-repo-email.sh @@ -75,19 +75,6 @@ test_expect_success 'noop interactive rebase does not care about ident' ' git rebase -i HEAD^ ' -test_expect_success REBASE_P \ - 'fast-forward rebase does not care about ident (preserve)' ' - git checkout -B tmp side-without-commit && - git rebase -p main -' - -test_expect_success REBASE_P \ - 'non-fast-forward rebase refuses to write commits (preserve)' ' - test_when_finished "git rebase --abort || true" && - git checkout -B tmp side-with-commit && - test_must_fail git rebase -p main -' - test_expect_success 'author.name overrides user.name' ' test_config user.name user && test_config user.email user@example.com && diff --git a/t/t7518-ident-corner-cases.sh b/t/t7518-ident-corner-cases.sh index 905957bd0a..fffdb6ff2e 100755 --- a/t/t7518-ident-corner-cases.sh +++ b/t/t7518-ident-corner-cases.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='corner cases in ident strings' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # confirm that we do not segfault _and_ that we do not say "(null)", as diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh index f488d930df..a5e2233cb1 100755 --- a/t/t7519-status-fsmonitor.sh +++ b/t/t7519-status-fsmonitor.sh @@ -390,7 +390,7 @@ test_expect_success 'status succeeds after staging/unstaging' ' # during a call to 'git status'. Otherwise, we verify that we _do_ call it. check_sparse_index_behavior () { git -C full status --porcelain=v2 >expect && - GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \ + GIT_TRACE2_EVENT="$(pwd)/trace2.txt" \ git -C sparse status --porcelain=v2 >actual && test_region $1 index ensure_full_index trace2.txt && test_region fsm_hook query trace2.txt && diff --git a/t/t7525-status-rename.sh b/t/t7525-status-rename.sh index a62736dce0..22bf5c7e5d 100755 --- a/t/t7525-status-rename.sh +++ b/t/t7525-status-rename.sh @@ -2,6 +2,7 @@ test_description='git status rename detection options' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7526-commit-pathspec-file.sh b/t/t7526-commit-pathspec-file.sh index 5fbe47ebcd..dca62fc48e 100755 --- a/t/t7526-commit-pathspec-file.sh +++ b/t/t7526-commit-pathspec-file.sh @@ -2,6 +2,7 @@ test_description='commit --pathspec-from-file' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_tick diff --git a/t/t7528-signed-commit-ssh.sh b/t/t7528-signed-commit-ssh.sh new file mode 100755 index 0000000000..f47e995179 --- /dev/null +++ b/t/t7528-signed-commit-ssh.sh @@ -0,0 +1,462 @@ +#!/bin/sh + +test_description='ssh signed commit tests' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +. ./test-lib.sh +GNUPGHOME_NOT_USED=$GNUPGHOME +. "$TEST_DIRECTORY/lib-gpg.sh" + +test_expect_success GPGSSH 'create signed commits' ' + test_oid_cache <<-\EOF && + header sha1:gpgsig + header sha256:gpgsig-sha256 + EOF + + test_when_finished "test_unconfig commit.gpgsign" && + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + + echo 1 >file && git add file && + test_tick && git commit -S -m initial && + git tag initial && + git branch side && + + echo 2 >file && test_tick && git commit -a -S -m second && + git tag second && + + git checkout side && + echo 3 >elif && git add elif && + test_tick && git commit -m "third on side" && + + git checkout main && + test_tick && git merge -S side && + git tag merge && + + echo 4 >file && test_tick && git commit -a -m "fourth unsigned" && + git tag fourth-unsigned && + + test_tick && git commit --amend -S -m "fourth signed" && + git tag fourth-signed && + + git config commit.gpgsign true && + echo 5 >file && test_tick && git commit -a -m "fifth signed" && + git tag fifth-signed && + + git config commit.gpgsign false && + echo 6 >file && test_tick && git commit -a -m "sixth" && + git tag sixth-unsigned && + + git config commit.gpgsign true && + echo 7 >file && test_tick && git commit -a -m "seventh" --no-gpg-sign && + git tag seventh-unsigned && + + test_tick && git rebase -f HEAD^^ && git tag sixth-signed HEAD^ && + git tag seventh-signed && + + echo 8 >file && test_tick && git commit -a -m eighth -S"${GPGSSH_KEY_UNTRUSTED}" && + git tag eighth-signed-alt && + + # commit.gpgsign is still on but this must not be signed + 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. + 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="${GPGSSH_KEY_UNTRUSTED}" HEAD^{tree} >oid && + test_line_count = 1 oid && + git tag twelfth-signed-alt $(cat oid) && + + echo 13>file && test_tick && git commit -a -m thirteenth -S"${GPGSSH_KEY_ECDSA}" && + git tag thirteenth-signed-ecdsa +' + +test_expect_success GPGSSH 'sign commits using literal public keys with ssh-agent' ' + test_when_finished "test_unconfig commit.gpgsign" && + test_config gpg.format ssh && + eval $(ssh-agent) && + test_when_finished "kill ${SSH_AGENT_PID}" && + ssh-add "${GPGSSH_KEY_PRIMARY}" && + echo 1 >file && git add file && + git commit -a -m rsa-inline -S"$(cat "${GPGSSH_KEY_PRIMARY}.pub")" && + echo 2 >file && + test_config user.signingkey "$(cat "${GPGSSH_KEY_PRIMARY}.pub")" && + git commit -a -m rsa-config -S && + ssh-add "${GPGSSH_KEY_ECDSA}" && + echo 3 >file && + git commit -a -m ecdsa-inline -S"key::$(cat "${GPGSSH_KEY_ECDSA}.pub")" && + echo 4 >file && + test_config user.signingkey "key::$(cat "${GPGSSH_KEY_ECDSA}.pub")" && + git commit -a -m ecdsa-config -S +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'create signed commits with keys having defined lifetimes' ' + test_when_finished "test_unconfig commit.gpgsign" && + test_config gpg.format ssh && + + echo expired >file && test_tick && git commit -a -m expired -S"${GPGSSH_KEY_EXPIRED}" && + git tag expired-signed && + + echo notyetvalid >file && test_tick && git commit -a -m notyetvalid -S"${GPGSSH_KEY_NOTYETVALID}" && + git tag notyetvalid-signed && + + echo timeboxedvalid >file && test_tick && git commit -a -m timeboxedvalid -S"${GPGSSH_KEY_TIMEBOXEDVALID}" && + git tag timeboxedvalid-signed && + + echo timeboxedinvalid >file && test_tick && git commit -a -m timeboxedinvalid -S"${GPGSSH_KEY_TIMEBOXEDINVALID}" && + git tag timeboxedinvalid-signed +' + +test_expect_success GPGSSH 'verify and show signatures' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_config gpg.mintrustlevel UNDEFINED && + ( + for commit in initial second merge fourth-signed \ + fifth-signed sixth-signed seventh-signed tenth-signed \ + eleventh-signed + do + git verify-commit $commit && + git show --pretty=short --show-signature $commit >actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $commit OK || exit 1 + done + ) && + ( + for commit in merge^2 fourth-unsigned sixth-unsigned \ + seventh-unsigned ninth-unsigned + do + test_must_fail git verify-commit $commit && + git show --pretty=short --show-signature $commit >actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $commit OK || exit 1 + done + ) && + ( + for commit in eighth-signed-alt twelfth-signed-alt + do + git show --pretty=short --show-signature $commit >actual && + grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + grep "${GPGSSH_KEY_NOT_TRUSTED}" actual && + echo $commit OK || exit 1 + done + ) +' + +test_expect_success GPGSSH 'verify-commit exits failure on untrusted signature' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_must_fail git verify-commit eighth-signed-alt 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + grep "${GPGSSH_KEY_NOT_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-commit exits failure on expired signature key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_must_fail git verify-commit expired-signed 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-commit exits failure on not yet valid signature key' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_must_fail git verify-commit notyetvalid-signed 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-commit succeeds with commit date and key validity matching' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git verify-commit timeboxedvalid-signed 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual +' + +test_expect_success GPGSSH,GPGSSH_VERIFYTIME 'verify-commit exits failure with commit date outside of key validity' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_must_fail git verify-commit timeboxedinvalid-signed 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH 'verify-commit exits success with matching minTrustLevel' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_config gpg.minTrustLevel fully && + git verify-commit sixth-signed +' + +test_expect_success GPGSSH 'verify-commit exits success with low minTrustLevel' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_config gpg.minTrustLevel marginal && + git verify-commit sixth-signed +' + +test_expect_success GPGSSH 'verify-commit exits failure with high minTrustLevel' ' + test_config gpg.minTrustLevel ultimate && + test_must_fail git verify-commit eighth-signed-alt +' + +test_expect_success GPGSSH 'verify signatures with --raw' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + ( + for commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed + do + git verify-commit --raw $commit 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $commit OK || exit 1 + done + ) && + ( + for commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned + do + test_must_fail git verify-commit --raw $commit 2>actual && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $commit OK || exit 1 + done + ) && + ( + for commit in eighth-signed-alt + do + test_must_fail git verify-commit --raw $commit 2>actual && + grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual && + echo $commit OK || exit 1 + done + ) +' + +test_expect_success GPGSSH 'proper header is used for hash algorithm' ' + git cat-file commit fourth-signed >output && + grep "^$(test_oid header) -----BEGIN SSH SIGNATURE-----" output +' + +test_expect_success GPGSSH 'show signed commit with signature' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git show -s initial >commit && + git show -s --show-signature initial >show && + git verify-commit -v initial >verify.1 2>verify.2 && + git cat-file commit initial >cat && + grep -v -e "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" -e "Warning: " show >show.commit && + grep -e "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" -e "Warning: " show >show.gpg && + grep -v "^ " cat | grep -v "^gpgsig.* " >cat.commit && + test_cmp show.commit commit && + test_cmp show.gpg verify.2 && + test_cmp cat.commit verify.1 +' + +test_expect_success GPGSSH 'detect fudged signature' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git cat-file commit seventh-signed >raw && + sed -e "s/^seventh/7th forged/" raw >forged1 && + git hash-object -w -t commit forged1 >forged1.commit && + test_must_fail git verify-commit $(cat forged1.commit) && + git show --pretty=short --show-signature $(cat forged1.commit) >actual1 && + grep "${GPGSSH_BAD_SIGNATURE}" actual1 && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual1 && + ! grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual1 +' + +test_expect_success GPGSSH 'detect fudged signature with NUL' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git cat-file commit seventh-signed >raw && + cat raw >forged2 && + echo Qwik | tr "Q" "\000" >>forged2 && + git hash-object -w -t commit forged2 >forged2.commit && + test_must_fail git verify-commit $(cat forged2.commit) && + git show --pretty=short --show-signature $(cat forged2.commit) >actual2 && + grep "${GPGSSH_BAD_SIGNATURE}" actual2 && + ! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual2 +' + +test_expect_success GPGSSH 'amending already signed commit' ' + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + git checkout -f fourth-signed^0 && + git commit --amend -S --no-edit && + git verify-commit HEAD && + git show -s --show-signature HEAD >actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual && + ! grep "${GPGSSH_BAD_SIGNATURE}" actual +' + +test_expect_success GPGSSH 'show good signature with custom format' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && + cat >expect.tmpl <<-\EOF && + G + FINGERPRINT + principal with number 1 + FINGERPRINT + + EOF + sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && + git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual && + test_cmp expect actual +' + +test_expect_success GPGSSH 'show bad signature with custom format' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + cat >expect <<-\EOF && + B + + + + + EOF + git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat forged1.commit) >actual && + test_cmp expect actual +' + +test_expect_success GPGSSH 'show untrusted signature with custom format' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + cat >expect.tmpl <<-\EOF && + U + FINGERPRINT + + FINGERPRINT + + EOF + git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_UNTRUSTED}" | awk "{print \$2;}") && + sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && + test_cmp expect actual +' + +test_expect_success GPGSSH 'show untrusted signature with undefined trust level' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + cat >expect.tmpl <<-\EOF && + undefined + FINGERPRINT + + FINGERPRINT + + EOF + git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" eighth-signed-alt >actual && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_UNTRUSTED}" | awk "{print \$2;}") && + sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && + test_cmp expect actual +' + +test_expect_success GPGSSH 'show untrusted signature with ultimate trust level' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + cat >expect.tmpl <<-\EOF && + fully + FINGERPRINT + principal with number 1 + FINGERPRINT + + EOF + git log -1 --format="%GT%n%GK%n%GS%n%GF%n%GP" sixth-signed >actual && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && + sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && + test_cmp expect actual +' + +test_expect_success GPGSSH 'show lack of signature with custom format' ' + cat >expect <<-\EOF && + N + + + + + EOF + git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" seventh-unsigned >actual && + test_cmp expect actual +' + +test_expect_success GPGSSH 'log.showsignature behaves like --show-signature' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + test_config log.showsignature true && + git show initial >actual && + grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual +' + +test_expect_success GPGSSH 'check config gpg.format values' ' + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + test_config gpg.format ssh && + git commit -S --amend -m "success" && + test_config gpg.format OpEnPgP && + test_must_fail git commit -S --amend -m "fail" +' + +test_expect_failure GPGSSH 'detect fudged commit with double signature (TODO)' ' + sed -e "/gpgsig/,/END PGP/d" forged1 >double-base && + sed -n -e "/gpgsig/,/END PGP/p" forged1 | \ + sed -e "s/^$(test_oid header)//;s/^ //" | gpg --dearmor >double-sig1.sig && + gpg -o double-sig2.sig -u 29472784 --detach-sign double-base && + cat double-sig1.sig double-sig2.sig | gpg --enarmor >double-combined.asc && + sed -e "s/^\(-.*\)ARMORED FILE/\1SIGNATURE/;1s/^/$(test_oid header) /;2,\$s/^/ /" \ + double-combined.asc > double-gpgsig && + sed -e "/committer/r double-gpgsig" double-base >double-commit && + git hash-object -w -t commit double-commit >double-commit.commit && + test_must_fail git verify-commit $(cat double-commit.commit) && + git show --pretty=short --show-signature $(cat double-commit.commit) >double-actual && + grep "BAD signature from" double-actual && + grep "Good signature from" double-actual +' + +test_expect_failure GPGSSH 'show double signature with custom format (TODO)' ' + cat >expect <<-\EOF && + E + + + + + EOF + git log -1 --format="%G?%n%GK%n%GS%n%GF%n%GP" $(cat double-commit.commit) >actual && + test_cmp expect actual +' + + +test_expect_failure GPGSSH 'verify-commit verifies multiply signed commits (TODO)' ' + git init multiply-signed && + cd multiply-signed && + test_commit first && + echo 1 >second && + git add second && + tree=$(git write-tree) && + parent=$(git rev-parse HEAD^{commit}) && + git commit --gpg-sign -m second && + git cat-file commit HEAD && + # Avoid trailing whitespace. + sed -e "s/^Q//" -e "s/^Z/ /" >commit <<-EOF && + Qtree $tree + Qparent $parent + Qauthor A U Thor <author@example.com> 1112912653 -0700 + Qcommitter C O Mitter <committer@example.com> 1112912653 -0700 + Qgpgsig -----BEGIN PGP SIGNATURE----- + QZ + Q iHQEABECADQWIQRz11h0S+chaY7FTocTtvUezd5DDQUCX/uBDRYcY29tbWl0dGVy + Q QGV4YW1wbGUuY29tAAoJEBO29R7N3kMNd+8AoK1I8mhLHviPH+q2I5fIVgPsEtYC + Q AKCTqBh+VabJceXcGIZuF0Ry+udbBQ== + Q =tQ0N + Q -----END PGP SIGNATURE----- + Qgpgsig-sha256 -----BEGIN PGP SIGNATURE----- + QZ + Q iHQEABECADQWIQRz11h0S+chaY7FTocTtvUezd5DDQUCX/uBIBYcY29tbWl0dGVy + Q QGV4YW1wbGUuY29tAAoJEBO29R7N3kMN/NEAn0XO9RYSBj2dFyozi0JKSbssYMtO + Q AJwKCQ1BQOtuwz//IjU8TiS+6S4iUw== + Q =pIwP + Q -----END PGP SIGNATURE----- + Q + Qsecond + EOF + head=$(git hash-object -t commit -w commit) && + git reset --hard $head && + git verify-commit $head 2>actual && + grep "Good signature from" actual && + ! grep "BAD signature from" actual +' + +test_done diff --git a/t/t7601-merge-pull-config.sh b/t/t7601-merge-pull-config.sh index 1f652f433e..bd238d89b0 100755 --- a/t/t7601-merge-pull-config.sh +++ b/t/t7601-merge-pull-config.sh @@ -2,7 +2,7 @@ test_description='git merge -Testing pull.* configuration parsing.' +Testing pull.* configuration parsing and other things.' . ./test-lib.sh @@ -387,6 +387,26 @@ test_expect_success 'pull prevents non-fast-forward with "only" in pull.ff' ' test_must_fail git pull . c3 ' +test_expect_success 'already-up-to-date pull succeeds with unspecified pull.ff' ' + git reset --hard c1 && + git pull . c0 && + test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" +' + +test_expect_success 'already-up-to-date pull succeeds with "only" in pull.ff' ' + git reset --hard c1 && + test_config pull.ff only && + git pull . c0 && + test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" +' + +test_expect_success 'already-up-to-date pull/rebase succeeds with "only" in pull.ff' ' + git reset --hard c1 && + test_config pull.ff only && + git -c pull.rebase=true pull . c0 && + test "$(git rev-parse HEAD)" = "$(git rev-parse c1)" +' + test_expect_success 'merge c1 with c2 (ours in pull.twohead)' ' git reset --hard c1 && git config pull.twohead ours && diff --git a/t/t7604-merge-custom-message.sh b/t/t7604-merge-custom-message.sh index cd4f9607dc..eca7555101 100755 --- a/t/t7604-merge-custom-message.sh +++ b/t/t7604-merge-custom-message.sh @@ -4,6 +4,7 @@ test_description='git merge Testing merge when using a custom message for the merge commit.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_merge_msgs() { diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index 98eda3bfeb..0260ad6f0e 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -3,6 +3,8 @@ test_description='git repack works correctly' . ./test-lib.sh +. "${TEST_DIRECTORY}/lib-bitmap.sh" +. "${TEST_DIRECTORY}/lib-midx.sh" commit_and_pack () { test_commit "$@" 1>&2 && @@ -234,4 +236,140 @@ test_expect_success 'auto-bitmaps do not complain if unavailable' ' test_must_be_empty actual ' +objdir=.git/objects +midx=$objdir/pack/multi-pack-index + +test_expect_success 'setup for --write-midx tests' ' + git init midx && + ( + cd midx && + git config core.multiPackIndex true && + + test_commit base + ) +' + +test_expect_success '--write-midx unchanged' ' + ( + cd midx && + GIT_TEST_MULTI_PACK_INDEX=0 git repack && + test_path_is_missing $midx && + test_path_is_missing $midx-*.bitmap && + + GIT_TEST_MULTI_PACK_INDEX=0 git repack --write-midx && + + test_path_is_file $midx && + test_path_is_missing $midx-*.bitmap && + test_midx_consistent $objdir + ) +' + +test_expect_success '--write-midx with a new pack' ' + ( + cd midx && + test_commit loose && + + GIT_TEST_MULTI_PACK_INDEX=0 git repack --write-midx && + + test_path_is_file $midx && + test_path_is_missing $midx-*.bitmap && + test_midx_consistent $objdir + ) +' + +test_expect_success '--write-midx with -b' ' + ( + cd midx && + GIT_TEST_MULTI_PACK_INDEX=0 git repack -mb && + + test_path_is_file $midx && + test_path_is_file $midx-*.bitmap && + test_midx_consistent $objdir + ) +' + +test_expect_success '--write-midx with -d' ' + ( + cd midx && + test_commit repack && + + GIT_TEST_MULTI_PACK_INDEX=0 git repack -Ad --write-midx && + + test_path_is_file $midx && + test_path_is_missing $midx-*.bitmap && + test_midx_consistent $objdir + ) +' + +test_expect_success 'cleans up MIDX when appropriate' ' + ( + cd midx && + + test_commit repack-2 && + GIT_TEST_MULTI_PACK_INDEX=0 git repack -Adb --write-midx && + + checksum=$(midx_checksum $objdir) && + test_path_is_file $midx && + test_path_is_file $midx-$checksum.bitmap && + test_path_is_file $midx-$checksum.rev && + + test_commit repack-3 && + GIT_TEST_MULTI_PACK_INDEX=0 git repack -Adb --write-midx && + + test_path_is_file $midx && + test_path_is_missing $midx-$checksum.bitmap && + test_path_is_missing $midx-$checksum.rev && + test_path_is_file $midx-$(midx_checksum $objdir).bitmap && + test_path_is_file $midx-$(midx_checksum $objdir).rev && + + test_commit repack-4 && + GIT_TEST_MULTI_PACK_INDEX=0 git repack -Adb && + + find $objdir/pack -type f -name "multi-pack-index*" >files && + test_must_be_empty files + ) +' + +test_expect_success '--write-midx with preferred bitmap tips' ' + git init midx-preferred-tips && + test_when_finished "rm -fr midx-preferred-tips" && + ( + cd midx-preferred-tips && + + test_commit_bulk --message="%s" 103 && + + git log --format="%H" >commits.raw && + sort <commits.raw >commits && + + git log --format="create refs/tags/%s/%s %H" HEAD >refs && + git update-ref --stdin <refs && + + git repack --write-midx --write-bitmap-index && + test_path_is_file $midx && + test_path_is_file $midx-$(midx_checksum $objdir).bitmap && + + test-tool bitmap list-commits | sort >bitmaps && + comm -13 bitmaps commits >before && + test_line_count = 1 before && + + rm -fr $midx-$(midx_checksum $objdir).bitmap && + rm -fr $midx-$(midx_checksum $objdir).rev && + rm -fr $midx && + + # instead of constructing the snapshot ourselves (c.f., the test + # "write a bitmap with --refs-snapshot (preferred tips)" in + # t5326), mark the missing commit as preferred by adding it to + # the pack.preferBitmapTips configuration. + git for-each-ref --format="%(refname:rstrip=1)" \ + --points-at="$(cat before)" >missing && + git config pack.preferBitmapTips "$(cat missing)" && + git repack --write-midx --write-bitmap-index && + + test-tool bitmap list-commits | sort >bitmaps && + comm -13 bitmaps commits >after && + + ! test_cmp before after + ) +' + test_done diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh index 5ccaa440e0..bdbbcbf1ec 100755 --- a/t/t7703-repack-geometric.sh +++ b/t/t7703-repack-geometric.sh @@ -15,7 +15,7 @@ test_expect_success '--geometric with no packs' ' ( cd geometric && - git repack --geometric 2 >out && + git repack --write-midx --geometric 2 >out && test_i18ngrep "Nothing new to pack" out ) ' @@ -180,4 +180,26 @@ test_expect_success '--geometric ignores kept packs' ' ) ' +test_expect_success '--geometric chooses largest MIDX preferred pack' ' + git init geometric && + test_when_finished "rm -fr geometric" && + ( + cd geometric && + + # These packs already form a geometric progression. + test_commit_bulk --start=1 1 && # 3 objects + test_commit_bulk --start=2 2 && # 6 objects + ls $objdir/pack/pack-*.idx >before && + test_commit_bulk --start=4 4 && # 12 objects + ls $objdir/pack/pack-*.idx >after && + + git repack --geometric 2 -dbm && + + comm -3 before after | xargs -n 1 basename >expect && + test-tool read-midx --preferred-pack $objdir >actual && + + test_cmp expect actual + ) +' + test_done diff --git a/t/t7811-grep-open.sh b/t/t7811-grep-open.sh index a98785da79..1dd07141a7 100755 --- a/t/t7811-grep-open.sh +++ b/t/t7811-grep-open.sh @@ -3,6 +3,7 @@ test_description='git grep --open-files-in-pager ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-pager.sh unset PAGER GIT_PAGER @@ -114,8 +115,8 @@ test_expect_success 'modified file' ' unrelated EOF + test_when_finished "git reset --hard" && echo "enum grep_pat_token" >unrelated && - test_when_finished "git checkout HEAD unrelated" && GIT_PAGER=./less git grep -F -O "enum grep_pat_token" >out && test_cmp expect actual && test_must_be_empty out diff --git a/t/t7813-grep-icase-iso.sh b/t/t7813-grep-icase-iso.sh index 701e08a8e5..1227885737 100755 --- a/t/t7813-grep-icase-iso.sh +++ b/t/t7813-grep-icase-iso.sh @@ -2,6 +2,7 @@ test_description='grep icase on non-English locales' +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh test_expect_success GETTEXT_ISO_LOCALE 'setup' ' diff --git a/t/t7815-grep-binary.sh b/t/t7815-grep-binary.sh index 90ebb64f46..ac871287c0 100755 --- a/t/t7815-grep-binary.sh +++ b/t/t7815-grep-binary.sh @@ -2,6 +2,7 @@ test_description='git grep in binary files' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' " diff --git a/t/t7816-grep-binary-pattern.sh b/t/t7816-grep-binary-pattern.sh index 9d67a5fc4c..fdb2355649 100755 --- a/t/t7816-grep-binary-pattern.sh +++ b/t/t7816-grep-binary-pattern.sh @@ -2,6 +2,7 @@ test_description='git grep with a binary pattern files' +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh nul_match_internal () { diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 9b9f11a8e7..74aa638475 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -336,15 +336,15 @@ test_expect_success EXPENSIVE 'incremental-repack 2g limit' ' --no-progress --batch-size=2147483647 <run-2g.txt ' -test_expect_success 'maintenance.incremental-repack.auto' ' +run_incremental_repack_and_verify () { + test_commit A && git repack -adk && - git config core.multiPackIndex true && git multi-pack-index write && GIT_TRACE2_EVENT="$(pwd)/midx-init.txt" git \ -c maintenance.incremental-repack.auto=1 \ maintenance run --auto --task=incremental-repack 2>/dev/null && test_subcommand ! git multi-pack-index write --no-progress <midx-init.txt && - test_commit A && + test_commit B && git pack-objects --revs .git/objects/pack/pack <<-\EOF && HEAD ^HEAD~1 @@ -353,7 +353,7 @@ test_expect_success 'maintenance.incremental-repack.auto' ' -c maintenance.incremental-repack.auto=2 \ maintenance run --auto --task=incremental-repack 2>/dev/null && test_subcommand ! git multi-pack-index write --no-progress <trace-A && - test_commit B && + test_commit C && git pack-objects --revs .git/objects/pack/pack <<-\EOF && HEAD ^HEAD~1 @@ -362,6 +362,26 @@ test_expect_success 'maintenance.incremental-repack.auto' ' -c maintenance.incremental-repack.auto=2 \ maintenance run --auto --task=incremental-repack 2>/dev/null && test_subcommand git multi-pack-index write --no-progress <trace-B +} + +test_expect_success 'maintenance.incremental-repack.auto' ' + rm -rf incremental-repack-true && + git init incremental-repack-true && + ( + cd incremental-repack-true && + git config core.multiPackIndex true && + run_incremental_repack_and_verify + ) +' + +test_expect_success 'maintenance.incremental-repack.auto (when config is unset)' ' + rm -rf incremental-repack-unset && + git init incremental-repack-unset && + ( + cd incremental-repack-unset && + test_unconfig core.multiPackIndex && + run_incremental_repack_and_verify + ) ' test_expect_success 'pack-refs task' ' diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh index 66cd51102c..7b2049caa0 100755 --- a/t/t9102-git-svn-deep-rmdir.sh +++ b/t/t9102-git-svn-deep-rmdir.sh @@ -1,5 +1,7 @@ #!/bin/sh test_description='git svn rmdir' + +TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh index ead404589e..3320b1f39c 100755 --- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -5,6 +5,7 @@ test_description='git svn respects rewriteRoot during rebuild' +TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-svn.sh mkdir import diff --git a/t/t9128-git-svn-cmd-branch.sh b/t/t9128-git-svn-cmd-branch.sh index 4e95f791db..9871f5abc9 100755 --- a/t/t9128-git-svn-cmd-branch.sh +++ b/t/t9128-git-svn-cmd-branch.sh @@ -4,6 +4,8 @@ # test_description='git svn partial-rebuild tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize svnrepo' ' diff --git a/t/t9151-svn-mergeinfo.sh b/t/t9151-svn-mergeinfo.sh index 1fbe84feb1..c93a5beab2 100755 --- a/t/t9151-svn-mergeinfo.sh +++ b/t/t9151-svn-mergeinfo.sh @@ -5,9 +5,6 @@ test_description='git-svn svn mergeinfo properties' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./lib-git-svn.sh test_expect_success 'load svn dump' " diff --git a/t/t9167-git-svn-cmd-branch-subproject.sh b/t/t9167-git-svn-cmd-branch-subproject.sh index ba35fc06fc..d9fd111c10 100755 --- a/t/t9167-git-svn-cmd-branch-subproject.sh +++ b/t/t9167-git-svn-cmd-branch-subproject.sh @@ -4,6 +4,8 @@ # test_description='git svn branch for subproject clones' + +TEST_PASSES_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize svnrepo' ' diff --git a/t/t9302-fast-import-unpack-limit.sh b/t/t9302-fast-import-unpack-limit.sh index f519e4f1bf..d8b1f9442e 100755 --- a/t/t9302-fast-import-unpack-limit.sh +++ b/t/t9302-fast-import-unpack-limit.sh @@ -1,5 +1,7 @@ #!/bin/sh test_description='test git fast-import unpack limit' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create loose objects on import' ' diff --git a/t/t9303-fast-import-compression.sh b/t/t9303-fast-import-compression.sh index 57d916524e..4f5bf40587 100755 --- a/t/t9303-fast-import-compression.sh +++ b/t/t9303-fast-import-compression.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='compression setting of fast-import utility' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh import_large () { diff --git a/t/t9603-cvsimport-patchsets.sh b/t/t9603-cvsimport-patchsets.sh index 0e9daa5768..19f38f78f2 100755 --- a/t/t9603-cvsimport-patchsets.sh +++ b/t/t9603-cvsimport-patchsets.sh @@ -12,9 +12,6 @@ # bug. test_description='git cvsimport testing for correct patchset estimation' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./lib-cvs.sh setup_cvs_test_repository t9603 diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 5decc3b269..0f28c4ad94 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -5,9 +5,6 @@ test_description='test bash completion' -GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master -export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME - . ./lib-bash.sh complete () @@ -2148,6 +2145,9 @@ test_expect_success PERL 'send-email' ' --cover-from-description=Z --cover-letter Z EOF + test_completion "git send-email --val" <<-\EOF && + --validate Z + EOF test_completion "git send-email ma" "main " ' diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index eef2262a36..389153e591 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -680,6 +680,17 @@ test_have_prereq () { # Keep a list of missing prerequisites; restore # the negative marker if necessary. prerequisite=${negative_prereq:+!}$prerequisite + + # Abort if this prereq was marked as required + if test -n "$GIT_TEST_REQUIRE_PREREQ" + then + case " $GIT_TEST_REQUIRE_PREREQ " in + *" $prerequisite "*) + BAIL_OUT "required prereq $prerequisite failed" + ;; + esac + fi + if test -z "$missing_prereq" then missing_prereq=$prerequisite diff --git a/t/test-lib.sh b/t/test-lib.sh index 8361b5c1c5..0f7a137c7d 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -476,6 +476,13 @@ export GIT_TEST_MERGE_ALGORITHM GIT_TRACE_BARE=1 export GIT_TRACE_BARE +# Some tests scan the GIT_TRACE2_EVENT feed for events, but the +# default depth is 2, which frequently causes issues when the +# events are wrapped in new regions. Set it to a sufficiently +# large depth to avoid custom changes in the test suite. +GIT_TRACE2_EVENT_NESTING=100 +export GIT_TRACE2_EVENT_NESTING + # Use specific version of the index file format if test -n "${GIT_TEST_INDEX_VERSION:+isset}" then @@ -489,6 +496,13 @@ then export GIT_PERL_FATAL_WARNINGS fi +case $GIT_TEST_FSYNC in +'') + GIT_TEST_FSYNC=0 + export GIT_TEST_FSYNC + ;; +esac + # Add libc MALLOC and MALLOC_PERTURB test # only if we are not executing the test with valgrind if test -n "$valgrind" || @@ -589,17 +603,42 @@ USER_TERM="$TERM" TERM=dumb export TERM USER_TERM -error () { - say_color error "error: $*" +# What is written by tests to stdout and stderr is sent to different places +# depending on the test mode (e.g. /dev/null in non-verbose mode, piped to tee +# with --tee option, etc.). We save the original stdin to FD #6 and stdout and +# stderr to #5 and #7, so that the test framework can use them (e.g. for +# printing errors within the test framework) independently of the test mode. +exec 5>&1 +exec 6<&0 +exec 7>&2 + +_error_exit () { finalize_junit_xml GIT_EXIT_OK=t exit 1 } +error () { + say_color error "error: $*" + _error_exit +} + BUG () { error >&7 "bug in the test script: $*" } +BAIL_OUT () { + test $# -ne 1 && BUG "1 param" + + # Do not change "Bail out! " string. It's part of TAP syntax: + # https://testanything.org/tap-specification.html + local bail_out="Bail out! " + local message="$1" + + say_color >&5 error $bail_out "$message" + _error_exit +} + say () { say_color info "$*" } @@ -608,9 +647,7 @@ if test -n "$HARNESS_ACTIVE" then if test "$verbose" = t || test -n "$verbose_only" then - printf 'Bail out! %s\n' \ - 'verbose mode forbidden under TAP harness; try --verbose-log' - exit 1 + BAIL_OUT 'verbose mode forbidden under TAP harness; try --verbose-log' fi fi @@ -623,9 +660,6 @@ then exit 0 fi -exec 5>&1 -exec 6<&0 -exec 7>&2 if test "$verbose_log" = "t" then exec 3>>"$GIT_TEST_TEE_OUTPUT_FILE" 4>&3 @@ -655,6 +689,8 @@ test_fixed=0 test_broken=0 test_success=0 +test_missing_prereq= + test_external_has_tap=0 die () { @@ -720,7 +756,7 @@ test_failure_ () { say_color error "not ok $test_count - $1" shift printf '%s\n' "$*" | sed -e 's/^/# /' - test "$immediate" = "" || { finalize_junit_xml; GIT_EXIT_OK=t; exit 1; } + test "$immediate" = "" || _error_exit } test_known_broken_ok_ () { @@ -1055,6 +1091,14 @@ test_skip () { of_prereq=" of $test_prereq" fi skipped_reason="missing $missing_prereq${of_prereq}" + + # Keep a list of all the missing prereq for result aggregation + if test -z "$missing_prereq" + then + test_missing_prereq=$missing_prereq + else + test_missing_prereq="$test_missing_prereq,$missing_prereq" + fi fi case "$to_skip" in @@ -1161,6 +1205,7 @@ test_done () { fixed $test_fixed broken $test_broken failed $test_failure + missing_prereq $test_missing_prereq EOF fi @@ -1398,7 +1443,7 @@ then fi elif test_bool_env GIT_TEST_PASSING_SANITIZE_LEAK false then - error "GIT_TEST_PASSING_SANITIZE_LEAK=true has no effect except when compiled with SANITIZE=leak" + BAIL_OUT "GIT_TEST_PASSING_SANITIZE_LEAK=true has no effect except when compiled with SANITIZE=leak" fi # Last-minute variable setup @@ -1407,8 +1452,20 @@ HOME="$TRASH_DIRECTORY" GNUPGHOME="$HOME/gnupg-home-not-used" export HOME GNUPGHOME USER_HOME +# "rm -rf" existing trash directory, even if a previous run left it +# with bad permissions. +remove_trash_directory () { + dir="$1" + if ! rm -rf "$dir" 2>/dev/null + then + chmod -R u+rwx "$dir" + rm -rf "$dir" + fi + ! test -d "$dir" +} + # Test repository -rm -fr "$TRASH_DIRECTORY" || { +remove_trash_directory "$TRASH_DIRECTORY" || { GIT_EXIT_OK=t echo >&5 "FATAL: Cannot prepare test area" exit 1 @@ -1708,6 +1765,10 @@ build_option () { sed -ne "s/^$1: //p" } +test_lazy_prereq SIZE_T_IS_64BIT ' + test 8 -eq "$(build_option sizeof-size_t)" +' + test_lazy_prereq LONG_IS_64BIT ' test 8 -le "$(build_option sizeof-long)" ' @@ -1730,10 +1791,6 @@ test_lazy_prereq SHA1 ' esac ' -test_lazy_prereq REBASE_P ' - test -z "$GIT_TEST_SKIP_REBASE_P" -' - # Ensure that no test accidentally triggers a Git command # that runs the actual maintenance scheduler, affecting a user's # system permanently. |