diff options
Diffstat (limited to 't')
160 files changed, 6481 insertions, 2854 deletions
diff --git a/t/.gitattributes b/t/.gitattributes index 9930e28351..b9cea1795d 100644 --- a/t/.gitattributes +++ b/t/.gitattributes @@ -22,3 +22,4 @@ t[0-9][0-9][0-9][0-9]/* -whitespace /t7500/* eol=lf /t8005/*.txt eol=lf /t9*/*.dump eol=lf +/t0040*.sh whitespace=-indent-with-non-tab @@ -442,6 +442,10 @@ GIT_TEST_INDEX_VERSION=<n> exercises the index read/write code path for the index version specified. Can be set to any valid version (currently 2, 3, or 4). +GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=<boolean> if enabled will +use the boundary-based bitmap traversal algorithm. See the documentation +of `pack.useBitmapBoundaryTraversal` for more details. + GIT_TEST_PACK_SPARSE=<boolean> if disabled will default the pack-objects builtin to use the non-sparse object walk. This can still be overridden by the --sparse command-line argument. @@ -1098,6 +1102,12 @@ see test-lib-functions.sh for the full list and their options. the symbolic link in the file system and a part that does; then only the latter part need be protected by a SYMLINKS prerequisite (see below). + - test_path_is_executable + + This tests whether a file is executable and prints an error message + if not. This must be used only under the POSIXPERM prerequisite + (see below). + - test_oid_init This function loads facts and useful object IDs related to the hash diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh index 2ef70235b1..5e21e84f38 100644 --- a/t/annotate-tests.sh +++ b/t/annotate-tests.sh @@ -83,6 +83,15 @@ test_expect_success 'blame with --contents' ' check_count --contents=file A 2 ' +test_expect_success 'blame with --contents in a bare repo' ' + git clone --bare . bare-contents.git && + ( + cd bare-contents.git && + echo "1A quick brown fox jumps over the" >contents && + check_count --contents=contents A 1 + ) +' + test_expect_success 'blame with --contents changed' ' echo "1A quick brown fox jumps over the" >contents && echo "another lazy dog" >>contents && diff --git a/t/helper/test-cache-tree.c b/t/helper/test-cache-tree.c index 9507b356e2..e7236392c8 100644 --- a/t/helper/test-cache-tree.c +++ b/t/helper/test-cache-tree.c @@ -1,11 +1,11 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "gettext.h" #include "hex.h" #include "tree.h" #include "cache-tree.h" #include "parse-options.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" diff --git a/t/helper/test-config.c b/t/helper/test-config.c index ad78fc1768..ed444ca4c2 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -42,8 +42,11 @@ * */ -static int iterate_cb(const char *var, const char *value, void *data UNUSED) +static int iterate_cb(const char *var, const char *value, + const struct config_context *ctx, + void *data UNUSED) { + const struct key_value_info *kvi = ctx->kvi; static int nr; if (nr++) @@ -51,26 +54,29 @@ static int iterate_cb(const char *var, const char *value, void *data UNUSED) printf("key=%s\n", var); printf("value=%s\n", value ? value : "(null)"); - printf("origin=%s\n", current_config_origin_type()); - printf("name=%s\n", current_config_name()); - printf("lno=%d\n", current_config_line()); - printf("scope=%s\n", config_scope_name(current_config_scope())); + printf("origin=%s\n", config_origin_type_name(kvi->origin_type)); + printf("name=%s\n", kvi->filename ? kvi->filename : ""); + printf("lno=%d\n", kvi->linenr); + printf("scope=%s\n", config_scope_name(kvi->scope)); return 0; } -static int parse_int_cb(const char *var, const char *value, void *data) +static int parse_int_cb(const char *var, const char *value, + const struct config_context *ctx, void *data) { const char *key_to_match = data; if (!strcmp(key_to_match, var)) { - int parsed = git_config_int(value, value); + int parsed = git_config_int(value, value, ctx->kvi); printf("%d\n", parsed); } return 0; } -static int early_config_cb(const char *var, const char *value, void *vdata) +static int early_config_cb(const char *var, const char *value, + const struct config_context *ctx UNUSED, + void *vdata) { const char *key = vdata; @@ -176,7 +182,7 @@ int cmd__config(int argc, const char **argv) goto exit2; } } - if (!git_configset_get_value(&cs, argv[2], &v)) { + if (!git_configset_get_value(&cs, argv[2], &v, NULL)) { if (!v) printf("(NULL)\n"); else diff --git a/t/helper/test-delta.c b/t/helper/test-delta.c index e7d134ec25..6bc787a474 100644 --- a/t/helper/test-delta.c +++ b/t/helper/test-delta.c @@ -11,7 +11,6 @@ #include "test-tool.h" #include "git-compat-util.h" #include "delta.h" -#include "wrapper.h" static const char usage_str[] = "test-tool delta (-d|-p) <from_file> <data_file> <out_file>"; diff --git a/t/helper/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c index f22f7bd84a..c38f546e4f 100644 --- a/t/helper/test-dump-cache-tree.c +++ b/t/helper/test-dump-cache-tree.c @@ -1,10 +1,10 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "hash.h" #include "hex.h" #include "tree.h" #include "cache-tree.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" diff --git a/t/helper/test-dump-fsmonitor.c b/t/helper/test-dump-fsmonitor.c index 9a098a25cb..4f215fea02 100644 --- a/t/helper/test-dump-fsmonitor.c +++ b/t/helper/test-dump-fsmonitor.c @@ -1,5 +1,5 @@ #include "test-tool.h" -#include "cache.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" diff --git a/t/helper/test-dump-split-index.c b/t/helper/test-dump-split-index.c index d1badd7112..f29d18ef94 100644 --- a/t/helper/test-dump-split-index.c +++ b/t/helper/test-dump-split-index.c @@ -1,12 +1,13 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "hex.h" +#include "read-cache-ll.h" +#include "repository.h" #include "setup.h" #include "split-index.h" #include "ewah/ewok.h" -static void show_bit(size_t pos, void *data) +static void show_bit(size_t pos, void *data UNUSED) { printf(" %d", (int)pos); } diff --git a/t/helper/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c index df70be549f..b4af9712fe 100644 --- a/t/helper/test-dump-untracked-cache.c +++ b/t/helper/test-dump-untracked-cache.c @@ -1,8 +1,8 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "dir.h" #include "hex.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" diff --git a/t/helper/test-example-decorate.c b/t/helper/test-example-decorate.c index 2ed910adaa..8f59f6be4c 100644 --- a/t/helper/test-example-decorate.c +++ b/t/helper/test-example-decorate.c @@ -72,5 +72,7 @@ int cmd__example_decorate(int argc UNUSED, const char **argv UNUSED) if (objects_noticed != 2) BUG("should have 2 objects"); + clear_decoration(&n, NULL); + return 0; } diff --git a/t/helper/test-fast-rebase.c b/t/helper/test-fast-rebase.c index d1d63feaa9..cac20a72b3 100644 --- a/t/helper/test-fast-rebase.c +++ b/t/helper/test-fast-rebase.c @@ -12,15 +12,16 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "cache-tree.h" #include "commit.h" #include "environment.h" #include "gettext.h" +#include "hash.h" #include "hex.h" #include "lockfile.h" #include "merge-ort.h" #include "object-name.h" +#include "read-cache-ll.h" #include "refs.h" #include "revision.h" #include "sequencer.h" diff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c index 9f18c685b7..8280984d08 100644 --- a/t/helper/test-fsmonitor-client.c +++ b/t/helper/test-fsmonitor-client.c @@ -4,14 +4,13 @@ */ #include "test-tool.h" -#include "cache.h" #include "parse-options.h" #include "fsmonitor-ipc.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" #include "thread-utils.h" #include "trace2.h" -#include "wrapper.h" #ifndef HAVE_FSMONITOR_DAEMON_BACKEND int cmd__fsmonitor_client(int argc UNUSED, const char **argv UNUSED) diff --git a/t/helper/test-hash-speed.c b/t/helper/test-hash-speed.c index f40d9ad0c2..b235da594f 100644 --- a/t/helper/test-hash-speed.c +++ b/t/helper/test-hash-speed.c @@ -1,5 +1,5 @@ #include "test-tool.h" -#include "cache.h" +#include "hash-ll.h" #define NUM_SECONDS 3 diff --git a/t/helper/test-index-version.c b/t/helper/test-index-version.c index a06c45c1f8..f3c2dbe0a2 100644 --- a/t/helper/test-index-version.c +++ b/t/helper/test-index-version.c @@ -1,5 +1,5 @@ #include "test-tool.h" -#include "cache.h" +#include "read-cache-ll.h" int cmd__index_version(int argc UNUSED, const char **argv UNUSED) { diff --git a/t/helper/test-lazy-init-name-hash.c b/t/helper/test-lazy-init-name-hash.c index b83a75d19f..187a115d57 100644 --- a/t/helper/test-lazy-init-name-hash.c +++ b/t/helper/test-lazy-init-name-hash.c @@ -1,8 +1,9 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "environment.h" +#include "name-hash.h" #include "parse-options.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" #include "trace.h" diff --git a/t/helper/test-oid-array.c b/t/helper/test-oid-array.c index eef68833b7..aafe398ef0 100644 --- a/t/helper/test-oid-array.c +++ b/t/helper/test-oid-array.c @@ -4,7 +4,7 @@ #include "setup.h" #include "strbuf.h" -static int print_oid(const struct object_id *oid, void *data) +static int print_oid(const struct object_id *oid, void *data UNUSED) { puts(oid_to_hex(oid)); return 0; diff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c index 0f3fbeec53..67a964ef90 100644 --- a/t/helper/test-pack-mtimes.c +++ b/t/helper/test-pack-mtimes.c @@ -1,7 +1,7 @@ #include "test-tool.h" #include "hex.h" #include "strbuf.h" -#include "object-store.h" +#include "object-store-ll.h" #include "packfile.h" #include "pack-mtimes.h" #include "setup.h" diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c index 00fa281a9c..a4f6e24b0c 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -133,6 +133,8 @@ int cmd__parse_options(int argc, const char **argv) OPT_STRING(0, "st", &string, "st", "get another string (pervert ordering)"), OPT_STRING('o', NULL, &string, "str", "get another string"), OPT_NOOP_NOARG(0, "obsolete"), + OPT_SET_INT_F(0, "longhelp", &integer, "help text of this entry\n" + "spans multiple lines", 0, PARSE_OPT_NONEG), OPT_STRING_LIST(0, "list", &list, "str", "add str to list"), OPT_GROUP("Magic arguments"), OPT_NUMBER_CALLBACK(&integer, "set integer to NUM", diff --git a/t/helper/test-partial-clone.c b/t/helper/test-partial-clone.c index 362bd64a4c..910a128614 100644 --- a/t/helper/test-partial-clone.c +++ b/t/helper/test-partial-clone.c @@ -1,7 +1,7 @@ #include "test-tool.h" #include "hex.h" #include "repository.h" -#include "object-store.h" +#include "object-store-ll.h" #include "setup.h" /* diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index 164b6a6832..023ed2e1a7 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -1,8 +1,8 @@ #include "test-tool.h" -#include "cache.h" #include "abspath.h" #include "environment.h" #include "path.h" +#include "read-cache-ll.h" #include "setup.h" #include "string-list.h" #include "trace.h" diff --git a/t/helper/test-reach.c b/t/helper/test-reach.c index 5b6f217441..3e173399a0 100644 --- a/t/helper/test-reach.c +++ b/t/helper/test-reach.c @@ -1,5 +1,4 @@ #include "test-tool.h" -#include "alloc.h" #include "commit.h" #include "commit-reach.h" #include "config.h" @@ -139,7 +138,7 @@ int cmd__reach(int ac, const char **av) printf("%s(X,_,_,0,0):%d\n", av[1], can_all_from_reach_with_flag(&X_obj, 2, 4, 0, 0)); } else if (!strcmp(av[1], "commit_contains")) { - struct ref_filter filter; + struct ref_filter filter = REF_FILTER_INIT; struct contains_cache cache; init_contains_cache(&cache); diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c index c1ae276395..1acd362346 100644 --- a/t/helper/test-read-cache.c +++ b/t/helper/test-read-cache.c @@ -1,10 +1,9 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "config.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" -#include "wrapper.h" int cmd__read_cache(int argc, const char **argv) { diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c index 3ac496e27e..8c7a83f578 100644 --- a/t/helper/test-read-graph.c +++ b/t/helper/test-read-graph.c @@ -1,7 +1,7 @@ #include "test-tool.h" #include "commit-graph.h" #include "repository.h" -#include "object-store.h" +#include "object-store-ll.h" #include "bloom.h" #include "setup.h" diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index 211addaa00..e9a444ddba 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -2,7 +2,7 @@ #include "hex.h" #include "midx.h" #include "repository.h" -#include "object-store.h" +#include "object-store-ll.h" #include "pack-bitmap.h" #include "packfile.h" #include "setup.h" diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 6d8f844e9c..48552e6a9e 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -3,8 +3,11 @@ #include "refs.h" #include "setup.h" #include "worktree.h" -#include "object-store.h" +#include "object-store-ll.h" +#include "path.h" #include "repository.h" +#include "strbuf.h" +#include "revision.h" struct flag_definition { const char *name; @@ -116,8 +119,16 @@ static struct flag_definition pack_flags[] = { FLAG_DEF(PACK_REFS_PRUNE), static int cmd_pack_refs(struct ref_store *refs, const char **argv) { unsigned int flags = arg_flags(*argv++, "flags", pack_flags); + static struct ref_exclusions exclusions = REF_EXCLUSIONS_INIT; + static struct string_list included_refs = STRING_LIST_INIT_NODUP; + struct pack_refs_opts pack_opts = { .flags = flags, + .exclusions = &exclusions, + .includes = &included_refs }; - return refs_pack_refs(refs, flags); + if (pack_opts.flags & PACK_REFS_ALL) + string_list_append(pack_opts.includes, "*"); + + return refs_pack_refs(refs, &pack_opts); } static int cmd_create_symref(struct ref_store *refs, const char **argv) @@ -175,6 +186,15 @@ static int cmd_for_each_ref(struct ref_store *refs, const char **argv) return refs_for_each_ref_in(refs, prefix, each_ref, NULL); } +static int cmd_for_each_ref__exclude(struct ref_store *refs, const char **argv) +{ + const char *prefix = notnull(*argv++, "prefix"); + const char **exclude_patterns = argv; + + return refs_for_each_fullref_in(refs, prefix, exclude_patterns, each_ref, + NULL); +} + static int cmd_resolve_ref(struct ref_store *refs, const char **argv) { struct object_id oid = *null_oid(); @@ -257,11 +277,6 @@ static int cmd_delete_reflog(struct ref_store *refs, const char **argv) return refs_delete_reflog(refs, refname); } -static int cmd_reflog_expire(struct ref_store *refs, const char **argv) -{ - die("not supported yet"); -} - static int cmd_delete_ref(struct ref_store *refs, const char **argv) { const char *msg = notnull(*argv++, "msg"); @@ -307,6 +322,7 @@ static struct command commands[] = { { "delete-refs", cmd_delete_refs }, { "rename-ref", cmd_rename_ref }, { "for-each-ref", cmd_for_each_ref }, + { "for-each-ref--exclude", cmd_for_each_ref__exclude }, { "resolve-ref", cmd_resolve_ref }, { "verify-ref", cmd_verify_ref }, { "for-each-reflog", cmd_for_each_reflog }, @@ -315,7 +331,6 @@ static struct command commands[] = { { "reflog-exists", cmd_reflog_exists }, { "create-reflog", cmd_create_reflog }, { "delete-reflog", cmd_delete_reflog }, - { "reflog-expire", cmd_reflog_expire }, /* * backend transaction functions can't be tested separately */ diff --git a/t/helper/test-repository.c b/t/helper/test-repository.c index bafd2a5bf9..4cd8a952e5 100644 --- a/t/helper/test-repository.c +++ b/t/helper/test-repository.c @@ -4,7 +4,7 @@ #include "config.h" #include "environment.h" #include "hex.h" -#include "object-store.h" +#include "object-store-ll.h" #include "object.h" #include "repository.h" #include "setup.h" diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c index 0c62b9de18..f346951bc2 100644 --- a/t/helper/test-revision-walking.c +++ b/t/helper/test-revision-walking.c @@ -11,6 +11,7 @@ #include "test-tool.h" #include "commit.h" #include "diff.h" +#include "repository.h" #include "revision.h" #include "setup.h" diff --git a/t/helper/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c index 6e17f50d22..0a816a96e2 100644 --- a/t/helper/test-scrap-cache-tree.c +++ b/t/helper/test-scrap-cache-tree.c @@ -1,7 +1,7 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "lockfile.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" #include "tree.h" diff --git a/t/helper/test-sha1.c b/t/helper/test-sha1.c index 71fe5c6145..dcb7f6c003 100644 --- a/t/helper/test-sha1.c +++ b/t/helper/test-sha1.c @@ -1,5 +1,5 @@ #include "test-tool.h" -#include "cache.h" +#include "hash-ll.h" int cmd__sha1(int ac, const char **av) { diff --git a/t/helper/test-sha256.c b/t/helper/test-sha256.c index 0ac6a99d5f..08cf149001 100644 --- a/t/helper/test-sha256.c +++ b/t/helper/test-sha256.c @@ -1,5 +1,5 @@ #include "test-tool.h" -#include "cache.h" +#include "hash-ll.h" int cmd__sha256(int ac, const char **av) { diff --git a/t/helper/test-strcmp-offset.c b/t/helper/test-strcmp-offset.c index 96b9a5b529..d8473cf2fc 100644 --- a/t/helper/test-strcmp-offset.c +++ b/t/helper/test-strcmp-offset.c @@ -1,5 +1,5 @@ #include "test-tool.h" -#include "cache.h" +#include "read-cache-ll.h" int cmd__strcmp_offset(int argc UNUSED, const char **argv) { diff --git a/t/helper/test-userdiff.c b/t/helper/test-userdiff.c index 680124a676..0ce31ce59f 100644 --- a/t/helper/test-userdiff.c +++ b/t/helper/test-userdiff.c @@ -12,7 +12,9 @@ static int driver_cb(struct userdiff_driver *driver, return 0; } -static int cmd__userdiff_config(const char *var, const char *value, void *cb UNUSED) +static int cmd__userdiff_config(const char *var, const char *value, + const struct config_context *ctx UNUSED, + void *cb UNUSED) { if (userdiff_config(var, value) < 0) return -1; diff --git a/t/helper/test-wildmatch.c b/t/helper/test-wildmatch.c index a95bb4da9b..b4ff5f986a 100644 --- a/t/helper/test-wildmatch.c +++ b/t/helper/test-wildmatch.c @@ -1,4 +1,5 @@ #include "test-tool.h" +#include "wildmatch.h" int cmd__wildmatch(int argc, const char **argv) { diff --git a/t/helper/test-write-cache.c b/t/helper/test-write-cache.c index eace08072d..f084034d38 100644 --- a/t/helper/test-write-cache.c +++ b/t/helper/test-write-cache.c @@ -1,7 +1,7 @@ #define USE_THE_INDEX_VARIABLE #include "test-tool.h" -#include "cache.h" #include "lockfile.h" +#include "read-cache-ll.h" #include "repository.h" #include "setup.h" diff --git a/t/lib-commit-graph.sh b/t/lib-commit-graph.sh index 5d79e1a4e9..89b26676fb 100755 --- a/t/lib-commit-graph.sh +++ b/t/lib-commit-graph.sh @@ -14,24 +14,37 @@ graph_git_two_modes() { test_cmp expect output } +# graph_git_behavior <name> <directory> <branch> <compare> +# +# Ensures that a handful of traversal operations produce the same +# results with and without the commit-graph in use. +# +# NOTE: it is a bug to call this function with <directory> containing +# any characters in $IFS. graph_git_behavior() { MSG=$1 DIR=$2 BRANCH=$3 COMPARE=$4 test_expect_success "check normal git operations: $MSG" ' - cd "$TRASH_DIRECTORY/$DIR" && - 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 "${DIR:+-C $DIR} log --oneline $BRANCH" && + graph_git_two_modes "${DIR:+-C $DIR} log --topo-order $BRANCH" && + graph_git_two_modes "${DIR:+-C $DIR} log --graph $COMPARE..$BRANCH" && + graph_git_two_modes "${DIR:+-C $DIR} branch -vv" && + graph_git_two_modes "${DIR:+-C $DIR} merge-base -a $BRANCH $COMPARE" ' } graph_read_expect() { OPTIONAL="" NUM_CHUNKS=3 + DIR="." + if test "$1" = -C + then + shift + DIR="$1" + shift + fi if test -n "$2" then OPTIONAL=" $2" @@ -47,12 +60,15 @@ graph_read_expect() { then OPTIONS=" read_generation_data" fi - cat >expect <<- EOF + cat >"$DIR/expect" <<-EOF header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0 num_commits: $1 chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL options:$OPTIONS EOF - test-tool read-graph >output && - test_cmp expect output + ( + cd "$DIR" && + test-tool read-graph >output && + test_cmp expect output + ) } diff --git a/t/lib-credential.sh b/t/lib-credential.sh index f1ab92ba35..032b2d8fcc 100644 --- a/t/lib-credential.sh +++ b/t/lib-credential.sh @@ -44,6 +44,10 @@ helper_test_clean() { reject $1 https example.com user1 reject $1 https example.com user2 reject $1 https example.com user4 + reject $1 https example.com user-distinct-pass + reject $1 https example.com user-overwrite + reject $1 https example.com user-erase1 + reject $1 https example.com user-erase2 reject $1 http path.tld user reject $1 https timeout.tld user reject $1 https sso.tld @@ -167,6 +171,49 @@ helper_test() { EOF ' + test_expect_success "helper ($HELPER) overwrites on store" ' + check approve $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-overwrite + password=pass1 + EOF + check approve $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-overwrite + password=pass2 + EOF + check fill $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-overwrite + -- + protocol=https + host=example.com + username=user-overwrite + password=pass2 + EOF + check reject $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-overwrite + password=pass2 + EOF + check fill $HELPER <<-\EOF + protocol=https + host=example.com + username=user-overwrite + -- + protocol=https + host=example.com + username=user-overwrite + password=askpass-password + -- + askpass: Password for '\''https://user-overwrite@example.com'\'': + EOF + ' + test_expect_success "helper ($HELPER) can forget host" ' check reject $HELPER <<-\EOF && protocol=https @@ -221,6 +268,31 @@ helper_test() { EOF ' + test_expect_success "helper ($HELPER) does not erase a password distinct from input" ' + check approve $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-distinct-pass + password=pass1 + EOF + check reject $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-distinct-pass + password=pass2 + EOF + check fill $HELPER <<-\EOF + protocol=https + host=example.com + username=user-distinct-pass + -- + protocol=https + host=example.com + username=user-distinct-pass + password=pass1 + EOF + ' + test_expect_success "helper ($HELPER) can forget user" ' check reject $HELPER <<-\EOF && protocol=https @@ -272,6 +344,37 @@ helper_test() { EOF ' + test_expect_success "helper ($HELPER) erases all matching credentials" ' + check approve $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-erase1 + password=pass1 + EOF + check approve $HELPER <<-\EOF && + protocol=https + host=example.com + username=user-erase2 + password=pass1 + EOF + check reject $HELPER <<-\EOF && + protocol=https + host=example.com + EOF + check fill $HELPER <<-\EOF + protocol=https + host=example.com + -- + protocol=https + host=example.com + username=askpass-username + password=askpass-password + -- + askpass: Username for '\''https://example.com'\'': + askpass: Password for '\''https://askpass-username@example.com'\'': + EOF + ' + : ${GIT_TEST_LONG_CRED_BUFFER:=1024} # 23 bytes accounts for "wwwauth[]=basic realm=" plus NUL LONG_VALUE_LEN=$((GIT_TEST_LONG_CRED_BUFFER - 23)) diff --git a/t/lib-gpg.sh b/t/lib-gpg.sh index 114785586a..83b83c9abb 100644 --- a/t/lib-gpg.sh +++ b/t/lib-gpg.sh @@ -45,6 +45,28 @@ test_lazy_prereq GPG ' "$TEST_DIRECTORY"/lib-gpg/keyring.gpg && gpg --homedir "${GNUPGHOME}" --import-ownertrust \ "$TEST_DIRECTORY"/lib-gpg/ownertrust && + gpg --homedir "${GNUPGHOME}" --update-trustdb && + gpg --homedir "${GNUPGHOME}" </dev/null >/dev/null \ + --sign -u committer@example.com + ;; + esac +' + +test_lazy_prereq GPG2 ' + gpg_version=$(gpg --version 2>&1) + test $? != 127 || exit 1 + + case "$gpg_version" in + "gpg (GnuPG) "[01].*) + say "This test requires a GPG version >= v2.0.0" + exit 1 + ;; + *) + (gpgconf --kill all || : ) && + gpg --homedir "${GNUPGHOME}" --import \ + "$TEST_DIRECTORY"/lib-gpg/keyring.gpg && + gpg --homedir "${GNUPGHOME}" --import-ownertrust \ + "$TEST_DIRECTORY"/lib-gpg/ownertrust && gpg --homedir "${GNUPGHOME}" </dev/null >/dev/null \ --sign -u committer@example.com ;; @@ -135,8 +157,9 @@ test_lazy_prereq GPGSSH ' ' test_lazy_prereq GPGSSH_VERIFYTIME ' + test_have_prereq GPGSSH && # 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\"" && + ssh-keygen -Overify-time=INVALID -Y check-novalidate -n "git" -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 && diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index a22d138605..022276a6b9 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -92,6 +92,7 @@ PassEnv GIT_VALGRIND_OPTIONS PassEnv GNUPGHOME PassEnv ASAN_OPTIONS PassEnv LSAN_OPTIONS +PassEnv UBSAN_OPTIONS PassEnv GIT_TRACE PassEnv GIT_CONFIG_NOSYSTEM PassEnv GIT_TEST_SIDEBAND_ALL diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh index 901cc493ef..96ed3e1d69 100755 --- a/t/perf/p2000-sparse-operations.sh +++ b/t/perf/p2000-sparse-operations.sh @@ -131,5 +131,8 @@ test_perf_on_all git describe --dirty test_perf_on_all 'echo >>new && git describe --dirty' test_perf_on_all git diff-files test_perf_on_all git diff-files -- $SPARSE_CONE/a +test_perf_on_all git diff-tree HEAD +test_perf_on_all git diff-tree HEAD -- $SPARSE_CONE/a +test_perf_on_all "git worktree add ../temp && git worktree remove ../temp" test_done diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 402b201b5a..98b81e4d63 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -1014,7 +1014,7 @@ test_expect_success 'validate object ID for a known tree' ' ' test_expect_success 'showing tree with git ls-tree' ' - git ls-tree $tree >current + git ls-tree $tree >current ' test_expect_success 'git ls-tree output for a known tree' ' diff --git a/t/t0007-git-var.sh b/t/t0007-git-var.sh index eeb8539c1b..ff4fd9348c 100755 --- a/t/t0007-git-var.sh +++ b/t/t0007-git-var.sh @@ -147,6 +147,84 @@ test_expect_success 'get GIT_SEQUENCE_EDITOR with configuration and environment ) ' +test_expect_success POSIXPERM 'GIT_SHELL_PATH points to a valid executable' ' + shellpath=$(git var GIT_SHELL_PATH) && + test_path_is_executable "$shellpath" +' + +# We know in this environment that our shell will be one of a few fixed values +# that all end in "sh". +test_expect_success MINGW 'GIT_SHELL_PATH points to a suitable shell' ' + shellpath=$(git var GIT_SHELL_PATH) && + case "$shellpath" in + *sh) ;; + *) return 1;; + esac +' + +test_expect_success 'GIT_ATTR_SYSTEM produces expected output' ' + test_must_fail env GIT_ATTR_NOSYSTEM=1 git var GIT_ATTR_SYSTEM && + ( + sane_unset GIT_ATTR_NOSYSTEM && + systempath=$(git var GIT_ATTR_SYSTEM) && + test "$systempath" != "" + ) +' + +test_expect_success 'GIT_ATTR_GLOBAL points to the correct location' ' + TRASHDIR="$(test-tool path-utils normalize_path_copy "$(pwd)")" && + globalpath=$(XDG_CONFIG_HOME="$TRASHDIR/.config" git var GIT_ATTR_GLOBAL) && + test "$globalpath" = "$TRASHDIR/.config/git/attributes" && + ( + sane_unset XDG_CONFIG_HOME && + globalpath=$(HOME="$TRASHDIR" git var GIT_ATTR_GLOBAL) && + test "$globalpath" = "$TRASHDIR/.config/git/attributes" + ) +' + +test_expect_success 'GIT_CONFIG_SYSTEM points to the correct location' ' + TRASHDIR="$(test-tool path-utils normalize_path_copy "$(pwd)")" && + test_must_fail env GIT_CONFIG_NOSYSTEM=1 git var GIT_CONFIG_SYSTEM && + ( + sane_unset GIT_CONFIG_NOSYSTEM && + systempath=$(git var GIT_CONFIG_SYSTEM) && + test "$systempath" != "" && + systempath=$(GIT_CONFIG_SYSTEM=/dev/null git var GIT_CONFIG_SYSTEM) && + if test_have_prereq MINGW + then + test "$systempath" = "nul" + else + test "$systempath" = "/dev/null" + fi && + systempath=$(GIT_CONFIG_SYSTEM="$TRASHDIR/gitconfig" git var GIT_CONFIG_SYSTEM) && + test "$systempath" = "$TRASHDIR/gitconfig" + ) +' + +test_expect_success 'GIT_CONFIG_GLOBAL points to the correct location' ' + TRASHDIR="$(test-tool path-utils normalize_path_copy "$(pwd)")" && + HOME="$TRASHDIR" XDG_CONFIG_HOME="$TRASHDIR/foo" git var GIT_CONFIG_GLOBAL >actual && + echo "$TRASHDIR/foo/git/config" >expected && + echo "$TRASHDIR/.gitconfig" >>expected && + test_cmp expected actual && + ( + sane_unset XDG_CONFIG_HOME && + HOME="$TRASHDIR" git var GIT_CONFIG_GLOBAL >actual && + echo "$TRASHDIR/.config/git/config" >expected && + echo "$TRASHDIR/.gitconfig" >>expected && + test_cmp expected actual && + globalpath=$(GIT_CONFIG_GLOBAL=/dev/null git var GIT_CONFIG_GLOBAL) && + if test_have_prereq MINGW + then + test "$globalpath" = "nul" + else + test "$globalpath" = "/dev/null" + fi && + globalpath=$(GIT_CONFIG_GLOBAL="$TRASHDIR/gitconfig" git var GIT_CONFIG_GLOBAL) && + test "$globalpath" = "$TRASHDIR/gitconfig" + ) +' + # 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. @@ -164,8 +242,39 @@ test_expect_success 'git var -l lists config' ' test_cmp expect actual.bare ' +test_expect_success 'git var -l lists multiple global configs' ' + TRASHDIR="$(test-tool path-utils normalize_path_copy "$(pwd)")" && + HOME="$TRASHDIR" XDG_CONFIG_HOME="$TRASHDIR/foo" git var -l >actual && + grep "^GIT_CONFIG_GLOBAL=" actual >filtered && + echo "GIT_CONFIG_GLOBAL=$TRASHDIR/foo/git/config" >expected && + echo "GIT_CONFIG_GLOBAL=$TRASHDIR/.gitconfig" >>expected && + test_cmp expected filtered +' + +test_expect_success 'git var -l does not split multiline editors' ' + ( + GIT_EDITOR="!f() { + echo Hello! + }; f" && + export GIT_EDITOR && + echo "GIT_EDITOR=$GIT_EDITOR" >expected && + git var -l >var && + sed -n -e "/^GIT_EDITOR/,\$p" var | head -n 3 >actual && + test_cmp expected actual + ) +' + test_expect_success 'listing and asking for variables are exclusive' ' test_must_fail git var -l GIT_COMMITTER_IDENT ' +test_expect_success '`git var -l` works even without HOME' ' + ( + XDG_CONFIG_HOME= && + export XDG_CONFIG_HOME && + unset HOME && + git var -l + ) +' + test_done diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh index 0a5713c524..d1b3be8725 100755 --- a/t/t0030-stripspace.sh +++ b/t/t0030-stripspace.sh @@ -17,396 +17,378 @@ printf_git_stripspace () { printf "$1" | git stripspace } -test_expect_success \ - 'long lines without spaces should be unchanged' ' - echo "$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual && - - echo "$ttt$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual && - - echo "$ttt$ttt$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual && - - echo "$ttt$ttt$ttt$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual +test_expect_success 'long lines without spaces should be unchanged' ' + echo "$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$ttt$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$ttt$ttt$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && + + echo "$ttt$ttt$ttt$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual ' -test_expect_success \ - 'lines with spaces at the beginning should be unchanged' ' - echo "$sss$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual && +test_expect_success 'lines with spaces at the beginning should be unchanged' ' + echo "$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && - echo "$sss$sss$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual && + echo "$sss$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && - echo "$sss$sss$sss$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual + echo "$sss$sss$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual ' -test_expect_success \ - 'lines with intermediate spaces should be unchanged' ' - echo "$ttt$sss$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual && +test_expect_success 'lines with intermediate spaces should be unchanged' ' + echo "$ttt$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual && - echo "$ttt$sss$sss$ttt" >expect && - git stripspace <expect >actual && - test_cmp expect actual + echo "$ttt$sss$sss$ttt" >expect && + git stripspace <expect >actual && + test_cmp expect actual ' -test_expect_success \ - 'consecutive blank lines should be unified' ' - printf "$ttt\n\n$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && +test_expect_success 'consecutive blank lines should be unified' ' + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt\n\n$ttt\n" > expect && - printf "$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && - printf "$ttt$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$ttt$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$ttt$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && - printf "$ttt\n\n\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && + printf "$ttt\n\n\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$ttt\n" > expect && - printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt\n\n$ttt\n" > expect && - printf "$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && - printf "$ttt$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt$ttt\n\n$ttt\n" > expect && + printf "$ttt$ttt$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$ttt\n" > expect && - printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$ttt$ttt\n" > expect && - printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$ttt$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && - printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual + printf "$ttt\n\n$ttt$ttt$ttt\n" > expect && + printf "$ttt\n\t\n \n\n \t\t\n$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual ' -test_expect_success \ - 'only consecutive blank lines should be completely removed' ' +test_expect_success 'only consecutive blank lines should be completely removed' ' + printf "\n" | git stripspace >actual && + test_must_be_empty actual && - printf "\n" | git stripspace >actual && - test_must_be_empty actual && + printf "\n\n\n" | git stripspace >actual && + test_must_be_empty actual && - printf "\n\n\n" | git stripspace >actual && - test_must_be_empty actual && + printf "$sss\n$sss\n$sss\n" | git stripspace >actual && + test_must_be_empty actual && - printf "$sss\n$sss\n$sss\n" | git stripspace >actual && - test_must_be_empty actual && + printf "$sss$sss\n$sss\n\n" | git stripspace >actual && + test_must_be_empty actual && - printf "$sss$sss\n$sss\n\n" | git stripspace >actual && - test_must_be_empty actual && + printf "\n$sss\n$sss$sss\n" | git stripspace >actual && + test_must_be_empty actual && - printf "\n$sss\n$sss$sss\n" | git stripspace >actual && - test_must_be_empty actual && + printf "$sss$sss$sss$sss\n\n\n" | git stripspace >actual && + test_must_be_empty actual && - printf "$sss$sss$sss$sss\n\n\n" | git stripspace >actual && - test_must_be_empty actual && + printf "\n$sss$sss$sss$sss\n\n" | git stripspace >actual && + test_must_be_empty actual && - printf "\n$sss$sss$sss$sss\n\n" | git stripspace >actual && - test_must_be_empty actual && - - printf "\n\n$sss$sss$sss$sss\n" | git stripspace >actual && - test_must_be_empty actual + printf "\n\n$sss$sss$sss$sss\n" | git stripspace >actual && + test_must_be_empty actual ' -test_expect_success \ - 'consecutive blank lines at the beginning should be removed' ' - printf "$ttt\n" > expect && - printf "\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && +test_expect_success 'consecutive blank lines at the beginning should be removed' ' + printf "$ttt\n" > expect && + printf "\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n" > expect && - printf "\n\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n" > expect && + printf "\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt\n" > expect && - printf "\n\n\n$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt\n" > expect && + printf "\n\n\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt$ttt\n" > expect && - printf "\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt$ttt\n" > expect && + printf "\n\n\n$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt$ttt$ttt\n" > expect && - printf "\n\n\n$ttt$ttt$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt$ttt$ttt\n" > expect && + printf "\n\n\n$ttt$ttt$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n" > expect && + printf "$ttt\n" > expect && - printf "$sss\n$sss\n$sss\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$sss\n$sss\n$sss\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "\n$sss\n$sss$sss\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "\n$sss\n$sss$sss\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$sss$sss\n$sss\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$sss$sss\n$sss\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$sss$sss$sss\n\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$sss$sss$sss\n\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "\n$sss$sss$sss\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "\n$sss$sss$sss\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "\n\n$sss$sss$sss\n$ttt\n" | git stripspace >actual && - test_cmp expect actual + printf "\n\n$sss$sss$sss\n$ttt\n" | git stripspace >actual && + test_cmp expect actual ' -test_expect_success \ - 'consecutive blank lines at the end should be removed' ' - printf "$ttt\n" > expect && - printf "$ttt\n\n" | git stripspace >actual && - test_cmp expect actual && +test_expect_success 'consecutive blank lines at the end should be removed' ' + printf "$ttt\n" > expect && + printf "$ttt\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n" > expect && - printf "$ttt\n\n\n\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n" > expect && + printf "$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt\n" > expect && - printf "$ttt$ttt\n\n\n\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt\n" > expect && + printf "$ttt$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt$ttt\n" > expect && - printf "$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt$ttt\n" > expect && + printf "$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt$ttt$ttt\n" > expect && - printf "$ttt$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt$ttt$ttt\n" > expect && + printf "$ttt$ttt$ttt$ttt\n\n\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n" > expect && + printf "$ttt\n" > expect && - printf "$ttt\n$sss\n$sss\n$sss\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n$sss\n$sss\n$sss\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$sss\n$sss$sss\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$sss\n$sss$sss\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n$sss$sss\n$sss\n\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n$sss$sss\n$sss\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n$sss$sss$sss\n\n\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n$sss$sss$sss\n\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n$sss$sss$sss\n\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n\n$sss$sss$sss\n\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n\n\n$sss$sss$sss\n" | git stripspace >actual && - test_cmp expect actual + printf "$ttt\n\n\n$sss$sss$sss\n" | git stripspace >actual && + test_cmp expect actual ' -test_expect_success \ - 'text without newline at end should end with newline' ' - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$ttt" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$ttt$ttt" +test_expect_success 'text without newline at end should end with newline' ' + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$ttt" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$ttt$ttt" ' # text plus spaces at the end: -test_expect_success \ - 'text plus spaces without newline at end should end with newline' ' - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$sss" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$sss" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$ttt$sss" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$sss$sss" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$sss$sss" && - test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$sss$sss$sss" +test_expect_success 'text plus spaces without newline at end should end with newline' ' + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$sss" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$sss" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$ttt$sss" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$sss$sss" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$ttt$sss$sss" && + test_stdout_line_count -gt 0 printf_git_stripspace "$ttt$sss$sss$sss" ' -test_expect_success \ - 'text plus spaces without newline at end should not show spaces' ' - printf "$ttt$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$ttt$ttt$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$ttt$ttt$ttt$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$ttt$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$ttt$ttt$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$ttt$sss$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null +test_expect_success 'text plus spaces without newline at end should not show spaces' ' + printf "$ttt$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$ttt$ttt$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$ttt$ttt$ttt$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$ttt$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$ttt$ttt$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$ttt$sss$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null ' -test_expect_success \ - 'text plus spaces without newline should show the correct lines' ' - printf "$ttt\n" >expect && - printf "$ttt$sss" | git stripspace >actual && - test_cmp expect actual && +test_expect_success 'text plus spaces without newline should show the correct lines' ' + printf "$ttt\n" >expect && + printf "$ttt$sss" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n" >expect && - printf "$ttt$sss$sss" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n" >expect && + printf "$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n" >expect && - printf "$ttt$sss$sss$sss" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n" >expect && + printf "$ttt$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt\n" >expect && - printf "$ttt$ttt$sss" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt\n" >expect && + printf "$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt\n" >expect && - printf "$ttt$ttt$sss$sss" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt\n" >expect && + printf "$ttt$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt$ttt\n" >expect && - printf "$ttt$ttt$ttt$sss" | git stripspace >actual && - test_cmp expect actual + printf "$ttt$ttt$ttt\n" >expect && + printf "$ttt$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual ' -test_expect_success \ - 'text plus spaces at end should not show spaces' ' - echo "$ttt$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - echo "$ttt$ttt$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - echo "$ttt$ttt$ttt$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - echo "$ttt$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - echo "$ttt$ttt$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - echo "$ttt$sss$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null +test_expect_success 'text plus spaces at end should not show spaces' ' + echo "$ttt$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + echo "$ttt$ttt$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + echo "$ttt$ttt$ttt$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + echo "$ttt$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + echo "$ttt$ttt$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + echo "$ttt$sss$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null ' -test_expect_success \ - 'text plus spaces at end should be cleaned and newline must remain' ' - echo "$ttt" >expect && - echo "$ttt$sss" | git stripspace >actual && - test_cmp expect actual && +test_expect_success 'text plus spaces at end should be cleaned and newline must remain' ' + echo "$ttt" >expect && + echo "$ttt$sss" | git stripspace >actual && + test_cmp expect actual && - echo "$ttt" >expect && - echo "$ttt$sss$sss" | git stripspace >actual && - test_cmp expect actual && + echo "$ttt" >expect && + echo "$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && - echo "$ttt" >expect && - echo "$ttt$sss$sss$sss" | git stripspace >actual && - test_cmp expect actual && + echo "$ttt" >expect && + echo "$ttt$sss$sss$sss" | git stripspace >actual && + test_cmp expect actual && - echo "$ttt$ttt" >expect && - echo "$ttt$ttt$sss" | git stripspace >actual && - test_cmp expect actual && + echo "$ttt$ttt" >expect && + echo "$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual && - echo "$ttt$ttt" >expect && - echo "$ttt$ttt$sss$sss" | git stripspace >actual && - test_cmp expect actual && + echo "$ttt$ttt" >expect && + echo "$ttt$ttt$sss$sss" | git stripspace >actual && + test_cmp expect actual && - echo "$ttt$ttt$ttt" >expect && - echo "$ttt$ttt$ttt$sss" | git stripspace >actual && - test_cmp expect actual + echo "$ttt$ttt$ttt" >expect && + echo "$ttt$ttt$ttt$sss" | git stripspace >actual && + test_cmp expect actual ' # spaces only: -test_expect_success \ - 'spaces with newline at end should be replaced with empty string' ' - echo | git stripspace >actual && - test_must_be_empty actual && +test_expect_success 'spaces with newline at end should be replaced with empty string' ' + echo | git stripspace >actual && + test_must_be_empty actual && - echo "$sss" | git stripspace >actual && - test_must_be_empty actual && + echo "$sss" | git stripspace >actual && + test_must_be_empty actual && - echo "$sss$sss" | git stripspace >actual && - test_must_be_empty actual && + echo "$sss$sss" | git stripspace >actual && + test_must_be_empty actual && - echo "$sss$sss$sss" | git stripspace >actual && - test_must_be_empty actual && + echo "$sss$sss$sss" | git stripspace >actual && + test_must_be_empty actual && - echo "$sss$sss$sss$sss" | git stripspace >actual && - test_must_be_empty actual + echo "$sss$sss$sss$sss" | git stripspace >actual && + test_must_be_empty actual ' -test_expect_success \ - 'spaces without newline at end should not show spaces' ' - printf "" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$sss$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null && - printf "$sss$sss$sss$sss" | git stripspace >tmp && - ! grep " " tmp >/dev/null +test_expect_success 'spaces without newline at end should not show spaces' ' + printf "" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$sss$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null && + printf "$sss$sss$sss$sss" | git stripspace >tmp && + ! grep " " tmp >/dev/null ' -test_expect_success \ - 'spaces without newline at end should be replaced with empty string' ' - printf "" | git stripspace >actual && - test_must_be_empty actual && +test_expect_success 'spaces without newline at end should be replaced with empty string' ' + printf "" | git stripspace >actual && + test_must_be_empty actual && - printf "$sss$sss" | git stripspace >actual && - test_must_be_empty actual && + printf "$sss$sss" | git stripspace >actual && + test_must_be_empty actual && - printf "$sss$sss$sss" | git stripspace >actual && - test_must_be_empty actual && + printf "$sss$sss$sss" | git stripspace >actual && + test_must_be_empty actual && - printf "$sss$sss$sss$sss" | git stripspace >actual && - test_must_be_empty actual + printf "$sss$sss$sss$sss" | git stripspace >actual && + test_must_be_empty actual ' -test_expect_success \ - 'consecutive text lines should be unchanged' ' - printf "$ttt$ttt\n$ttt\n" >expect && - printf "$ttt$ttt\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && +test_expect_success 'consecutive text lines should be unchanged' ' + printf "$ttt$ttt\n$ttt\n" >expect && + printf "$ttt$ttt\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n$ttt$ttt\n$ttt\n" >expect && - printf "$ttt\n$ttt$ttt\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n$ttt$ttt\n$ttt\n" >expect && + printf "$ttt\n$ttt$ttt\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" >expect && - printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" >expect && + printf "$ttt\n$ttt\n$ttt\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" >expect && - printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" >expect && + printf "$ttt\n$ttt\n\n$ttt$ttt\n$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" >expect && - printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" | git stripspace >actual && - test_cmp expect actual && + printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" >expect && + printf "$ttt$ttt\n\n$ttt\n$ttt$ttt\n" | git stripspace >actual && + test_cmp expect actual && - printf "$ttt\n$ttt$ttt\n\n$ttt\n" >expect && - printf "$ttt\n$ttt$ttt\n\n$ttt\n" | git stripspace >actual && - test_cmp expect actual + printf "$ttt\n$ttt$ttt\n\n$ttt\n" >expect && + printf "$ttt\n$ttt$ttt\n\n$ttt\n" | git stripspace >actual && + test_cmp expect actual ' test_expect_success 'strip comments, too' ' diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 7d7ecfd571..e19a199636 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -30,11 +30,12 @@ usage: test-tool parse-options <options> -F, --file <file> set file to <file> String options - -s, --string <string> - get a string + -s, --string <string> get a string --string2 <str> get another string --st <st> get another string (pervert ordering) -o <str> get another string + --longhelp help text of this entry + spans multiple lines --list <str> add str to list Magic arguments diff --git a/t/t0041-usage.sh b/t/t0041-usage.sh index c4fc34eb18..9ea974b0c6 100755 --- a/t/t0041-usage.sh +++ b/t/t0041-usage.sh @@ -5,6 +5,7 @@ test_description='Test commands behavior when given invalid argument value' 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/t0091-bugreport.sh b/t/t0091-bugreport.sh index b6d2f591ac..f6998269be 100755 --- a/t/t0091-bugreport.sh +++ b/t/t0091-bugreport.sh @@ -5,29 +5,50 @@ test_description='git bugreport' TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -# Headers "[System Info]" will be followed by a non-empty line if we put some -# information there; we can make sure all our headers were followed by some -# information to check if the command was successful. -HEADER_PATTERN="^\[.*\]$" - -check_all_headers_populated () { - while read -r line - do - if test "$(grep "$HEADER_PATTERN" "$line")" - then - echo "$line" - read -r nextline - if test -z "$nextline"; then - return 1; - fi - fi - done -} - -test_expect_success 'creates a report with content in the right places' ' - test_when_finished rm git-bugreport-check-headers.txt && - git bugreport -s check-headers && - check_all_headers_populated <git-bugreport-check-headers.txt +test_expect_success 'create a report' ' + git bugreport -s format && + test_file_not_empty git-bugreport-format.txt +' + +test_expect_success 'report contains wanted template (before first section)' ' + sed -ne "/^\[/q;p" git-bugreport-format.txt >actual && + cat >expect <<-\EOF && + Thank you for filling out a Git bug report! + Please answer the following questions to help us understand your issue. + + What did you do before the bug happened? (Steps to reproduce your issue) + + What did you expect to happen? (Expected behavior) + + What happened instead? (Actual behavior) + + What'\''s different between what you expected and what actually happened? + + Anything else you want to add: + + Please review the rest of the bug report below. + You can delete any lines you don'\''t wish to share. + + + EOF + test_cmp expect actual +' + +test_expect_success 'sanity check "System Info" section' ' + test_when_finished rm -f git-bugreport-format.txt && + + sed -ne "/^\[System Info\]$/,/^$/p" <git-bugreport-format.txt >system && + + # The beginning should match "git version --build-info" verbatim, + # but rather than checking bit-for-bit equality, just test some basics. + grep "git version [0-9]." system && + grep "shell-path: ." system && + + # After the version, there should be some more info. + # This is bound to differ from environment to environment, + # so we just do some rather high-level checks. + grep "uname: ." system && + grep "compiler info: ." system ' test_expect_success 'dies if file with same name as report already exists' ' diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh index b4e9135118..cfba686132 100755 --- a/t/t0211-trace2-perf.sh +++ b/t/t0211-trace2-perf.sh @@ -203,7 +203,7 @@ test_expect_success 'stopwatch timer test/test1' ' have_timer_event "main" "timer" "test" "test1" 5 actual ' -test_expect_success PTHREAD 'stopwatch timer test/test2' ' +test_expect_success PTHREADS 'stopwatch timer test/test2' ' test_when_finished "rm trace.perf actual" && test_config_global trace2.perfBrief 1 && test_config_global trace2.perfTarget "$(pwd)/trace.perf" && @@ -249,7 +249,7 @@ test_expect_success 'global counter test/test1' ' have_counter_event "main" "counter" "test" "test1" 15 actual ' -test_expect_success PTHREAD 'global counter test/test2' ' +test_expect_success PTHREADS 'global counter test/test2' ' test_when_finished "rm trace.perf actual" && test_config_global trace2.perfBrief 1 && test_config_global trace2.perfTarget "$(pwd)/trace.perf" && diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 3fb1b0c162..88c524f655 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -26,7 +26,7 @@ TEST_PASSES_SANITIZE_LEAK=true . "$TEST_DIRECTORY"/lib-read-tree.sh read_tree_twoway () { - git read-tree -m "$1" "$2" && git ls-files --stage + git read-tree -m "$1" "$2" && git ls-files --stage } compare_change () { diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index cdc077ce12..a7c2ed0d7c 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -37,315 +37,312 @@ check_cache_at () { esac } -test_expect_success \ - setup \ - 'echo frotz >frotz && - echo nitfol >nitfol && - echo bozbar >bozbar && - echo rezrov >rezrov && - git update-index --add nitfol bozbar rezrov && - treeH=$(git write-tree) && - echo treeH $treeH && - git ls-tree $treeH && - - echo gnusto >bozbar && - git update-index --add frotz bozbar --force-remove rezrov && - git ls-files --stage >M.out && - treeM=$(git write-tree) && - echo treeM $treeM && - git ls-tree $treeM && - cp bozbar bozbar.M && - cp frotz frotz.M && - cp nitfol nitfol.M && - git diff-tree $treeH $treeM' - -test_expect_success \ - '1, 2, 3 - no carry forward' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >1-3.out && - cmp M.out 1-3.out && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol && - check_cache_at bozbar clean && - check_cache_at frotz clean && - check_cache_at nitfol clean' - -test_expect_success \ - '4 - carry forward local addition.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo "+100644 X 0 yomin" >expected && - echo yomin >yomin && - git update-index --add yomin && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >4.out && - test_might_fail git diff -U0 --no-index M.out 4.out >4diff.out && - compare_change 4diff.out expected && - check_cache_at yomin clean && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol && - echo yomin >yomin1 && - diff yomin yomin1 && - rm -f yomin1' - -test_expect_success \ - '5 - carry forward local addition.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - read_tree_u_must_succeed -m -u $treeH && - echo yomin >yomin && - git update-index --add yomin && - echo yomin yomin >yomin && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >5.out && - test_might_fail git diff -U0 --no-index M.out 5.out >5diff.out && - compare_change 5diff.out expected && - check_cache_at yomin dirty && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol && - : dirty index should have prevented -u from checking it out. && - echo yomin yomin >yomin1 && - diff yomin yomin1 && - rm -f yomin1' - -test_expect_success \ - '6 - local addition already has the same.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo frotz >frotz && - git update-index --add frotz && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >6.out && - test_cmp M.out 6.out && - check_cache_at frotz clean && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol && - echo frotz >frotz1 && - diff frotz frotz1 && - rm -f frotz1' - -test_expect_success \ - '7 - local addition already has the same.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo frotz >frotz && - git update-index --add frotz && - echo frotz frotz >frotz && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >7.out && - test_cmp M.out 7.out && - check_cache_at frotz dirty && - test_cmp bozbar.M bozbar && - test_cmp nitfol.M nitfol && - : dirty index should have prevented -u from checking it out. && - echo frotz frotz >frotz1 && - diff frotz frotz1 && - rm -f frotz1' - -test_expect_success \ - '8 - conflicting addition.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo frotz frotz >frotz && - git update-index --add frotz && - ! read_tree_u_must_succeed -m -u $treeH $treeM' - -test_expect_success \ - '9 - conflicting addition.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo frotz frotz >frotz && - git update-index --add frotz && - echo frotz >frotz && - ! read_tree_u_must_succeed -m -u $treeH $treeM' - -test_expect_success \ - '10 - path removed.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo rezrov >rezrov && - git update-index --add rezrov && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >10.out && - cmp M.out 10.out && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol +test_expect_success setup ' + echo frotz >frotz && + echo nitfol >nitfol && + echo bozbar >bozbar && + echo rezrov >rezrov && + git update-index --add nitfol bozbar rezrov && + treeH=$(git write-tree) && + echo treeH $treeH && + git ls-tree $treeH && + + echo gnusto >bozbar && + git update-index --add frotz bozbar --force-remove rezrov && + git ls-files --stage >M.out && + treeM=$(git write-tree) && + echo treeM $treeM && + git ls-tree $treeM && + cp bozbar bozbar.M && + cp frotz frotz.M && + cp nitfol nitfol.M && + git diff-tree $treeH $treeM ' -test_expect_success \ - '11 - dirty path removed.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo rezrov >rezrov && - git update-index --add rezrov && - echo rezrov rezrov >rezrov && - ! read_tree_u_must_succeed -m -u $treeH $treeM' - -test_expect_success \ - '12 - unmatching local changes being removed.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo rezrov rezrov >rezrov && - git update-index --add rezrov && - ! read_tree_u_must_succeed -m -u $treeH $treeM' - -test_expect_success \ - '13 - unmatching local changes being removed.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo rezrov rezrov >rezrov && - git update-index --add rezrov && - echo rezrov >rezrov && - ! read_tree_u_must_succeed -m -u $treeH $treeM' +test_expect_success '1, 2, 3 - no carry forward' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >1-3.out && + cmp M.out 1-3.out && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol && + check_cache_at bozbar clean && + check_cache_at frotz clean && + check_cache_at nitfol clean +' + +test_expect_success '4 - carry forward local addition.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo "+100644 X 0 yomin" >expected && + echo yomin >yomin && + git update-index --add yomin && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >4.out && + test_might_fail git diff -U0 --no-index M.out 4.out >4diff.out && + compare_change 4diff.out expected && + check_cache_at yomin clean && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol && + echo yomin >yomin1 && + diff yomin yomin1 && + rm -f yomin1 +' + +test_expect_success '5 - carry forward local addition.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + read_tree_u_must_succeed -m -u $treeH && + echo yomin >yomin && + git update-index --add yomin && + echo yomin yomin >yomin && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >5.out && + test_might_fail git diff -U0 --no-index M.out 5.out >5diff.out && + compare_change 5diff.out expected && + check_cache_at yomin dirty && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol && + : dirty index should have prevented -u from checking it out. && + echo yomin yomin >yomin1 && + diff yomin yomin1 && + rm -f yomin1 +' + +test_expect_success '6 - local addition already has the same.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo frotz >frotz && + git update-index --add frotz && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >6.out && + test_cmp M.out 6.out && + check_cache_at frotz clean && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol && + echo frotz >frotz1 && + diff frotz frotz1 && + rm -f frotz1 +' + +test_expect_success '7 - local addition already has the same.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo frotz >frotz && + git update-index --add frotz && + echo frotz frotz >frotz && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >7.out && + test_cmp M.out 7.out && + check_cache_at frotz dirty && + test_cmp bozbar.M bozbar && + test_cmp nitfol.M nitfol && + : dirty index should have prevented -u from checking it out. && + echo frotz frotz >frotz1 && + diff frotz frotz1 && + rm -f frotz1 +' + +test_expect_success '8 - conflicting addition.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo frotz frotz >frotz && + git update-index --add frotz && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' + +test_expect_success '9 - conflicting addition.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo frotz frotz >frotz && + git update-index --add frotz && + echo frotz >frotz && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' + +test_expect_success '10 - path removed.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo rezrov >rezrov && + git update-index --add rezrov && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >10.out && + cmp M.out 10.out && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol +' + +test_expect_success '11 - dirty path removed.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo rezrov >rezrov && + git update-index --add rezrov && + echo rezrov rezrov >rezrov && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' + +test_expect_success '12 - unmatching local changes being removed.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo rezrov rezrov >rezrov && + git update-index --add rezrov && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' + +test_expect_success '13 - unmatching local changes being removed.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo rezrov rezrov >rezrov && + git update-index --add rezrov && + echo rezrov >rezrov && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' cat >expected <<EOF -100644 X 0 nitfol +100644 X 0 nitfol EOF -test_expect_success \ - '14 - unchanged in two heads.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo nitfol nitfol >nitfol && - git update-index --add nitfol && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >14.out && - test_must_fail git diff -U0 --no-index M.out 14.out >14diff.out && - compare_change 14diff.out expected && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - check_cache_at nitfol clean && - echo nitfol nitfol >nitfol1 && - diff nitfol nitfol1 && - rm -f nitfol1' - -test_expect_success \ - '15 - unchanged in two heads.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo nitfol nitfol >nitfol && - git update-index --add nitfol && - echo nitfol nitfol nitfol >nitfol && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >15.out && - test_must_fail git diff -U0 --no-index M.out 15.out >15diff.out && - compare_change 15diff.out expected && - check_cache_at nitfol dirty && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - echo nitfol nitfol nitfol >nitfol1 && - diff nitfol nitfol1 && - rm -f nitfol1' - -test_expect_success \ - '16 - conflicting local change.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo bozbar bozbar >bozbar && - git update-index --add bozbar && - ! read_tree_u_must_succeed -m -u $treeH $treeM' - -test_expect_success \ - '17 - conflicting local change.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo bozbar bozbar >bozbar && - git update-index --add bozbar && - echo bozbar bozbar bozbar >bozbar && - ! read_tree_u_must_succeed -m -u $treeH $treeM' - -test_expect_success \ - '18 - local change already having a good result.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo gnusto >bozbar && - git update-index --add bozbar && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >18.out && - test_cmp M.out 18.out && - check_cache_at bozbar clean && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol +test_expect_success '14 - unchanged in two heads.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo nitfol nitfol >nitfol && + git update-index --add nitfol && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >14.out && + test_must_fail git diff -U0 --no-index M.out 14.out >14diff.out && + compare_change 14diff.out expected && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + check_cache_at nitfol clean && + echo nitfol nitfol >nitfol1 && + diff nitfol nitfol1 && + rm -f nitfol1 ' -test_expect_success \ - '19 - local change already having a good result, further modified.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo gnusto >bozbar && - git update-index --add bozbar && - echo gnusto gnusto >bozbar && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >19.out && - test_cmp M.out 19.out && - check_cache_at bozbar dirty && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol && - echo gnusto gnusto >bozbar1 && - diff bozbar bozbar1 && - rm -f bozbar1' - -test_expect_success \ - '20 - no local change, use new tree.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo bozbar >bozbar && - git update-index --add bozbar && - read_tree_u_must_succeed -m -u $treeH $treeM && - git ls-files --stage >20.out && - test_cmp M.out 20.out && - check_cache_at bozbar clean && - test_cmp bozbar.M bozbar && - test_cmp frotz.M frotz && - test_cmp nitfol.M nitfol +test_expect_success '15 - unchanged in two heads.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo nitfol nitfol >nitfol && + git update-index --add nitfol && + echo nitfol nitfol nitfol >nitfol && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >15.out && + test_must_fail git diff -U0 --no-index M.out 15.out >15diff.out && + compare_change 15diff.out expected && + check_cache_at nitfol dirty && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + echo nitfol nitfol nitfol >nitfol1 && + diff nitfol nitfol1 && + rm -f nitfol1 ' -test_expect_success \ - '21 - no local change, dirty cache.' \ - 'rm -f .git/index nitfol bozbar rezrov frotz && - read_tree_u_must_succeed --reset -u $treeH && - echo bozbar >bozbar && - git update-index --add bozbar && - echo gnusto gnusto >bozbar && - ! read_tree_u_must_succeed -m -u $treeH $treeM' +test_expect_success '16 - conflicting local change.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo bozbar bozbar >bozbar && + git update-index --add bozbar && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' + +test_expect_success '17 - conflicting local change.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo bozbar bozbar >bozbar && + git update-index --add bozbar && + echo bozbar bozbar bozbar >bozbar && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' + +test_expect_success '18 - local change already having a good result.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo gnusto >bozbar && + git update-index --add bozbar && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >18.out && + test_cmp M.out 18.out && + check_cache_at bozbar clean && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol +' + +test_expect_success '19 - local change already having a good result, further modified.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo gnusto >bozbar && + git update-index --add bozbar && + echo gnusto gnusto >bozbar && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >19.out && + test_cmp M.out 19.out && + check_cache_at bozbar dirty && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol && + echo gnusto gnusto >bozbar1 && + diff bozbar bozbar1 && + rm -f bozbar1 +' + +test_expect_success '20 - no local change, use new tree.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo bozbar >bozbar && + git update-index --add bozbar && + read_tree_u_must_succeed -m -u $treeH $treeM && + git ls-files --stage >20.out && + test_cmp M.out 20.out && + check_cache_at bozbar clean && + test_cmp bozbar.M bozbar && + test_cmp frotz.M frotz && + test_cmp nitfol.M nitfol +' + +test_expect_success '21 - no local change, dirty cache.' ' + rm -f .git/index nitfol bozbar rezrov frotz && + read_tree_u_must_succeed --reset -u $treeH && + echo bozbar >bozbar && + git update-index --add bozbar && + echo gnusto gnusto >bozbar && + ! read_tree_u_must_succeed -m -u $treeH $treeM +' # Also make sure we did not break DF vs DF/DF case. -test_expect_success \ - 'DF vs DF/DF case setup.' \ - 'rm -f .git/index && - echo DF >DF && - git update-index --add DF && - treeDF=$(git write-tree) && - echo treeDF $treeDF && - git ls-tree $treeDF && - - rm -f DF && - mkdir DF && - echo DF/DF >DF/DF && - git update-index --add --remove DF DF/DF && - treeDFDF=$(git write-tree) && - echo treeDFDF $treeDFDF && - git ls-tree $treeDFDF && - git ls-files --stage >DFDF.out' - -test_expect_success \ - 'DF vs DF/DF case test.' \ - 'rm -f .git/index && - rm -fr DF && - echo DF >DF && - git update-index --add DF && - read_tree_u_must_succeed -m -u $treeDF $treeDFDF && - git ls-files --stage >DFDFcheck.out && - test_cmp DFDF.out DFDFcheck.out && - check_cache_at DF/DF clean' +test_expect_success 'DF vs DF/DF case setup.' ' + rm -f .git/index && + echo DF >DF && + git update-index --add DF && + treeDF=$(git write-tree) && + echo treeDF $treeDF && + git ls-tree $treeDF && + + rm -f DF && + mkdir DF && + echo DF/DF >DF/DF && + git update-index --add --remove DF DF/DF && + treeDFDF=$(git write-tree) && + echo treeDFDF $treeDFDF && + git ls-tree $treeDFDF && + git ls-files --stage >DFDF.out +' + +test_expect_success 'DF vs DF/DF case test.' ' + rm -f .git/index && + rm -fr DF && + echo DF >DF && + git update-index --add DF && + read_tree_u_must_succeed -m -u $treeDF $treeDFDF && + git ls-files --stage >DFDFcheck.out && + test_cmp DFDF.out DFDFcheck.out && + check_cache_at DF/DF clean +' test_done diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index 8eac74b59c..d73a0be1b9 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -89,7 +89,8 @@ done for opt in --buffer \ --follow-symlinks \ --batch-all-objects \ - -z + -z \ + -Z do test_expect_success "usage: bad option combination: $opt without batch mode" ' test_incompatible_usage git cat-file $opt && @@ -109,26 +110,12 @@ strlen () { echo_without_newline "$1" | wc -c | sed -e 's/^ *//' } -maybe_remove_timestamp () { - if test -z "$2"; then - echo_without_newline "$1" - else - echo_without_newline "$(printf '%s\n' "$1" | remove_timestamp)" - fi -} - -remove_timestamp () { - sed -e 's/ [0-9][0-9]* [-+][0-9][0-9][0-9][0-9]$//' -} - - run_tests () { type=$1 sha1=$2 size=$3 content=$4 pretty_content=$5 - no_ts=$6 batch_output="$sha1 $type $size $content" @@ -163,21 +150,21 @@ $content" test -z "$content" || test_expect_success "Content of $type is correct" ' - maybe_remove_timestamp "$content" $no_ts >expect && - maybe_remove_timestamp "$(git cat-file $type $sha1)" $no_ts >actual && + echo_without_newline "$content" >expect && + git cat-file $type $sha1 >actual && test_cmp expect actual ' test_expect_success "Pretty content of $type is correct" ' - maybe_remove_timestamp "$pretty_content" $no_ts >expect && - maybe_remove_timestamp "$(git cat-file -p $sha1)" $no_ts >actual && + echo_without_newline "$pretty_content" >expect && + git cat-file -p $sha1 >actual && test_cmp expect actual ' test -z "$content" || test_expect_success "--batch output of $type is correct" ' - maybe_remove_timestamp "$batch_output" $no_ts >expect && - maybe_remove_timestamp "$(echo $sha1 | git cat-file --batch)" $no_ts >actual && + echo "$batch_output" >expect && + echo $sha1 | git cat-file --batch >actual && test_cmp expect actual ' @@ -191,9 +178,8 @@ $content" do test -z "$content" || test_expect_success "--batch-command $opt output of $type content is correct" ' - maybe_remove_timestamp "$batch_output" $no_ts >expect && - maybe_remove_timestamp "$(test_write_lines "contents $sha1" | - git cat-file --batch-command $opt)" $no_ts >actual && + echo "$batch_output" >expect && + test_write_lines "contents $sha1" | git cat-file --batch-command $opt >actual && test_cmp expect actual ' @@ -228,10 +214,9 @@ $content" test_expect_success "--batch without type ($type)" ' { echo "$size" && - maybe_remove_timestamp "$content" $no_ts + echo "$content" } >expect && - echo $sha1 | git cat-file --batch="%(objectsize)" >actual.full && - maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual && + echo $sha1 | git cat-file --batch="%(objectsize)" >actual && test_cmp expect actual ' @@ -239,10 +224,9 @@ $content" test_expect_success "--batch without size ($type)" ' { echo "$type" && - maybe_remove_timestamp "$content" $no_ts + echo "$content" } >expect && - echo $sha1 | git cat-file --batch="%(objecttype)" >actual.full && - maybe_remove_timestamp "$(cat actual.full)" $no_ts >actual && + echo $sha1 | git cat-file --batch="%(objecttype)" >actual && test_cmp expect actual ' } @@ -284,7 +268,7 @@ test_expect_success '--batch-check without %(rest) considers whole line' ' tree_sha1=$(git write-tree) tree_size=$(($(test_oid rawsz) + 13)) -tree_pretty_content="100644 blob $hello_sha1 hello" +tree_pretty_content="100644 blob $hello_sha1 hello${LF}" run_tests 'tree' $tree_sha1 $tree_size "" "$tree_pretty_content" @@ -292,12 +276,12 @@ commit_message="Initial commit" commit_sha1=$(echo_without_newline "$commit_message" | git commit-tree $tree_sha1) commit_size=$(($(test_oid hexsz) + 137)) commit_content="tree $tree_sha1 -author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> 0 +0000 -committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 0 +0000 +author $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL> $GIT_AUTHOR_DATE +committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE $commit_message" -run_tests 'commit' $commit_sha1 $commit_size "$commit_content" "$commit_content" 1 +run_tests 'commit' $commit_sha1 $commit_size "$commit_content" "$commit_content" tag_header_without_timestamp="object $hello_sha1 type blob @@ -311,11 +295,13 @@ $tag_description" tag_sha1=$(echo_without_newline "$tag_content" | git hash-object -t tag --stdin -w) tag_size=$(strlen "$tag_content") -run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" 1 +run_tests 'tag' $tag_sha1 $tag_size "$tag_content" "$tag_content" -test_expect_success \ - "Reach a blob from a tag pointing to it" \ - "test '$hello_content' = \"\$(git cat-file blob $tag_sha1)\"" +test_expect_success "Reach a blob from a tag pointing to it" ' + echo_without_newline "$hello_content" >expect && + git cat-file blob $tag_sha1 >actual && + test_cmp expect actual +' for batch in batch batch-check batch-command do @@ -351,30 +337,47 @@ do done test_expect_success "--batch-check for a non-existent named object" ' - test "foobar42 missing -foobar84 missing" = \ - "$( ( echo foobar42 && echo_without_newline foobar84 ) | git cat-file --batch-check)" + cat >expect <<-EOF && + foobar42 missing + foobar84 missing + EOF + + printf "foobar42\nfoobar84" >in && + git cat-file --batch-check <in >actual && + test_cmp expect actual ' test_expect_success "--batch-check for a non-existent hash" ' - test "0000000000000000000000000000000000000042 missing -0000000000000000000000000000000000000084 missing" = \ - "$( ( echo 0000000000000000000000000000000000000042 && - echo_without_newline 0000000000000000000000000000000000000084 ) | - git cat-file --batch-check)" + cat >expect <<-EOF && + 0000000000000000000000000000000000000042 missing + 0000000000000000000000000000000000000084 missing + EOF + + printf "0000000000000000000000000000000000000042\n0000000000000000000000000000000000000084" >in && + git cat-file --batch-check <in >actual && + test_cmp expect actual ' test_expect_success "--batch for an existent and a non-existent hash" ' - test "$tag_sha1 tag $tag_size -$tag_content -0000000000000000000000000000000000000000 missing" = \ - "$( ( echo $tag_sha1 && - echo_without_newline 0000000000000000000000000000000000000000 ) | - git cat-file --batch)" + cat >expect <<-EOF && + $tag_sha1 tag $tag_size + $tag_content + 0000000000000000000000000000000000000000 missing + EOF + + printf "$tag_sha1\n0000000000000000000000000000000000000000" >in && + git cat-file --batch <in >actual && + test_cmp expect actual ' test_expect_success "--batch-check for an empty line" ' - test " missing" = "$(echo | git cat-file --batch-check)" + cat >expect <<-EOF && + missing + EOF + + echo >in && + git cat-file --batch-check <in >actual && + test_cmp expect actual ' test_expect_success 'empty --batch-check notices missing object' ' @@ -390,23 +393,34 @@ deadbeef " -batch_output="$hello_sha1 blob $hello_size -$hello_content -$commit_sha1 commit $commit_size -$commit_content -$tag_sha1 tag $tag_size -$tag_content -deadbeef missing - missing" +printf "%s\0" \ + "$hello_sha1 blob $hello_size" \ + "$hello_content" \ + "$commit_sha1 commit $commit_size" \ + "$commit_content" \ + "$tag_sha1 tag $tag_size" \ + "$tag_content" \ + "deadbeef missing" \ + " missing" >batch_output test_expect_success '--batch with multiple sha1s gives correct format' ' - test "$(maybe_remove_timestamp "$batch_output" 1)" = "$(maybe_remove_timestamp "$(echo_without_newline "$batch_input" | git cat-file --batch)" 1)" + tr "\0" "\n" <batch_output >expect && + echo_without_newline "$batch_input" >in && + git cat-file --batch <in >actual && + test_cmp expect actual ' test_expect_success '--batch, -z with multiple sha1s gives correct format' ' echo_without_newline_nul "$batch_input" >in && - test "$(maybe_remove_timestamp "$batch_output" 1)" = \ - "$(maybe_remove_timestamp "$(git cat-file --batch -z <in)" 1)" + tr "\0" "\n" <batch_output >expect && + git cat-file --batch -z <in >actual && + test_cmp expect actual +' + +test_expect_success '--batch, -Z with multiple sha1s gives correct format' ' + echo_without_newline_nul "$batch_input" >in && + git cat-file --batch -Z <in >actual && + test_cmp batch_output actual ' batch_check_input="$hello_sha1 @@ -417,36 +431,55 @@ deadbeef " -batch_check_output="$hello_sha1 blob $hello_size -$tree_sha1 tree $tree_size -$commit_sha1 commit $commit_size -$tag_sha1 tag $tag_size -deadbeef missing - missing" +printf "%s\0" \ + "$hello_sha1 blob $hello_size" \ + "$tree_sha1 tree $tree_size" \ + "$commit_sha1 commit $commit_size" \ + "$tag_sha1 tag $tag_size" \ + "deadbeef missing" \ + " missing" >batch_check_output test_expect_success "--batch-check with multiple sha1s gives correct format" ' - test "$batch_check_output" = \ - "$(echo_without_newline "$batch_check_input" | git cat-file --batch-check)" + tr "\0" "\n" <batch_check_output >expect && + echo_without_newline "$batch_check_input" >in && + git cat-file --batch-check <in >actual && + test_cmp expect actual ' test_expect_success "--batch-check, -z with multiple sha1s gives correct format" ' - echo_without_newline_nul "$batch_check_input" >in && - test "$batch_check_output" = "$(git cat-file --batch-check -z <in)" + tr "\0" "\n" <batch_check_output >expect && + echo_without_newline_nul "$batch_check_input" >in && + git cat-file --batch-check -z <in >actual && + test_cmp expect actual ' -test_expect_success FUNNYNAMES '--batch-check, -z with newline in input' ' +test_expect_success "--batch-check, -Z with multiple sha1s gives correct format" ' + echo_without_newline_nul "$batch_check_input" >in && + git cat-file --batch-check -Z <in >actual && + test_cmp batch_check_output actual +' + +test_expect_success FUNNYNAMES 'setup with newline in input' ' touch -- "newline${LF}embedded" && git add -- "newline${LF}embedded" && git commit -m "file with newline embedded" && test_tick && - printf "HEAD:newline${LF}embedded" >in && - git cat-file --batch-check -z <in >actual && + printf "HEAD:newline${LF}embedded" >in +' +test_expect_success FUNNYNAMES '--batch-check, -z with newline in input' ' + git cat-file --batch-check -z <in >actual && echo "$(git rev-parse "HEAD:newline${LF}embedded") blob 0" >expect && test_cmp expect actual ' +test_expect_success FUNNYNAMES '--batch-check, -Z with newline in input' ' + git cat-file --batch-check -Z <in >actual && + printf "%s\0" "$(git rev-parse "HEAD:newline${LF}embedded") blob 0" >expect && + test_cmp expect actual +' + batch_command_multiple_info="info $hello_sha1 info $tree_sha1 info $commit_sha1 @@ -470,7 +503,13 @@ test_expect_success '--batch-command with multiple info calls gives correct form echo "$batch_command_multiple_info" | tr "\n" "\0" >in && git cat-file --batch-command --buffer -z <in >actual && - test_cmp expect actual + test_cmp expect actual && + + echo "$batch_command_multiple_info" | tr "\n" "\0" >in && + tr "\n" "\0" <expect >expect_nul && + git cat-file --batch-command --buffer -Z <in >actual && + + test_cmp expect_nul actual ' batch_command_multiple_contents="contents $hello_sha1 @@ -480,27 +519,30 @@ contents deadbeef flush" test_expect_success '--batch-command with multiple command calls gives correct format' ' - remove_timestamp >expect <<-EOF && - $hello_sha1 blob $hello_size - $hello_content - $commit_sha1 commit $commit_size - $commit_content - $tag_sha1 tag $tag_size - $tag_content - deadbeef missing - EOF + printf "%s\0" \ + "$hello_sha1 blob $hello_size" \ + "$hello_content" \ + "$commit_sha1 commit $commit_size" \ + "$commit_content" \ + "$tag_sha1 tag $tag_size" \ + "$tag_content" \ + "deadbeef missing" >expect_nul && + tr "\0" "\n" <expect_nul >expect && echo "$batch_command_multiple_contents" >in && - git cat-file --batch-command --buffer <in >actual_raw && + git cat-file --batch-command --buffer <in >actual && - remove_timestamp <actual_raw >actual && test_cmp expect actual && echo "$batch_command_multiple_contents" | tr "\n" "\0" >in && - git cat-file --batch-command --buffer -z <in >actual_raw && + git cat-file --batch-command --buffer -z <in >actual && - remove_timestamp <actual_raw >actual && - test_cmp expect actual + test_cmp expect actual && + + echo "$batch_command_multiple_contents" | tr "\n" "\0" >in && + git cat-file --batch-command --buffer -Z <in >actual && + + test_cmp expect_nul actual ' test_expect_success 'setup blobs which are likely to delta' ' @@ -840,6 +882,13 @@ test_expect_success 'git cat-file --batch-check --follow-symlinks works for brok test_cmp expect actual ' +test_expect_success 'git cat-file --batch-check --follow-symlinks -Z works for broken in-repo, same-dir links' ' + printf "HEAD:broken-same-dir-link\0" >in && + printf "dangling 25\0HEAD:broken-same-dir-link\0" >expect && + git cat-file --batch-check --follow-symlinks -Z <in >actual && + test_cmp expect actual +' + test_expect_success 'git cat-file --batch-check --follow-symlinks works for same-dir links-to-links' ' echo HEAD:link-to-link | git cat-file --batch-check --follow-symlinks >actual && test_cmp found actual @@ -854,6 +903,15 @@ test_expect_success 'git cat-file --batch-check --follow-symlinks works for pare test_cmp expect actual ' +test_expect_success 'git cat-file --batch-check --follow-symlinks -Z works for parent-dir links' ' + echo HEAD:dir/parent-dir-link | git cat-file --batch-check --follow-symlinks >actual && + test_cmp found actual && + printf "notdir 29\0HEAD:dir/parent-dir-link/nope\0" >expect && + printf "HEAD:dir/parent-dir-link/nope\0" >in && + git cat-file --batch-check --follow-symlinks -Z <in >actual && + test_cmp expect actual +' + test_expect_success 'git cat-file --batch-check --follow-symlinks works for .. links' ' echo dangling 22 >expect && echo HEAD:dir/link-dir/nope >>expect && @@ -968,6 +1026,13 @@ test_expect_success 'git cat-file --batch-check --follow-symlink breaks loops' ' test_cmp expect actual ' +test_expect_success 'git cat-file --batch-check --follow-symlink -Z breaks loops' ' + printf "loop 10\0HEAD:loop1\0" >expect && + printf "HEAD:loop1\0" >in && + git cat-file --batch-check --follow-symlinks -Z <in >actual && + test_cmp expect actual +' + test_expect_success 'git cat-file --batch --follow-symlink returns correct sha and mode' ' echo HEAD:morx | git cat-file --batch >expect && echo HEAD:morx | git cat-file --batch --follow-symlinks >actual && diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index a63d0cc222..8a95adf4b5 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -2180,4 +2180,83 @@ test_expect_success 'sparse index is not expanded: diff-files' ' ensure_not_expanded diff-files -- "deep/*" ' +test_expect_success 'diff-tree' ' + init_repos && + + # Test change inside sparse cone + tree1=$(git -C sparse-index rev-parse HEAD^{tree}) && + tree2=$(git -C sparse-index rev-parse update-deep^{tree}) && + test_all_match git diff-tree $tree1 $tree2 && + test_all_match git diff-tree $tree1 $tree2 -- deep/a && + test_all_match git diff-tree HEAD update-deep && + test_all_match git diff-tree HEAD update-deep -- deep/a && + + # Test change outside sparse cone + tree3=$(git -C sparse-index rev-parse update-folder1^{tree}) && + test_all_match git diff-tree $tree1 $tree3 && + test_all_match git diff-tree $tree1 $tree3 -- folder1/a && + test_all_match git diff-tree HEAD update-folder1 && + test_all_match git diff-tree HEAD update-folder1 -- folder1/a && + + # Check that SKIP_WORKTREE files are not materialized + test_path_is_missing sparse-checkout/folder1/a && + test_path_is_missing sparse-index/folder1/a && + test_path_is_missing sparse-checkout/folder2/a && + test_path_is_missing sparse-index/folder2/a +' + +test_expect_success 'sparse-index is not expanded: diff-tree' ' + init_repos && + + tree1=$(git -C sparse-index rev-parse HEAD^{tree}) && + tree2=$(git -C sparse-index rev-parse update-deep^{tree}) && + tree3=$(git -C sparse-index rev-parse update-folder1^{tree}) && + + ensure_not_expanded diff-tree $tree1 $tree2 && + ensure_not_expanded diff-tree $tree1 $tree2 -- deep/a && + ensure_not_expanded diff-tree HEAD update-deep && + ensure_not_expanded diff-tree HEAD update-deep -- deep/a && + ensure_not_expanded diff-tree $tree1 $tree3 && + ensure_not_expanded diff-tree $tree1 $tree3 -- folder1/a && + ensure_not_expanded diff-tree HEAD update-folder1 && + ensure_not_expanded diff-tree HEAD update-folder1 -- folder1/a +' + +test_expect_success 'worktree' ' + init_repos && + + write_script edit-contents <<-\EOF && + echo text >>"$1" + EOF + + for repo in full-checkout sparse-checkout sparse-index + do + worktree=${repo}-wt && + git -C $repo worktree add ../$worktree && + + # Compare worktree content with "ls" + (cd $repo && ls) >worktree_contents && + (cd $worktree && ls) >new_worktree_contents && + test_cmp worktree_contents new_worktree_contents && + + # Compare index content with "ls-files --sparse" + git -C $repo ls-files --sparse >index_contents && + git -C $worktree ls-files --sparse >new_index_contents && + test_cmp index_contents new_index_contents && + + git -C $repo worktree remove ../$worktree || return 1 + done && + + test_all_match git worktree add .worktrees/hotfix && + run_on_all ../edit-contents .worktrees/hotfix/deep/a && + test_all_match test_must_fail git worktree remove .worktrees/hotfix +' + +test_expect_success 'worktree is not expanded' ' + init_repos && + + ensure_not_expanded worktree add .worktrees/hotfix && + ensure_not_expanded worktree remove .worktrees/hotfix +' + test_done diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 86bfbc2b36..387d336c91 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1668,6 +1668,21 @@ test_expect_success 'urlmatch' ' test_cmp expect actual ' +test_expect_success 'urlmatch with --show-scope' ' + cat >.git/config <<-\EOF && + [http "https://weak.example.com"] + sslVerify = false + cookieFile = /tmp/cookie.txt + EOF + + cat >expect <<-EOF && + local http.cookiefile /tmp/cookie.txt + local http.sslverify false + EOF + git config --get-urlmatch --show-scope HTTP https://weak.example.com >actual && + test_cmp expect actual +' + test_expect_success 'urlmatch favors more specific URLs' ' cat >.git/config <<-\EOF && [http "https://example.com/"] @@ -2055,6 +2070,12 @@ test_expect_success '--show-origin blob ref' ' test_cmp expect output ' +test_expect_success '--show-origin with --default' ' + git config --show-origin --default foo some.key >actual && + echo "command line: foo" >expect && + test_cmp expect actual +' + test_expect_success '--show-scope with --list' ' cat >expect <<-EOF && global user.global=true @@ -2123,6 +2144,12 @@ test_expect_success '--show-scope with --show-origin' ' test_cmp expect output ' +test_expect_success '--show-scope with --default' ' + git config --show-scope --default foo some.key >actual && + echo "command foo" >expect && + test_cmp expect actual +' + test_expect_success 'override global and system config' ' test_when_finished rm -f \"\$HOME\"/.gitconfig && cat >"$HOME"/.gitconfig <<-EOF && diff --git a/t/t1301-shared-repo.sh b/t/t1301-shared-repo.sh index ae5cd3f5a0..e5a0d65caa 100755 --- a/t/t1301-shared-repo.sh +++ b/t/t1301-shared-repo.sh @@ -52,6 +52,28 @@ test_expect_success 'shared=all' ' test 2 = $(git config core.sharedrepository) ' +test_expect_failure 'template can set core.bare' ' + test_when_finished "rm -rf subdir" && + test_when_finished "rm -rf templates" && + test_config core.bare true && + umask 0022 && + mkdir -p templates/ && + cp .git/config templates/config && + git init --template=templates subdir && + test_path_exists subdir/HEAD +' + +test_expect_success 'template can set core.bare but overridden by command line' ' + test_when_finished "rm -rf subdir" && + test_when_finished "rm -rf templates" && + test_config core.bare true && + umask 0022 && + mkdir -p templates/ && + cp .git/config templates/config && + git init --no-bare --template=templates subdir && + test_path_exists subdir/.git/HEAD +' + test_expect_success POSIXPERM 'update-server-info honors core.sharedRepository' ' : > a1 && git add a1 && diff --git a/t/t1419-exclude-refs.sh b/t/t1419-exclude-refs.sh new file mode 100755 index 0000000000..5d8c86b657 --- /dev/null +++ b/t/t1419-exclude-refs.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +test_description='test exclude_patterns functionality in main ref store' + +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +for_each_ref__exclude () { + GIT_TRACE2_PERF=1 test-tool ref-store main \ + for-each-ref--exclude "$@" >actual.raw + cut -d ' ' -f 2 actual.raw +} + +for_each_ref () { + git for-each-ref --format='%(refname)' "$@" +} + +assert_jumps () { + local nr="$1" + local trace="$2" + + grep -q "name:jumps_made value:$nr$" $trace +} + +assert_no_jumps () { + ! assert_jumps ".*" "$1" +} + +test_expect_success 'setup' ' + test_commit --no-tag base && + base="$(git rev-parse HEAD)" && + + for name in foo bar baz quux + do + for i in 1 2 3 + do + echo "create refs/heads/$name/$i $base" || return 1 + done || return 1 + done >in && + echo "delete refs/heads/main" >>in && + + git update-ref --stdin <in && + git pack-refs --all +' + +test_expect_success 'excluded region in middle' ' + for_each_ref__exclude refs/heads refs/heads/foo >actual 2>perf && + for_each_ref refs/heads/bar refs/heads/baz refs/heads/quux >expect && + + test_cmp expect actual && + assert_jumps 1 perf +' + +test_expect_success 'excluded region at beginning' ' + for_each_ref__exclude refs/heads refs/heads/bar >actual 2>perf && + for_each_ref refs/heads/baz refs/heads/foo refs/heads/quux >expect && + + test_cmp expect actual && + assert_jumps 1 perf +' + +test_expect_success 'excluded region at end' ' + for_each_ref__exclude refs/heads refs/heads/quux >actual 2>perf && + for_each_ref refs/heads/foo refs/heads/bar refs/heads/baz >expect && + + test_cmp expect actual && + assert_jumps 1 perf +' + +test_expect_success 'disjoint excluded regions' ' + for_each_ref__exclude refs/heads refs/heads/bar refs/heads/quux >actual 2>perf && + for_each_ref refs/heads/baz refs/heads/foo >expect && + + test_cmp expect actual && + assert_jumps 2 perf +' + +test_expect_success 'adjacent, non-overlapping excluded regions' ' + for_each_ref__exclude refs/heads refs/heads/bar refs/heads/baz >actual 2>perf && + for_each_ref refs/heads/foo refs/heads/quux >expect && + + test_cmp expect actual && + assert_jumps 1 perf +' + +test_expect_success 'overlapping excluded regions' ' + for_each_ref__exclude refs/heads refs/heads/ba refs/heads/baz >actual 2>perf && + for_each_ref refs/heads/foo refs/heads/quux >expect && + + test_cmp expect actual && + assert_jumps 1 perf +' + +test_expect_success 'several overlapping excluded regions' ' + for_each_ref__exclude refs/heads \ + refs/heads/bar refs/heads/baz refs/heads/foo >actual 2>perf && + for_each_ref refs/heads/quux >expect && + + test_cmp expect actual && + assert_jumps 1 perf +' + +test_expect_success 'non-matching excluded section' ' + for_each_ref__exclude refs/heads refs/heads/does/not/exist >actual 2>perf && + for_each_ref >expect && + + test_cmp expect actual && + assert_no_jumps perf +' + +test_expect_success 'meta-characters are discarded' ' + for_each_ref__exclude refs/heads "refs/heads/ba*" >actual 2>perf && + for_each_ref >expect && + + test_cmp expect actual && + assert_no_jumps perf +' + +test_done diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 21d65b207b..7bbf2f7831 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -1036,9 +1036,9 @@ test_expect_success 'fsck detects problems in worktree index' ' test_cmp expect actual ' -test_expect_success 'fsck reports problems in main index without filename' ' +test_expect_success 'fsck reports problems in current worktree index without filename' ' test_when_finished "rm -f .git/index && git read-tree HEAD" && - echo "this object will be removed to break the main index" >file && + echo "this object will be removed to break current worktree index" >file && git add file && blob=$(git rev-parse :file) && remove_object $blob && diff --git a/t/t1507-rev-parse-upstream.sh b/t/t1507-rev-parse-upstream.sh index cb9ef7e329..b9af6b3ac0 100755 --- a/t/t1507-rev-parse-upstream.sh +++ b/t/t1507-rev-parse-upstream.sh @@ -5,6 +5,7 @@ test_description='test <branch>@{upstream} 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/t1508-at-combinations.sh b/t/t1508-at-combinations.sh index 87a4286414..e841309d0e 100755 --- a/t/t1508-at-combinations.sh +++ b/t/t1508-at-combinations.sh @@ -4,6 +4,7 @@ test_description='test various @{X} syntax combinations together' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh check() { diff --git a/t/t1514-rev-parse-push.sh b/t/t1514-rev-parse-push.sh index d868a08110..a835a196aa 100755 --- a/t/t1514-rev-parse-push.sh +++ b/t/t1514-rev-parse-push.sh @@ -4,6 +4,7 @@ test_description='test <branch>@{push} syntax' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh resolve () { diff --git a/t/t1800-hook.sh b/t/t1800-hook.sh index 0f0c706d07..750011d717 100755 --- a/t/t1800-hook.sh +++ b/t/t1800-hook.sh @@ -156,25 +156,15 @@ test_expect_success 'git hook run a hook with a bad shebang' ' mkdir bad-hooks && write_script bad-hooks/test-hook "/bad/path/no/spaces" </dev/null && - # TODO: We should emit the same (or at least a more similar) - # error on MINGW (essentially Git for Windows) and all other - # platforms.. See the OS-specific code in start_command() - if test_have_prereq !MINGW - then - cat >expect <<-\EOF - fatal: cannot run bad-hooks/test-hook: ... - EOF - else - cat >expect <<-\EOF - error: cannot spawn bad-hooks/test-hook: ... - EOF - fi && test_expect_code 1 git \ -c core.hooksPath=bad-hooks \ hook run test-hook >out 2>err && test_must_be_empty out && - sed -e "s/test-hook: .*/test-hook: .../" <err >actual && - test_cmp expect actual + + # TODO: We should emit the same (or at least a more similar) + # error on MINGW (essentially Git for Windows) and all other + # platforms.. See the OS-specific code in start_command() + grep -E "^(error|fatal): cannot (exec|spawn) .*bad-hooks/test-hook" err ' test_expect_success 'stdin to hooks' ' diff --git a/t/t2027-checkout-track.sh b/t/t2027-checkout-track.sh index dca35aa3e3..a8bbc60954 100755 --- a/t/t2027-checkout-track.sh +++ b/t/t2027-checkout-track.sh @@ -5,6 +5,7 @@ test_description='tests for git branch --track' 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/t2200-add-update.sh b/t/t2200-add-update.sh index be394f1131..c01492f33f 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -197,4 +197,15 @@ test_expect_success '"add -u non-existent" should fail' ' ! grep "non-existent" actual ' +test_expect_success '"commit -a" implies "add -u" if index becomes empty' ' + git rm -rf \* && + git commit -m clean-slate && + test_commit file1 && + rm file1.t && + test_tick && + git commit -a -m remove && + git ls-tree HEAD: >out && + test_must_be_empty out +' + test_done diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh index d587e0b20d..051363acbb 100755 --- a/t/t2400-worktree-add.sh +++ b/t/t2400-worktree-add.sh @@ -298,17 +298,24 @@ test_expect_success '"add" no auto-vivify with --detach and <branch> omitted' ' test_must_fail git -C mish/mash symbolic-ref HEAD ' -test_expect_success '"add" -b/-B mutually exclusive' ' - test_must_fail git worktree add -b poodle -B poodle bamboo main -' - -test_expect_success '"add" -b/--detach mutually exclusive' ' - test_must_fail git worktree add -b poodle --detach bamboo main -' +# Helper function to test mutually exclusive options. +# +# Note: Quoted arguments containing spaces are not supported. +test_wt_add_excl () { + local opts="$*" && + test_expect_success "'worktree add' with '$opts' has mutually exclusive options" ' + test_must_fail git worktree add $opts 2>actual && + grep -E "fatal:( options)? .* cannot be used together" actual + ' +} -test_expect_success '"add" -B/--detach mutually exclusive' ' - test_must_fail git worktree add -B poodle --detach bamboo main -' +test_wt_add_excl -b poodle -B poodle bamboo main +test_wt_add_excl -b poodle --detach bamboo main +test_wt_add_excl -B poodle --detach bamboo main +test_wt_add_excl --orphan --detach bamboo +test_wt_add_excl --orphan --no-checkout bamboo +test_wt_add_excl --orphan bamboo main +test_wt_add_excl --orphan -b bamboo wtdir/ main test_expect_success '"add -B" fails if the branch is checked out' ' git rev-parse newmain >before && @@ -326,10 +333,111 @@ test_expect_success 'add -B' ' ' test_expect_success 'add --quiet' ' + test_when_finished "git worktree remove -f -f another-worktree" && git worktree add --quiet another-worktree main 2>actual && test_must_be_empty actual ' +test_expect_success 'add --quiet -b' ' + test_when_finished "git branch -D quietnewbranch" && + test_when_finished "git worktree remove -f -f another-worktree" && + git worktree add --quiet -b quietnewbranch another-worktree 2>actual && + test_must_be_empty actual +' + +test_expect_success '"add --orphan"' ' + test_when_finished "git worktree remove -f -f orphandir" && + git worktree add --orphan -b neworphan orphandir && + echo refs/heads/neworphan >expected && + git -C orphandir symbolic-ref HEAD >actual && + test_cmp expected actual +' + +test_expect_success '"add --orphan (no -b)"' ' + test_when_finished "git worktree remove -f -f neworphan" && + git worktree add --orphan neworphan && + echo refs/heads/neworphan >expected && + git -C neworphan symbolic-ref HEAD >actual && + test_cmp expected actual +' + +test_expect_success '"add --orphan --quiet"' ' + test_when_finished "git worktree remove -f -f orphandir" && + git worktree add --quiet --orphan -b neworphan orphandir 2>log.actual && + test_must_be_empty log.actual && + echo refs/heads/neworphan >expected && + git -C orphandir symbolic-ref HEAD >actual && + test_cmp expected actual +' + +test_expect_success '"add --orphan" fails if the branch already exists' ' + test_when_finished "git branch -D existingbranch" && + git worktree add -b existingbranch orphandir main && + git worktree remove orphandir && + test_must_fail git worktree add --orphan -b existingbranch orphandir +' + +test_expect_success '"add --orphan" with empty repository' ' + test_when_finished "rm -rf empty_repo" && + echo refs/heads/newbranch >expected && + GIT_DIR="empty_repo" git init --bare && + git -C empty_repo worktree add --orphan -b newbranch worktreedir && + git -C empty_repo/worktreedir symbolic-ref HEAD >actual && + test_cmp expected actual +' + +test_expect_success '"add" worktree with orphan branch and lock' ' + git worktree add --lock --orphan -b orphanbr orphan-with-lock && + test_when_finished "git worktree unlock orphan-with-lock || :" && + test -f .git/worktrees/orphan-with-lock/locked +' + +test_expect_success '"add" worktree with orphan branch, lock, and reason' ' + lock_reason="why not" && + git worktree add --detach --lock --reason "$lock_reason" orphan-with-lock-reason main && + test_when_finished "git worktree unlock orphan-with-lock-reason || :" && + test -f .git/worktrees/orphan-with-lock-reason/locked && + echo "$lock_reason" >expect && + test_cmp expect .git/worktrees/orphan-with-lock-reason/locked +' + +# Note: Quoted arguments containing spaces are not supported. +test_wt_add_orphan_hint () { + local context="$1" && + local use_branch=$2 && + shift 2 && + local opts="$*" && + test_expect_success "'worktree add' show orphan hint in bad/orphan HEAD w/ $context" ' + test_when_finished "rm -rf repo" && + git init repo && + (cd repo && test_commit commit) && + git -C repo switch --orphan noref && + test_must_fail git -C repo worktree add $opts foobar/ 2>actual && + ! grep "error: unknown switch" actual && + grep "hint: If you meant to create a worktree containing a new orphan branch" actual && + if [ $use_branch -eq 1 ] + then + grep -E "^hint: +git worktree add --orphan -b [^ ]+ [^ ]+$" actual + else + grep -E "^hint: +git worktree add --orphan [^ ]+$" actual + fi + + ' +} + +test_wt_add_orphan_hint 'no opts' 0 +test_wt_add_orphan_hint '-b' 1 -b foobar_branch +test_wt_add_orphan_hint '-B' 1 -B foobar_branch + +test_expect_success "'worktree add' doesn't show orphan hint in bad/orphan HEAD w/ --quiet" ' + test_when_finished "rm -rf repo" && + git init repo && + (cd repo && test_commit commit) && + test_must_fail git -C repo worktree add --quiet foobar_branch foobar/ 2>actual && + ! grep "error: unknown switch" actual && + ! grep "hint: If you meant to create a worktree containing a new orphan branch" actual +' + test_expect_success 'local clone from linked checkout' ' git clone --local here here-clone && ( cd here-clone && git fsck ) @@ -446,6 +554,14 @@ setup_remote_repo () { ) } +test_expect_success '"add" <path> <remote/branch> w/ no HEAD' ' + test_when_finished rm -rf repo_upstream repo_local foo && + setup_remote_repo repo_upstream repo_local && + git -C repo_local config --bool core.bare true && + git -C repo_local branch -D main && + git -C repo_local worktree add ./foo repo_upstream/foo +' + test_expect_success '--no-track avoids setting up tracking' ' test_when_finished rm -rf repo_upstream repo_local foo && setup_remote_repo repo_upstream repo_local && @@ -528,6 +644,35 @@ test_expect_success 'git worktree add --guess-remote sets up tracking' ' test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo ) ' +test_expect_success 'git worktree add --guess-remote sets up tracking (quiet)' ' + test_when_finished rm -rf repo_a repo_b foo && + setup_remote_repo repo_a repo_b && + ( + cd repo_b && + git worktree add --quiet --guess-remote ../foo 2>actual && + test_must_be_empty actual + ) && + ( + cd foo && + test_branch_upstream foo repo_a foo && + test_cmp_rev refs/remotes/repo_a/foo refs/heads/foo + ) +' + +test_expect_success 'git worktree --no-guess-remote (quiet)' ' + test_when_finished rm -rf repo_a repo_b foo && + setup_remote_repo repo_a repo_b && + ( + cd repo_b && + git worktree add --quiet --no-guess-remote ../foo + ) && + ( + cd foo && + test_must_fail git config "branch.foo.remote" && + test_must_fail git config "branch.foo.merge" && + test_cmp_rev ! refs/remotes/repo_a/foo refs/heads/foo + ) +' test_expect_success 'git worktree add with worktree.guessRemote sets up tracking' ' test_when_finished rm -rf repo_a repo_b foo && @@ -560,6 +705,348 @@ test_expect_success 'git worktree --no-guess-remote option overrides config' ' ) ' +test_dwim_orphan () { + local info_text="No possible source branch, inferring '--orphan'" && + local fetch_error_text="fatal: No local or remote refs exist despite at least one remote" && + local orphan_hint="hint: If you meant to create a worktree containing a new orphan branch" && + local invalid_ref_regex="^fatal: invalid reference: " && + local bad_combo_regex="^fatal: '[-a-z]*' and '[-a-z]*' cannot be used together" && + + local git_ns="repo" && + local dashc_args="-C $git_ns" && + local use_cd=0 && + + local bad_head=0 && + local empty_repo=1 && + local local_ref=0 && + local use_quiet=0 && + local remote=0 && + local remote_ref=0 && + local use_detach=0 && + local use_new_branch=0 && + + local outcome="$1" && + local outcome_text && + local success && + shift && + local args="" && + local context="" && + case "$outcome" in + "infer") + success=1 && + outcome_text='"add" DWIM infer --orphan' + ;; + "no_infer") + success=1 && + outcome_text='"add" DWIM doesnt infer --orphan' + ;; + "fetch_error") + success=0 && + outcome_text='"add" error need fetch' + ;; + "fatal_orphan_bad_combo") + success=0 && + outcome_text='"add" error inferred "--orphan" gives illegal opts combo' + ;; + "warn_bad_head") + success=0 && + outcome_text='"add" error, warn on bad HEAD, hint use orphan' + ;; + *) + echo "test_dwim_orphan(): invalid outcome: '$outcome'" >&2 && + return 1 + ;; + esac && + while [ $# -gt 0 ] + do + case "$1" in + # How and from where to create the worktree + "-C_repo") + use_cd=0 && + git_ns="repo" && + dashc_args="-C $git_ns" && + context="$context, 'git -C repo'" + ;; + "-C_wt") + use_cd=0 && + git_ns="wt" && + dashc_args="-C $git_ns" && + context="$context, 'git -C wt'" + ;; + "cd_repo") + use_cd=1 && + git_ns="repo" && + dashc_args="" && + context="$context, 'cd repo && git'" + ;; + "cd_wt") + use_cd=1 && + git_ns="wt" && + dashc_args="" && + context="$context, 'cd wt && git'" + ;; + + # Bypass the "pull first" warning + "force") + args="$args --force" && + context="$context, --force" + ;; + + # Try to use remote refs when DWIM + "guess_remote") + args="$args --guess-remote" && + context="$context, --guess-remote" + ;; + "no_guess_remote") + args="$args --no-guess-remote" && + context="$context, --no-guess-remote" + ;; + + # Whether there is at least one local branch present + "local_ref") + empty_repo=0 && + local_ref=1 && + context="$context, >=1 local branches" + ;; + "no_local_ref") + empty_repo=0 && + context="$context, 0 local branches" + ;; + + # Whether the HEAD points at a valid ref (skip this opt when no refs) + "good_head") + # requires: local_ref + context="$context, valid HEAD" + ;; + "bad_head") + bad_head=1 && + context="$context, invalid (or orphan) HEAD" + ;; + + # Whether the code path is tested with the base add command, -b, or --detach + "no_-b") + use_new_branch=0 && + context="$context, no --branch" + ;; + "-b") + use_new_branch=1 && + context="$context, --branch" + ;; + "detach") + use_detach=1 && + context="$context, --detach" + ;; + + # Whether to check that all output is suppressed (except errors) + # or that the output is as expected + "quiet") + use_quiet=1 && + args="$args --quiet" && + context="$context, --quiet" + ;; + "no_quiet") + use_quiet=0 && + context="$context, no --quiet (expect output)" + ;; + + # Whether there is at least one remote attached to the repo + "remote") + empty_repo=0 && + remote=1 && + context="$context, >=1 remotes" + ;; + "no_remote") + empty_repo=0 && + remote=0 && + context="$context, 0 remotes" + ;; + + # Whether there is at least one valid remote ref + "remote_ref") + # requires: remote + empty_repo=0 && + remote_ref=1 && + context="$context, >=1 fetched remote branches" + ;; + "no_remote_ref") + empty_repo=0 && + remote_ref=0 && + context="$context, 0 fetched remote branches" + ;; + + # Options or flags that become illegal when --orphan is inferred + "no_checkout") + args="$args --no-checkout" && + context="$context, --no-checkout" + ;; + "track") + args="$args --track" && + context="$context, --track" + ;; + + # All other options are illegal + *) + echo "test_dwim_orphan(): invalid arg: '$1'" >&2 && + return 1 + ;; + esac && + shift + done && + context="${context#', '}" && + if [ $use_new_branch -eq 1 ] + then + args="$args -b foo" + elif [ $use_detach -eq 1 ] + then + args="$args --detach" + else + context="DWIM (no --branch), $context" + fi && + if [ $empty_repo -eq 1 ] + then + context="empty repo, $context" + fi && + args="$args ../foo" && + context="${context%', '}" && + test_expect_success "$outcome_text w/ $context" ' + test_when_finished "rm -rf repo" && + git init repo && + if [ $local_ref -eq 1 ] && [ "$git_ns" = "repo" ] + then + (cd repo && test_commit commit) && + if [ $bad_head -eq 1 ] + then + git -C repo symbolic-ref HEAD refs/heads/badbranch + fi + elif [ $local_ref -eq 1 ] && [ "$git_ns" = "wt" ] + then + test_when_finished "git -C repo worktree remove -f ../wt" && + git -C repo worktree add --orphan -b main ../wt && + (cd wt && test_commit commit) && + if [ $bad_head -eq 1 ] + then + git -C wt symbolic-ref HEAD refs/heads/badbranch + fi + elif [ $local_ref -eq 0 ] && [ "$git_ns" = "wt" ] + then + test_when_finished "git -C repo worktree remove -f ../wt" && + git -C repo worktree add --orphan -b orphanbranch ../wt + fi && + + if [ $remote -eq 1 ] + then + test_when_finished "rm -rf upstream" && + git init upstream && + (cd upstream && test_commit commit) && + git -C upstream switch -c foo && + git -C repo remote add upstream ../upstream + fi && + + if [ $remote_ref -eq 1 ] + then + git -C repo fetch + fi && + if [ $success -eq 1 ] + then + test_when_finished git -C repo worktree remove ../foo + fi && + ( + if [ $use_cd -eq 1 ] + then + cd $git_ns + fi && + if [ "$outcome" = "infer" ] + then + git $dashc_args worktree add $args 2>actual && + if [ $use_quiet -eq 1 ] + then + test_must_be_empty actual + else + grep "$info_text" actual + fi + elif [ "$outcome" = "no_infer" ] + then + git $dashc_args worktree add $args 2>actual && + if [ $use_quiet -eq 1 ] + then + test_must_be_empty actual + else + ! grep "$info_text" actual + fi + elif [ "$outcome" = "fetch_error" ] + then + test_must_fail git $dashc_args worktree add $args 2>actual && + grep "$fetch_error_text" actual + elif [ "$outcome" = "fatal_orphan_bad_combo" ] + then + test_must_fail git $dashc_args worktree add $args 2>actual && + if [ $use_quiet -eq 1 ] + then + ! grep "$info_text" actual + else + grep "$info_text" actual + fi && + grep "$bad_combo_regex" actual + elif [ "$outcome" = "warn_bad_head" ] + then + test_must_fail git $dashc_args worktree add $args 2>actual && + if [ $use_quiet -eq 1 ] + then + grep "$invalid_ref_regex" actual && + ! grep "$orphan_hint" actual + else + headpath=$(git $dashc_args rev-parse --path-format=absolute --git-path HEAD) && + headcontents=$(cat "$headpath") && + grep "HEAD points to an invalid (or orphaned) reference" actual && + grep "HEAD path: .$headpath." actual && + grep "HEAD contents: .$headcontents." actual && + grep "$orphan_hint" actual && + ! grep "$info_text" actual + fi && + grep "$invalid_ref_regex" actual + else + # Unreachable + false + fi + ) && + if [ $success -ne 1 ] + then + test_path_is_missing foo + fi + ' +} + +for quiet_mode in "no_quiet" "quiet" +do + for changedir_type in "cd_repo" "cd_wt" "-C_repo" "-C_wt" + do + dwim_test_args="$quiet_mode $changedir_type" + test_dwim_orphan 'infer' $dwim_test_args no_-b + test_dwim_orphan 'no_infer' $dwim_test_args no_-b local_ref good_head + test_dwim_orphan 'infer' $dwim_test_args no_-b no_local_ref no_remote no_remote_ref no_guess_remote + test_dwim_orphan 'infer' $dwim_test_args no_-b no_local_ref remote no_remote_ref no_guess_remote + test_dwim_orphan 'fetch_error' $dwim_test_args no_-b no_local_ref remote no_remote_ref guess_remote + test_dwim_orphan 'infer' $dwim_test_args no_-b no_local_ref remote no_remote_ref guess_remote force + test_dwim_orphan 'no_infer' $dwim_test_args no_-b no_local_ref remote remote_ref guess_remote + + test_dwim_orphan 'infer' $dwim_test_args -b + test_dwim_orphan 'no_infer' $dwim_test_args -b local_ref good_head + test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref no_remote no_remote_ref no_guess_remote + test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote no_remote_ref no_guess_remote + test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote no_remote_ref guess_remote + test_dwim_orphan 'infer' $dwim_test_args -b no_local_ref remote remote_ref guess_remote + + test_dwim_orphan 'warn_bad_head' $dwim_test_args no_-b local_ref bad_head + test_dwim_orphan 'warn_bad_head' $dwim_test_args -b local_ref bad_head + test_dwim_orphan 'warn_bad_head' $dwim_test_args detach local_ref bad_head + done + + test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode no_-b no_checkout + test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode no_-b track + test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode -b no_checkout + test_dwim_orphan 'fatal_orphan_bad_combo' $quiet_mode -b track +done + post_checkout_hook () { test_when_finished "rm -rf .git/hooks" && mkdir .git/hooks && diff --git a/t/t2407-worktree-heads.sh b/t/t2407-worktree-heads.sh index 019a40df2c..469443d8ae 100755 --- a/t/t2407-worktree-heads.sh +++ b/t/t2407-worktree-heads.sh @@ -58,7 +58,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in bisect' ' git -C wt-4 bisect good wt-1 && test_must_fail git branch -f wt-4 HEAD 2>err && - grep "cannot force update the branch '\''wt-4'\'' checked out at.*wt-4" err + grep "cannot force update the branch '\''wt-4'\'' used by worktree at.*wt-4" err ' test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (apply)' ' @@ -68,7 +68,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (app test_must_fail git -C wt-2 rebase --apply conflict-2 && test_must_fail git branch -f wt-2 HEAD 2>err && - grep "cannot force update the branch '\''wt-2'\'' checked out at.*wt-2" err + grep "cannot force update the branch '\''wt-2'\'' used by worktree at.*wt-2" err ' test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (merge)' ' @@ -78,7 +78,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase (mer test_must_fail git -C wt-2 rebase conflict-2 && test_must_fail git branch -f wt-2 HEAD 2>err && - grep "cannot force update the branch '\''wt-2'\'' checked out at.*wt-2" err + grep "cannot force update the branch '\''wt-2'\'' used by worktree at.*wt-2" err ' test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase with --update-refs' ' @@ -90,7 +90,7 @@ test_expect_success !SANITIZE_LEAK 'refuse to overwrite: worktree in rebase with for i in 3 4 do test_must_fail git branch -f can-be-updated HEAD 2>err && - grep "cannot force update the branch '\''can-be-updated'\'' checked out at.*wt-3" err || + grep "cannot force update the branch '\''can-be-updated'\'' used by worktree at.*wt-3" err || return 1 done ' @@ -150,7 +150,7 @@ test_expect_success 'refuse to overwrite when in error states' ' for i in 1 2 do test_must_fail git branch -f fake-$i HEAD 2>err && - grep "cannot force update the branch '\''fake-$i'\'' checked out at" err || + grep "cannot force update the branch '\''fake-$i'\'' used by worktree at" err || return 1 done ' diff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh index dd7770e85d..7308a3d4e2 100755 --- a/t/t3007-ls-files-recurse-submodules.sh +++ b/t/t3007-ls-files-recurse-submodules.sh @@ -299,6 +299,39 @@ test_expect_success '--recurse-submodules does not support --error-unmatch' ' test_i18ngrep "does not support --error-unmatch" actual ' +test_expect_success '--recurse-submodules parses submodule repo config' ' + test_config -C submodule index.sparse "invalid non-boolean value" && + test_must_fail git ls-files --recurse-submodules 2>err && + grep "bad boolean config value" err +' + +test_expect_success '--recurse-submodules parses submodule worktree config' ' + test_config -C submodule extensions.worktreeConfig true && + test_config -C submodule --worktree index.sparse "invalid non-boolean value" && + + test_must_fail git ls-files --recurse-submodules 2>err && + grep "bad boolean config value" err +' + +test_expect_success '--recurse-submodules submodules ignore super project worktreeConfig extension' ' + # Enable worktree config in both super project & submodule, set an + # invalid config in the submodule worktree config + test_config extensions.worktreeConfig true && + test_config -C submodule extensions.worktreeConfig true && + test_config -C submodule --worktree index.sparse "invalid non-boolean value" && + + # Now, disable the worktree config in the submodule. Note that we need + # to manually re-enable extensions.worktreeConfig when the test is + # finished, otherwise the test_unconfig of index.sparse will not work. + test_unconfig -C submodule extensions.worktreeConfig && + test_when_finished "git -C submodule config extensions.worktreeConfig true" && + + # With extensions.worktreeConfig disabled in the submodule, the invalid + # worktree config is not picked up. + git ls-files --recurse-submodules 2>err && + ! grep "bad boolean config value" err +' + test_incompatible_with_recurse_submodules () { test_expect_success "--recurse-submodules and $1 are incompatible" " test_must_fail git ls-files --recurse-submodules $1 2>actual && diff --git a/t/t3013-ls-files-format.sh b/t/t3013-ls-files-format.sh index ef6fb53f7f..6e6ea0b6f3 100755 --- a/t/t3013-ls-files-format.sh +++ b/t/t3013-ls-files-format.sh @@ -38,6 +38,41 @@ test_expect_success 'git ls-files --format objectname v.s. -s' ' test_cmp expect actual ' +test_expect_success 'git ls-files --format objecttype' ' + git ls-files --format="%(objectname)" o1.txt o4.txt o6.txt >objectname && + git cat-file --batch-check="%(objecttype)" >expect <objectname && + git ls-files --format="%(objecttype)" o1.txt o4.txt o6.txt >actual && + test_cmp expect actual +' + +test_expect_success 'git ls-files --format objectsize' ' + cat>expect <<-\EOF && +26 +29 +27 +26 +- +26 + EOF + git ls-files --format="%(objectsize)" >actual && + + test_cmp expect actual +' + +test_expect_success 'git ls-files --format objectsize:padded' ' + cat>expect <<-\EOF && + 26 + 29 + 27 + 26 + - + 26 + EOF + git ls-files --format="%(objectsize:padded)" >actual && + + test_cmp expect actual +' + test_expect_success 'git ls-files --format v.s. --eol' ' git ls-files --eol >tmp && sed -e "s/ / /g" -e "s/ */ /g" tmp >expect 2>err && diff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh index 217006d1bf..5af2dac0e4 100755 --- a/t/t3101-ls-tree-dirname.sh +++ b/t/t3101-ls-tree-dirname.sh @@ -154,6 +154,14 @@ EOF test_output ' +test_expect_success 'ls-tree --no-full-name' ' + git -C path0 ls-tree --no-full-name $tree a >current && + cat >expected <<-EOF && + 040000 tree X a + EOF + test_output +' + test_expect_success 'ls-tree --full-tree' ' ( cd path1/b/c && diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 98b6c8ac34..daf1666df7 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -8,6 +8,7 @@ test_description='git branch assorted tests' 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-rebase.sh diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh index be20ebe1d5..b17f388f56 100755 --- a/t/t3202-show-branch.sh +++ b/t/t3202-show-branch.sh @@ -119,6 +119,22 @@ test_expect_success 'show branch --remotes' ' test_must_be_empty actual.out ' +test_expect_success 'show-branch --sparse' ' + test_when_finished "git checkout branch10 && git branch -D branchA" && + git checkout -b branchA branch10 && + git merge -s ours -m "merge 1 and 10 to make A" branch1 && + git commit --allow-empty -m "another" && + + git show-branch --sparse >out && + grep "merge 1 and 10 to make A" out && + + git show-branch >out && + ! grep "merge 1 and 10 to make A" out && + + git show-branch --no-sparse >out && + ! grep "merge 1 and 10 to make A" out +' + test_expect_success 'setup show branch --list' ' sed "s/^> //" >expect <<-\EOF > [branch1] branch1 @@ -197,6 +213,15 @@ done <<\EOF --reflog --current EOF +# unnegatable options +for opt in topo-order date-order reflog +do + test_expect_success "show-branch --no-$opt (should fail)" ' + test_must_fail git show-branch --no-$opt 2>err && + grep "unknown option .no-$opt." err + ' +done + test_expect_success 'error descriptions on non-existent branch' ' cat >expect <<-EOF && error: No branch named '\''non-existent'\'.' diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 93f8295339..758963b189 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -55,9 +55,17 @@ cat >expect <<'EOF' EOF test_expect_success 'git branch -r shows remote branches' ' git branch -r >actual && + test_cmp expect actual && + + git branch --remotes >actual && test_cmp expect actual ' +test_expect_success 'git branch --no-remotes is rejected' ' + test_must_fail git branch --no-remotes 2>err && + grep "unknown option .no-remotes." err +' + cat >expect <<'EOF' branch-one branch-two @@ -68,9 +76,17 @@ cat >expect <<'EOF' EOF test_expect_success 'git branch -a shows local and remote branches' ' git branch -a >actual && + test_cmp expect actual && + + git branch --all >actual && test_cmp expect actual ' +test_expect_success 'git branch --no-all is rejected' ' + test_must_fail git branch --no-all 2>err && + grep "unknown option .no-all." err +' + cat >expect <<'EOF' two one diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh index 3399344f25..594e3e43e1 100755 --- a/t/t3204-branch-name-interpretation.sh +++ b/t/t3204-branch-name-interpretation.sh @@ -9,6 +9,7 @@ This script aims to check the behavior of those corner cases. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh expect_branch() { diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index 07a0ff93de..7326adb70f 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -19,101 +19,138 @@ test_expect_success 'enable reflogs' ' git config core.logallrefupdates true ' -test_expect_success \ - 'prepare a trivial repository' \ - 'echo Hello > A && - git update-index --add A && - git commit -m "Initial commit." && - HEAD=$(git rev-parse --verify HEAD)' +test_expect_success 'prepare a trivial repository' ' + echo Hello > A && + git update-index --add A && + git commit -m "Initial commit." && + HEAD=$(git rev-parse --verify HEAD) +' SHA1= -test_expect_success \ - 'see if git show-ref works as expected' \ - 'git branch a && - SHA1=$(cat .git/refs/heads/a) && - echo "$SHA1 refs/heads/a" >expect && - git show-ref a >result && - test_cmp expect result' - -test_expect_success \ - 'see if a branch still exists when packed' \ - 'git branch b && - git pack-refs --all && - rm -f .git/refs/heads/b && - echo "$SHA1 refs/heads/b" >expect && - git show-ref b >result && - test_cmp expect result' +test_expect_success 'see if git show-ref works as expected' ' + git branch a && + SHA1=$(cat .git/refs/heads/a) && + echo "$SHA1 refs/heads/a" >expect && + git show-ref a >result && + test_cmp expect result +' + +test_expect_success 'see if a branch still exists when packed' ' + git branch b && + git pack-refs --all && + rm -f .git/refs/heads/b && + echo "$SHA1 refs/heads/b" >expect && + git show-ref b >result && + test_cmp expect result +' test_expect_success 'git branch c/d should barf if branch c exists' ' - git branch c && - git pack-refs --all && - rm -f .git/refs/heads/c && - test_must_fail git branch c/d + git branch c && + git pack-refs --all && + rm -f .git/refs/heads/c && + test_must_fail git branch c/d ' -test_expect_success \ - 'see if a branch still exists after git pack-refs --prune' \ - 'git branch e && - git pack-refs --all --prune && - echo "$SHA1 refs/heads/e" >expect && - git show-ref e >result && - test_cmp expect result' +test_expect_success 'see if a branch still exists after git pack-refs --prune' ' + git branch e && + git pack-refs --all --prune && + echo "$SHA1 refs/heads/e" >expect && + git show-ref e >result && + test_cmp expect result +' test_expect_success 'see if git pack-refs --prune remove ref files' ' - git branch f && - git pack-refs --all --prune && - ! test -f .git/refs/heads/f + git branch f && + git pack-refs --all --prune && + ! test -f .git/refs/heads/f ' test_expect_success 'see if git pack-refs --prune removes empty dirs' ' - git branch r/s/t && - git pack-refs --all --prune && - ! test -e .git/refs/heads/r + git branch r/s/t && + git pack-refs --all --prune && + ! test -e .git/refs/heads/r ' -test_expect_success \ - 'git branch g should work when git branch g/h has been deleted' \ - 'git branch g/h && - git pack-refs --all --prune && - git branch -d g/h && - git branch g && - git pack-refs --all && - git branch -d g' +test_expect_success 'git branch g should work when git branch g/h has been deleted' ' + git branch g/h && + git pack-refs --all --prune && + git branch -d g/h && + git branch g && + git pack-refs --all && + git branch -d g +' test_expect_success 'git branch i/j/k should barf if branch i exists' ' - git branch i && - git pack-refs --all --prune && - test_must_fail git branch i/j/k + git branch i && + git pack-refs --all --prune && + test_must_fail git branch i/j/k +' + +test_expect_success 'test git branch k after branch k/l/m and k/lm have been deleted' ' + git branch k/l && + git branch k/lm && + git branch -d k/l && + git branch k/l/m && + git branch -d k/l/m && + git branch -d k/lm && + git branch k ' -test_expect_success \ - 'test git branch k after branch k/l/m and k/lm have been deleted' \ - 'git branch k/l && - git branch k/lm && - git branch -d k/l && - git branch k/l/m && - git branch -d k/l/m && - git branch -d k/lm && - git branch k' - -test_expect_success \ - 'test git branch n after some branch deletion and pruning' \ - 'git branch n/o && - git branch n/op && - git branch -d n/o && - git branch n/o/p && - git branch -d n/op && - git pack-refs --all --prune && - git branch -d n/o/p && - git branch n' - -test_expect_success \ - 'see if up-to-date packed refs are preserved' \ - 'git branch q && - git pack-refs --all --prune && - git update-ref refs/heads/q refs/heads/q && - ! test -f .git/refs/heads/q' +test_expect_success 'test git branch n after some branch deletion and pruning' ' + git branch n/o && + git branch n/op && + git branch -d n/o && + git branch n/o/p && + git branch -d n/op && + git pack-refs --all --prune && + git branch -d n/o/p && + git branch n +' + +test_expect_success 'test excluded refs are not packed' ' + git branch dont_pack1 && + git branch dont_pack2 && + git branch pack_this && + git pack-refs --all --exclude "refs/heads/dont_pack*" && + test -f .git/refs/heads/dont_pack1 && + test -f .git/refs/heads/dont_pack2 && + ! test -f .git/refs/heads/pack_this' + +test_expect_success 'test --no-exclude refs clears excluded refs' ' + git branch dont_pack3 && + git branch dont_pack4 && + git pack-refs --all --exclude "refs/heads/dont_pack*" --no-exclude && + ! test -f .git/refs/heads/dont_pack3 && + ! test -f .git/refs/heads/dont_pack4' + +test_expect_success 'test only included refs are packed' ' + git branch pack_this1 && + git branch pack_this2 && + git tag dont_pack5 && + git pack-refs --include "refs/heads/pack_this*" && + test -f .git/refs/tags/dont_pack5 && + ! test -f .git/refs/heads/pack_this1 && + ! test -f .git/refs/heads/pack_this2' + +test_expect_success 'test --no-include refs clears included refs' ' + git branch pack1 && + git branch pack2 && + git pack-refs --include "refs/heads/pack*" --no-include && + test -f .git/refs/heads/pack1 && + test -f .git/refs/heads/pack2' + +test_expect_success 'test --exclude takes precedence over --include' ' + git branch dont_pack5 && + git pack-refs --include "refs/heads/pack*" --exclude "refs/heads/pack*" && + test -f .git/refs/heads/dont_pack5' + +test_expect_success 'see if up-to-date packed refs are preserved' ' + git branch q && + git pack-refs --all --prune && + git update-ref refs/heads/q refs/heads/q && + ! test -f .git/refs/heads/q +' test_expect_success 'pack, prune and repack' ' git tag foo && diff --git a/t/t3301-notes.sh b/t/t3301-notes.sh index 3288aaec7d..d734000d2f 100755 --- a/t/t3301-notes.sh +++ b/t/t3301-notes.sh @@ -362,6 +362,7 @@ test_expect_success 'do not create empty note with -m ""' ' ' test_expect_success 'create note with combination of -m and -F' ' + test_when_finished git notes remove HEAD && cat >expect-combine_m_and_F <<-EOF && foo @@ -380,6 +381,41 @@ test_expect_success 'create note with combination of -m and -F' ' test_cmp expect-combine_m_and_F actual ' +test_expect_success 'create note with combination of -m and -F and --separator' ' + test_when_finished git notes remove HEAD && + cat >expect-combine_m_and_F <<-\EOF && + foo + ------- + xyzzy + ------- + bar + ------- + zyxxy + ------- + baz + EOF + echo "xyzzy" >note_a && + echo "zyxxy" >note_b && + git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --separator="-------" && + git notes show >actual && + test_cmp expect-combine_m_and_F actual +' + +test_expect_success 'create note with combination of -m and -F and --no-separator' ' + cat >expect-combine_m_and_F <<-\EOF && + foo + xyzzy + bar + zyxxy + baz + EOF + echo "xyzzy" >note_a && + echo "zyxxy" >note_b && + git notes add -m "foo" -F note_a -m "bar" -F note_b -m "baz" --no-separator && + git notes show >actual && + test_cmp expect-combine_m_and_F actual +' + test_expect_success 'remove note with "git notes remove"' ' git notes remove HEAD^ && git notes remove && @@ -521,6 +557,112 @@ test_expect_success 'listing non-existing notes fails' ' test_must_be_empty actual ' +test_expect_success 'append: specify a separator with an empty arg' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --separator="" -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify a separator without arg' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --separator -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify as --no-separator' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --no-separator -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify separator with line break' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + ------- + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --separator="-------$LF" -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify separator without line break' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + ------- + notes-2 + EOF + + git notes add -m "notes-1" && + git notes append --separator="-------" -m "notes-2" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append: specify separator with multiple messages' ' + test_when_finished git notes remove HEAD && + cat >expect <<-\EOF && + notes-1 + ------- + notes-2 + ------- + notes-3 + EOF + + git notes add -m "notes-1" && + git notes append --separator="-------" -m "notes-2" -m "notes-3" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note with combination of -m and -F and --separator' ' + test_when_finished git notes remove HEAD && + cat >expect-combine_m_and_F <<-\EOF && + m-notes-1 + ------- + f-notes-1 + ------- + m-notes-2 + ------- + f-notes-2 + ------- + m-notes-3 + EOF + + echo "f-notes-1" >note_a && + echo "f-notes-2" >note_b && + git notes append -m "m-notes-1" -F note_a -m "m-notes-2" -F note_b -m "m-notes-3" --separator="-------" && + git notes show >actual && + test_cmp expect-combine_m_and_F actual +' + test_expect_success 'append to existing note with "git notes append"' ' cat >expect <<-EOF && Initial set of notes @@ -818,6 +960,33 @@ test_expect_success 'create note from blob with "git notes add -C" reuses blob i test_cmp blob actual ' +test_expect_success 'create note from blob with "-C", also specify "-m", "-F" and "--separator"' ' + # 8th will be reuseed in following tests, so rollback when the test is done + test_when_finished "git notes remove && git notes add -C $(cat blob)" && + commit=$(git rev-parse HEAD) && + cat >expect <<-EOF && + commit $commit + Author: A U Thor <author@example.com> + Date: Thu Apr 7 15:20:13 2005 -0700 + + ${indent}8th + + Notes: + ${indent}This is a blob object + ${indent}------- + ${indent}This is created by -m + ${indent}------- + ${indent}This is created by -F + EOF + + git notes remove && + echo "This is a blob object" | git hash-object -w --stdin >blob && + echo "This is created by -F" >note_a && + git notes add -C $(cat blob) -m "This is created by -m" -F note_a --separator="-------" && + git log -1 >actual && + test_cmp expect actual +' + test_expect_success 'create note from other note with "git notes add -c"' ' test_commit 9th && commit=$(git rev-parse HEAD) && diff --git a/t/t3321-notes-stripspace.sh b/t/t3321-notes-stripspace.sh new file mode 100755 index 0000000000..36abdca5ee --- /dev/null +++ b/t/t3321-notes-stripspace.sh @@ -0,0 +1,578 @@ +#!/bin/sh +# +# Copyright (c) 2023 Teng Long +# + +test_description='Test commit notes with stripspace behavior' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh + +MULTI_LF="$LF$LF$LF" +write_script fake_editor <<\EOF +echo "$MSG" >"$1" +echo "$MSG" >&2 +EOF +GIT_EDITOR=./fake_editor +export GIT_EDITOR + +test_expect_success 'setup the commit' ' + test_commit 1st +' + +test_expect_success 'add note by editor' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying single "-m", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}first-line${MULTI_LF}second-line${LF}" && + git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -m "${LF}first-line${MULTI_LF}second-line${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying single "-m" and "--no-stripspace" ' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF}first-line${MULTI_LF}second-line + EOF + + git notes add --no-stripspace \ + -m "${LF}first-line${MULTI_LF}second-line${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying multiple "-m", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}" \ + -m "first-line" \ + -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -m "${LF}" \ + -m "first-line" \ + -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add notes by specifying multiple "-m" and "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line${LF} + EOF + + git notes add --no-stripspace \ + -m "${LF}" \ + -m "first-line" \ + -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying single "-F", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add -F note-file && + git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -F note-file && + git notes show >actual +' + +test_expect_success 'add note by specifying single "-F" and "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add --no-stripspace -F note-file && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying multiple "-F", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + file-1-first-line + + file-1-second-line + + file-2-first-line + + file-2-second-line + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --stripspace -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying multiple "-F" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add --no-stripspace -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by editor' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "first-line" && + MSG="${MULTI_LF}second-line${LF}" git notes append && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by specifying single "-m"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}first-line" && + git notes append -m "${MULTI_LF}second-line${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by specifying multiple "-m"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + git notes add -m "${LF}first-line" && + git notes append -m "${MULTI_LF}" \ + -m "second-line" \ + -m "${LF}" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying single "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add -F note-file && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add notes by specifying multiple "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + file-1-first-line + + file-1-second-line + + file-2-first-line + + file-2-second-line + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by specifying single "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + initial-line + + first-line + + second-line + EOF + + cat >note-file <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + git notes add -m "initial-line" && + git notes append -F note-file && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append notes by specifying multiple "-F"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + initial-line + + file-1-first-line + + file-1-second-line + + file-2-first-line + + file-2-second-line + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -m "initial-line" && + git notes append -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'append note by specifying multiple "-F" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + initial-line + ${LF}${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + cat >note-file-1 <<-EOF && + ${LF} + file-1-first-line + ${MULTI_LF} + file-1-second-line + ${LF} + EOF + + cat >note-file-2 <<-EOF && + ${LF} + file-2-first-line + ${MULTI_LF} + file-2-second-line + ${LF} + EOF + + git notes add -m "initial-line" && + git notes append --no-stripspace -F note-file-1 -F note-file-2 && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add notes with empty messages' ' + rev=$(git rev-parse HEAD) && + git notes add -m "${LF}" \ + -m "${MULTI_LF}" \ + -m "${LF}" >actual 2>&1 && + test_i18ngrep "Removing note for object" actual +' + +test_expect_success 'add note by specifying "-C", "--no-stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat expect | git hash-object -w --stdin >blob && + git notes add -C $(cat blob) && + git notes show >actual && + test_cmp expect actual && + git notes remove && + git notes add --no-stripspace -C $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'reuse note by specifying "-C" and "--stripspace"' ' + test_when_finished "git notes remove" && + cat >data <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat >expect <<-EOF && + first-line + + second-line + EOF + + cat data | git hash-object -w --stdin >blob && + git notes add --stripspace -C $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'reuse with "-C" and add note with "-m", "-m" will stripspace all together' ' + test_when_finished "git notes remove" && + cat >data <<-EOF && + ${LF} + first-line + ${MULTI_LF} + second-line + ${LF} + EOF + + cat >expect <<-EOF && + first-line + + second-line + + third-line + EOF + + cat data | git hash-object -w --stdin >blob && + git notes add -C $(cat blob) -m "third-line" && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note with "-m" and reuse note with "-C", "-C" will not stripspace all together' ' + test_when_finished "git notes remove" && + cat >data <<-EOF && + + second-line + EOF + + cat >expect <<-EOF && + first-line + ${LF} + second-line + EOF + + cat data | git hash-object -w --stdin >blob && + git notes add -m "first-line" -C $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying "-c", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + echo "initial-line" | git hash-object -w --stdin >blob && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add -c $(cat blob) && + git notes show >actual && + test_cmp expect actual && + git notes remove && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --stripspace -c $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'add note by specifying "-c" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF}first-line${MULTI_LF}second-line${LF} + EOF + + echo "initial-line" | git hash-object -w --stdin >blob && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --no-stripspace -c $(cat blob) && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'edit note by specifying "-c", "--stripspace" is the default behavior' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + first-line + + second-line + EOF + + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes edit && + git notes show >actual && + test_cmp expect actual && + git notes remove && + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes edit --stripspace && + git notes show >actual && + test_cmp expect actual +' + +test_expect_success 'edit note by specifying "-c" with "--no-stripspace"' ' + test_when_finished "git notes remove" && + cat >expect <<-EOF && + ${LF}first-line${MULTI_LF}second-line${LF} + EOF + + MSG="${LF}first-line${MULTI_LF}second-line${LF}" git notes add --no-stripspace && + git notes show >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh index 79b0640c00..e9e03ca4b5 100755 --- a/t/t3402-rebase-merge.sh +++ b/t/t3402-rebase-merge.sh @@ -8,6 +8,7 @@ test_description='git rebase --merge test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh T="A quick brown fox diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index ff0afad63e..8ea2bf1302 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -604,7 +604,8 @@ test_expect_success 'clean error after failed "exec"' ' echo "edited again" > file7 && git add file7 && test_must_fail git rebase --continue 2>error && - test_i18ngrep "you have staged changes in your working tree" error + test_i18ngrep "you have staged changes in your working tree" error && + test_i18ngrep ! "could not open.*for reading" error ' test_expect_success 'rebase a detached HEAD' ' @@ -758,7 +759,7 @@ test_expect_success 'reword' ' git show HEAD~2 | grep "C changed" ' -test_expect_success 'no uncommited changes when rewording the todo list is reloaded' ' +test_expect_success 'no uncommitted changes when rewording and the todo list is reloaded' ' git checkout E && test_when_finished "git checkout @{-1}" && ( @@ -1276,20 +1277,34 @@ test_expect_success 'todo count' ' ' test_expect_success 'rebase -i commits that overwrite untracked files (pick)' ' - git checkout --force branch2 && + git checkout --force A && git clean -f && + cat >todo <<-EOF && + exec >file2 + pick $(git rev-parse B) B + pick $(git rev-parse C) C + pick $(git rev-parse D) D + exec cat .git/rebase-merge/done >actual + EOF ( - set_fake_editor && - FAKE_LINES="edit 1 2" git rebase -i A - ) && - test_cmp_rev HEAD F && - test_path_is_missing file6 && - >file6 && - test_must_fail git rebase --continue && - test_cmp_rev HEAD F && - rm file6 && + set_replace_editor todo && + test_must_fail git rebase -i A + ) && + test_cmp_rev HEAD B && + test_cmp_rev REBASE_HEAD C && + head -n3 todo >expect && + test_cmp expect .git/rebase-merge/done && + rm file2 && + test_path_is_missing .git/rebase-merge/patch && + echo changed >file1 && + git add file1 && + test_must_fail git rebase --continue 2>err && + grep "error: you have staged changes in your working tree" err && + git reset --hard HEAD && git rebase --continue && - test_cmp_rev HEAD I + test_cmp_rev HEAD D && + tail -n3 todo >>expect && + test_cmp expect actual ' test_expect_success 'rebase -i commits that overwrite untracked files (squash)' ' @@ -1305,7 +1320,14 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)' >file6 && test_must_fail git rebase --continue && test_cmp_rev HEAD F && + test_cmp_rev REBASE_HEAD I && rm file6 && + test_path_is_missing .git/rebase-merge/patch && + echo changed >file1 && + git add file1 && + test_must_fail git rebase --continue 2>err && + grep "error: you have staged changes in your working tree" err && + git reset --hard HEAD && git rebase --continue && test $(git cat-file commit HEAD | sed -ne \$p) = I && git reset --hard original-branch2 @@ -1323,7 +1345,14 @@ test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' ' >file6 && test_must_fail git rebase --continue && test $(git cat-file commit HEAD | sed -ne \$p) = F && + test_cmp_rev REBASE_HEAD I && rm file6 && + test_path_is_missing .git/rebase-merge/patch && + echo changed >file1 && + git add file1 && + test_must_fail git rebase --continue 2>err && + grep "error: you have staged changes in your working tree" err && + git reset --hard HEAD && git rebase --continue && test $(git cat-file commit HEAD | sed -ne \$p) = I ' @@ -1596,6 +1625,32 @@ test_expect_success 'static check of bad command' ' test C = $(git cat-file commit HEAD^ | sed -ne \$p) ' +test_expect_success 'the first command cannot be a fixup' ' + rebase_setup_and_clean fixup-first && + + cat >orig <<-EOF && + fixup $(git log -1 --format="%h %s" B) + pick $(git log -1 --format="%h %s" C) + EOF + + ( + set_replace_editor orig && + test_must_fail git rebase -i A 2>actual + ) && + grep "cannot .fixup. without a previous commit" actual && + grep "You can fix this with .git rebase --edit-todo.." actual && + # verify that the todo list has not been truncated + grep -v "^#" .git/rebase-merge/git-rebase-todo >actual && + test_cmp orig actual && + + test_must_fail git rebase --edit-todo 2>actual && + grep "cannot .fixup. without a previous commit" actual && + grep "You can fix this with .git rebase --edit-todo.." actual && + # verify that the todo list has not been truncated + grep -v "^#" .git/rebase-merge/git-rebase-todo >actual && + test_cmp orig actual +' + test_expect_success 'tabs and spaces are accepted in the todolist' ' rebase_setup_and_clean indented-comment && write_script add-indent.sh <<-\EOF && diff --git a/t/t3418-rebase-continue.sh b/t/t3418-rebase-continue.sh index 2d0789e554..c4e2fcac67 100755 --- a/t/t3418-rebase-continue.sh +++ b/t/t3418-rebase-continue.sh @@ -115,15 +115,23 @@ test_expect_success '--skip after failed fixup cleans commit message' ' test_when_finished "test_might_fail git rebase --abort" && git checkout -b with-conflicting-fixup && test_commit wants-fixup && - test_commit "fixup! wants-fixup" wants-fixup.t 1 wants-fixup-1 && - test_commit "fixup! wants-fixup" wants-fixup.t 2 wants-fixup-2 && - test_commit "fixup! wants-fixup" wants-fixup.t 3 wants-fixup-3 && + test_commit "fixup 1" wants-fixup.t 1 wants-fixup-1 && + test_commit "fixup 2" wants-fixup.t 2 wants-fixup-2 && + test_commit "fixup 3" wants-fixup.t 3 wants-fixup-3 && test_must_fail env FAKE_LINES="1 fixup 2 squash 4" \ git rebase -i HEAD~4 && : now there is a conflict, and comments in the commit message && - git show HEAD >out && - grep "fixup! wants-fixup" out && + test_commit_message HEAD <<-\EOF && + # This is a combination of 2 commits. + # This is the 1st commit message: + + wants-fixup + + # The commit message #2 will be skipped: + + # fixup 1 + EOF : skip and continue && echo "cp \"\$1\" .git/copy.txt" | write_script copy-editor.sh && @@ -133,33 +141,49 @@ test_expect_success '--skip after failed fixup cleans commit message' ' test_path_is_missing .git/copy.txt && : now the comments in the commit message should have been cleaned up && - git show HEAD >out && - ! grep "fixup! wants-fixup" out && + test_commit_message HEAD -m wants-fixup && : now, let us ensure that "squash" is handled correctly && git reset --hard wants-fixup-3 && - test_must_fail env FAKE_LINES="1 squash 4 squash 2 squash 4" \ + test_must_fail env FAKE_LINES="1 squash 2 squash 1 squash 3 squash 1" \ git rebase -i HEAD~4 && - : the first squash failed, but there are two more in the chain && + : the second squash failed, but there are two more in the chain && (test_set_editor "$PWD/copy-editor.sh" && test_must_fail git rebase --skip) && : not the final squash, no need to edit the commit message && test_path_is_missing .git/copy.txt && - : The first squash was skipped, therefore: && - git show HEAD >out && - test_i18ngrep "# This is a combination of 2 commits" out && - test_i18ngrep "# This is the commit message #2:" out && + : The first and third squashes succeeded, therefore: && + test_commit_message HEAD <<-\EOF && + # This is a combination of 3 commits. + # This is the 1st commit message: + + wants-fixup + + # This is the commit message #2: + + fixup 1 + + # This is the commit message #3: + + fixup 2 + EOF (test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) && - git show HEAD >out && - test_i18ngrep ! "# This is a combination" out && + test_commit_message HEAD <<-\EOF && + wants-fixup + + fixup 1 + + fixup 2 + EOF : Final squash failed, but there was still a squash && - test_i18ngrep "# This is a combination of 2 commits" .git/copy.txt && - test_i18ngrep "# This is the commit message #2:" .git/copy.txt + head -n1 .git/copy.txt >first-line && + test_i18ngrep "# This is a combination of 3 commits" first-line && + test_i18ngrep "# This is the commit message #3:" .git/copy.txt ' test_expect_success 'setup rerere database' ' @@ -244,6 +268,24 @@ test_expect_success 'the todo command "break" works' ' test_path_is_file execed ' +test_expect_success 'patch file is removed before break command' ' + test_when_finished "git rebase --abort" && + cat >todo <<-\EOF && + pick commit-new-file-F2-on-topic-branch + break + EOF + + ( + set_replace_editor todo && + test_must_fail git rebase -i --onto commit-new-file-F2 HEAD + ) && + test_path_is_file .git/rebase-merge/patch && + echo 22>F2 && + git add F2 && + git rebase --continue && + test_path_is_missing .git/rebase-merge/patch +' + test_expect_success '--reschedule-failed-exec' ' test_when_finished "git rebase --abort" && test_must_fail git rebase -x false --reschedule-failed-exec HEAD^ && diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh index 96ae0edf1e..59b5d6b6f2 100755 --- a/t/t3430-rebase-merges.sh +++ b/t/t3430-rebase-merges.sh @@ -128,14 +128,24 @@ test_expect_success 'generate correct todo list' ' ' test_expect_success '`reset` refuses to overwrite untracked files' ' - git checkout -b refuse-to-reset && + git checkout B && test_commit dont-overwrite-untracked && - git checkout @{-1} && - : >dont-overwrite-untracked.t && - echo "reset refs/tags/dont-overwrite-untracked" >script-from-scratch && + cat >script-from-scratch <<-EOF && + exec >dont-overwrite-untracked.t + pick $(git rev-parse B) B + reset refs/tags/dont-overwrite-untracked + pick $(git rev-parse C) C + exec cat .git/rebase-merge/done >actual + EOF test_config sequence.editor \""$PWD"/replace-editor.sh\" && - test_must_fail git rebase -ir HEAD && - git rebase --abort + test_must_fail git rebase -ir A && + test_cmp_rev HEAD B && + head -n3 script-from-scratch >expect && + test_cmp expect .git/rebase-merge/done && + rm dont-overwrite-untracked.t && + git rebase --continue && + tail -n3 script-from-scratch >>expect && + test_cmp expect actual ' test_expect_success '`reset` rejects trees' ' @@ -165,12 +175,16 @@ test_expect_success 'failed `merge -C` writes patch (may be rescheduled, too)' ' test_config sequence.editor \""$PWD"/replace-editor.sh\" && test_tick && test_must_fail git rebase -ir HEAD && + test_cmp_rev REBASE_HEAD H^0 && grep "^merge -C .* G$" .git/rebase-merge/done && grep "^merge -C .* G$" .git/rebase-merge/git-rebase-todo && - test_path_is_file .git/rebase-merge/patch && + test_path_is_missing .git/rebase-merge/patch && + echo changed >file1 && + git add file1 && + test_must_fail git rebase --continue 2>err && + grep "error: you have staged changes in your working tree" err && : fail because of merge conflict && - rm G.t .git/rebase-merge/patch && git reset --hard conflicting-G && test_must_fail git rebase --continue && ! grep "^merge -C .* G$" .git/rebase-merge/git-rebase-todo && @@ -586,4 +600,15 @@ test_expect_success 'progress shows the correct total' ' test_line_count = 14 progress ' +test_expect_success 'truncate label names' ' + commit=$(git commit-tree -p HEAD^ -p HEAD -m "0123456789 我 123" HEAD^{tree}) && + git merge --ff-only $commit && + + done="$(git rev-parse --git-path rebase-merge/done)" && + git -c rebase.maxLabelLength=14 rebase --rebase-merges -x "cp \"$done\" out" --root && + grep "label 0123456789-我$" out && + git -c rebase.maxLabelLength=13 rebase --rebase-merges -x "cp \"$done\" out" --root && + grep "label 0123456789-$" out +' + test_done diff --git a/t/t3437-rebase-fixup-options.sh b/t/t3437-rebase-fixup-options.sh index dd3b301fa7..7929e2e2e3 100755 --- a/t/t3437-rebase-fixup-options.sh +++ b/t/t3437-rebase-fixup-options.sh @@ -21,21 +21,6 @@ TEST_PASSES_SANITIZE_LEAK=true EMPTY="" -# test_commit_message <rev> -m <msg> -# test_commit_message <rev> <path> -# Verify that the commit message of <rev> matches -# <msg> or the content of <path>. -test_commit_message () { - git show --no-patch --pretty=format:%B "$1" >actual && - case "$2" in - -m) - echo "$3" >expect && - test_cmp expect actual ;; - *) - test_cmp "$2" actual ;; - esac -} - get_author () { rev="$1" && git log -1 --pretty=format:"%an %ae %at" "$rev" diff --git a/t/t3500-cherry.sh b/t/t3500-cherry.sh index 0458a58b4b..78c3eac54b 100755 --- a/t/t3500-cherry.sh +++ b/t/t3500-cherry.sh @@ -16,46 +16,43 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_AUTHOR_EMAIL=bogus_email_address export GIT_AUTHOR_EMAIL -test_expect_success \ - 'prepare repository with topic branch, and check cherry finds the 2 patches from there' \ - 'echo First > A && - git update-index --add A && - test_tick && - git commit -m "Add A." && - - git checkout -b my-topic-branch && - - echo Second > B && - git update-index --add B && - test_tick && - git commit -m "Add B." && - - echo AnotherSecond > C && - git update-index --add C && - test_tick && - git commit -m "Add C." && - - git checkout -f main && - rm -f B C && - - echo Third >> A && - git update-index A && - test_tick && - git commit -m "Modify A." && - - expr "$(echo $(git cherry main my-topic-branch) )" : "+ [^ ]* + .*" +test_expect_success 'prepare repository with topic branch, and check cherry finds the 2 patches from there' ' + echo First > A && + git update-index --add A && + test_tick && + git commit -m "Add A." && + + git checkout -b my-topic-branch && + + echo Second > B && + git update-index --add B && + test_tick && + git commit -m "Add B." && + + echo AnotherSecond > C && + git update-index --add C && + test_tick && + git commit -m "Add C." && + + git checkout -f main && + rm -f B C && + + echo Third >> A && + git update-index A && + test_tick && + git commit -m "Modify A." && + + expr "$(echo $(git cherry main my-topic-branch) )" : "+ [^ ]* + .*" ' -test_expect_success \ - 'check that cherry with limit returns only the top patch'\ - 'expr "$(echo $(git cherry main my-topic-branch my-topic-branch^1) )" : "+ [^ ]*" +test_expect_success 'check that cherry with limit returns only the top patch' ' + expr "$(echo $(git cherry main my-topic-branch my-topic-branch^1) )" : "+ [^ ]*" ' -test_expect_success \ - 'cherry-pick one of the 2 patches, and check cherry recognized one and only one as new' \ - 'git cherry-pick my-topic-branch^0 && - echo $(git cherry main my-topic-branch) && - expr "$(echo $(git cherry main my-topic-branch) )" : "+ [^ ]* - .*" +test_expect_success 'cherry-pick one of the 2 patches, and check cherry recognized one and only one as new' ' + git cherry-pick my-topic-branch^0 && + echo $(git cherry main my-topic-branch) && + expr "$(echo $(git cherry main my-topic-branch) )" : "+ [^ ]* - .*" ' test_expect_success 'cherry ignores whitespace' ' diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 82dd768944..7623689da2 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -24,17 +24,17 @@ test_mode_in_index () { esac } -test_expect_success \ - 'Test of git add' \ - 'touch foo && git add foo' +test_expect_success 'Test of git add' ' + touch foo && git add foo +' -test_expect_success \ - 'Post-check that foo is in the index' \ - 'git ls-files foo | grep foo' +test_expect_success 'Post-check that foo is in the index' ' + git ls-files foo | grep foo +' -test_expect_success \ - 'Test that "git add -- -q" works' \ - 'touch -- -q && git add -- -q' +test_expect_success 'Test that "git add -- -q" works' ' + touch -- -q && git add -- -q +' BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch' @@ -284,14 +284,14 @@ test_expect_success POSIXPERM,SANITY 'git add (add.ignore-errors = false)' ' rm -f foo2 test_expect_success POSIXPERM,SANITY '--no-ignore-errors overrides config' ' - git config add.ignore-errors 1 && - git reset --hard && - date >foo1 && - date >foo2 && - chmod 0 foo2 && - test_must_fail git add --verbose --no-ignore-errors . && - ! ( git ls-files foo1 | grep foo1 ) && - git config add.ignore-errors 0 + git config add.ignore-errors 1 && + git reset --hard && + date >foo1 && + date >foo2 && + chmod 0 foo2 && + test_must_fail git add --verbose --no-ignore-errors . && + ! ( git ls-files foo1 | grep foo1 ) && + git config add.ignore-errors 0 ' rm -f foo2 diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index 3982b6b49d..34aabb7f5f 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -734,6 +734,44 @@ test_expect_success 'colors can be overridden' ' test_cmp expect actual ' +test_expect_success 'brackets appear without color' ' + git reset --hard && + test_when_finished "git rm -f bracket-test" && + test_write_lines context old more-context >bracket-test && + git add bracket-test && + test_write_lines context new more-context another-one >bracket-test && + + test_write_lines quit >input && + git add -i >actual <input && + + sed "s/^|//" >expect <<-\EOF && + | staged unstaged path + | 1: +3/-0 +2/-1 bracket-test + | + |*** Commands *** + | 1: [s]tatus 2: [u]pdate 3: [r]evert 4: [a]dd untracked + | 5: [p]atch 6: [d]iff 7: [q]uit 8: [h]elp + |What now> Bye. + EOF + + test_cmp expect actual +' + +test_expect_success 'colors can be skipped with color.ui=false' ' + git reset --hard && + test_when_finished "git rm -f color-test" && + test_write_lines context old more-context >color-test && + git add color-test && + test_write_lines context new more-context another-one >color-test && + + test_write_lines help quit >input && + force_color git \ + -c color.ui=false \ + add -i >actual.raw <input && + test_decode_color <actual.raw >actual && + test_cmp actual.raw actual +' + test_expect_success 'colorized diffs respect diff.wsErrorHighlight' ' git reset --hard && diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 376cc8f4ab..0b3dfeaea2 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -1211,19 +1211,19 @@ test_expect_success 'stash with file including $IFS character' ' ' test_expect_success 'stash with pathspec matching multiple paths' ' - echo original >file && - echo original >other-file && - git commit -m "two" file other-file && - echo modified >file && - echo modified >other-file && - git stash push -- "*file" && - echo original >expect && - test_cmp expect file && - test_cmp expect other-file && - git stash pop && - echo modified >expect && - test_cmp expect file && - test_cmp expect other-file + echo original >file && + echo original >other-file && + git commit -m "two" file other-file && + echo modified >file && + echo modified >other-file && + git stash push -- "*file" && + echo original >expect && + test_cmp expect file && + test_cmp expect other-file && + git stash pop && + echo modified >expect && + test_cmp expect file && + test_cmp expect other-file ' test_expect_success 'stash push -p with pathspec shows no changes only once' ' diff --git a/t/t4000-diff-format.sh b/t/t4000-diff-format.sh index bfcaae390f..8d50331b8c 100755 --- a/t/t4000-diff-format.sh +++ b/t/t4000-diff-format.sh @@ -5,6 +5,9 @@ test_description='Test built-in diff output engine. +We happen to know that all diff plumbing and diff Porcelain share the +same command line parser, so testing one should be sufficient; pick +diff-files as a representative. ' TEST_PASSES_SANITIZE_LEAK=true @@ -16,9 +19,11 @@ Line 2 line 3' cat path0 >path1 chmod +x path1 +mkdir path2 +>path2/path3 test_expect_success 'update-index --add two files with and without +x.' ' - git update-index --add path0 path1 + git update-index --add path0 path1 path2/path3 ' mv path0 path0- @@ -91,4 +96,31 @@ test_expect_success 'git diff-files --patch --no-patch does not show the patch' test_must_be_empty err ' + +# Smudge path2/path3 so that dirstat has something to show +date >path2/path3 + +for format in stat raw numstat shortstat summary \ + dirstat cumulative dirstat-by-file \ + patch-with-raw patch-with-stat compact-summary +do + test_expect_success "--no-patch in 'git diff-files --no-patch --$format' is a no-op" ' + git diff-files --no-patch "--$format" >actual && + git diff-files "--$format" >expect && + test_cmp expect actual + ' + + test_expect_success "--no-patch clears all previous ones" ' + git diff-files --$format -s -p >actual && + git diff-files -p >expect && + test_cmp expect actual + ' + + test_expect_success "--no-patch in 'git diff --no-patch --$format' is a no-op" ' + git diff --no-patch "--$format" >actual && + git diff "--$format" >expect && + test_cmp expect actual + ' +done + test_done diff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh index ea52e5b91b..7afc883ec3 100755 --- a/t/t4002-diff-basic.sh +++ b/t/t4002-diff-basic.sh @@ -284,132 +284,131 @@ cmp_diff_files_output () { test_cmp "$1" .test-tmp } -test_expect_success \ - 'diff-tree of known trees.' \ - 'git diff-tree $tree_O $tree_A >.test-a && - cmp -s .test-a .test-plain-OA' - -test_expect_success \ - 'diff-tree of known trees.' \ - 'git diff-tree -r $tree_O $tree_A >.test-a && - cmp -s .test-a .test-recursive-OA' - -test_expect_success \ - 'diff-tree of known trees.' \ - 'git diff-tree $tree_O $tree_B >.test-a && - cmp -s .test-a .test-plain-OB' - -test_expect_success \ - 'diff-tree of known trees.' \ - 'git diff-tree -r $tree_O $tree_B >.test-a && - cmp -s .test-a .test-recursive-OB' - -test_expect_success \ - 'diff-tree of known trees.' \ - 'git diff-tree $tree_A $tree_B >.test-a && - cmp -s .test-a .test-plain-AB' - -test_expect_success \ - 'diff-tree of known trees.' \ - 'git diff-tree -r $tree_A $tree_B >.test-a && - cmp -s .test-a .test-recursive-AB' - -test_expect_success \ - 'diff-tree --stdin of known trees.' \ - 'echo $tree_A $tree_B | git diff-tree --stdin > .test-a && - echo $tree_A $tree_B > .test-plain-ABx && - cat .test-plain-AB >> .test-plain-ABx && - cmp -s .test-a .test-plain-ABx' - -test_expect_success \ - 'diff-tree --stdin of known trees.' \ - 'echo $tree_A $tree_B | git diff-tree -r --stdin > .test-a && - echo $tree_A $tree_B > .test-recursive-ABx && - cat .test-recursive-AB >> .test-recursive-ABx && - cmp -s .test-a .test-recursive-ABx' - -test_expect_success \ - 'diff-cache O with A in cache' \ - 'git read-tree $tree_A && - git diff-index --cached $tree_O >.test-a && - cmp -s .test-a .test-recursive-OA' - -test_expect_success \ - 'diff-cache O with B in cache' \ - 'git read-tree $tree_B && - git diff-index --cached $tree_O >.test-a && - cmp -s .test-a .test-recursive-OB' - -test_expect_success \ - 'diff-cache A with B in cache' \ - 'git read-tree $tree_B && - git diff-index --cached $tree_A >.test-a && - cmp -s .test-a .test-recursive-AB' - -test_expect_success \ - 'diff-files with O in cache and A checked out' \ - 'rm -fr Z [A-Z][A-Z] && - git read-tree $tree_A && - git checkout-index -f -a && - git read-tree --reset $tree_O && - test_must_fail git update-index --refresh -q && - git diff-files >.test-a && - cmp_diff_files_output .test-a .test-recursive-OA' - -test_expect_success \ - 'diff-files with O in cache and B checked out' \ - 'rm -fr Z [A-Z][A-Z] && - git read-tree $tree_B && - git checkout-index -f -a && - git read-tree --reset $tree_O && - test_must_fail git update-index --refresh -q && - git diff-files >.test-a && - cmp_diff_files_output .test-a .test-recursive-OB' - -test_expect_success \ - 'diff-files with A in cache and B checked out' \ - 'rm -fr Z [A-Z][A-Z] && - git read-tree $tree_B && - git checkout-index -f -a && - git read-tree --reset $tree_A && - test_must_fail git update-index --refresh -q && - git diff-files >.test-a && - cmp_diff_files_output .test-a .test-recursive-AB' +test_expect_success 'diff-tree of known trees.' ' + git diff-tree $tree_O $tree_A >.test-a && + cmp -s .test-a .test-plain-OA +' + +test_expect_success 'diff-tree of known trees.' ' + git diff-tree -r $tree_O $tree_A >.test-a && + cmp -s .test-a .test-recursive-OA +' + +test_expect_success 'diff-tree of known trees.' ' + git diff-tree $tree_O $tree_B >.test-a && + cmp -s .test-a .test-plain-OB +' + +test_expect_success 'diff-tree of known trees.' ' + git diff-tree -r $tree_O $tree_B >.test-a && + cmp -s .test-a .test-recursive-OB +' + +test_expect_success 'diff-tree of known trees.' ' + git diff-tree $tree_A $tree_B >.test-a && + cmp -s .test-a .test-plain-AB +' + +test_expect_success 'diff-tree of known trees.' ' + git diff-tree -r $tree_A $tree_B >.test-a && + cmp -s .test-a .test-recursive-AB +' + +test_expect_success 'diff-tree --stdin of known trees.' ' + echo $tree_A $tree_B | git diff-tree --stdin > .test-a && + echo $tree_A $tree_B > .test-plain-ABx && + cat .test-plain-AB >> .test-plain-ABx && + cmp -s .test-a .test-plain-ABx +' + +test_expect_success 'diff-tree --stdin of known trees.' ' + echo $tree_A $tree_B | git diff-tree -r --stdin > .test-a && + echo $tree_A $tree_B > .test-recursive-ABx && + cat .test-recursive-AB >> .test-recursive-ABx && + cmp -s .test-a .test-recursive-ABx +' + +test_expect_success 'diff-cache O with A in cache' ' + git read-tree $tree_A && + git diff-index --cached $tree_O >.test-a && + cmp -s .test-a .test-recursive-OA +' + +test_expect_success 'diff-cache O with B in cache' ' + git read-tree $tree_B && + git diff-index --cached $tree_O >.test-a && + cmp -s .test-a .test-recursive-OB +' + +test_expect_success 'diff-cache A with B in cache' ' + git read-tree $tree_B && + git diff-index --cached $tree_A >.test-a && + cmp -s .test-a .test-recursive-AB +' + +test_expect_success 'diff-files with O in cache and A checked out' ' + rm -fr Z [A-Z][A-Z] && + git read-tree $tree_A && + git checkout-index -f -a && + git read-tree --reset $tree_O && + test_must_fail git update-index --refresh -q && + git diff-files >.test-a && + cmp_diff_files_output .test-a .test-recursive-OA +' + +test_expect_success 'diff-files with O in cache and B checked out' ' + rm -fr Z [A-Z][A-Z] && + git read-tree $tree_B && + git checkout-index -f -a && + git read-tree --reset $tree_O && + test_must_fail git update-index --refresh -q && + git diff-files >.test-a && + cmp_diff_files_output .test-a .test-recursive-OB +' + +test_expect_success 'diff-files with A in cache and B checked out' ' + rm -fr Z [A-Z][A-Z] && + git read-tree $tree_B && + git checkout-index -f -a && + git read-tree --reset $tree_A && + test_must_fail git update-index --refresh -q && + git diff-files >.test-a && + cmp_diff_files_output .test-a .test-recursive-AB +' ################################################################ # Now we have established the baseline, we do not have to # rely on individual object ID values that much. -test_expect_success \ - 'diff-tree O A == diff-tree -R A O' \ - 'git diff-tree $tree_O $tree_A >.test-a && - git diff-tree -R $tree_A $tree_O >.test-b && - cmp -s .test-a .test-b' - -test_expect_success \ - 'diff-tree -r O A == diff-tree -r -R A O' \ - 'git diff-tree -r $tree_O $tree_A >.test-a && - git diff-tree -r -R $tree_A $tree_O >.test-b && - cmp -s .test-a .test-b' - -test_expect_success \ - 'diff-tree B A == diff-tree -R A B' \ - 'git diff-tree $tree_B $tree_A >.test-a && - git diff-tree -R $tree_A $tree_B >.test-b && - cmp -s .test-a .test-b' - -test_expect_success \ - 'diff-tree -r B A == diff-tree -r -R A B' \ - 'git diff-tree -r $tree_B $tree_A >.test-a && - git diff-tree -r -R $tree_A $tree_B >.test-b && - cmp -s .test-a .test-b' - -test_expect_success \ - 'diff can read from stdin' \ - 'test_must_fail git diff --no-index -- MN - < NN | - grep -v "^index" | sed "s#/-#/NN#" >.test-a && - test_must_fail git diff --no-index -- MN NN | - grep -v "^index" >.test-b && - test_cmp .test-a .test-b' +test_expect_success 'diff-tree O A == diff-tree -R A O' ' + git diff-tree $tree_O $tree_A >.test-a && + git diff-tree -R $tree_A $tree_O >.test-b && + cmp -s .test-a .test-b +' + +test_expect_success 'diff-tree -r O A == diff-tree -r -R A O' ' + git diff-tree -r $tree_O $tree_A >.test-a && + git diff-tree -r -R $tree_A $tree_O >.test-b && + cmp -s .test-a .test-b +' + +test_expect_success 'diff-tree B A == diff-tree -R A B' ' + git diff-tree $tree_B $tree_A >.test-a && + git diff-tree -R $tree_A $tree_B >.test-b && + cmp -s .test-a .test-b +' + +test_expect_success 'diff-tree -r B A == diff-tree -r -R A B' ' + git diff-tree -r $tree_B $tree_A >.test-a && + git diff-tree -r -R $tree_A $tree_B >.test-b && + cmp -s .test-a .test-b' + +test_expect_success 'diff can read from stdin' ' + test_must_fail git diff --no-index -- MN - < NN | + grep -v "^index" | sed "s#/-#/NN#" >.test-a && + test_must_fail git diff --no-index -- MN NN | + grep -v "^index" >.test-b && + test_cmp .test-a .test-b +' test_done diff --git a/t/t4003-diff-rename-1.sh b/t/t4003-diff-rename-1.sh index 181e9683a7..ebe091828c 100755 --- a/t/t4003-diff-rename-1.sh +++ b/t/t4003-diff-rename-1.sh @@ -11,20 +11,20 @@ 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' \ - 'COPYING_test_data >COPYING && - echo frotz >rezrov && - git update-index --add COPYING rezrov && - tree=$(git write-tree) && - echo $tree' - -test_expect_success \ - 'prepare work tree' \ - 'sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 && - sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 && - rm -f COPYING && - git update-index --add --remove COPYING COPYING.?' +test_expect_success 'prepare reference tree' ' + COPYING_test_data >COPYING && + echo frotz >rezrov && + git update-index --add COPYING rezrov && + tree=$(git write-tree) && + echo $tree +' + +test_expect_success 'prepare work tree' ' + sed -e 's/HOWEVER/However/' <COPYING >COPYING.1 && + sed -e 's/GPL/G.P.L/g' <COPYING >COPYING.2 && + rm -f COPYING && + git update-index --add --remove COPYING COPYING.? +' # tree has COPYING and rezrov. work tree has COPYING.1 and COPYING.2, # both are slightly edited, and unchanged rezrov. So we say you @@ -57,14 +57,14 @@ rename to COPYING.2 + This file is licensed under the G.P.L v2, or a later version EOF -test_expect_success \ - 'validate output from rename/copy detection (#1)' \ - 'compare_diff_patch current expected' +test_expect_success 'validate output from rename/copy detection (#1)' ' + compare_diff_patch current expected +' -test_expect_success \ - 'prepare work tree again' \ - 'mv COPYING.2 COPYING && - git update-index --add --remove COPYING COPYING.1 COPYING.2' +test_expect_success 'prepare work tree again' ' + mv COPYING.2 COPYING && + git update-index --add --remove COPYING COPYING.1 COPYING.2 +' # tree has COPYING and rezrov. work tree has COPYING and COPYING.1, # both are slightly edited, and unchanged rezrov. So we say you @@ -95,14 +95,14 @@ copy to COPYING.1 + However, in order to allow a migration to GPLv3 if that seems like EOF -test_expect_success \ - 'validate output from rename/copy detection (#2)' \ - 'compare_diff_patch current expected' +test_expect_success 'validate output from rename/copy detection (#2)' ' + compare_diff_patch current expected +' -test_expect_success \ - 'prepare work tree once again' \ - 'COPYING_test_data >COPYING && - git update-index --add --remove COPYING COPYING.1' +test_expect_success 'prepare work tree once again' ' + COPYING_test_data >COPYING && + git update-index --add --remove COPYING COPYING.1 +' # tree has COPYING and rezrov. work tree has COPYING and COPYING.1, # but COPYING is not edited. We say you copy-and-edit COPYING.1; this @@ -123,8 +123,8 @@ copy to COPYING.1 + However, in order to allow a migration to GPLv3 if that seems like EOF -test_expect_success \ - 'validate output from rename/copy detection (#3)' \ - 'compare_diff_patch current expected' +test_expect_success 'validate output from rename/copy detection (#3)' ' + compare_diff_patch current expected +' test_done diff --git a/t/t4004-diff-rename-symlink.sh b/t/t4004-diff-rename-symlink.sh index 8def4d4aee..1d70d4d221 100755 --- a/t/t4004-diff-rename-symlink.sh +++ b/t/t4004-diff-rename-symlink.sh @@ -14,21 +14,21 @@ TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh -test_expect_success SYMLINKS \ - 'prepare reference tree' \ - 'echo xyzzy | tr -d '\\\\'012 >yomin && - ln -s xyzzy frotz && - git update-index --add frotz yomin && - tree=$(git write-tree) && - echo $tree' +test_expect_success SYMLINKS 'prepare reference tree' ' + echo xyzzy | tr -d '\\\\'012 >yomin && + ln -s xyzzy frotz && + git update-index --add frotz yomin && + tree=$(git write-tree) && + echo $tree +' -test_expect_success SYMLINKS \ - 'prepare work tree' \ - 'mv frotz rezrov && - rm -f yomin && - ln -s xyzzy nitfol && - ln -s xzzzy bozbar && - git update-index --add --remove frotz rezrov nitfol bozbar yomin' +test_expect_success SYMLINKS 'prepare work tree' ' + mv frotz rezrov && + rm -f yomin && + ln -s xyzzy nitfol && + ln -s xzzzy bozbar && + git update-index --add --remove frotz rezrov nitfol bozbar yomin +' # tree has frotz pointing at xyzzy, and yomin that contains xyzzy to # confuse things. work tree has rezrov (xyzzy) nitfol (xyzzy) and @@ -36,9 +36,9 @@ test_expect_success SYMLINKS \ # rezrov and nitfol are rename/copy of frotz and bozbar should be # a new creation. -test_expect_success SYMLINKS 'setup diff output' " - GIT_DIFF_OPTS=--unified=0 git diff-index -C -p $tree >current && - cat >expected <<\EOF +test_expect_success SYMLINKS 'setup diff output' ' + GIT_DIFF_OPTS=--unified=0 git diff-index -C -p $tree >current && + cat >expected <<\EOF diff --git a/bozbar b/bozbar new file mode 120000 --- /dev/null @@ -62,10 +62,10 @@ deleted file mode 100644 -xyzzy \ No newline at end of file EOF -" +' -test_expect_success SYMLINKS \ - 'validate diff output' \ - 'compare_diff_patch current expected' +test_expect_success SYMLINKS 'validate diff output' ' + compare_diff_patch current expected +' test_done diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index b298f220e0..fcd2473e52 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -1,7 +1,7 @@ #!/bin/sh # # Copyright (c) 2006 Johannes E. Schindelin -# +# Copyright (c) 2023 Google LLC test_description='Test special whitespace in diff engine. @@ -11,6 +11,43 @@ TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh +for opt_res in --patch --quiet -s --stat --shortstat --dirstat=lines \ + --raw! --name-only! --name-status! +do + opts=${opt_res%!} expect_failure= + test "$opts" = "$opt_res" || + expect_failure="test_expect_code 1" + + test_expect_success "status with $opts (different)" ' + echo foo >x && + git add x && + echo bar >x && + test_expect_code 1 git diff -w $opts --exit-code x + ' + + test_expect_success POSIXPERM "status with $opts (mode differs)" ' + test_when_finished "git update-index --chmod=-x x" && + echo foo >x && + git add x && + git update-index --chmod=+x x && + test_expect_code 1 git diff -w $opts --exit-code x + ' + + test_expect_success "status with $opts (removing an empty file)" ' + : >x && + git add x && + rm x && + test_expect_code 1 git diff -w $opts --exit-code -- x + ' + + test_expect_success "status with $opts (different but equivalent)" ' + echo foo >x && + git add x && + echo " foo" >x && + $expect_failure git diff -w $opts --exit-code x + ' +done + test_expect_success "Ray Lehtiniemi's example" ' cat <<-\EOF >x && do { diff --git a/t/t4017-diff-retval.sh b/t/t4017-diff-retval.sh index 5bc28ad9f0..f439f469bd 100755 --- a/t/t4017-diff-retval.sh +++ b/t/t4017-diff-retval.sh @@ -138,4 +138,9 @@ test_expect_success 'check honors conflict marker length' ' git reset --hard ' +test_expect_success 'option errors are not confused by --exit-code' ' + test_must_fail git diff --exit-code --nonsense 2>err && + grep '^usage:' err +' + test_done diff --git a/t/t4040-whitespace-status.sh b/t/t4040-whitespace-status.sh index e70e020ae9..eec3d73dc2 100755 --- a/t/t4040-whitespace-status.sh +++ b/t/t4040-whitespace-status.sh @@ -28,8 +28,7 @@ test_expect_success 'diff-tree --exit-code' ' test_expect_success 'diff-tree -b --exit-code' ' git diff -b --exit-code HEAD^ HEAD && - git diff-tree -b -p --exit-code HEAD^ HEAD && - git diff-tree -b --exit-code HEAD^ HEAD + git diff-tree -b -p --exit-code HEAD^ HEAD ' test_expect_success 'diff-index --cached --exit-code' ' diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 4e9fa0403d..5f059f65fc 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -205,4 +205,83 @@ test_expect_success POSIXPERM,SYMLINKS 'diff --no-index normalizes: mode not lik test_cmp expected actual ' +test_expect_success "diff --no-index treats '-' as stdin" ' + cat >expect <<-EOF && + diff --git a/- b/a/1 + index $ZERO_OID..$(git hash-object --stdin <a/1) 100644 + --- a/- + +++ b/a/1 + @@ -1 +1 @@ + -x + +1 + EOF + + test_write_lines x | test_expect_code 1 \ + git -c core.abbrev=no diff --no-index -- - a/1 >actual && + test_cmp expect actual && + + test_write_lines 1 | git diff --no-index -- a/1 - >actual && + test_must_be_empty actual +' + +test_expect_success "diff --no-index -R treats '-' as stdin" ' + cat >expect <<-EOF && + diff --git b/a/1 a/- + index $(git hash-object --stdin <a/1)..$ZERO_OID 100644 + --- b/a/1 + +++ a/- + @@ -1 +1 @@ + -1 + +x + EOF + + test_write_lines x | test_expect_code 1 \ + git -c core.abbrev=no diff --no-index -R -- - a/1 >actual && + test_cmp expect actual && + + test_write_lines 1 | git diff --no-index -R -- a/1 - >actual && + test_must_be_empty actual +' + +test_expect_success 'diff --no-index refuses to diff stdin and a directory' ' + test_must_fail git diff --no-index -- - a </dev/null 2>err && + grep "fatal: cannot compare stdin to a directory" err +' + +test_expect_success PIPE 'diff --no-index refuses to diff a named pipe and a directory' ' + test_when_finished "rm -f pipe" && + mkfifo pipe && + test_must_fail git diff --no-index -- pipe a 2>err && + grep "fatal: cannot compare a named pipe to a directory" err +' + +test_expect_success PIPE,SYMLINKS 'diff --no-index reads from pipes' ' + test_when_finished "rm -f old new new-link" && + mkfifo old && + mkfifo new && + ln -s new new-link && + { + (test_write_lines a b c >old) & + } && + test_when_finished "kill $! || :" && + { + (test_write_lines a x c >new) & + } && + test_when_finished "kill $! || :" && + + cat >expect <<-EOF && + diff --git a/old b/new-link + --- a/old + +++ b/new-link + @@ -1,3 +1,3 @@ + a + -b + +x + c + EOF + + test_expect_code 1 git diff --no-index old new-link >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4141-apply-too-large.sh b/t/t4141-apply-too-large.sh index 58742d4fc5..20cc1209f6 100755 --- a/t/t4141-apply-too-large.sh +++ b/t/t4141-apply-too-large.sh @@ -17,7 +17,7 @@ test_expect_success EXPENSIVE 'git apply rejects patches that are too large' ' EOF test-tool genzeros } | test_copy_bytes $sz | test_must_fail git apply 2>err && - grep "git apply: failed to read" err + grep "patch too large" err ' test_done diff --git a/t/t4202-log.sh b/t/t4202-log.sh index ae73aef922..af4a123cd2 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -187,6 +187,21 @@ test_expect_success 'git config log.follow does not die with no paths' ' git log -- ' +test_expect_success 'git log --follow rejects unsupported pathspec magic' ' + test_must_fail git log --follow ":(top,glob,icase)ichi" 2>stderr && + # check full error message; we want to be sure we mention both + # of the rejected types (glob,icase), but not the allowed one (top) + echo "fatal: pathspec magic not supported by --follow: ${SQ}glob${SQ}, ${SQ}icase${SQ}" >expect && + test_cmp expect stderr +' + +test_expect_success 'log.follow disabled with unsupported pathspec magic' ' + test_config log.follow true && + git log --format=%s ":(glob,icase)ichi" >actual && + echo third >expect && + test_cmp expect actual +' + test_expect_success 'git config log.follow is overridden by --no-follow' ' test_config log.follow true && git log --no-follow --pretty="format:%s" ichi >actual && @@ -2343,10 +2358,10 @@ test_expect_success 'log --decorate does not include things outside filter' ' ' test_expect_success 'log --end-of-options' ' - git update-ref refs/heads/--source HEAD && - git log --end-of-options --source >actual && - git log >expect && - test_cmp expect actual + git update-ref refs/heads/--source HEAD && + git log --end-of-options --source >actual && + git log >expect && + test_cmp expect actual ' test_expect_success 'set up commits with different authors' ' diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh index fa7f987284..2016132f51 100755 --- a/t/t4203-mailmap.sh +++ b/t/t4203-mailmap.sh @@ -466,7 +466,7 @@ test_expect_success 'gitmailmap(5) example output: example #1' ' Author Jane Doe <jane@laptop.(none)> maps to Jane Doe <jane@laptop.(none)> Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com> - Author Jane D <jane@desktop.(none)> maps to Jane Doe <jane@desktop.(none)> + Author Jane D. <jane@desktop.(none)> maps to Jane Doe <jane@desktop.(none)> Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com> EOF git -C doc log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual && @@ -494,7 +494,7 @@ test_expect_success 'gitmailmap(5) example output: example #2' ' Author Jane Doe <jane@laptop.(none)> maps to Jane Doe <jane@example.com> Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com> - Author Jane D <jane@desktop.(none)> maps to Jane Doe <jane@example.com> + Author Jane D. <jane@desktop.(none)> maps to Jane Doe <jane@example.com> Committer C O Mitter <committer@example.com> maps to C O Mitter <committer@example.com> EOF git -C doc log --reverse --pretty=format:"Author %an <%ae> maps to %aN <%aE>%nCommitter %cn <%ce> maps to %cN <%cE>%n" >actual && diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index 4cf8a77667..dd9035aa38 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -1012,10 +1012,25 @@ test_expect_success '%(describe:tags) vs git describe --tags' ' test_expect_success '%(describe:abbrev=...) vs git describe --abbrev=...' ' test_when_finished "git tag -d tagname" && + + # Case 1: We have commits between HEAD and the most recent tag + # reachable from it + test_commit --no-tag file && + git describe --abbrev=15 >expect && + git log -1 --format="%(describe:abbrev=15)" >actual && + test_cmp expect actual && + + # Make sure the hash used is at least 15 digits long + sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" <actual >hexpart && + test 16 -le $(wc -c <hexpart) && + + # Case 2: We have a tag at HEAD, describe directly gives the + # name of the tag git tag -a -m tagged tagname && git describe --abbrev=15 >expect && git log -1 --format="%(describe:abbrev=15)" >actual && - test_cmp expect actual + test_cmp expect actual && + test tagname = $(cat actual) ' test_expect_success 'log --pretty with space stealing' ' diff --git a/t/t4206-log-follow-harder-copies.sh b/t/t4206-log-follow-harder-copies.sh index 33ecf82c7f..9167b0351f 100755 --- a/t/t4206-log-follow-harder-copies.sh +++ b/t/t4206-log-follow-harder-copies.sh @@ -16,29 +16,29 @@ Line 2 Line 3 ' -test_expect_success \ - 'add a file path0 and commit.' \ - 'git add path0 && - git commit -m "Add path0"' +test_expect_success 'add a file path0 and commit.' ' + git add path0 && + git commit -m "Add path0" +' echo >path0 'New line 1 New line 2 New line 3 ' -test_expect_success \ - 'Change path0.' \ - 'git add path0 && - git commit -m "Change path0"' +test_expect_success 'Change path0.' ' + git add path0 && + git commit -m "Change path0" +' cat <path0 >path1 -test_expect_success \ - 'copy path0 to path1.' \ - 'git add path1 && - git commit -m "Copy path1 from path0"' +test_expect_success 'copy path0 to path1.' ' + git add path1 && + git commit -m "Copy path1 from path0" +' -test_expect_success \ - 'find the copy path0 -> path1 harder' \ - 'git log --follow --name-status --pretty="format:%s" path1 > current' +test_expect_success 'find the copy path0 -> path1 harder' ' + git log --follow --name-status --pretty="format:%s" path1 > current +' cat >expected <<\EOF Copy path1 from path0 @@ -51,8 +51,8 @@ Add path0 A path0 EOF -test_expect_success \ - 'validate the output.' \ - 'compare_diff_patch current expected' +test_expect_success 'validate the output.' ' + compare_diff_patch current expected +' test_done diff --git a/t/t4217-log-limit.sh b/t/t4217-log-limit.sh index 6e01e2629c..613f0710e9 100755 --- a/t/t4217-log-limit.sh +++ b/t/t4217-log-limit.sh @@ -2,6 +2,7 @@ test_description='git log with filter options limiting the output' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup test' ' diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index d2ce236d61..745089479c 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -208,7 +208,7 @@ test_expect_success 'unpack with OFS_DELTA' ' ' test_expect_success 'unpack with OFS_DELTA (core.fsyncmethod=batch)' ' - check_unpack test-3-${packname_3} obj-list "$BATCH_CONFIGURATION" + check_unpack test-3-${packname_3} obj-list "$BATCH_CONFIGURATION" ' test_expect_success 'compare delta flavors' ' @@ -263,97 +263,97 @@ test_expect_success 'survive missing objects/pack directory' ' ) ' -test_expect_success \ - 'verify pack' \ - 'git verify-pack test-1-${packname_1}.idx \ - test-2-${packname_2}.idx \ - test-3-${packname_3}.idx' - -test_expect_success \ - 'verify pack -v' \ - 'git verify-pack -v test-1-${packname_1}.idx \ - test-2-${packname_2}.idx \ - test-3-${packname_3}.idx' - -test_expect_success \ - 'verify-pack catches mismatched .idx and .pack files' \ - 'cat test-1-${packname_1}.idx >test-3.idx && - cat test-2-${packname_2}.pack >test-3.pack && - if git verify-pack test-3.idx - then false - else :; - fi' - -test_expect_success \ - 'verify-pack catches a corrupted pack signature' \ - 'cat test-1-${packname_1}.pack >test-3.pack && - echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=2 && - if git verify-pack test-3.idx - then false - else :; - fi' - -test_expect_success \ - 'verify-pack catches a corrupted pack version' \ - 'cat test-1-${packname_1}.pack >test-3.pack && - echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=7 && - if git verify-pack test-3.idx - then false - else :; - fi' - -test_expect_success \ - 'verify-pack catches a corrupted type/size of the 1st packed object data' \ - 'cat test-1-${packname_1}.pack >test-3.pack && - echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=12 && - if git verify-pack test-3.idx - then false - else :; - fi' - -test_expect_success \ - 'verify-pack catches a corrupted sum of the index file itself' \ - 'l=$(wc -c <test-3.idx) && - l=$(expr $l - 20) && - cat test-1-${packname_1}.pack >test-3.pack && - printf "%20s" "" | dd of=test-3.idx count=20 bs=1 conv=notrunc seek=$l && - if git verify-pack test-3.pack - then false - else :; - fi' - -test_expect_success \ - 'build pack index for an existing pack' \ - 'cat test-1-${packname_1}.pack >test-3.pack && - git index-pack -o tmp.idx test-3.pack && - cmp tmp.idx test-1-${packname_1}.idx && - - git index-pack --promisor=message test-3.pack && - cmp test-3.idx test-1-${packname_1}.idx && - echo message >expect && - test_cmp expect test-3.promisor && - - cat test-2-${packname_2}.pack >test-3.pack && - git index-pack -o tmp.idx test-2-${packname_2}.pack && - cmp tmp.idx test-2-${packname_2}.idx && - - git index-pack test-3.pack && - cmp test-3.idx test-2-${packname_2}.idx && - - cat test-3-${packname_3}.pack >test-3.pack && - git index-pack -o tmp.idx test-3-${packname_3}.pack && - cmp tmp.idx test-3-${packname_3}.idx && - - git index-pack test-3.pack && - cmp test-3.idx test-3-${packname_3}.idx && - - cat test-1-${packname_1}.pack >test-4.pack && - rm -f test-4.keep && - git index-pack --keep=why test-4.pack && - cmp test-1-${packname_1}.idx test-4.idx && - test -f test-4.keep && - - :' +test_expect_success 'verify pack' ' + git verify-pack test-1-${packname_1}.idx \ + test-2-${packname_2}.idx \ + test-3-${packname_3}.idx +' + +test_expect_success 'verify pack -v' ' + git verify-pack -v test-1-${packname_1}.idx \ + test-2-${packname_2}.idx \ + test-3-${packname_3}.idx +' + +test_expect_success 'verify-pack catches mismatched .idx and .pack files' ' + cat test-1-${packname_1}.idx >test-3.idx && + cat test-2-${packname_2}.pack >test-3.pack && + if git verify-pack test-3.idx + then false + else :; + fi +' + +test_expect_success 'verify-pack catches a corrupted pack signature' ' + cat test-1-${packname_1}.pack >test-3.pack && + echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=2 && + if git verify-pack test-3.idx + then false + else :; + fi +' + +test_expect_success 'verify-pack catches a corrupted pack version' ' + cat test-1-${packname_1}.pack >test-3.pack && + echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=7 && + if git verify-pack test-3.idx + then false + else :; + fi +' + +test_expect_success 'verify-pack catches a corrupted type/size of the 1st packed object data' ' + cat test-1-${packname_1}.pack >test-3.pack && + echo | dd of=test-3.pack count=1 bs=1 conv=notrunc seek=12 && + if git verify-pack test-3.idx + then false + else :; + fi +' + +test_expect_success 'verify-pack catches a corrupted sum of the index file itself' ' + l=$(wc -c <test-3.idx) && + l=$(expr $l - 20) && + cat test-1-${packname_1}.pack >test-3.pack && + printf "%20s" "" | dd of=test-3.idx count=20 bs=1 conv=notrunc seek=$l && + if git verify-pack test-3.pack + then false + else :; + fi +' + +test_expect_success 'build pack index for an existing pack' ' + cat test-1-${packname_1}.pack >test-3.pack && + git index-pack -o tmp.idx test-3.pack && + cmp tmp.idx test-1-${packname_1}.idx && + + git index-pack --promisor=message test-3.pack && + cmp test-3.idx test-1-${packname_1}.idx && + echo message >expect && + test_cmp expect test-3.promisor && + + cat test-2-${packname_2}.pack >test-3.pack && + git index-pack -o tmp.idx test-2-${packname_2}.pack && + cmp tmp.idx test-2-${packname_2}.idx && + + git index-pack test-3.pack && + cmp test-3.idx test-2-${packname_2}.idx && + + cat test-3-${packname_3}.pack >test-3.pack && + git index-pack -o tmp.idx test-3-${packname_3}.pack && + cmp tmp.idx test-3-${packname_3}.idx && + + git index-pack test-3.pack && + cmp test-3.idx test-3-${packname_3}.idx && + + cat test-1-${packname_1}.pack >test-4.pack && + rm -f test-4.keep && + git index-pack --keep=why test-4.pack && + cmp test-1-${packname_1}.idx test-4.idx && + test -f test-4.keep && + + : +' test_expect_success 'unpacking with --strict' ' diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 3ccaaeb397..226490d60d 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -8,55 +8,55 @@ test_description='mmap sliding window tests' TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh -test_expect_success \ - 'setup' \ - 'rm -f .git/index* && - for i in a b c - do - echo $i >$i && - test-tool genrandom "$i" 32768 >>$i && - git update-index --add $i || return 1 - done && - echo d >d && cat c >>d && git update-index --add d && - tree=$(git write-tree) && - commit1=$(git commit-tree $tree </dev/null) && - git update-ref HEAD $commit1 && - git repack -a -d && - test "$(git count-objects)" = "0 objects, 0 kilobytes" && - pack1=$(ls .git/objects/pack/*.pack) && - test -f "$pack1"' - -test_expect_success \ - 'verify-pack -v, defaults' \ - 'git verify-pack -v "$pack1"' - -test_expect_success \ - 'verify-pack -v, packedGitWindowSize == 1 page' \ - 'git config core.packedGitWindowSize 512 && - git verify-pack -v "$pack1"' - -test_expect_success \ - 'verify-pack -v, packedGit{WindowSize,Limit} == 1 page' \ - 'git config core.packedGitWindowSize 512 && - git config core.packedGitLimit 512 && - git verify-pack -v "$pack1"' - -test_expect_success \ - 'repack -a -d, packedGit{WindowSize,Limit} == 1 page' \ - 'git config core.packedGitWindowSize 512 && - git config core.packedGitLimit 512 && - commit2=$(git commit-tree $tree -p $commit1 </dev/null) && - git update-ref HEAD $commit2 && - git repack -a -d && - test "$(git count-objects)" = "0 objects, 0 kilobytes" && - pack2=$(ls .git/objects/pack/*.pack) && - test -f "$pack2" && - test "$pack1" \!= "$pack2"' - -test_expect_success \ - 'verify-pack -v, defaults' \ - 'git config --unset core.packedGitWindowSize && - git config --unset core.packedGitLimit && - git verify-pack -v "$pack2"' +test_expect_success 'setup' ' + rm -f .git/index* && + for i in a b c + do + echo $i >$i && + test-tool genrandom "$i" 32768 >>$i && + git update-index --add $i || return 1 + done && + echo d >d && cat c >>d && git update-index --add d && + tree=$(git write-tree) && + commit1=$(git commit-tree $tree </dev/null) && + git update-ref HEAD $commit1 && + git repack -a -d && + test "$(git count-objects)" = "0 objects, 0 kilobytes" && + pack1=$(ls .git/objects/pack/*.pack) && + test -f "$pack1" +' + +test_expect_success 'verify-pack -v, defaults' ' + git verify-pack -v "$pack1" +' + +test_expect_success 'verify-pack -v, packedGitWindowSize == 1 page' ' + git config core.packedGitWindowSize 512 && + git verify-pack -v "$pack1" +' + +test_expect_success 'verify-pack -v, packedGit{WindowSize,Limit} == 1 page' ' + git config core.packedGitWindowSize 512 && + git config core.packedGitLimit 512 && + git verify-pack -v "$pack1" +' + +test_expect_success 'repack -a -d, packedGit{WindowSize,Limit} == 1 page' ' + git config core.packedGitWindowSize 512 && + git config core.packedGitLimit 512 && + commit2=$(git commit-tree $tree -p $commit1 </dev/null) && + git update-ref HEAD $commit2 && + git repack -a -d && + test "$(git count-objects)" = "0 objects, 0 kilobytes" && + pack2=$(ls .git/objects/pack/*.pack) && + test -f "$pack2" && + test "$pack1" \!= "$pack2" +' + +test_expect_success 'verify-pack -v, defaults' ' + git config --unset core.packedGitWindowSize && + git config --unset core.packedGitLimit && + git verify-pack -v "$pack2" +' test_done diff --git a/t/t5303-pack-corruption-resilience.sh b/t/t5303-pack-corruption-resilience.sh index 2926e8dfc4..61469ef4a6 100755 --- a/t/t5303-pack-corruption-resilience.sh +++ b/t/t5303-pack-corruption-resilience.sh @@ -59,304 +59,304 @@ do_corrupt_object() { printf '\0' > zero -test_expect_success \ - 'initial setup validation' \ - 'create_test_files && - create_new_pack && - git prune-packed && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'create corruption in header of first object' \ - 'do_corrupt_object $blob_1 0 < zero && - test_must_fail git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_1 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and loose copy of first delta allows for partial recovery' \ - 'git prune-packed && - test_must_fail git cat-file blob $blob_2 > /dev/null && - mv ${pack}.idx tmp && - git hash-object -t blob -w file_2 && - mv tmp ${pack}.idx && - test_must_fail git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'create corruption in data of first object' \ - 'create_new_pack && - git prune-packed && - chmod +w ${pack}.pack && - perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack && - test_must_fail git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_1 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and loose copy of second object allows for partial recovery' \ - 'git prune-packed && - test_must_fail git cat-file blob $blob_2 > /dev/null && - mv ${pack}.idx tmp && - git hash-object -t blob -w file_2 && - mv tmp ${pack}.idx && - test_must_fail git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'create corruption in header of first delta' \ - 'create_new_pack && - git prune-packed && - do_corrupt_object $blob_2 0 < zero && - git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_2 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and then a repack "clears" the corruption' \ - 'do_repack && - git prune-packed && - git verify-pack ${pack}.pack && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'create corruption in data of first delta' \ - 'create_new_pack && - git prune-packed && - chmod +w ${pack}.pack && - perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && - git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_2 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and then a repack "clears" the corruption' \ - 'do_repack && - git prune-packed && - git verify-pack ${pack}.pack && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' \ - 'create_new_pack && - git prune-packed && - do_corrupt_object $blob_2 2 < zero && - git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_2 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and then a repack "clears" the corruption' \ - 'do_repack && - git prune-packed && - git verify-pack ${pack}.pack && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'corruption #0 in delta base reference of first delta (OBJ_OFS_DELTA)' \ - 'create_new_pack --delta-base-offset && - git prune-packed && - do_corrupt_object $blob_2 2 < zero && - git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_2 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and then a repack "clears" the corruption' \ - 'do_repack --delta-base-offset && - git prune-packed && - git verify-pack ${pack}.pack && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'corruption #1 in delta base reference of first delta (OBJ_OFS_DELTA)' \ - 'create_new_pack --delta-base-offset && - git prune-packed && - printf "\001" | do_corrupt_object $blob_2 2 && - git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_2 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and then a repack "clears" the corruption' \ - 'do_repack --delta-base-offset && - git prune-packed && - git verify-pack ${pack}.pack && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and a redundant pack allows for full recovery too' \ - 'do_corrupt_object $blob_2 2 < zero && - git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null && - mv ${pack}.idx tmp && - git hash-object -t blob -w file_1 && - git hash-object -t blob -w file_2 && - printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack && - git prune-packed && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'corruption of delta base reference pointing to wrong object' \ - 'create_new_pack --delta-base-offset && - git prune-packed && - printf "\220\033" | do_corrupt_object $blob_3 2 && - git cat-file blob $blob_1 >/dev/null && - git cat-file blob $blob_2 >/dev/null && - test_must_fail git cat-file blob $blob_3 >/dev/null' - -test_expect_success \ - '... but having a loose copy allows for full recovery' \ - 'mv ${pack}.idx tmp && - git hash-object -t blob -w file_3 && - mv tmp ${pack}.idx && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - '... and then a repack "clears" the corruption' \ - 'do_repack --delta-base-offset --no-reuse-delta && - git prune-packed && - git verify-pack ${pack}.pack && - git cat-file blob $blob_1 > /dev/null && - git cat-file blob $blob_2 > /dev/null && - git cat-file blob $blob_3 > /dev/null' - -test_expect_success \ - 'corrupting header to have too small output buffer fails unpack' \ - 'create_new_pack && - git prune-packed && - printf "\262\001" | do_corrupt_object $blob_1 0 && - test_must_fail git cat-file blob $blob_1 > /dev/null && - test_must_fail git cat-file blob $blob_2 > /dev/null && - test_must_fail git cat-file blob $blob_3 > /dev/null' +test_expect_success 'initial setup validation' ' + create_test_files && + create_new_pack && + git prune-packed && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'create corruption in header of first object' ' + do_corrupt_object $blob_1 0 < zero && + test_must_fail git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and loose copy of first delta allows for partial recovery' ' + git prune-packed && + test_must_fail git cat-file blob $blob_2 > /dev/null && + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + test_must_fail git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'create corruption in data of first object' ' + create_new_pack && + git prune-packed && + chmod +w ${pack}.pack && + perl -i.bak -pe "s/ base /abcdef/" ${pack}.pack && + test_must_fail git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and loose copy of second object allows for partial recovery' ' + git prune-packed && + test_must_fail git cat-file blob $blob_2 > /dev/null && + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + test_must_fail git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'create corruption in header of first delta' ' + create_new_pack && + git prune-packed && + do_corrupt_object $blob_2 0 < zero && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and then a repack "clears" the corruption' ' + do_repack && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'create corruption in data of first delta' ' + create_new_pack && + git prune-packed && + chmod +w ${pack}.pack && + perl -i.bak -pe "s/ delta1 /abcdefgh/" ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and then a repack "clears" the corruption' ' + do_repack && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'corruption in delta base reference of first delta (OBJ_REF_DELTA)' ' + create_new_pack && + git prune-packed && + do_corrupt_object $blob_2 2 < zero && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and then a repack "clears" the corruption' ' + do_repack && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'corruption #0 in delta base reference of first delta (OBJ_OFS_DELTA)' ' + create_new_pack --delta-base-offset && + git prune-packed && + do_corrupt_object $blob_2 2 < zero && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and then a repack "clears" the corruption' ' + do_repack --delta-base-offset && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'corruption #1 in delta base reference of first delta (OBJ_OFS_DELTA)' ' + create_new_pack --delta-base-offset && + git prune-packed && + printf "\001" | do_corrupt_object $blob_2 2 && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_2 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and then a repack "clears" the corruption' ' + do_repack --delta-base-offset && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and a redundant pack allows for full recovery too' ' + do_corrupt_object $blob_2 2 < zero && + git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null && + mv ${pack}.idx tmp && + git hash-object -t blob -w file_1 && + git hash-object -t blob -w file_2 && + printf "$blob_1\n$blob_2\n" | git pack-objects .git/objects/pack/pack && + git prune-packed && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'corruption of delta base reference pointing to wrong object' ' + create_new_pack --delta-base-offset && + git prune-packed && + printf "\220\033" | do_corrupt_object $blob_3 2 && + git cat-file blob $blob_1 >/dev/null && + git cat-file blob $blob_2 >/dev/null && + test_must_fail git cat-file blob $blob_3 >/dev/null +' + +test_expect_success '... but having a loose copy allows for full recovery' ' + mv ${pack}.idx tmp && + git hash-object -t blob -w file_3 && + mv tmp ${pack}.idx && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success '... and then a repack "clears" the corruption' ' + do_repack --delta-base-offset --no-reuse-delta && + git prune-packed && + git verify-pack ${pack}.pack && + git cat-file blob $blob_1 > /dev/null && + git cat-file blob $blob_2 > /dev/null && + git cat-file blob $blob_3 > /dev/null +' + +test_expect_success 'corrupting header to have too small output buffer fails unpack' ' + create_new_pack && + git prune-packed && + printf "\262\001" | do_corrupt_object $blob_1 0 && + test_must_fail git cat-file blob $blob_1 > /dev/null && + test_must_fail git cat-file blob $blob_2 > /dev/null && + test_must_fail git cat-file blob $blob_3 > /dev/null +' # \0 - empty base # \1 - one byte in result # \1 - one literal byte (X) -test_expect_success \ - 'apply good minimal delta' \ - 'printf "\0\1\1X" > minimal_delta && - test-tool delta -p /dev/null minimal_delta /dev/null' +test_expect_success 'apply good minimal delta' ' + printf "\0\1\1X" > minimal_delta && + test-tool delta -p /dev/null minimal_delta /dev/null +' # \0 - empty base # \1 - 1 byte in result # \2 - two literal bytes (one too many) -test_expect_success \ - 'apply delta with too many literal bytes' \ - 'printf "\0\1\2XX" > too_big_literal && - test_must_fail test-tool delta -p /dev/null too_big_literal /dev/null' +test_expect_success 'apply delta with too many literal bytes' ' + printf "\0\1\2XX" > too_big_literal && + test_must_fail test-tool delta -p /dev/null too_big_literal /dev/null +' # \4 - four bytes in base # \1 - one byte in result # \221 - copy, one byte offset, one byte size # \0 - copy from offset 0 # \2 - copy two bytes (one too many) -test_expect_success \ - 'apply delta with too many copied bytes' \ - 'printf "\4\1\221\0\2" > too_big_copy && - printf base >base && - test_must_fail test-tool delta -p base too_big_copy /dev/null' +test_expect_success 'apply delta with too many copied bytes' ' + printf "\4\1\221\0\2" > too_big_copy && + printf base >base && + test_must_fail test-tool delta -p base too_big_copy /dev/null +' # \0 - empty base # \2 - two bytes in result # \2 - two literal bytes (we are short one) -test_expect_success \ - 'apply delta with too few literal bytes' \ - 'printf "\0\2\2X" > truncated_delta && - test_must_fail test-tool delta -p /dev/null truncated_delta /dev/null' +test_expect_success 'apply delta with too few literal bytes' ' + printf "\0\2\2X" > truncated_delta && + test_must_fail test-tool delta -p /dev/null truncated_delta /dev/null +' # \0 - empty base # \1 - one byte in result # \221 - copy, one byte offset, one byte size # \0 - copy from offset 0 # \1 - copy one byte (we are short one) -test_expect_success \ - 'apply delta with too few bytes in base' \ - 'printf "\0\1\221\0\1" > truncated_base && - test_must_fail test-tool delta -p /dev/null truncated_base /dev/null' +test_expect_success 'apply delta with too few bytes in base' ' + printf "\0\1\221\0\1" > truncated_base && + test_must_fail test-tool delta -p /dev/null truncated_base /dev/null +' # \4 - four bytes in base # \2 - two bytes in result @@ -366,20 +366,20 @@ test_expect_success \ # # Note that the literal byte is necessary to get past the uninteresting minimum # delta size check. -test_expect_success \ - 'apply delta with truncated copy parameters' \ - 'printf "\4\2\1X\221" > truncated_copy_delta && - printf base >base && - test_must_fail test-tool delta -p base truncated_copy_delta /dev/null' +test_expect_success 'apply delta with truncated copy parameters' ' + printf "\4\2\1X\221" > truncated_copy_delta && + printf base >base && + test_must_fail test-tool delta -p base truncated_copy_delta /dev/null +' # \0 - empty base # \1 - one byte in result # \1 - one literal byte (X) # \1 - trailing garbage command -test_expect_success \ - 'apply delta with trailing garbage literal' \ - 'printf "\0\1\1X\1" > tail_garbage_literal && - test_must_fail test-tool delta -p /dev/null tail_garbage_literal /dev/null' +test_expect_success 'apply delta with trailing garbage literal' ' + printf "\0\1\1X\1" > tail_garbage_literal && + test_must_fail test-tool delta -p /dev/null tail_garbage_literal /dev/null +' # \4 - four bytes in base # \1 - one byte in result @@ -387,19 +387,19 @@ test_expect_success \ # \221 - copy, one byte offset, one byte size # \0 - copy from offset 0 # \1 - copy 1 byte -test_expect_success \ - 'apply delta with trailing garbage copy' \ - 'printf "\4\1\1X\221\0\1" > tail_garbage_copy && - printf base >base && - test_must_fail test-tool delta -p /dev/null tail_garbage_copy /dev/null' +test_expect_success 'apply delta with trailing garbage copy' ' + printf "\4\1\1X\221\0\1" > tail_garbage_copy && + printf base >base && + test_must_fail test-tool delta -p /dev/null tail_garbage_copy /dev/null +' # \0 - empty base # \1 - one byte in result # \1 - one literal byte (X) # \0 - bogus opcode -test_expect_success \ - 'apply delta with trailing garbage opcode' \ - 'printf "\0\1\1X\0" > tail_garbage_opcode && - test_must_fail test-tool delta -p /dev/null tail_garbage_opcode /dev/null' +test_expect_success 'apply delta with trailing garbage opcode' ' + printf "\0\1\1X\0" > tail_garbage_opcode && + test_must_fail test-tool delta -p /dev/null tail_garbage_opcode /dev/null +' test_done diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index f367327441..b4df545e5a 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -350,4 +350,18 @@ test_expect_success 'old reachable-from-recent retained with bitmaps' ' test_must_fail git cat-file -e $to_drop ' +test_expect_success 'gc.recentObjectsHook' ' + add_blob && + test-tool chmtime =-86500 $BLOB_FILE && + + write_script precious-objects <<-EOF && + echo $BLOB + EOF + test_config gc.recentObjectsHook ./precious-objects && + + git prune --expire=now && + + git cat-file -p $BLOB +' + test_done diff --git a/t/t5306-pack-nobase.sh b/t/t5306-pack-nobase.sh index 846c5ca7d3..0d50c6b4bc 100755 --- a/t/t5306-pack-nobase.sh +++ b/t/t5306-pack-nobase.sh @@ -12,18 +12,17 @@ TEST_PASSES_SANITIZE_LEAK=true # Create A-B chain # -test_expect_success \ - 'setup base' \ - 'test_write_lines a b c d e f g h i >text && - echo side >side && - git update-index --add text side && - A=$(echo A | git commit-tree $(git write-tree)) && +test_expect_success 'setup base' ' + test_write_lines a b c d e f g h i >text && + echo side >side && + git update-index --add text side && + A=$(echo A | git commit-tree $(git write-tree)) && - echo m >>text && - git update-index text && - B=$(echo B | git commit-tree $(git write-tree) -p $A) && - git update-ref HEAD $B - ' + echo m >>text && + git update-index text && + B=$(echo B | git commit-tree $(git write-tree) -p $A) && + git update-ref HEAD $B +' # Create repository with C whose parent is B. # Repository contains C, C^{tree}, C:text, B, B^{tree}. @@ -31,52 +30,49 @@ test_expect_success \ # Repository is missing A (parent of B). # Repository is missing A:side. # -test_expect_success \ - 'setup patch_clone' \ - 'base_objects=$(pwd)/.git/objects && - (mkdir patch_clone && - cd patch_clone && - git init && - echo "$base_objects" >.git/objects/info/alternates && - echo q >>text && - git read-tree $B && - git update-index text && - git update-ref HEAD $(echo C | git commit-tree $(git write-tree) -p $B) && - rm .git/objects/info/alternates && +test_expect_success 'setup patch_clone' ' + base_objects=$(pwd)/.git/objects && + (mkdir patch_clone && + cd patch_clone && + git init && + echo "$base_objects" >.git/objects/info/alternates && + echo q >>text && + git read-tree $B && + git update-index text && + git update-ref HEAD $(echo C | git commit-tree $(git write-tree) -p $B) && + rm .git/objects/info/alternates && - git --git-dir=../.git cat-file commit $B | - git hash-object -t commit -w --stdin && + git --git-dir=../.git cat-file commit $B | + git hash-object -t commit -w --stdin && - git --git-dir=../.git cat-file tree "$B^{tree}" | - git hash-object -t tree -w --stdin - ) && - C=$(git --git-dir=patch_clone/.git rev-parse HEAD) - ' + git --git-dir=../.git cat-file tree "$B^{tree}" | + git hash-object -t tree -w --stdin + ) && + C=$(git --git-dir=patch_clone/.git rev-parse HEAD) +' # Clone patch_clone indirectly by cloning base and fetching. # -test_expect_success \ - 'indirectly clone patch_clone' \ - '(mkdir user_clone && - cd user_clone && - git init && - git pull ../.git && - test $(git rev-parse HEAD) = $B && +test_expect_success 'indirectly clone patch_clone' ' + (mkdir user_clone && + cd user_clone && + git init && + git pull ../.git && + test $(git rev-parse HEAD) = $B && - git pull ../patch_clone/.git && - test $(git rev-parse HEAD) = $C - ) - ' + git pull ../patch_clone/.git && + test $(git rev-parse HEAD) = $C + ) +' # Cloning the patch_clone directly should fail. # -test_expect_success \ - 'clone of patch_clone is incomplete' \ - '(mkdir user_direct && - cd user_direct && - git init && - test_must_fail git fetch ../patch_clone/.git - ) - ' +test_expect_success 'clone of patch_clone is incomplete' ' + (mkdir user_direct && + cd user_direct && + git init && + test_must_fail git fetch ../patch_clone/.git + ) +' test_done diff --git a/t/t5310-pack-bitmaps.sh b/t/t5310-pack-bitmaps.sh index 526a5a506e..78c1c6c923 100755 --- a/t/t5310-pack-bitmaps.sh +++ b/t/t5310-pack-bitmaps.sh @@ -9,6 +9,10 @@ test_description='exercise basic bitmap functionality' # their place. GIT_TEST_MULTI_PACK_INDEX_WRITE_BITMAP=0 +# Likewise, allow individual tests to control whether or not they use +# the boundary-based traversal. +sane_unset GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL + objpath () { echo ".git/objects/$(echo "$1" | sed -e 's|\(..\)|\1/|')" } @@ -457,6 +461,13 @@ test_bitmap_cases () { test_bitmap_cases +GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=1 +export GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL + +test_bitmap_cases + +sane_unset GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL + test_expect_success 'incremental repack fails when bitmaps are requested' ' test_commit more-1 && test_must_fail git repack -d 2>err && @@ -468,6 +479,33 @@ test_expect_success 'incremental repack can disable bitmaps' ' git repack -d --no-write-bitmap-index ' +test_expect_success 'boundary-based traversal is used when requested' ' + git repack -a -d --write-bitmap-index && + + for argv in \ + "git -c pack.useBitmapBoundaryTraversal=true" \ + "git -c feature.experimental=true" \ + "GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=1 git" + do + eval "GIT_TRACE2_EVENT=1 $argv rev-list --objects \ + --use-bitmap-index second..other 2>perf" && + grep "\"region_enter\".*\"label\":\"haves/boundary\"" perf || + return 1 + done && + + for argv in \ + "git -c pack.useBitmapBoundaryTraversal=false" \ + "git -c feature.experimental=true -c pack.useBitmapBoundaryTraversal=false" \ + "GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=0 git -c pack.useBitmapBoundaryTraversal=true" \ + "GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL=0 git -c feature.experimental=true" + do + eval "GIT_TRACE2_EVENT=1 $argv rev-list --objects \ + --use-bitmap-index second..other 2>perf" && + grep "\"region_enter\".*\"label\":\"haves/classic\"" perf || + return 1 + done +' + test_bitmap_cases "pack.writeBitmapLookupTable" test_expect_success 'verify writing bitmap lookup table when enabled' ' diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh index b6e1211578..ba65f17dd9 100755 --- a/t/t5318-commit-graph.sh +++ b/t/t5318-commit-graph.sh @@ -24,12 +24,10 @@ test_expect_success 'usage shown with an error on unknown sub-command' ' test_cmp expect actual ' +objdir=".git/objects" + test_expect_success 'setup full repo' ' - mkdir full && - cd "$TRASH_DIRECTORY/full" && - git init && - git config core.commitGraph true && - objdir=".git/objects" + git init full ' test_expect_success POSIXPERM 'tweak umask for modebit tests' ' @@ -37,31 +35,28 @@ test_expect_success POSIXPERM 'tweak umask for modebit tests' ' ' test_expect_success 'verify graph with no graph file' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph verify + git -C full commit-graph verify ' test_expect_success 'write graph with no packs' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write --object-dir $objdir && - test_path_is_missing $objdir/info/commit-graph + git -C full commit-graph write --object-dir $objdir && + test_path_is_missing full/$objdir/info/commit-graph ' test_expect_success 'exit with correct error on bad input to --stdin-packs' ' - cd "$TRASH_DIRECTORY/full" && echo doesnotexist >in && - test_expect_code 1 git commit-graph write --stdin-packs <in 2>stderr && + test_expect_code 1 git -C full commit-graph write --stdin-packs \ + <in 2>stderr && test_i18ngrep "error adding pack" stderr ' test_expect_success 'create commits and repack' ' - cd "$TRASH_DIRECTORY/full" && for i in $(test_seq 3) do - test_commit $i && - git branch commits/$i || return 1 + test_commit -C full $i && + git -C full branch commits/$i || return 1 done && - git repack + git -C full repack ' . "$TEST_DIRECTORY"/lib-commit-graph.sh @@ -69,117 +64,106 @@ test_expect_success 'create commits and repack' ' graph_git_behavior 'no graph' full commits/3 commits/1 test_expect_success 'exit with correct error on bad input to --stdin-commits' ' - cd "$TRASH_DIRECTORY/full" && # invalid, non-hex OID - echo HEAD >in && - test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr && + echo HEAD | test_expect_code 1 git -C full commit-graph write \ + --stdin-commits 2>stderr && test_i18ngrep "unexpected non-hex object ID: HEAD" stderr && # non-existent OID - echo $ZERO_OID >in && - test_expect_code 1 git commit-graph write --stdin-commits <in 2>stderr && + echo $ZERO_OID | test_expect_code 1 git -C full commit-graph write \ + --stdin-commits 2>stderr && test_i18ngrep "invalid object" stderr && # valid commit and tree OID - git rev-parse HEAD HEAD^{tree} >in && - git commit-graph write --stdin-commits <in && - graph_read_expect 3 generation_data + git -C full rev-parse HEAD HEAD^{tree} >in && + git -C full commit-graph write --stdin-commits <in && + graph_read_expect -C full 3 generation_data ' test_expect_success 'write graph' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "3" generation_data + git -C full commit-graph write && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 3 generation_data ' test_expect_success POSIXPERM 'write graph has correct permissions' ' - test_path_is_file $objdir/info/commit-graph && + test_path_is_file full/$objdir/info/commit-graph && echo "-r--r--r--" >expect && - test_modebits $objdir/info/commit-graph >actual && + test_modebits full/$objdir/info/commit-graph >actual && test_cmp expect actual ' graph_git_behavior 'graph exists' full commits/3 commits/1 test_expect_success 'Add more commits' ' - cd "$TRASH_DIRECTORY/full" && - git reset --hard commits/1 && + git -C full reset --hard commits/1 && for i in $(test_seq 4 5) do - test_commit $i && - git branch commits/$i || return 1 + test_commit -C full $i && + git -C full branch commits/$i || return 1 done && - git reset --hard commits/2 && + git -C full reset --hard commits/2 && for i in $(test_seq 6 7) do - test_commit $i && - git branch commits/$i || return 1 + test_commit -C full $i && + git -C full branch commits/$i || return 1 done && - git reset --hard commits/2 && - git merge commits/4 && - git branch merge/1 && - git reset --hard commits/4 && - git merge commits/6 && - git branch merge/2 && - git reset --hard commits/3 && - git merge commits/5 commits/7 && - git branch merge/3 && - git repack + git -C full reset --hard commits/2 && + git -C full merge commits/4 && + git -C full branch merge/1 && + git -C full reset --hard commits/4 && + git -C full merge commits/6 && + git -C full branch merge/2 && + git -C full reset --hard commits/3 && + git -C full merge commits/5 commits/7 && + git -C full branch merge/3 && + git -C full repack ' test_expect_success 'commit-graph write progress off for redirected stderr' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write 2>err && + git -C full commit-graph write 2>err && test_must_be_empty err ' test_expect_success 'commit-graph write force progress on for stderr' ' - cd "$TRASH_DIRECTORY/full" && - GIT_PROGRESS_DELAY=0 git commit-graph write --progress 2>err && + GIT_PROGRESS_DELAY=0 git -C full commit-graph write --progress 2>err && test_file_not_empty err ' test_expect_success 'commit-graph write with the --no-progress option' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write --no-progress 2>err && + git -C full commit-graph write --no-progress 2>err && test_must_be_empty err ' test_expect_success 'commit-graph write --stdin-commits progress off for redirected stderr' ' - cd "$TRASH_DIRECTORY/full" && - git rev-parse commits/5 >in && - git commit-graph write --stdin-commits <in 2>err && + git -C full rev-parse commits/5 >in && + git -C full commit-graph write --stdin-commits <in 2>err && test_must_be_empty err ' test_expect_success 'commit-graph write --stdin-commits force progress on for stderr' ' - cd "$TRASH_DIRECTORY/full" && - git rev-parse commits/5 >in && - GIT_PROGRESS_DELAY=0 git commit-graph write --stdin-commits --progress <in 2>err && + git -C full rev-parse commits/5 >in && + GIT_PROGRESS_DELAY=0 git -C full commit-graph write --stdin-commits \ + --progress <in 2>err && test_i18ngrep "Collecting commits from input" err ' test_expect_success 'commit-graph write --stdin-commits with the --no-progress option' ' - cd "$TRASH_DIRECTORY/full" && - git rev-parse commits/5 >in && - git commit-graph write --stdin-commits --no-progress <in 2>err && + git -C full rev-parse commits/5 >in && + git -C full commit-graph write --stdin-commits --no-progress <in 2>err && test_must_be_empty err ' test_expect_success 'commit-graph verify progress off for redirected stderr' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph verify 2>err && + git -C full commit-graph verify 2>err && test_must_be_empty err ' test_expect_success 'commit-graph verify force progress on for stderr' ' - cd "$TRASH_DIRECTORY/full" && - GIT_PROGRESS_DELAY=0 git commit-graph verify --progress 2>err && + GIT_PROGRESS_DELAY=0 git -C full commit-graph verify --progress 2>err && test_file_not_empty err ' test_expect_success 'commit-graph verify with the --no-progress option' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph verify --no-progress 2>err && + git -C full commit-graph verify --no-progress 2>err && test_must_be_empty err ' @@ -194,10 +178,9 @@ test_expect_success 'commit-graph verify with the --no-progress option' ' # 1 test_expect_success 'write graph with merges' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "10" "generation_data extra_edges" + git -C full commit-graph write && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 10 "generation_data extra_edges" ' graph_git_behavior 'merge 1 vs 2' full merge/1 merge/2 @@ -205,12 +188,11 @@ graph_git_behavior 'merge 1 vs 3' full merge/1 merge/3 graph_git_behavior 'merge 2 vs 3' full merge/2 merge/3 test_expect_success 'Add one more commit' ' - cd "$TRASH_DIRECTORY/full" && - test_commit 8 && - git branch commits/8 && - ls $objdir/pack | grep idx >existing-idx && - git repack && - ls $objdir/pack| grep idx | grep -v -f existing-idx >new-idx + test_commit -C full 8 && + git -C full branch commits/8 && + ls full/$objdir/pack | grep idx >existing-idx && + git -C full repack && + ls full/$objdir/pack| grep idx | grep -v -f existing-idx >new-idx ' # Current graph structure: @@ -229,114 +211,101 @@ graph_git_behavior 'mixed mode, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'mixed mode, commit 8 vs merge 2' full commits/8 merge/2 test_expect_success 'write graph with new commit' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "11" "generation_data extra_edges" + git -C full commit-graph write && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 11 "generation_data extra_edges" ' graph_git_behavior 'full graph, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'full graph, commit 8 vs merge 2' full commits/8 merge/2 test_expect_success 'write graph with nothing new' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "11" "generation_data extra_edges" + git -C full commit-graph write && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 11 "generation_data extra_edges" ' graph_git_behavior 'cleared graph, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'cleared graph, commit 8 vs merge 2' full commits/8 merge/2 test_expect_success 'build graph from latest pack with closure' ' - cd "$TRASH_DIRECTORY/full" && - cat new-idx | git commit-graph write --stdin-packs && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "9" "generation_data extra_edges" + git -C full commit-graph write --stdin-packs <new-idx && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 9 "generation_data extra_edges" ' graph_git_behavior 'graph from pack, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'graph from pack, commit 8 vs merge 2' full commits/8 merge/2 test_expect_success 'build graph from commits with closure' ' - cd "$TRASH_DIRECTORY/full" && - git tag -a -m "merge" tag/merge merge/2 && - git rev-parse tag/merge >commits-in && - git rev-parse merge/1 >>commits-in && - cat commits-in | git commit-graph write --stdin-commits && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "6" "generation_data" + git -C full tag -a -m "merge" tag/merge merge/2 && + git -C full rev-parse tag/merge >commits-in && + git -C full rev-parse merge/1 >>commits-in && + git -C full commit-graph write --stdin-commits <commits-in && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 6 "generation_data" ' graph_git_behavior 'graph from commits, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'graph from commits, commit 8 vs merge 2' full commits/8 merge/2 test_expect_success 'build graph from commits with append' ' - cd "$TRASH_DIRECTORY/full" && - git rev-parse merge/3 | git commit-graph write --stdin-commits --append && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "10" "generation_data extra_edges" + git -C full rev-parse merge/3 >in && + git -C full commit-graph write --stdin-commits --append <in && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 10 "generation_data extra_edges" ' graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2 test_expect_success 'build graph using --reachable' ' - cd "$TRASH_DIRECTORY/full" && - git commit-graph write --reachable && - test_path_is_file $objdir/info/commit-graph && - graph_read_expect "11" "generation_data extra_edges" + git -C full commit-graph write --reachable && + test_path_is_file full/$objdir/info/commit-graph && + graph_read_expect -C full 11 "generation_data extra_edges" ' graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1 graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2 test_expect_success 'setup bare repo' ' - cd "$TRASH_DIRECTORY" && - git clone --bare --no-local full bare && - cd bare && - git config core.commitGraph true && - baredir="./objects" + git clone --bare --no-local full bare ' graph_git_behavior 'bare repo, commit 8 vs merge 1' bare commits/8 merge/1 graph_git_behavior 'bare repo, commit 8 vs merge 2' bare commits/8 merge/2 test_expect_success 'write graph in bare repo' ' - cd "$TRASH_DIRECTORY/bare" && - git commit-graph write && - test_path_is_file $baredir/info/commit-graph && - graph_read_expect "11" "generation_data extra_edges" + git -C bare commit-graph write && + test_path_is_file bare/objects/info/commit-graph && + graph_read_expect -C bare 11 "generation_data extra_edges" ' graph_git_behavior 'bare repo with graph, commit 8 vs merge 1' bare commits/8 merge/1 graph_git_behavior 'bare repo with graph, commit 8 vs merge 2' bare commits/8 merge/2 test_expect_success 'perform fast-forward merge in full repo' ' - cd "$TRASH_DIRECTORY/full" && - git checkout -b merge-5-to-8 commits/5 && - git merge commits/8 && - git show-ref -s merge-5-to-8 >output && - git show-ref -s commits/8 >expect && + git -C full checkout -b merge-5-to-8 commits/5 && + git -C full merge commits/8 && + git -C full show-ref -s merge-5-to-8 >output && + git -C full show-ref -s commits/8 >expect && test_cmp expect output ' test_expect_success 'check that gc computes commit-graph' ' - cd "$TRASH_DIRECTORY/full" && - git commit --allow-empty -m "blank" && - git commit-graph write --reachable && - cp $objdir/info/commit-graph commit-graph-before-gc && - git reset --hard HEAD~1 && - git config gc.writeCommitGraph true && - git gc && - cp $objdir/info/commit-graph commit-graph-after-gc && + test_commit -C full --no-tag blank && + git -C full commit-graph write --reachable && + cp full/$objdir/info/commit-graph commit-graph-before-gc && + git -C full reset --hard HEAD~1 && + test_config -C full gc.writeCommitGraph true && + git -C full gc && + cp full/$objdir/info/commit-graph commit-graph-after-gc && ! test_cmp_bin commit-graph-before-gc commit-graph-after-gc && - git commit-graph write --reachable && - test_cmp_bin commit-graph-after-gc $objdir/info/commit-graph + git -C full commit-graph write --reachable && + test_cmp_bin commit-graph-after-gc full/$objdir/info/commit-graph ' test_expect_success 'replace-objects invalidates commit-graph' ' - cd "$TRASH_DIRECTORY" && test_when_finished rm -rf replace && git clone full replace && ( @@ -359,7 +328,6 @@ test_expect_success 'replace-objects invalidates commit-graph' ' ' test_expect_success 'commit grafts invalidate commit-graph' ' - cd "$TRASH_DIRECTORY" && test_when_finished rm -rf graft && git clone --template= full graft && ( @@ -384,7 +352,6 @@ test_expect_success 'commit grafts invalidate commit-graph' ' ' test_expect_success 'replace-objects invalidates commit-graph' ' - cd "$TRASH_DIRECTORY" && test_when_finished rm -rf shallow && git clone --depth 2 "file://$TRASH_DIRECTORY/full" shallow && ( @@ -427,24 +394,25 @@ test_expect_success 'warn on improper hash version' ' ' test_expect_success TIME_IS_64BIT,TIME_T_IS_64BIT 'lower layers have overflow chunk' ' - cd "$TRASH_DIRECTORY/full" && UNIX_EPOCH_ZERO="@0 +0000" && FUTURE_DATE="@4147483646 +0000" && - rm -f .git/objects/info/commit-graph && - test_commit --date "$FUTURE_DATE" future-1 && - test_commit --date "$UNIX_EPOCH_ZERO" old-1 && - git commit-graph write --reachable && - test_commit --date "$FUTURE_DATE" future-2 && - test_commit --date "$UNIX_EPOCH_ZERO" old-2 && - git commit-graph write --reachable --split=no-merge && - test_commit extra && - git commit-graph write --reachable --split=no-merge && - git commit-graph write --reachable && - graph_read_expect 16 "generation_data generation_data_overflow extra_edges" && - mv .git/objects/info/commit-graph commit-graph-upgraded && - git commit-graph write --reachable && - graph_read_expect 16 "generation_data generation_data_overflow extra_edges" && - test_cmp .git/objects/info/commit-graph commit-graph-upgraded + rm -f full/.git/objects/info/commit-graph && + test_commit -C full --date "$FUTURE_DATE" future-1 && + test_commit -C full --date "$UNIX_EPOCH_ZERO" old-1 && + git -C full commit-graph write --reachable && + test_commit -C full --date "$FUTURE_DATE" future-2 && + test_commit -C full --date "$UNIX_EPOCH_ZERO" old-2 && + git -C full commit-graph write --reachable --split=no-merge && + test_commit -C full extra && + git -C full commit-graph write --reachable --split=no-merge && + git -C full commit-graph write --reachable && + graph_read_expect -C full 16 \ + "generation_data generation_data_overflow extra_edges" && + mv full/.git/objects/info/commit-graph commit-graph-upgraded && + git -C full commit-graph write --reachable && + graph_read_expect -C full 16 \ + "generation_data generation_data_overflow extra_edges" && + test_cmp full/.git/objects/info/commit-graph commit-graph-upgraded ' # the verify tests below expect the commit-graph to contain @@ -454,10 +422,11 @@ test_expect_success TIME_IS_64BIT,TIME_T_IS_64BIT 'lower layers have overflow ch # and the tests will likely break. test_expect_success 'git commit-graph verify' ' - cd "$TRASH_DIRECTORY/full" && - git rev-parse commits/8 | git -c commitGraph.generationVersion=1 commit-graph write --stdin-commits && - git commit-graph verify >output && - graph_read_expect 9 extra_edges 1 + git -C full rev-parse commits/8 >in && + git -C full -c commitGraph.generationVersion=1 commit-graph write \ + --stdin-commits <in && + git -C full commit-graph verify >output && + graph_read_expect -C full 9 extra_edges 1 ' NUM_COMMITS=9 @@ -481,39 +450,39 @@ GRAPH_BYTE_FANOUT2=$(($GRAPH_FANOUT_OFFSET + 4 * 255)) GRAPH_OID_LOOKUP_OFFSET=$(($GRAPH_FANOUT_OFFSET + 4 * 256)) GRAPH_BYTE_OID_LOOKUP_ORDER=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 8)) GRAPH_BYTE_OID_LOOKUP_MISSING=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * 4 + 10)) +GRAPH_COMMIT_DATA_WIDTH=$(($HASH_LEN + 16)) GRAPH_COMMIT_DATA_OFFSET=$(($GRAPH_OID_LOOKUP_OFFSET + $HASH_LEN * $NUM_COMMITS)) GRAPH_BYTE_COMMIT_TREE=$GRAPH_COMMIT_DATA_OFFSET GRAPH_BYTE_COMMIT_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN)) GRAPH_BYTE_COMMIT_EXTRA_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 4)) GRAPH_BYTE_COMMIT_WRONG_PARENT=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 3)) GRAPH_BYTE_COMMIT_GENERATION=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 11)) +GRAPH_BYTE_COMMIT_GENERATION_LAST=$(($GRAPH_BYTE_COMMIT_GENERATION + $(($NUM_COMMITS - 1)) * $GRAPH_COMMIT_DATA_WIDTH)) GRAPH_BYTE_COMMIT_DATE=$(($GRAPH_COMMIT_DATA_OFFSET + $HASH_LEN + 12)) -GRAPH_COMMIT_DATA_WIDTH=$(($HASH_LEN + 16)) GRAPH_OCTOPUS_DATA_OFFSET=$(($GRAPH_COMMIT_DATA_OFFSET + \ $GRAPH_COMMIT_DATA_WIDTH * $NUM_COMMITS)) GRAPH_BYTE_OCTOPUS=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4)) GRAPH_BYTE_FOOTER=$(($GRAPH_OCTOPUS_DATA_OFFSET + 4 * $NUM_OCTOPUS_EDGES)) corrupt_graph_setup() { - cd "$TRASH_DIRECTORY/full" && - test_when_finished mv commit-graph-backup $objdir/info/commit-graph && - cp $objdir/info/commit-graph commit-graph-backup && - chmod u+w $objdir/info/commit-graph + test_when_finished mv commit-graph-backup full/$objdir/info/commit-graph && + cp full/$objdir/info/commit-graph commit-graph-backup && + chmod u+w full/$objdir/info/commit-graph } corrupt_graph_verify() { grepstr=$1 - test_must_fail git commit-graph verify 2>test_err && + test_must_fail git -C full commit-graph verify 2>test_err && grep -v "^+" test_err >err && test_i18ngrep "$grepstr" err && if test "$2" != "no-copy" then - cp $objdir/info/commit-graph commit-graph-pre-write-test + cp full/$objdir/info/commit-graph commit-graph-pre-write-test fi && - git status --short && - GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE=true git commit-graph write && - chmod u+w $objdir/info/commit-graph && - git commit-graph verify + git -C full status --short && + GIT_TEST_COMMIT_GRAPH_DIE_ON_PARSE=true git -C full commit-graph write && + chmod u+w full/$objdir/info/commit-graph && + git -C full commit-graph verify } # usage: corrupt_graph_and_verify <position> <data> <string> [<zero_pos>] @@ -527,24 +496,24 @@ corrupt_graph_and_verify() { data="${2:-\0}" grepstr=$3 corrupt_graph_setup && - orig_size=$(wc -c < $objdir/info/commit-graph) && + orig_size=$(wc -c <full/$objdir/info/commit-graph) && zero_pos=${4:-${orig_size}} && - printf "$data" | dd of="$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc && - dd of="$objdir/info/commit-graph" bs=1 seek="$zero_pos" if=/dev/null && - test-tool genzeros $(($orig_size - $zero_pos)) >>"$objdir/info/commit-graph" && + printf "$data" | dd of="full/$objdir/info/commit-graph" bs=1 seek="$pos" conv=notrunc && + dd of="full/$objdir/info/commit-graph" bs=1 seek="$zero_pos" if=/dev/null && + test-tool genzeros $(($orig_size - $zero_pos)) >>"full/$objdir/info/commit-graph" && corrupt_graph_verify "$grepstr" } test_expect_success POSIXPERM,SANITY 'detect permission problem' ' corrupt_graph_setup && - chmod 000 $objdir/info/commit-graph && + chmod 000 full/$objdir/info/commit-graph && corrupt_graph_verify "Could not open" "no-copy" ' test_expect_success 'detect too small' ' corrupt_graph_setup && - echo "a small graph" >$objdir/info/commit-graph && + echo "a small graph" >full/$objdir/info/commit-graph && corrupt_graph_verify "too small" ' @@ -628,11 +597,6 @@ test_expect_success 'detect incorrect generation number' ' "generation for commit" ' -test_expect_success 'detect incorrect generation number' ' - corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\01" \ - "commit-graph generation for commit" -' - test_expect_success 'detect incorrect commit date' ' corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_DATE "\01" \ "commit date" @@ -654,34 +618,51 @@ test_expect_success 'detect incorrect chunk count' ' $GRAPH_CHUNK_LOOKUP_OFFSET ' +test_expect_success 'detect mixed generation numbers (non-zero to zero)' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION_LAST "\0\0\0\0" \ + "both zero and non-zero generations" +' + +test_expect_success 'detect mixed generation numbers (zero to non-zero)' ' + corrupt_graph_and_verify $GRAPH_BYTE_COMMIT_GENERATION "\0\0\0\0" \ + "both zero and non-zero generations" +' + test_expect_success 'git fsck (checks commit-graph when config set to true)' ' - cd "$TRASH_DIRECTORY/full" && - git fsck && + git -C full 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 + cp commit-graph-pre-write-test full/$objdir/info/commit-graph && + test_must_fail git -C full -c core.commitGraph=true fsck ' test_expect_success 'git fsck (ignores commit-graph when config set to false)' ' - cd "$TRASH_DIRECTORY/full" && - git fsck && + git -C full 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 + cp commit-graph-pre-write-test full/$objdir/info/commit-graph && + git -C full -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" && + test_when_finished "git -C full config core.commitGraph true" && - git fsck && + git -C full 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 + test_unconfig -C full core.commitGraph && + cp commit-graph-pre-write-test full/$objdir/info/commit-graph && + test_must_fail git -C full fsck +' + +test_expect_success 'git fsck shows commit-graph output with --progress' ' + git -C "$TRASH_DIRECTORY/full" fsck --progress 2>err && + grep "Verifying commits in commit graph" err +' + +test_expect_success 'git fsck suppresses commit-graph output with --no-progress' ' + git -C "$TRASH_DIRECTORY/full" fsck --no-progress 2>err && + ! grep "Verifying commits in commit graph" err ' test_expect_success 'setup non-the_repository tests' ' @@ -782,32 +763,33 @@ test_expect_success 'corrupt commit-graph write (missing tree)' ' # test_expect_success 'set up and verify repo with generation data overflow chunk' ' - objdir=".git/objects" && UNIX_EPOCH_ZERO="@0 +0000" && FUTURE_DATE="@2147483646 +0000" && - cd "$TRASH_DIRECTORY" && - mkdir repo && - cd repo && - git init && - test_commit --date "$UNIX_EPOCH_ZERO" 1 && - test_commit 2 && - test_commit --date "$UNIX_EPOCH_ZERO" 3 && - git commit-graph write --reachable && - graph_read_expect 3 generation_data && - test_commit --date "$FUTURE_DATE" 4 && - test_commit 5 && - test_commit --date "$UNIX_EPOCH_ZERO" 6 && - git branch left && - git reset --hard 3 && - test_commit 7 && - test_commit --date "$FUTURE_DATE" 8 && - test_commit 9 && - git branch right && - git reset --hard 3 && - test_merge M left right && - git commit-graph write --reachable && - graph_read_expect 10 "generation_data generation_data_overflow" && - git commit-graph verify + + git init repo && + ( + cd repo && + + test_commit --date "$UNIX_EPOCH_ZERO" 1 && + test_commit 2 && + test_commit --date "$UNIX_EPOCH_ZERO" 3 && + git commit-graph write --reachable && + graph_read_expect 3 generation_data && + test_commit --date "$FUTURE_DATE" 4 && + test_commit 5 && + test_commit --date "$UNIX_EPOCH_ZERO" 6 && + git branch left && + git reset --hard 3 && + test_commit 7 && + test_commit --date "$FUTURE_DATE" 8 && + test_commit 9 && + git branch right && + git reset --hard 3 && + test_merge M left right && + git commit-graph write --reachable && + graph_read_expect 10 "generation_data generation_data_overflow" && + git commit-graph verify + ) ' graph_git_behavior 'generation data overflow chunk repo' repo left right diff --git a/t/t5319-multi-pack-index.sh b/t/t5319-multi-pack-index.sh index 0883c7c6bd..1bcc02004d 100755 --- a/t/t5319-multi-pack-index.sh +++ b/t/t5319-multi-pack-index.sh @@ -485,6 +485,18 @@ test_expect_success 'git-fsck incorrect offset' ' git -c core.multiPackIndex=false fsck ' +test_expect_success 'git fsck shows MIDX output with --progress' ' + git fsck --progress 2>err && + grep "Verifying OID order in multi-pack-index" err && + grep "Verifying object offsets" err +' + +test_expect_success 'git fsck suppresses MIDX output with --no-progress' ' + git fsck --no-progress 2>err && + ! grep "Verifying OID order in multi-pack-index" err && + ! grep "Verifying object offsets" err +' + test_expect_success 'corrupt MIDX is not reused' ' corrupt_midx_and_verify $MIDX_BYTE_OFFSET "\377" $objdir \ "incorrect object offset" && diff --git a/t/t5324-split-commit-graph.sh b/t/t5324-split-commit-graph.sh index 669ddc645f..36c4141e67 100755 --- a/t/t5324-split-commit-graph.sh +++ b/t/t5324-split-commit-graph.sh @@ -351,7 +351,8 @@ test_expect_success 'add octopus merge' ' git branch merge/octopus && git commit-graph write --reachable --split && git commit-graph verify --progress 2>err && - test_line_count = 3 err && + test_line_count = 1 err && + grep "Verifying commits in commit graph: 100% (18/18)" err && test_i18ngrep ! warning err && test_line_count = 3 $graphdir/commit-graph-chain ' diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh index f771c442d4..70d1b58709 100755 --- a/t/t5326-multi-pack-bitmaps.sh +++ b/t/t5326-multi-pack-bitmaps.sh @@ -478,4 +478,39 @@ test_expect_success 'git fsck correctly identifies good and bad bitmaps' ' grep "bitmap file '\''$packbitmap'\'' has invalid checksum" err ' +test_expect_success 'corrupt MIDX with bitmap causes fallback' ' + git init corrupt-midx-bitmap && + ( + cd corrupt-midx-bitmap && + + test_commit first && + git repack -d && + test_commit second && + git repack -d && + + git multi-pack-index write --bitmap && + checksum=$(midx_checksum $objdir) && + for f in $midx $midx-$checksum.bitmap + do + mv $f $f.bak || return 1 + done && + + # pack everything together, invalidating the MIDX + git repack -ad && + # then restore the now-stale MIDX + for f in $midx $midx-$checksum.bitmap + do + mv $f.bak $f || return 1 + done && + + git rev-list --count --objects --use-bitmap-index HEAD >out 2>err && + # should attempt opening the broken pack twice (once + # from the attempt to load it via the stale bitmap, and + # again when attempting to load it from the stale MIDX) + # before falling back to the non-MIDX case + test 2 -eq $(grep -c "could not open pack" err) && + test 6 -eq $(cat out) + ) +' + test_done diff --git a/t/t5328-commit-graph-64bit-time.sh b/t/t5328-commit-graph-64bit-time.sh index 57e4d9c699..e9c521c061 100755 --- a/t/t5328-commit-graph-64bit-time.sh +++ b/t/t5328-commit-graph-64bit-time.sh @@ -37,39 +37,39 @@ test_expect_success 'lower layers have overflow chunk' ' graph_git_behavior 'overflow' '' HEAD~2 HEAD test_expect_success 'set up and verify repo with generation data overflow chunk' ' - mkdir repo && - cd repo && - git init && - test_commit --date "$UNIX_EPOCH_ZERO" 1 && - test_commit 2 && - test_commit --date "$UNIX_EPOCH_ZERO" 3 && - git commit-graph write --reachable && - graph_read_expect 3 generation_data && - test_commit --date "$FUTURE_DATE" 4 && - test_commit 5 && - test_commit --date "$UNIX_EPOCH_ZERO" 6 && - git branch left && - git reset --hard 3 && - test_commit 7 && - test_commit --date "$FUTURE_DATE" 8 && - test_commit 9 && - git branch right && - git reset --hard 3 && - test_merge M left right && - git commit-graph write --reachable && - graph_read_expect 10 "generation_data generation_data_overflow" && - git commit-graph verify + git init repo && + ( + cd repo && + test_commit --date "$UNIX_EPOCH_ZERO" 1 && + test_commit 2 && + test_commit --date "$UNIX_EPOCH_ZERO" 3 && + git commit-graph write --reachable && + graph_read_expect 3 generation_data && + test_commit --date "$FUTURE_DATE" 4 && + test_commit 5 && + test_commit --date "$UNIX_EPOCH_ZERO" 6 && + git branch left && + git reset --hard 3 && + test_commit 7 && + test_commit --date "$FUTURE_DATE" 8 && + test_commit 9 && + git branch right && + git reset --hard 3 && + test_merge M left right && + git commit-graph write --reachable && + graph_read_expect 10 "generation_data generation_data_overflow" && + git commit-graph verify + ) ' graph_git_behavior 'overflow 2' repo left right test_expect_success 'single commit with generation data exceeding UINT32_MAX' ' git init repo-uint32-max && - cd repo-uint32-max && - test_commit --date "@4294967297 +0000" 1 && - git commit-graph write --reachable && - graph_read_expect 1 "generation_data" && - git commit-graph verify + test_commit -C repo-uint32-max --date "@4294967297 +0000" 1 && + git -C repo-uint32-max commit-graph write --reachable && + graph_read_expect -C repo-uint32-max 1 "generation_data" && + git -C repo-uint32-max commit-graph verify ' test_done diff --git a/t/t5329-pack-objects-cruft.sh b/t/t5329-pack-objects-cruft.sh index 303f7a5d84..45667d4999 100755 --- a/t/t5329-pack-objects-cruft.sh +++ b/t/t5329-pack-objects-cruft.sh @@ -739,4 +739,175 @@ test_expect_success 'cruft objects are freshend via loose' ' ) ' +test_expect_success 'gc.recentObjectsHook' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + # Create a handful of objects. + # + # - one reachable commit, "base", designated for the reachable + # pack + # - one unreachable commit, "cruft.discard", which is marked + # for deletion + # - one unreachable commit, "cruft.old", which would be marked + # for deletion, but is rescued as an extra cruft tip + # - one unreachable commit, "cruft.new", which is not marked + # for deletion + test_commit base && + git branch -M main && + + git checkout --orphan discard && + git rm -fr . && + test_commit --no-tag cruft.discard && + + git checkout --orphan old && + git rm -fr . && + test_commit --no-tag cruft.old && + cruft_old="$(git rev-parse HEAD)" && + + git checkout --orphan new && + git rm -fr . && + test_commit --no-tag cruft.new && + cruft_new="$(git rev-parse HEAD)" && + + git checkout main && + git branch -D discard old new && + git reflog expire --all --expire=all && + + # mark cruft.old with an mtime that is many minutes + # older than the expiration period, and mark cruft.new + # with an mtime that is in the future (and thus not + # eligible for pruning). + test-tool chmtime -2000 "$objdir/$(test_oid_to_path $cruft_old)" && + test-tool chmtime +1000 "$objdir/$(test_oid_to_path $cruft_new)" && + + # Write the list of cruft objects we expect to + # accumulate, which is comprised of everything reachable + # from cruft.old and cruft.new, but not cruft.discard. + git rev-list --objects --no-object-names \ + $cruft_old $cruft_new >cruft.raw && + sort cruft.raw >cruft.expect && + + # Write the script to list extra tips, which are limited + # to cruft.old, in this case. + write_script extra-tips <<-EOF && + echo $cruft_old + EOF + git config gc.recentObjectsHook ./extra-tips && + + git repack --cruft --cruft-expiration=now -d && + + mtimes="$(ls .git/objects/pack/pack-*.mtimes)" && + git show-index <${mtimes%.mtimes}.idx >cruft && + cut -d" " -f2 cruft | sort >cruft.actual && + test_cmp cruft.expect cruft.actual && + + # Ensure that the "old" objects are removed after + # dropping the gc.recentObjectsHook hook. + git config --unset gc.recentObjectsHook && + git repack --cruft --cruft-expiration=now -d && + + mtimes="$(ls .git/objects/pack/pack-*.mtimes)" && + git show-index <${mtimes%.mtimes}.idx >cruft && + cut -d" " -f2 cruft | sort >cruft.actual && + + git rev-list --objects --no-object-names $cruft_new >cruft.raw && + cp cruft.expect cruft.old && + sort cruft.raw >cruft.expect && + test_cmp cruft.expect cruft.actual && + + # ensure objects which are no longer in the cruft pack were + # removed from the repository + for object in $(comm -13 cruft.expect cruft.old) + do + test_must_fail git cat-file -t $object || return 1 + done + ) +' + +test_expect_success 'multi-valued gc.recentObjectsHook' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + git branch -M main && + + git checkout --orphan cruft.a && + git rm -fr . && + test_commit --no-tag cruft.a && + cruft_a="$(git rev-parse HEAD)" && + + git checkout --orphan cruft.b && + git rm -fr . && + test_commit --no-tag cruft.b && + cruft_b="$(git rev-parse HEAD)" && + + git checkout main && + git branch -D cruft.a cruft.b && + git reflog expire --all --expire=all && + + echo "echo $cruft_a" | write_script extra-tips.a && + echo "echo $cruft_b" | write_script extra-tips.b && + echo "false" | write_script extra-tips.c && + + git rev-list --objects --no-object-names $cruft_a $cruft_b \ + >cruft.raw && + sort cruft.raw >cruft.expect && + + # ensure that each extra cruft tip is saved by its + # respective hook + git config --add gc.recentObjectsHook ./extra-tips.a && + git config --add gc.recentObjectsHook ./extra-tips.b && + git repack --cruft --cruft-expiration=now -d && + + mtimes="$(ls .git/objects/pack/pack-*.mtimes)" && + git show-index <${mtimes%.mtimes}.idx >cruft && + cut -d" " -f2 cruft | sort >cruft.actual && + test_cmp cruft.expect cruft.actual && + + # ensure that a dirty exit halts cruft pack generation + git config --add gc.recentObjectsHook ./extra-tips.c && + test_must_fail git repack --cruft --cruft-expiration=now -d 2>err && + grep "unable to enumerate additional recent objects" err && + + # and that the existing cruft pack is left alone + test_path_is_file "$mtimes" + ) +' + +test_expect_success 'additional cruft blobs via gc.recentObjectsHook' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + + blob=$(echo "unreachable" | git hash-object -w --stdin) && + + # mark the unreachable blob we wrote above as having + # aged out of the retention period + test-tool chmtime -2000 "$objdir/$(test_oid_to_path $blob)" && + + # Write the script to list extra tips, which is just the + # extra blob as above. + write_script extra-tips <<-EOF && + echo $blob + EOF + git config gc.recentObjectsHook ./extra-tips && + + git repack --cruft --cruft-expiration=now -d && + + mtimes="$(ls .git/objects/pack/pack-*.mtimes)" && + git show-index <${mtimes%.mtimes}.idx >cruft && + cut -d" " -f2 cruft >actual && + echo $blob >expect && + test_cmp expect actual + ) +' + test_done diff --git a/t/t5351-unpack-large-objects.sh b/t/t5351-unpack-large-objects.sh index 8c8af99b84..43cbcd5d49 100755 --- a/t/t5351-unpack-large-objects.sh +++ b/t/t5351-unpack-large-objects.sh @@ -55,7 +55,7 @@ check_fsync_events () { cat >expect && sed -n \ - -e '/^{"event":"data",.*"category":"fsync",/ { + -e '/^{"event":"counter",.*"category":"fsync",/ { s/.*"category":"fsync",//; s/}$//; p; @@ -78,8 +78,8 @@ test_expect_success 'unpack big object in stream (core.fsyncmethod=batch)' ' flush_count=1 fi && check_fsync_events trace2.txt <<-EOF && - "key":"fsync/writeout-only","value":"6" - "key":"fsync/hardware-flush","value":"$flush_count" + "name":"writeout-only","count":6 + "name":"hardware-flush","count":$flush_count EOF test_dir_is_empty dest.git/objects/pack && diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh index cc07889667..51737eeafe 100755 --- a/t/t5404-tracking-branches.sh +++ b/t/t5404-tracking-branches.sh @@ -5,6 +5,7 @@ test_description='tracking branch update checks for git push' 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/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh index 5f3ff051ca..ad7f8c6f00 100755 --- a/t/t5407-post-rewrite-hook.sh +++ b/t/t5407-post-rewrite-hook.sh @@ -17,6 +17,12 @@ test_expect_success 'setup' ' git checkout A^0 && test_commit E bar E && test_commit F foo F && + git checkout B && + git merge E && + git tag merge-E && + test_commit G G && + test_commit H H && + test_commit I I && git checkout main && test_hook --setup post-rewrite <<-EOF @@ -173,6 +179,48 @@ test_fail_interactive_rebase () { ) } +test_expect_success 'git rebase with failed pick' ' + clear_hook_input && + cat >todo <<-\EOF && + exec >bar + merge -C merge-E E + exec >G + pick G + exec >H 2>I + pick H + fixup I + EOF + + ( + set_replace_editor todo && + test_must_fail git rebase -i D D 2>err + ) && + grep "would be overwritten" err && + rm bar && + + test_must_fail git rebase --continue 2>err && + grep "would be overwritten" err && + rm G && + + test_must_fail git rebase --continue 2>err && + grep "would be overwritten" err && + rm H && + + test_must_fail git rebase --continue 2>err && + grep "would be overwritten" err && + rm I && + + git rebase --continue && + echo rebase >expected.args && + cat >expected.data <<-EOF && + $(git rev-parse merge-E) $(git rev-parse HEAD~2) + $(git rev-parse G) $(git rev-parse HEAD~1) + $(git rev-parse H) $(git rev-parse HEAD) + $(git rev-parse I) $(git rev-parse HEAD) + EOF + verify_hook_input +' + test_expect_success 'git rebase -i (unchanged)' ' git reset --hard D && clear_hook_input && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 4bb9f877ca..5399feda92 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -1127,6 +1127,52 @@ do ' done +test_expect_success 'prepare source branch' ' + echo one >onebranch && + git checkout --orphan onebranch && + git rm --cached -r . && + git add onebranch && + git commit -m onebranch && + git rev-list --objects onebranch -- >actual && + # 3 objects should be created, at least ... + test 3 -le $(wc -l <actual) +' + +validate_store_type () { + git -C dest count-objects -v >actual && + case "$store_type" in + packed) + grep "^count: 0$" actual ;; + loose) + grep "^packs: 0$" actual ;; + esac || { + echo "store_type is $store_type" + cat actual + false + } +} + +test_unpack_limit () { + store_type=$1 + + case "$store_type" in + packed) fetch_limit=1 transfer_limit=10000 ;; + loose) fetch_limit=10000 transfer_limit=1 ;; + esac + + test_expect_success "fetch trumps transfer limit" ' + rm -fr dest && + git --bare init dest && + git -C dest config fetch.unpacklimit $fetch_limit && + git -C dest config transfer.unpacklimit $transfer_limit && + git -C dest fetch .. onebranch && + validate_store_type + ' +} + +test_unpack_limit packed +test_unpack_limit loose + setup_negotiation_tip () { SERVER="$1" URL="$2" diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 19ebefa5ac..87163d7745 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -120,6 +120,17 @@ test_expect_success setup ' ' +for cmd in push fetch +do + for opt in ipv4 ipv6 + do + test_expect_success "reject 'git $cmd --no-$opt'" ' + test_must_fail git $cmd --no-$opt 2>err && + grep "unknown option .no-$opt" err + ' + done +done + test_expect_success 'fetch without wildcard' ' mk_empty testrepo && ( diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh index a448e169bd..6d4944a728 100755 --- a/t/t5517-push-mirror.sh +++ b/t/t5517-push-mirror.sh @@ -5,6 +5,7 @@ test_description='pushing to a mirror repository' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh D=$(pwd) diff --git a/t/t5525-fetch-tagopt.sh b/t/t5525-fetch-tagopt.sh index 45815f7378..3a28f1ded5 100755 --- a/t/t5525-fetch-tagopt.sh +++ b/t/t5525-fetch-tagopt.sh @@ -2,6 +2,7 @@ test_description='tagopt variable affects "git fetch" and is overridden by commandline.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh setup_clone () { diff --git a/t/t5546-receive-limits.sh b/t/t5546-receive-limits.sh index eed3c9d81a..9fc9ba552f 100755 --- a/t/t5546-receive-limits.sh +++ b/t/t5546-receive-limits.sh @@ -9,10 +9,26 @@ TEST_PASSES_SANITIZE_LEAK=true # When the limit is 1, `git receive-pack` will call `git index-pack`. # When the limit is 10000, `git receive-pack` will call `git unpack-objects`. +validate_store_type () { + git -C dest count-objects -v >actual && + case "$store_type" in + index) + grep "^count: 0$" actual ;; + unpack) + grep "^packs: 0$" actual ;; + esac || { + echo "store_type is $store_type" + cat actual + false; + } +} + test_pack_input_limit () { - case "$1" in - index) unpack_limit=1 ;; - unpack) unpack_limit=10000 ;; + store_type=$1 + + case "$store_type" in + index) unpack_limit=1 other_limit=10000 ;; + unpack) unpack_limit=10000 other_limit=1 ;; esac test_expect_success 'prepare destination repository' ' @@ -43,6 +59,19 @@ test_pack_input_limit () { git --git-dir=dest config receive.maxInputSize 0 && git push dest HEAD ' + + test_expect_success 'prepare destination repository (once more)' ' + rm -fr dest && + git --bare init dest + ' + + test_expect_success 'receive trumps transfer' ' + git --git-dir=dest config receive.unpacklimit "$unpack_limit" && + git --git-dir=dest config transfer.unpacklimit "$other_limit" && + git push dest HEAD && + validate_store_type + ' + } test_expect_success "create known-size (1024 bytes) commit" ' diff --git a/t/t5571-pre-push-hook.sh b/t/t5571-pre-push-hook.sh index a11b20e378..448134c4bf 100755 --- a/t/t5571-pre-push-hook.sh +++ b/t/t5571-pre-push-hook.sh @@ -4,6 +4,7 @@ test_description='check pre-push hooks' 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/t5583-push-branches.sh b/t/t5583-push-branches.sh index e7e1b6dab6..320f49c753 100755 --- a/t/t5583-push-branches.sh +++ b/t/t5583-push-branches.sh @@ -5,6 +5,7 @@ test_description='check the consisitency of behavior of --all and --branches' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh delete_refs() { diff --git a/t/t5606-clone-options.sh b/t/t5606-clone-options.sh index 27f9f77638..5890319b97 100755 --- a/t/t5606-clone-options.sh +++ b/t/t5606-clone-options.sh @@ -120,6 +120,16 @@ test_expect_success 'prefers -c config over --template config' ' ' +test_expect_failure 'prefers --template config even for core.bare' ' + + template="$TRASH_DIRECTORY/template-with-bare-config" && + mkdir "$template" && + git config --file "$template/config" core.bare true && + git clone "--template=$template" parent clone-bare-config && + test "$(git -C clone-bare-config config --local core.bare)" = "true" && + test_path_is_file clone-bare-config/HEAD +' + test_expect_success 'prefers config "clone.defaultRemoteName" over default' ' test_config_global clone.defaultRemoteName from_config && diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index f519d2a87a..8759fc2853 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -257,8 +257,8 @@ test_expect_success 'partial clone with transfer.fsckobjects=1 works with submod test_commit -C submodule mycommit && test_create_repo src_with_sub && - test_config -C src_with_sub uploadpack.allowfilter 1 && - test_config -C src_with_sub uploadpack.allowanysha1inwant 1 && + git -C src_with_sub config uploadpack.allowfilter 1 && + git -C src_with_sub config uploadpack.allowanysha1inwant 1 && test_config_global protocol.file.allow always && @@ -270,6 +270,12 @@ test_expect_success 'partial clone with transfer.fsckobjects=1 works with submod test_when_finished rm -rf dst ' +test_expect_success 'lazily fetched .gitmodules works' ' + git clone --filter="blob:none" --no-checkout "file://$(pwd)/src_with_sub" dst && + git -C dst fetch && + test_when_finished rm -rf dst +' + test_expect_success 'partial clone with transfer.fsckobjects=1 uses index-pack --fsck-objects' ' git init src && test_commit -C src x && diff --git a/t/t5811-proto-disable-git.sh b/t/t5811-proto-disable-git.sh index 8ac6b2a1d0..ed773e7432 100755 --- a/t/t5811-proto-disable-git.sh +++ b/t/t5811-proto-disable-git.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test disabling of git-over-tcp in clone/fetch' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY/lib-proto-disable.sh" . "$TEST_DIRECTORY/lib-git-daemon.sh" diff --git a/t/t6017-rev-list-stdin.sh b/t/t6017-rev-list-stdin.sh index 05162512a0..a57f1ae2ba 100755 --- a/t/t6017-rev-list-stdin.sh +++ b/t/t6017-rev-list-stdin.sh @@ -48,7 +48,9 @@ test_expect_success setup ' git add file-$i && test_tick && git commit -m side-$i || exit - done + done && + + git update-ref refs/heads/-dashed-branch HEAD ) ' @@ -60,6 +62,12 @@ check side-1 ^side-7 -- file-2 check side-3 ^side-4 -- file-3 check side-3 ^side-2 check side-3 ^side-2 -- file-1 +check --all +check --all --not --branches +check --glob=refs/heads +check --glob=refs/heads -- +check --glob=refs/heads -- file-1 +check --end-of-options -dashed-branch test_expect_success 'not only --stdin' ' cat >expect <<-EOF && @@ -78,4 +86,45 @@ test_expect_success 'not only --stdin' ' test_cmp expect actual ' +test_expect_success 'pseudo-opt with missing value' ' + cat >input <<-EOF && + --glob + refs/heads + EOF + + cat >expect <<-EOF && + fatal: Option ${SQ}--glob${SQ} requires a value + EOF + + test_must_fail git rev-list --stdin <input 2>error && + test_cmp expect error +' + +test_expect_success 'pseudo-opt with invalid value' ' + cat >input <<-EOF && + --no-walk=garbage + EOF + + cat >expect <<-EOF && + error: invalid argument to --no-walk + fatal: invalid option ${SQ}--no-walk=garbage${SQ} in --stdin mode + EOF + + test_must_fail git rev-list --stdin <input 2>error && + test_cmp expect error +' + +test_expect_success 'unknown option without --end-of-options' ' + cat >input <<-EOF && + -dashed-branch + EOF + + cat >expect <<-EOF && + fatal: invalid option ${SQ}-dashed-branch${SQ} in --stdin mode + EOF + + test_must_fail git rev-list --stdin <input 2>error && + test_cmp expect error +' + test_done diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh index dface8bcfe..3e6bcbf30c 100755 --- a/t/t6020-bundle-misc.sh +++ b/t/t6020-bundle-misc.sh @@ -619,6 +619,12 @@ test_expect_success TTY 'create --quiet disables all bundle progress' ' test_must_be_empty err ' +test_expect_success 'bundle progress with --no-quiet' ' + GIT_PROGRESS_DELAY=0 \ + git bundle create --no-quiet out.bundle --all 2>err && + grep "%" err +' + test_expect_success 'read bundle over stdin' ' git bundle create some.bundle HEAD && diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh index a313849406..7ddbd96e58 100755 --- a/t/t6040-tracking-info.sh +++ b/t/t6040-tracking-info.sh @@ -5,6 +5,7 @@ test_description='remote tracking stats' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh advance () { diff --git a/t/t6050-replace.sh b/t/t6050-replace.sh index 2500acc2ef..c9925edf20 100755 --- a/t/t6050-replace.sh +++ b/t/t6050-replace.sh @@ -62,59 +62,59 @@ HASH6= HASH7= test_expect_success 'set up buggy branch' ' - echo "line 1" >>hello && - echo "line 2" >>hello && - echo "line 3" >>hello && - echo "line 4" >>hello && - add_and_commit_file hello "4 lines" && - HASH1=$(git rev-parse --verify HEAD) && - echo "line BUG" >>hello && - echo "line 6" >>hello && - echo "line 7" >>hello && - echo "line 8" >>hello && - add_and_commit_file hello "4 more lines with a BUG" && - HASH2=$(git rev-parse --verify HEAD) && - echo "line 9" >>hello && - echo "line 10" >>hello && - add_and_commit_file hello "2 more lines" && - HASH3=$(git rev-parse --verify HEAD) && - echo "line 11" >>hello && - add_and_commit_file hello "1 more line" && - HASH4=$(git rev-parse --verify HEAD) && - sed -e "s/BUG/5/" hello >hello.new && - mv hello.new hello && - add_and_commit_file hello "BUG fixed" && - HASH5=$(git rev-parse --verify HEAD) && - echo "line 12" >>hello && - echo "line 13" >>hello && - add_and_commit_file hello "2 more lines" && - HASH6=$(git rev-parse --verify HEAD) && - echo "line 14" >>hello && - echo "line 15" >>hello && - echo "line 16" >>hello && - add_and_commit_file hello "again 3 more lines" && - HASH7=$(git rev-parse --verify HEAD) + echo "line 1" >>hello && + echo "line 2" >>hello && + echo "line 3" >>hello && + echo "line 4" >>hello && + add_and_commit_file hello "4 lines" && + HASH1=$(git rev-parse --verify HEAD) && + echo "line BUG" >>hello && + echo "line 6" >>hello && + echo "line 7" >>hello && + echo "line 8" >>hello && + add_and_commit_file hello "4 more lines with a BUG" && + HASH2=$(git rev-parse --verify HEAD) && + echo "line 9" >>hello && + echo "line 10" >>hello && + add_and_commit_file hello "2 more lines" && + HASH3=$(git rev-parse --verify HEAD) && + echo "line 11" >>hello && + add_and_commit_file hello "1 more line" && + HASH4=$(git rev-parse --verify HEAD) && + sed -e "s/BUG/5/" hello >hello.new && + mv hello.new hello && + add_and_commit_file hello "BUG fixed" && + HASH5=$(git rev-parse --verify HEAD) && + echo "line 12" >>hello && + echo "line 13" >>hello && + add_and_commit_file hello "2 more lines" && + HASH6=$(git rev-parse --verify HEAD) && + echo "line 14" >>hello && + echo "line 15" >>hello && + echo "line 16" >>hello && + add_and_commit_file hello "again 3 more lines" && + HASH7=$(git rev-parse --verify HEAD) ' test_expect_success 'replace the author' ' - git cat-file commit $HASH2 | grep "author A U Thor" && - R=$(git cat-file commit $HASH2 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) && - git cat-file commit $R | grep "author O Thor" && - git update-ref refs/replace/$HASH2 $R && - git show HEAD~5 | grep "O Thor" && - git show $HASH2 | grep "O Thor" + git cat-file commit $HASH2 | grep "author A U Thor" && + R=$(git cat-file commit $HASH2 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) && + git cat-file commit $R | grep "author O Thor" && + git update-ref refs/replace/$HASH2 $R && + git show HEAD~5 | grep "O Thor" && + git show $HASH2 | grep "O Thor" ' test_expect_success 'test --no-replace-objects option' ' - git cat-file commit $HASH2 | grep "author O Thor" && - git --no-replace-objects cat-file commit $HASH2 | grep "author A U Thor" && - git show $HASH2 | grep "O Thor" && - git --no-replace-objects show $HASH2 | grep "A U Thor" + git cat-file commit $HASH2 | grep "author O Thor" && + git --no-replace-objects cat-file commit $HASH2 | grep "author A U Thor" && + git show $HASH2 | grep "O Thor" && + git --no-replace-objects show $HASH2 | grep "A U Thor" ' test_expect_success 'test GIT_NO_REPLACE_OBJECTS env variable' ' - GIT_NO_REPLACE_OBJECTS=1 git cat-file commit $HASH2 | grep "author A U Thor" && - GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 | grep "A U Thor" + GIT_NO_REPLACE_OBJECTS=1 git cat-file commit $HASH2 | grep "author A U Thor" && + GIT_NO_REPLACE_OBJECTS=1 git show $HASH2 | grep "A U Thor" ' test_expect_success 'test core.usereplacerefs config option' ' @@ -132,64 +132,64 @@ tagger T A Gger <> 0 +0000 EOF test_expect_success 'tag replaced commit' ' - git update-ref refs/tags/mytag $(git mktag <tag.sig) + git update-ref refs/tags/mytag $(git mktag <tag.sig) ' test_expect_success '"git fsck" works' ' - git fsck main >fsck_main.out && - test_i18ngrep "dangling commit $R" fsck_main.out && - test_i18ngrep "dangling tag $(git show-ref -s refs/tags/mytag)" fsck_main.out && - test -z "$(git fsck)" + git fsck main >fsck_main.out && + test_i18ngrep "dangling commit $R" fsck_main.out && + test_i18ngrep "dangling tag $(git show-ref -s refs/tags/mytag)" fsck_main.out && + test -z "$(git fsck)" ' test_expect_success 'repack, clone and fetch work' ' - git repack -a -d && - git clone --no-hardlinks . clone_dir && - ( - cd clone_dir && - git show HEAD~5 | grep "A U Thor" && - git show $HASH2 | grep "A U Thor" && - git cat-file commit $R && - git repack -a -d && - test_must_fail git cat-file commit $R && - git fetch ../ "refs/replace/*:refs/replace/*" && - git show HEAD~5 | grep "O Thor" && - git show $HASH2 | grep "O Thor" && - git cat-file commit $R - ) + git repack -a -d && + git clone --no-hardlinks . clone_dir && + ( + cd clone_dir && + git show HEAD~5 | grep "A U Thor" && + git show $HASH2 | grep "A U Thor" && + git cat-file commit $R && + git repack -a -d && + test_must_fail git cat-file commit $R && + git fetch ../ "refs/replace/*:refs/replace/*" && + git show HEAD~5 | grep "O Thor" && + git show $HASH2 | grep "O Thor" && + git cat-file commit $R + ) ' test_expect_success '"git replace" listing and deleting' ' - test "$HASH2" = "$(git replace -l)" && - test "$HASH2" = "$(git replace)" && - aa=${HASH2%??????????????????????????????????????} && - test "$HASH2" = "$(git replace --list "$aa*")" && - test_must_fail git replace -d $R && - test_must_fail git replace --delete && - test_must_fail git replace -l -d $HASH2 && - git replace -d $HASH2 && - git show $HASH2 | grep "A U Thor" && - test -z "$(git replace -l)" + test "$HASH2" = "$(git replace -l)" && + test "$HASH2" = "$(git replace)" && + aa=${HASH2%??????????????????????????????????????} && + test "$HASH2" = "$(git replace --list "$aa*")" && + test_must_fail git replace -d $R && + test_must_fail git replace --delete && + test_must_fail git replace -l -d $HASH2 && + git replace -d $HASH2 && + git show $HASH2 | grep "A U Thor" && + test -z "$(git replace -l)" ' test_expect_success '"git replace" replacing' ' - git replace $HASH2 $R && - git show $HASH2 | grep "O Thor" && - test_must_fail git replace $HASH2 $R && - git replace -f $HASH2 $R && - test_must_fail git replace -f && - test "$HASH2" = "$(git replace)" + git replace $HASH2 $R && + git show $HASH2 | grep "O Thor" && + test_must_fail git replace $HASH2 $R && + git replace -f $HASH2 $R && + test_must_fail git replace -f && + test "$HASH2" = "$(git replace)" ' test_expect_success '"git replace" resolves sha1' ' - SHORTHASH2=$(git rev-parse --short=8 $HASH2) && - git replace -d $SHORTHASH2 && - git replace $SHORTHASH2 $R && - git show $HASH2 | grep "O Thor" && - test_must_fail git replace $HASH2 $R && - git replace -f $HASH2 $R && - test_must_fail git replace --force && - test "$HASH2" = "$(git replace)" + SHORTHASH2=$(git rev-parse --short=8 $HASH2) && + git replace -d $SHORTHASH2 && + git replace $SHORTHASH2 $R && + git show $HASH2 | grep "O Thor" && + test_must_fail git replace $HASH2 $R && + git replace -f $HASH2 $R && + test_must_fail git replace --force && + test "$HASH2" = "$(git replace)" ' # This creates a side branch where the bug in H2 @@ -207,79 +207,79 @@ test_expect_success '"git replace" resolves sha1' ' # Then we replace H6 with P6. # test_expect_success 'create parallel branch without the bug' ' - git replace -d $HASH2 && - git show $HASH2 | grep "A U Thor" && - git checkout $HASH1 && - git cherry-pick $HASH2 && - git show $HASH5 | git apply && - git commit --amend -m "hello: 4 more lines WITHOUT the bug" hello && - PARA2=$(git rev-parse --verify HEAD) && - git cherry-pick $HASH3 && - PARA3=$(git rev-parse --verify HEAD) && - git cherry-pick $HASH4 && - PARA4=$(git rev-parse --verify HEAD) && - git cherry-pick $HASH6 && - PARA6=$(git rev-parse --verify HEAD) && - git replace $HASH6 $PARA6 && - git checkout main && - cur=$(git rev-parse --verify HEAD) && - test "$cur" = "$HASH7" && - git log --pretty=oneline | grep $PARA2 && - git remote add cloned ./clone_dir + git replace -d $HASH2 && + git show $HASH2 | grep "A U Thor" && + git checkout $HASH1 && + git cherry-pick $HASH2 && + git show $HASH5 | git apply && + git commit --amend -m "hello: 4 more lines WITHOUT the bug" hello && + PARA2=$(git rev-parse --verify HEAD) && + git cherry-pick $HASH3 && + PARA3=$(git rev-parse --verify HEAD) && + git cherry-pick $HASH4 && + PARA4=$(git rev-parse --verify HEAD) && + git cherry-pick $HASH6 && + PARA6=$(git rev-parse --verify HEAD) && + git replace $HASH6 $PARA6 && + git checkout main && + cur=$(git rev-parse --verify HEAD) && + test "$cur" = "$HASH7" && + git log --pretty=oneline | grep $PARA2 && + git remote add cloned ./clone_dir ' test_expect_success 'push to cloned repo' ' - git push cloned $HASH6^:refs/heads/parallel && - ( - cd clone_dir && - git checkout parallel && - git log --pretty=oneline | grep $PARA2 - ) + git push cloned $HASH6^:refs/heads/parallel && + ( + cd clone_dir && + git checkout parallel && + git log --pretty=oneline | grep $PARA2 + ) ' test_expect_success 'push branch with replacement' ' - git cat-file commit $PARA3 | grep "author A U Thor" && - S=$(git cat-file commit $PARA3 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) && - git cat-file commit $S | grep "author O Thor" && - git replace $PARA3 $S && - git show $HASH6~2 | grep "O Thor" && - git show $PARA3 | grep "O Thor" && - git push cloned $HASH6^:refs/heads/parallel2 && - ( - cd clone_dir && - git checkout parallel2 && - git log --pretty=oneline | grep $PARA3 && - git show $PARA3 | grep "A U Thor" - ) + git cat-file commit $PARA3 | grep "author A U Thor" && + S=$(git cat-file commit $PARA3 | sed -e "s/A U/O/" | git hash-object -t commit --stdin -w) && + git cat-file commit $S | grep "author O Thor" && + git replace $PARA3 $S && + git show $HASH6~2 | grep "O Thor" && + git show $PARA3 | grep "O Thor" && + git push cloned $HASH6^:refs/heads/parallel2 && + ( + cd clone_dir && + git checkout parallel2 && + git log --pretty=oneline | grep $PARA3 && + git show $PARA3 | grep "A U Thor" + ) ' test_expect_success 'fetch branch with replacement' ' - git branch tofetch $HASH6 && - ( - cd clone_dir && - git fetch origin refs/heads/tofetch:refs/heads/parallel3 && - git log --pretty=oneline parallel3 >output.txt && - ! grep $PARA3 output.txt && - git show $PARA3 >para3.txt && - grep "A U Thor" para3.txt && - git fetch origin "refs/replace/*:refs/replace/*" && - git log --pretty=oneline parallel3 >output.txt && - grep $PARA3 output.txt && - git show $PARA3 >para3.txt && - grep "O Thor" para3.txt - ) + git branch tofetch $HASH6 && + ( + cd clone_dir && + git fetch origin refs/heads/tofetch:refs/heads/parallel3 && + git log --pretty=oneline parallel3 >output.txt && + ! grep $PARA3 output.txt && + git show $PARA3 >para3.txt && + grep "A U Thor" para3.txt && + git fetch origin "refs/replace/*:refs/replace/*" && + git log --pretty=oneline parallel3 >output.txt && + grep $PARA3 output.txt && + git show $PARA3 >para3.txt && + grep "O Thor" para3.txt + ) ' test_expect_success 'bisect and replacements' ' - git bisect start $HASH7 $HASH1 && - test "$PARA3" = "$(git rev-parse --verify HEAD)" && - git bisect reset && - GIT_NO_REPLACE_OBJECTS=1 git bisect start $HASH7 $HASH1 && - test "$HASH4" = "$(git rev-parse --verify HEAD)" && - git bisect reset && - git --no-replace-objects bisect start $HASH7 $HASH1 && - test "$HASH4" = "$(git rev-parse --verify HEAD)" && - git bisect reset + git bisect start $HASH7 $HASH1 && + test "$PARA3" = "$(git rev-parse --verify HEAD)" && + git bisect reset && + GIT_NO_REPLACE_OBJECTS=1 git bisect start $HASH7 $HASH1 && + test "$HASH4" = "$(git rev-parse --verify HEAD)" && + git bisect reset && + git --no-replace-objects bisect start $HASH7 $HASH1 && + test "$HASH4" = "$(git rev-parse --verify HEAD)" && + git bisect reset ' test_expect_success 'index-pack and replacements' ' diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index c9afcef201..0a5c487540 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -85,6 +85,7 @@ check_describe e-1-gHASH --tags HEAD^^ check_describe c-2-gHASH --tags HEAD^^2 check_describe B --tags HEAD^^2^ check_describe e --tags HEAD^^^ +check_describe e --tags --exact-match HEAD^^^ check_describe heads/main --all HEAD check_describe tags/c-6-gHASH --all HEAD^ @@ -96,6 +97,13 @@ check_describe A-3-gHASH --long HEAD^^2 check_describe c-7-gHASH --tags check_describe e-3-gHASH --first-parent --tags +check_describe c-7-gHASH --tags --no-exact-match HEAD +check_describe e-3-gHASH --first-parent --tags --no-exact-match HEAD + +test_expect_success '--exact-match failure' ' + test_must_fail git describe --exact-match HEAD 2>err +' + test_expect_success 'describe --contains defaults to HEAD without commit-ish' ' echo "A^0" >expect && git checkout A && diff --git a/t/t6135-pathspec-with-attrs.sh b/t/t6135-pathspec-with-attrs.sh index 457cc167c7..f70c395e75 100755 --- a/t/t6135-pathspec-with-attrs.sh +++ b/t/t6135-pathspec-with-attrs.sh @@ -65,7 +65,8 @@ test_expect_success 'setup .gitattributes' ' fileValue label=foo fileWrongLabel label☺ EOF - git add .gitattributes && + echo fileSetLabel label1 >sub/.gitattributes && + git add .gitattributes sub/.gitattributes && git commit -m "add attributes" ' @@ -78,7 +79,17 @@ test_expect_success 'check specific set attr' ' test_cmp expect actual ' -test_expect_success 'check specific set attr (2)' ' +test_expect_success 'check set attr with pathspec pattern' ' + echo sub/fileSetLabel >expect && + + git ls-files ":(attr:label)sub" >actual && + test_cmp expect actual && + + git ls-files ":(attr:label)sub/" >actual && + test_cmp expect actual +' + +test_expect_success 'check specific set attr in tree-ish' ' cat <<-\EOF >expect && HEAD:fileSetLabel HEAD:sub/fileSetLabel @@ -87,6 +98,16 @@ test_expect_success 'check specific set attr (2)' ' test_cmp expect actual ' +test_expect_success 'check specific set attr with pathspec pattern in tree-ish' ' + echo HEAD:sub/fileSetLabel >expect && + + git grep -l content HEAD ":(attr:label)sub" >actual && + test_cmp expect actual && + + git grep -l content HEAD ":(attr:label)sub/" >actual && + test_cmp expect actual +' + test_expect_success 'check specific unset attr' ' cat <<-\EOF >expect && fileUnsetLabel @@ -137,6 +158,7 @@ test_expect_success 'check unspecified attr' ' fileC fileNoLabel fileWrongLabel + sub/.gitattributes sub/fileA sub/fileAB sub/fileAC @@ -161,6 +183,7 @@ test_expect_success 'check unspecified attr (2)' ' HEAD:fileC HEAD:fileNoLabel HEAD:fileWrongLabel + HEAD:sub/.gitattributes HEAD:sub/fileA HEAD:sub/fileAB HEAD:sub/fileAC @@ -180,6 +203,7 @@ test_expect_success 'check multiple unspecified attr' ' fileC fileNoLabel fileWrongLabel + sub/.gitattributes sub/fileC sub/fileNoLabel sub/fileWrongLabel @@ -253,4 +277,22 @@ test_expect_success 'backslash cannot be used as a value' ' test_i18ngrep "for value matching" actual ' +test_expect_success 'reading from .gitattributes in a subdirectory (1)' ' + git ls-files ":(attr:label1)" >actual && + test_write_lines "sub/fileSetLabel" >expect && + test_cmp expect actual +' + +test_expect_success 'reading from .gitattributes in a subdirectory (2)' ' + git ls-files ":(attr:label1)sub" >actual && + test_write_lines "sub/fileSetLabel" >expect && + test_cmp expect actual +' + +test_expect_success 'reading from .gitattributes in a subdirectory (3)' ' + git ls-files ":(attr:label1)sub/" >actual && + test_write_lines "sub/fileSetLabel" >expect && + test_cmp expect actual +' + test_done diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index 5c00607608..7b943fd34c 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -6,6 +6,7 @@ test_description='for-each-ref test' . ./test-lib.sh +GNUPGHOME_NOT_USED=$GNUPGHOME . "$TEST_DIRECTORY"/lib-gpg.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -448,6 +449,41 @@ test_expect_success 'exercise glob patterns with prefixes' ' ' cat >expected <<\EOF +refs/tags/bar +refs/tags/baz +refs/tags/testtag +EOF + +test_expect_success 'exercise patterns with prefix exclusions' ' + for tag in foo/one foo/two foo/three bar baz + do + git tag "$tag" || return 1 + done && + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && + git for-each-ref --format="%(refname)" \ + refs/tags/ --exclude=refs/tags/foo >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/tags/bar +refs/tags/baz +refs/tags/foo/one +refs/tags/testtag +EOF + +test_expect_success 'exercise patterns with pattern exclusions' ' + for tag in foo/one foo/two foo/three bar baz + do + git tag "$tag" || return 1 + done && + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && + git for-each-ref --format="%(refname)" \ + refs/tags/ --exclude="refs/tags/foo/t*" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF 'refs/heads/main' 'refs/remotes/origin/main' 'refs/tags/testtag' @@ -561,6 +597,144 @@ test_expect_success 'color.ui=always does not override tty check' ' test_cmp expected.bare actual ' +test_expect_success 'setup for describe atom tests' ' + git init -b master describe-repo && + ( + cd describe-repo && + + test_commit --no-tag one && + git tag tagone && + + test_commit --no-tag two && + git tag -a -m "tag two" tagtwo + ) +' + +test_expect_success 'describe atom vs git describe' ' + ( + cd describe-repo && + + git for-each-ref --format="%(objectname)" \ + refs/tags/ >obj && + while read hash + do + if desc=$(git describe $hash) + then + : >expect-contains-good + else + : >expect-contains-bad + fi && + echo "$hash $desc" || return 1 + done <obj >expect && + test_path_exists expect-contains-good && + test_path_exists expect-contains-bad && + + git for-each-ref --format="%(objectname) %(describe)" \ + refs/tags/ >actual 2>err && + test_cmp expect actual && + test_must_be_empty err + ) +' + +test_expect_success 'describe:tags vs describe --tags' ' + ( + cd describe-repo && + git describe --tags >expect && + git for-each-ref --format="%(describe:tags)" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'describe:abbrev=... vs describe --abbrev=...' ' + ( + cd describe-repo && + + # Case 1: We have commits between HEAD and the most + # recent tag reachable from it + test_commit --no-tag file && + git describe --abbrev=14 >expect && + git for-each-ref --format="%(describe:abbrev=14)" \ + refs/heads/master >actual && + test_cmp expect actual && + + # Make sure the hash used is atleast 14 digits long + sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" <actual >hexpart && + test 15 -le $(wc -c <hexpart) && + + # Case 2: We have a tag at HEAD, describe directly gives + # the name of the tag + git tag -a -m tagged tagname && + git describe --abbrev=14 >expect && + git for-each-ref --format="%(describe:abbrev=14)" \ + refs/heads/master >actual && + test_cmp expect actual && + test tagname = $(cat actual) + ) +' + +test_expect_success 'describe:match=... vs describe --match ...' ' + ( + cd describe-repo && + git tag -a -m "tag foo" tag-foo && + git describe --match "*-foo" >expect && + git for-each-ref --format="%(describe:match="*-foo")" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'describe:exclude:... vs describe --exclude ...' ' + ( + cd describe-repo && + git tag -a -m "tag bar" tag-bar && + git describe --exclude "*-bar" >expect && + git for-each-ref --format="%(describe:exclude="*-bar")" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'deref with describe atom' ' + ( + cd describe-repo && + cat >expect <<-\EOF && + + tagname + tagname + tagname + + tagtwo + EOF + git for-each-ref --format="%(*describe)" >actual && + test_cmp expect actual + ) +' + +test_expect_success 'err on bad describe atom arg' ' + ( + cd describe-repo && + + # The bad arg is the only arg passed to describe atom + cat >expect <<-\EOF && + fatal: unrecognized %(describe) argument: baz + EOF + test_must_fail git for-each-ref --format="%(describe:baz)" \ + refs/heads/master 2>actual && + test_cmp expect actual && + + # The bad arg is in the middle of the option string + # passed to the describe atom + cat >expect <<-\EOF && + fatal: unrecognized %(describe) argument: qux=1,abbrev=14 + EOF + test_must_fail git for-each-ref \ + --format="%(describe:tags,qux=1,abbrev=14)" \ + ref/heads/master 2>actual && + test_cmp expect actual + ) +' + cat >expected <<\EOF heads/main tags/main @@ -843,16 +1017,16 @@ test_expect_success 'Verify sorts with raw' ' test_expect_success 'Verify sorts with raw:size' ' cat >expected <<-EOF && refs/myblobs/blob8 - refs/myblobs/first refs/myblobs/blob7 - refs/heads/main refs/myblobs/blob4 refs/myblobs/blob1 refs/myblobs/blob2 refs/myblobs/blob3 refs/myblobs/blob5 refs/myblobs/blob6 + refs/myblobs/first refs/mytrees/first + refs/heads/main EOF git for-each-ref --format="%(refname)" --sort=raw:size \ refs/heads/main refs/myblobs/ refs/mytrees/first >actual && @@ -964,6 +1138,17 @@ test_expect_success 'for-each-ref --format compare with cat-file --batch' ' test_cmp expected actual ' +test_expect_success 'verify sorts with contents:size' ' + cat >expect <<-\EOF && + refs/heads/main + refs/heads/newtag + refs/heads/ambiguous + EOF + git for-each-ref --format="%(refname)" \ + --sort=contents:size refs/heads/ >actual && + test_cmp expect actual +' + test_expect_success 'set up multiple-sort tags' ' for when in 100000 200000 do @@ -1522,4 +1707,192 @@ test_expect_success 'git for-each-ref with non-existing refs' ' test_must_be_empty actual ' +GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" +TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" + +test_expect_success GPG 'setup for signature atom using gpg' ' + git checkout -b signed && + + test_when_finished "test_unconfig commit.gpgSign" && + + echo "1" >file && + git add file && + test_tick && + git commit -S -m "file: 1" && + git tag first-signed && + + echo "2" >file && + test_tick && + git commit -a -m "file: 2" && + git tag second-unsigned && + + git config commit.gpgSign 1 && + echo "3" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 3" && + git tag third-unsigned && + + test_tick && + git rebase -f HEAD^^ && git tag second-signed HEAD^ && + git tag third-signed && + + echo "4" >file && + test_tick && + git commit -a -SB7227189 -m "file: 4" && + git tag fourth-signed && + + echo "5" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 5" && + git tag fifth-unsigned && + + echo "6" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 6" && + + test_tick && + git rebase -f HEAD^^ && + git tag fifth-signed HEAD^ && + git tag sixth-signed && + + echo "7" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 7" && + git tag seventh-unsigned +' + +test_expect_success GPGSSH 'setup for signature atom using ssh' ' + test_when_finished "test_unconfig gpg.format user.signingkey" && + + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + echo "8" >file && + test_tick && + git add file && + git commit -S -m "file: 8" && + git tag eighth-signed-ssh +' + +test_expect_success GPG2 'bare signature atom' ' + git verify-commit first-signed 2>expect && + echo >>expect && + git for-each-ref refs/tags/first-signed \ + --format="%(signature)" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show good signature with custom format' ' + git verify-commit first-signed && + cat >expect <<-\EOF && + G + 13B6F51ECDDE430D + C O Mitter <committer@example.com> + 73D758744BE721698EC54E8713B6F51ECDDE430D + 73D758744BE721698EC54E8713B6F51ECDDE430D + EOF + git for-each-ref refs/tags/first-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' +test_expect_success GPGSSH 'show good signature with custom format + with ssh' ' + 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 for-each-ref refs/tags/eighth-signed-ssh \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'signature atom with grade option and bad signature' ' + git cat-file commit third-signed >raw && + sed -e "s/^file: 3/file: 3 forged/" raw >forged1 && + FORGED1=$(git hash-object -w -t commit forged1) && + git update-ref refs/tags/third-signed "$FORGED1" && + test_must_fail git verify-commit "$FORGED1" && + + cat >expect <<-\EOF && + B + 13B6F51ECDDE430D + C O Mitter <committer@example.com> + + + EOF + git for-each-ref refs/tags/third-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with custom format' ' + cat >expect <<-\EOF && + U + 65A0EEA02E30CAD7 + Eris Discordia <discord@example.net> + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 + D4BE22311AD3131E5EDA29A461092E85B7227189 + EOF + git for-each-ref refs/tags/fourth-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with undefined trust level' ' + cat >expect <<-\EOF && + undefined + 65A0EEA02E30CAD7 + Eris Discordia <discord@example.net> + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 + D4BE22311AD3131E5EDA29A461092E85B7227189 + EOF + git for-each-ref refs/tags/fourth-signed \ + --format="$TRUSTLEVEL_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with ultimate trust level' ' + cat >expect <<-\EOF && + ultimate + 13B6F51ECDDE430D + C O Mitter <committer@example.com> + 73D758744BE721698EC54E8713B6F51ECDDE430D + 73D758744BE721698EC54E8713B6F51ECDDE430D + EOF + git for-each-ref refs/tags/sixth-signed \ + --format="$TRUSTLEVEL_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show unknown signature with custom format' ' + cat >expect <<-\EOF && + E + 13B6F51ECDDE430D + + + + EOF + GNUPGHOME="$GNUPGHOME_NOT_USED" git for-each-ref \ + refs/tags/sixth-signed --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show lack of signature with custom format' ' + cat >expect <<-\EOF && + N + + + + + EOF + git for-each-ref refs/tags/seventh-unsigned \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index 1ce5f490e9..af223e44d6 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -45,6 +45,8 @@ test_expect_success 'check signed tags with --points-at' ' sed -e "s/Z$//" >expect <<-\EOF && refs/heads/side Z refs/tags/annotated-tag four + refs/tags/doubly-annotated-tag An annotated tag + refs/tags/doubly-signed-tag A signed tag refs/tags/four Z refs/tags/signed-tag four EOF diff --git a/t/t6406-merge-attr.sh b/t/t6406-merge-attr.sh index 5e4e4dd6d9..9677180a5b 100755 --- a/t/t6406-merge-attr.sh +++ b/t/t6406-merge-attr.sh @@ -56,6 +56,12 @@ test_expect_success setup ' ) >"$ours+" cat "$ours+" >"$ours" rm -f "$ours+" + + if test -f ./please-abort + then + echo >>./please-abort killing myself + kill -9 $$ + fi exit "$exit" EOF chmod +x ./custom-merge @@ -162,6 +168,23 @@ test_expect_success 'custom merge backend' ' rm -f $o $a $b ' +test_expect_success !WINDOWS 'custom merge driver that is killed with a signal' ' + test_when_finished "rm -f output please-abort" && + + git reset --hard anchor && + git config --replace-all \ + merge.custom.driver "./custom-merge %O %A %B 0 %P" && + git config --replace-all \ + merge.custom.name "custom merge driver for testing" && + + >./please-abort && + echo "* merge=custom" >.gitattributes && + test_must_fail git merge main && + git ls-files -u >output && + git diff --name-only HEAD >>output && + test_must_be_empty output +' + test_expect_success 'up-to-date merge without common ancestor' ' git init repo1 && git init repo2 && diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 898a920532..f136ea76f7 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -174,6 +174,13 @@ test_expect_success 'do not move directory over existing directory' ' test_must_fail git mv path2 path0 ' +test_expect_success 'rename directory to non-existing directory' ' + mkdir dir-a && + >dir-a/f && + git add dir-a && + git mv dir-a non-existing-dir +' + test_expect_success 'move into "."' ' git mv path1/path2/ . ' diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index 0fe6ba93a2..e689db4292 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -2188,4 +2188,23 @@ test_expect_success 'Does --[no-]contains stop at commits? Yes!' ' test_cmp expected actual ' +test_expect_success 'If tag is created then tag message file is unlinked' ' + test_when_finished "git tag -d foo" && + write_script fakeeditor <<-\EOF && + echo Message >.git/TAG_EDITMSG + EOF + GIT_EDITOR=./fakeeditor git tag -a foo && + test_path_is_missing .git/TAG_EDITMSG +' + +test_expect_success 'If tag cannot be created then tag message file is not unlinked' ' + test_when_finished "git tag -d foo/bar && rm .git/TAG_EDITMSG" && + write_script fakeeditor <<-\EOF && + echo Message >.git/TAG_EDITMSG + EOF + git tag foo/bar && + test_must_fail env GIT_EDITOR=./fakeeditor git tag -a foo && + test_path_exists .git/TAG_EDITMSG +' + test_done diff --git a/t/t7101-reset-empty-subdirs.sh b/t/t7101-reset-empty-subdirs.sh index 638bb04e21..89cf98b30c 100755 --- a/t/t7101-reset-empty-subdirs.sh +++ b/t/t7101-reset-empty-subdirs.sh @@ -10,57 +10,57 @@ TEST_PASSES_SANITIZE_LEAK=true . "$TEST_DIRECTORY"/lib-diff-data.sh test_expect_success 'creating initial files' ' - mkdir path0 && - COPYING_test_data >path0/COPYING && - git add path0/COPYING && - git commit -m add -a + mkdir path0 && + COPYING_test_data >path0/COPYING && + git add path0/COPYING && + git commit -m add -a ' test_expect_success 'creating second files' ' - mkdir path1 && - mkdir path1/path2 && - 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 && - git add path0/COPYING-TOO && - git commit -m change -a + mkdir path1 && + mkdir path1/path2 && + 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 && + git add path0/COPYING-TOO && + git commit -m change -a ' test_expect_success 'resetting tree HEAD^' ' - git reset --hard HEAD^ + git reset --hard HEAD^ ' test_expect_success 'checking initial files exist after rewind' ' - test -d path0 && - test -f path0/COPYING + test -d path0 && + test -f path0/COPYING ' test_expect_success 'checking lack of path1/path2/COPYING' ' - ! test -f path1/path2/COPYING + ! test -f path1/path2/COPYING ' test_expect_success 'checking lack of path1/COPYING' ' - ! test -f path1/COPYING + ! test -f path1/COPYING ' test_expect_success 'checking lack of COPYING' ' - ! test -f COPYING + ! test -f COPYING ' test_expect_success 'checking checking lack of path1/COPYING-TOO' ' - ! test -f path0/COPYING-TOO + ! test -f path0/COPYING-TOO ' test_expect_success 'checking lack of path1/path2' ' - ! test -d path1/path2 + ! test -d path1/path2 ' test_expect_success 'checking lack of path1' ' - ! test -d path1 + ! test -d path1 ' test_done diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 22477f3a31..4287863ae6 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -71,6 +71,16 @@ check_changes () { done | test_cmp .cat_expect - } +# no negated form for various type of resets +for opt in soft mixed hard merge keep +do + test_expect_success "no 'git reset --no-$opt'" ' + test_when_finished "rm -f err" && + test_must_fail git reset --no-$opt 2>err && + grep "error: unknown option .no-$opt." err + ' +done + test_expect_success 'reset --hard message' ' hex=$(git log -1 --format="%h") && git reset --hard >.actual && diff --git a/t/t7110-reset-merge.sh b/t/t7110-reset-merge.sh index eb881be95b..772480a345 100755 --- a/t/t7110-reset-merge.sh +++ b/t/t7110-reset-merge.sh @@ -9,17 +9,17 @@ TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' - printf "line %d\n" 1 2 3 >file1 && - cat file1 >file2 && - git add file1 file2 && - test_tick && - git commit -m "Initial commit" && - git tag initial && - echo line 4 >>file1 && - cat file1 >file2 && - test_tick && - git commit -m "add line 4 to file1" file1 && - git tag second + printf "line %d\n" 1 2 3 >file1 && + cat file1 >file2 && + git add file1 file2 && + test_tick && + git commit -m "Initial commit" && + git tag initial && + echo line 4 >>file1 && + cat file1 >file2 && + test_tick && + git commit -m "add line 4 to file1" file1 && + git tag second ' # The next test will test the following: @@ -29,19 +29,19 @@ test_expect_success setup ' # file1: C C C D --merge D D D # file2: C D D D --merge C D D test_expect_success 'reset --merge is ok with changes in file it does not touch' ' - git reset --merge HEAD^ && - ! grep 4 file1 && - grep 4 file2 && - test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && - test -z "$(git diff --cached)" + git reset --merge HEAD^ && + ! grep 4 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff --cached)" ' test_expect_success 'reset --merge is ok when switching back' ' - git reset --merge second && - grep 4 file1 && - grep 4 file2 && - test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && - test -z "$(git diff --cached)" + git reset --merge second && + grep 4 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" ' # The next test will test the following: @@ -51,21 +51,21 @@ test_expect_success 'reset --merge is ok when switching back' ' # file1: C C C D --keep D D D # file2: C D D D --keep C D D test_expect_success 'reset --keep is ok with changes in file it does not touch' ' - git reset --hard second && - cat file1 >file2 && - git reset --keep HEAD^ && - ! grep 4 file1 && - grep 4 file2 && - test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && - test -z "$(git diff --cached)" + git reset --hard second && + cat file1 >file2 && + git reset --keep HEAD^ && + ! grep 4 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff --cached)" ' test_expect_success 'reset --keep is ok when switching back' ' - git reset --keep second && - grep 4 file1 && - grep 4 file2 && - test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && - test -z "$(git diff --cached)" + git reset --keep second && + grep 4 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" ' # The next test will test the following: @@ -75,28 +75,28 @@ test_expect_success 'reset --keep is ok when switching back' ' # file1: B B C D --merge D D D # file2: C D D D --merge C D D test_expect_success 'reset --merge discards changes added to index (1)' ' - git reset --hard second && - cat file1 >file2 && - echo "line 5" >> file1 && - git add file1 && - git reset --merge HEAD^ && - ! grep 4 file1 && - ! grep 5 file1 && - grep 4 file2 && - test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && - test -z "$(git diff --cached)" + git reset --hard second && + cat file1 >file2 && + echo "line 5" >> file1 && + git add file1 && + git reset --merge HEAD^ && + ! grep 4 file1 && + ! grep 5 file1 && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff --cached)" ' test_expect_success 'reset --merge is ok again when switching back (1)' ' - git reset --hard initial && - echo "line 5" >> file2 && - git add file2 && - git reset --merge second && - ! grep 4 file2 && - ! grep 5 file1 && - grep 4 file1 && - test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && - test -z "$(git diff --cached)" + git reset --hard initial && + echo "line 5" >> file2 && + git add file2 && + git reset --merge second && + ! grep 4 file2 && + ! grep 5 file1 && + grep 4 file1 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" ' # The next test will test the following: @@ -105,10 +105,10 @@ test_expect_success 'reset --merge is ok again when switching back (1)' ' # ---------------------------------------------------- # file1: B B C D --keep (disallowed) test_expect_success 'reset --keep fails with changes in index in files it touches' ' - git reset --hard second && - echo "line 5" >> file1 && - git add file1 && - test_must_fail git reset --keep HEAD^ + git reset --hard second && + echo "line 5" >> file1 && + git add file1 && + test_must_fail git reset --keep HEAD^ ' # The next test will test the following: @@ -118,23 +118,23 @@ test_expect_success 'reset --keep fails with changes in index in files it touche # file1: C C C D --merge D D D # file2: C C D D --merge D D D test_expect_success 'reset --merge discards changes added to index (2)' ' - git reset --hard second && - echo "line 4" >> file2 && - git add file2 && - git reset --merge HEAD^ && - ! grep 4 file2 && - test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && - test -z "$(git diff)" && - test -z "$(git diff --cached)" + git reset --hard second && + echo "line 4" >> file2 && + git add file2 && + git reset --merge HEAD^ && + ! grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff)" && + test -z "$(git diff --cached)" ' test_expect_success 'reset --merge is ok again when switching back (2)' ' - git reset --hard initial && - git reset --merge second && - ! grep 4 file2 && - grep 4 file1 && - test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && - test -z "$(git diff --cached)" + git reset --hard initial && + git reset --merge second && + ! grep 4 file2 && + grep 4 file1 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" ' # The next test will test the following: @@ -144,21 +144,21 @@ test_expect_success 'reset --merge is ok again when switching back (2)' ' # file1: C C C D --keep D D D # file2: C C D D --keep C D D test_expect_success 'reset --keep keeps changes it does not touch' ' - git reset --hard second && - echo "line 4" >> file2 && - git add file2 && - git reset --keep HEAD^ && - grep 4 file2 && - test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && - test -z "$(git diff --cached)" + git reset --hard second && + echo "line 4" >> file2 && + git add file2 && + git reset --keep HEAD^ && + grep 4 file2 && + test "$(git rev-parse HEAD)" = "$(git rev-parse initial)" && + test -z "$(git diff --cached)" ' test_expect_success 'reset --keep keeps changes when switching back' ' - git reset --keep second && - grep 4 file2 && - grep 4 file1 && - test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && - test -z "$(git diff --cached)" + git reset --keep second && + grep 4 file2 && + grep 4 file1 && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" ' # The next test will test the following: @@ -167,14 +167,14 @@ test_expect_success 'reset --keep keeps changes when switching back' ' # ---------------------------------------------------- # file1: A B B C --merge (disallowed) test_expect_success 'reset --merge fails with changes in file it touches' ' - git reset --hard second && - echo "line 5" >> file1 && - test_tick && - git commit -m "add line 5" file1 && - sed -e "s/line 1/changed line 1/" <file1 >file3 && - mv file3 file1 && - test_must_fail git reset --merge HEAD^ 2>err.log && - grep file1 err.log | grep "not uptodate" + git reset --hard second && + echo "line 5" >> file1 && + test_tick && + git commit -m "add line 5" file1 && + sed -e "s/line 1/changed line 1/" <file1 >file3 && + mv file3 file1 && + test_must_fail git reset --merge HEAD^ 2>err.log && + grep file1 err.log | grep "not uptodate" ' # The next test will test the following: @@ -183,36 +183,36 @@ test_expect_success 'reset --merge fails with changes in file it touches' ' # ---------------------------------------------------- # file1: A B B C --keep (disallowed) test_expect_success 'reset --keep fails with changes in file it touches' ' - git reset --hard second && - echo "line 5" >> file1 && - test_tick && - git commit -m "add line 5" file1 && - sed -e "s/line 1/changed line 1/" <file1 >file3 && - mv file3 file1 && - test_must_fail git reset --keep HEAD^ 2>err.log && - grep file1 err.log | grep "not uptodate" + git reset --hard second && + echo "line 5" >> file1 && + test_tick && + git commit -m "add line 5" file1 && + sed -e "s/line 1/changed line 1/" <file1 >file3 && + mv file3 file1 && + test_must_fail git reset --keep HEAD^ 2>err.log && + grep file1 err.log | grep "not uptodate" ' test_expect_success 'setup 3 different branches' ' - git reset --hard second && - git branch branch1 && - git branch branch2 && - git branch branch3 && - git checkout branch1 && - echo "line 5 in branch1" >> file1 && - test_tick && - git commit -a -m "change in branch1" && - git checkout branch2 && - echo "line 5 in branch2" >> file1 && - test_tick && - git commit -a -m "change in branch2" && - git tag third && - git checkout branch3 && - echo a new file >file3 && - rm -f file1 && - git add file3 && - test_tick && - git commit -a -m "change in branch3" + git reset --hard second && + git branch branch1 && + git branch branch2 && + git branch branch3 && + git checkout branch1 && + echo "line 5 in branch1" >> file1 && + test_tick && + git commit -a -m "change in branch1" && + git checkout branch2 && + echo "line 5 in branch2" >> file1 && + test_tick && + git commit -a -m "change in branch2" && + git tag third && + git checkout branch3 && + echo a new file >file3 && + rm -f file1 && + git add file3 && + test_tick && + git commit -a -m "change in branch3" ' # The next test will test the following: @@ -221,12 +221,12 @@ test_expect_success 'setup 3 different branches' ' # ---------------------------------------------------- # file1: X U B C --merge C C C test_expect_success '"reset --merge HEAD^" is ok with pending merge' ' - git checkout third && - test_must_fail git merge branch1 && - git reset --merge HEAD^ && - test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && - test -z "$(git diff --cached)" && - test -z "$(git diff)" + git checkout third && + test_must_fail git merge branch1 && + git reset --merge HEAD^ && + test "$(git rev-parse HEAD)" = "$(git rev-parse second)" && + test -z "$(git diff --cached)" && + test -z "$(git diff)" ' # The next test will test the following: @@ -235,10 +235,10 @@ test_expect_success '"reset --merge HEAD^" is ok with pending merge' ' # ---------------------------------------------------- # file1: X U B C --keep (disallowed) test_expect_success '"reset --keep HEAD^" fails with pending merge' ' - git reset --hard third && - test_must_fail git merge branch1 && - test_must_fail git reset --keep HEAD^ 2>err.log && - test_i18ngrep "middle of a merge" err.log + git reset --hard third && + test_must_fail git merge branch1 && + test_must_fail git reset --keep HEAD^ 2>err.log && + test_i18ngrep "middle of a merge" err.log ' # The next test will test the following: @@ -247,12 +247,12 @@ test_expect_success '"reset --keep HEAD^" fails with pending merge' ' # ---------------------------------------------------- # file1: X U B B --merge B B B test_expect_success '"reset --merge HEAD" is ok with pending merge' ' - git reset --hard third && - test_must_fail git merge branch1 && - git reset --merge HEAD && - test "$(git rev-parse HEAD)" = "$(git rev-parse third)" && - test -z "$(git diff --cached)" && - test -z "$(git diff)" + git reset --hard third && + test_must_fail git merge branch1 && + git reset --merge HEAD && + test "$(git rev-parse HEAD)" = "$(git rev-parse third)" && + test -z "$(git diff --cached)" && + test -z "$(git diff)" ' # The next test will test the following: @@ -261,36 +261,36 @@ test_expect_success '"reset --merge HEAD" is ok with pending merge' ' # ---------------------------------------------------- # file1: X U B B --keep (disallowed) test_expect_success '"reset --keep HEAD" fails with pending merge' ' - git reset --hard third && - test_must_fail git merge branch1 && - test_must_fail git reset --keep HEAD 2>err.log && - test_i18ngrep "middle of a merge" err.log + git reset --hard third && + test_must_fail git merge branch1 && + test_must_fail git reset --keep HEAD 2>err.log && + test_i18ngrep "middle of a merge" err.log ' test_expect_success '--merge is ok with added/deleted merge' ' - git reset --hard third && - rm -f file2 && - test_must_fail git merge branch3 && - ! test -f file2 && - test -f file3 && - git diff --exit-code file3 && - git diff --exit-code branch3 file3 && - git reset --merge HEAD && - ! test -f file3 && - ! test -f file2 && - git diff --exit-code --cached + git reset --hard third && + rm -f file2 && + test_must_fail git merge branch3 && + ! test -f file2 && + test -f file3 && + git diff --exit-code file3 && + git diff --exit-code branch3 file3 && + git reset --merge HEAD && + ! test -f file3 && + ! test -f file2 && + git diff --exit-code --cached ' test_expect_success '--keep fails with added/deleted merge' ' - git reset --hard third && - rm -f file2 && - test_must_fail git merge branch3 && - ! test -f file2 && - test -f file3 && - git diff --exit-code file3 && - git diff --exit-code branch3 file3 && - test_must_fail git reset --keep HEAD 2>err.log && - test_i18ngrep "middle of a merge" err.log + git reset --hard third && + rm -f file2 && + test_must_fail git merge branch3 && + ! test -f file2 && + test -f file3 && + git diff --exit-code file3 && + git diff --exit-code branch3 file3 && + test_must_fail git reset --keep HEAD 2>err.log && + test_i18ngrep "middle of a merge" err.log ' test_done diff --git a/t/t7111-reset-table.sh b/t/t7111-reset-table.sh index 78f25c1c7e..01b7c3503c 100755 --- a/t/t7111-reset-table.sh +++ b/t/t7111-reset-table.sh @@ -10,9 +10,9 @@ TEST_PASSES_SANITIZE_LEAK=true test_expect_success 'creating initial commits' ' - test_commit E file1 && - test_commit D file1 && - test_commit C file1 + test_commit E file1 && + test_commit D file1 && + test_commit C file1 ' while read W1 I1 H1 T opt W2 I2 H2 @@ -74,13 +74,13 @@ B C C C keep B C C EOF test_expect_success 'setting up branches to test with unmerged entries' ' - git reset --hard C && - git branch branch1 && - git branch branch2 && - git checkout branch1 && - test_commit B1 file1 && - git checkout branch2 && - test_commit B file1 + git reset --hard C && + git branch branch1 && + git branch branch2 && + git checkout branch1 && + test_commit B1 file1 && + git checkout branch2 && + test_commit B file1 ' while read W1 I1 H1 T opt W2 I2 H2 diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 61ad47b0c1..35b9e6ed6b 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -372,75 +372,75 @@ test_expect_success 'checkout specific path while in subdirectory' ' ' test_expect_success 'checkout w/--track sets up tracking' ' - git config branch.autosetupmerge false && - git checkout main && - git checkout --track -b track1 && - test "$(git config branch.track1.remote)" && - test "$(git config branch.track1.merge)" + git config branch.autosetupmerge false && + git checkout main && + git checkout --track -b track1 && + test "$(git config branch.track1.remote)" && + test "$(git config branch.track1.merge)" ' test_expect_success 'checkout w/autosetupmerge=always sets up tracking' ' - test_when_finished git config branch.autosetupmerge false && - git config branch.autosetupmerge always && - git checkout main && - git checkout -b track2 && - test "$(git config branch.track2.remote)" && - test "$(git config branch.track2.merge)" + test_when_finished git config branch.autosetupmerge false && + git config branch.autosetupmerge always && + git checkout main && + git checkout -b track2 && + test "$(git config branch.track2.remote)" && + test "$(git config branch.track2.merge)" ' test_expect_success 'checkout w/--track from non-branch HEAD fails' ' - git checkout main^0 && - test_must_fail git symbolic-ref HEAD && - test_must_fail git checkout --track -b track && - test_must_fail git rev-parse --verify track && - test_must_fail git symbolic-ref HEAD && - test "z$(git rev-parse main^0)" = "z$(git rev-parse HEAD)" + git checkout main^0 && + test_must_fail git symbolic-ref HEAD && + test_must_fail git checkout --track -b track && + test_must_fail git rev-parse --verify track && + test_must_fail git symbolic-ref HEAD && + test "z$(git rev-parse main^0)" = "z$(git rev-parse HEAD)" ' test_expect_success 'checkout w/--track from tag fails' ' - git checkout main^0 && - test_must_fail git symbolic-ref HEAD && - test_must_fail git checkout --track -b track frotz && - test_must_fail git rev-parse --verify track && - test_must_fail git symbolic-ref HEAD && - test "z$(git rev-parse main^0)" = "z$(git rev-parse HEAD)" + git checkout main^0 && + test_must_fail git symbolic-ref HEAD && + test_must_fail git checkout --track -b track frotz && + test_must_fail git rev-parse --verify track && + test_must_fail git symbolic-ref HEAD && + test "z$(git rev-parse main^0)" = "z$(git rev-parse HEAD)" ' test_expect_success 'detach a symbolic link HEAD' ' - git checkout main && - git config --bool core.prefersymlinkrefs yes && - git checkout side && - git checkout main && - it=$(git symbolic-ref HEAD) && - test "z$it" = zrefs/heads/main && - here=$(git rev-parse --verify refs/heads/main) && - git checkout side^ && - test "z$(git rev-parse --verify refs/heads/main)" = "z$here" + git checkout main && + git config --bool core.prefersymlinkrefs yes && + git checkout side && + git checkout main && + it=$(git symbolic-ref HEAD) && + test "z$it" = zrefs/heads/main && + here=$(git rev-parse --verify refs/heads/main) && + git checkout side^ && + test "z$(git rev-parse --verify refs/heads/main)" = "z$here" ' test_expect_success 'checkout with --track fakes a sensible -b <name>' ' - git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" && - git update-ref refs/remotes/origin/koala/bear renamer && + git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" && + git update-ref refs/remotes/origin/koala/bear renamer && - git checkout --track origin/koala/bear && - test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" && - test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" && + git checkout --track origin/koala/bear && + test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" && + test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" && - git checkout main && git branch -D koala/bear && + git checkout main && git branch -D koala/bear && - git checkout --track refs/remotes/origin/koala/bear && - test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" && - test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" && + git checkout --track refs/remotes/origin/koala/bear && + test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" && + test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" && - git checkout main && git branch -D koala/bear && + git checkout main && git branch -D koala/bear && - git checkout --track remotes/origin/koala/bear && - test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" && - test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" + git checkout --track remotes/origin/koala/bear && + test "refs/heads/koala/bear" = "$(git symbolic-ref HEAD)" && + test "$(git rev-parse HEAD)" = "$(git rev-parse renamer)" ' test_expect_success 'checkout with --track, but without -b, fails with too short tracked name' ' - test_must_fail git checkout --track renamer + test_must_fail git checkout --track renamer ' setup_conflicting_index () { diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 3e8cf9b885..9918584464 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1351,6 +1351,22 @@ test_expect_success 'clone active submodule without submodule url set' ' ) ' +test_expect_success 'update submodules without url set in .gitconfig' ' + test_when_finished "rm -rf multisuper_clone" && + git clone file://"$pwd"/multisuper multisuper_clone && + + git -C multisuper_clone submodule init && + for s in sub0 sub1 sub2 sub3 + do + key=submodule.$s.url && + git -C multisuper_clone config --local --unset $key && + git -C multisuper_clone config --file .gitmodules --unset $key || return 1 + done && + + test_must_fail git -C multisuper_clone submodule update 2>err && + grep "cannot clone submodule .sub[0-3]. without a URL" err +' + test_expect_success 'clone --recurse-submodules with a pathspec works' ' test_when_finished "rm -rf multisuper_clone" && cat >expected <<-\EOF && diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index dae87090e0..fb82f760c3 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -1179,6 +1179,29 @@ test_expect_success 'submodule update --recursive skip submodules with strategy= test_cmp expect.err actual.err ' +add_submodule_commit_and_validate () { + HASH=$(git rev-parse HEAD) && + git update-index --add --cacheinfo 160000,$HASH,sub && + git commit -m "create submodule" && + echo "160000 commit $HASH sub" >expect && + git ls-tree HEAD -- sub >actual && + test_cmp expect actual +} + +test_expect_success 'commit with staged submodule change' ' + add_submodule_commit_and_validate +' + +test_expect_success 'commit with staged submodule change with ignoreSubmodules dirty' ' + test_config diff.ignoreSubmodules dirty && + add_submodule_commit_and_validate +' + +test_expect_success 'commit with staged submodule change with ignoreSubmodules all' ' + test_config diff.ignoreSubmodules all && + add_submodule_commit_and_validate +' + test_expect_success CASE_INSENSITIVE_FS,SYMLINKS \ 'submodule paths must not follow symlinks' ' diff --git a/t/t7502-commit-porcelain.sh b/t/t7502-commit-porcelain.sh index 38a532d81c..b5bf7de7cd 100755 --- a/t/t7502-commit-porcelain.sh +++ b/t/t7502-commit-porcelain.sh @@ -466,6 +466,25 @@ test_expect_success 'commit --trailer with -c and command' ' test_cmp expected actual ' +test_expect_success 'commit --trailer not confused by --- separator' ' + cat >msg <<-\EOF && + subject + + body with dashes + --- + in it + EOF + git commit --allow-empty --trailer="my-trailer: value" -F msg && + { + cat msg && + echo && + echo "my-trailer: value" + } >expected && + git cat-file commit HEAD >commit.msg && + sed -e "1,/^\$/d" commit.msg >actual && + test_cmp expected actual +' + test_expect_success 'multiple -m' ' >negative && diff --git a/t/t7508-status.sh b/t/t7508-status.sh index aed07c5b62..6928fd89f5 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -5,6 +5,7 @@ test_description='git status' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh @@ -91,7 +92,7 @@ test_expect_success 'status --column' ' # On branch main # Your branch and '\''upstream'\'' have diverged, # and have 1 and 2 different commits each, respectively. -# (use "git pull" to merge the remote branch into yours) +# (use "git pull" if you want to integrate the remote branch with yours) # # Changes to be committed: # (use "git restore --staged <file>..." to unstage) @@ -122,7 +123,7 @@ cat >expect <<\EOF # On branch main # Your branch and 'upstream' have diverged, # and have 1 and 2 different commits each, respectively. -# (use "git pull" to merge the remote branch into yours) +# (use "git pull" if you want to integrate the remote branch with yours) # # Changes to be committed: # (use "git restore --staged <file>..." to unstage) @@ -269,7 +270,7 @@ test_expect_success 'status with gitignore' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -334,7 +335,7 @@ test_expect_success 'status with gitignore (nothing untracked)' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -404,7 +405,7 @@ test_expect_success 'status -uno' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -466,7 +467,7 @@ test_expect_success 'status -unormal' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -521,7 +522,7 @@ test_expect_success 'status -uall' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -581,7 +582,7 @@ test_expect_success 'status with relative paths' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -649,7 +650,7 @@ test_expect_success TTY 'status with color.ui' ' On branch <GREEN>main<RESET> Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -772,7 +773,7 @@ test_expect_success 'status without relative paths' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -846,7 +847,6 @@ test_expect_success 'dry-run of partial commit excluding new file in index' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -900,7 +900,7 @@ test_expect_success 'status submodule summary is disabled by default' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -957,7 +957,7 @@ test_expect_success 'status submodule summary' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 1 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -1012,11 +1012,11 @@ test_expect_success 'status -s submodule summary' ' ' test_expect_success 'status submodule summary (clean submodule): commit' ' - cat >expect <<EOF && + cat >expect-status <<EOF && On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes not staged for commit: (use "git add <file>..." to update what will be committed) @@ -1032,12 +1032,13 @@ Untracked files: no changes added to commit (use "git add" and/or "git commit -a") EOF + sed "/git pull/d" expect-status > expect-commit && git commit -m "commit submodule" && git config status.submodulesummary 10 && test_must_fail git commit --dry-run >output && - test_cmp expect output && + test_cmp expect-commit output && git status >output && - test_cmp expect output + test_cmp expect-status output ' cat >expect <<EOF @@ -1064,7 +1065,6 @@ test_expect_success 'commit --dry-run submodule summary (--amend)' ' On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) Changes to be committed: (use "git restore --source=HEAD^1 --staged <file>..." to unstage) @@ -1116,7 +1116,7 @@ test_expect_success '--ignore-submodules=untracked suppresses submodules with un On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -1225,7 +1225,7 @@ test_expect_success "--ignore-submodules=untracked doesn't suppress submodules w On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -1282,7 +1282,7 @@ test_expect_success "--ignore-submodules=untracked doesn't suppress submodule su On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -1363,7 +1363,7 @@ cat > expect << EOF ; On branch main ; Your branch and 'upstream' have diverged, ; and have 2 and 2 different commits each, respectively. -; (use "git pull" to merge the remote branch into yours) +; (use "git pull" if you want to integrate the remote branch with yours) ; ; Changes to be committed: ; (use "git restore --staged <file>..." to unstage) @@ -1411,7 +1411,7 @@ test_expect_success "--ignore-submodules=all suppresses submodule summary" ' On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes not staged for commit: (use "git add <file>..." to update what will be committed) @@ -1437,7 +1437,7 @@ test_expect_success '.gitmodules ignore=all suppresses unstaged submodule summar On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) + (use "git pull" if you want to integrate the remote branch with yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) @@ -1519,8 +1519,8 @@ test_expect_success '"status.branch=true" weaker than "--no-branch"' ' ' test_expect_success '"status.branch=true" weaker than "--porcelain"' ' - git -c status.branch=true status --porcelain >actual && - test_cmp expected_nobranch actual + git -c status.branch=true status --porcelain >actual && + test_cmp expected_nobranch actual ' test_expect_success '"status.branch=false" same as "--no-branch"' ' @@ -1557,7 +1557,6 @@ test_expect_success 'git commit --dry-run will show a staged but ignored submodu On branch main Your branch and '\''upstream'\'' have diverged, and have 2 and 2 different commits each, respectively. - (use "git pull" to merge the remote branch into yours) Changes to be committed: (use "git restore --staged <file>..." to unstage) diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index ccbc416402..0d2dd29fe6 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -218,6 +218,13 @@ test_expect_success GPG 'amending already signed commit' ' ! grep "BAD signature from" actual ' +test_expect_success GPG2 'bare signature' ' + git verify-commit fifth-signed 2>expect && + echo >>expect && + git log -1 --format="%GG" fifth-signed >actual && + test_cmp expect actual +' + test_expect_success GPG 'show good signature with custom format' ' cat >expect <<-\EOF && G diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index 2f16d5787e..c2ab8a444a 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -774,6 +774,28 @@ EOF test_cmp expected actual ' +test_expect_success 'status when cherry-picking multiple commits' ' + git reset --hard cherry_branch && + test_when_finished "git cherry-pick --abort" && + test_must_fail git cherry-pick cherry_branch_second one_cherry && + TO_CHERRY_PICK=$(git rev-parse --short CHERRY_PICK_HEAD) && + cat >expected <<EOF && +On branch cherry_branch +You are currently cherry-picking commit $TO_CHERRY_PICK. + (fix conflicts and run "git cherry-pick --continue") + (use "git cherry-pick --skip" to skip this patch) + (use "git cherry-pick --abort" to cancel the cherry-pick operation) + +Unmerged paths: + (use "git add <file>..." to mark resolution) + both modified: main.txt + +no changes added to commit (use "git add" and/or "git commit -a") +EOF + git status --untracked-files=no >actual && + test_cmp expected actual +' + test_expect_success 'status when cherry-picking after committing conflict resolution' ' git reset --hard cherry_branch && test_when_finished "git cherry-pick --abort" && diff --git a/t/t7516-commit-races.sh b/t/t7516-commit-races.sh index 2d38a16480..bb95f09810 100755 --- a/t/t7516-commit-races.sh +++ b/t/t7516-commit-races.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git commit races' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'race to create orphan commit' ' diff --git a/t/t7518-ident-corner-cases.sh b/t/t7518-ident-corner-cases.sh index fffdb6ff2e..9ab2ae2f3b 100755 --- a/t/t7518-ident-corner-cases.sh +++ b/t/t7518-ident-corner-cases.sh @@ -20,10 +20,19 @@ test_expect_success 'empty name and missing email' ' ' test_expect_success 'commit rejects all-crud name' ' - test_must_fail env GIT_AUTHOR_NAME=" .;<>" \ + test_must_fail env GIT_AUTHOR_NAME=" ,;<>" \ git commit --allow-empty -m foo ' +test_expect_success 'commit does not strip trailing dot' ' + author_name="Pat Doe Jr." && + env GIT_AUTHOR_NAME="$author_name" \ + git commit --allow-empty -m foo && + git log -1 --format=%an >actual && + echo "$author_name" >expected && + test_cmp actual expected +' + # We must test the actual error message here, as an unwanted # auto-detection could fail for other reasons. test_expect_success 'empty configured name does not auto-detect' ' diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh index 0c241d6c14..78503158fd 100755 --- a/t/t7527-builtin-fsmonitor.sh +++ b/t/t7527-builtin-fsmonitor.sh @@ -809,6 +809,11 @@ my_match_and_clean () { status --porcelain=v2 >actual.without && test_cmp actual.with actual.without && + git -C super --no-optional-locks diff-index --name-status HEAD >actual.with && + git -C super --no-optional-locks -c core.fsmonitor=false \ + diff-index --name-status HEAD >actual.without && + test_cmp actual.with actual.without && + git -C super/dir_1/dir_2/sub reset --hard && git -C super/dir_1/dir_2/sub clean -d -f } diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 060e145957..fdc607277c 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -639,41 +639,41 @@ test_expect_success 'merge log message' ' test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c0, c2, c0, and c1' ' - git reset --hard c1 && - test_tick && - git merge c0 c2 c0 c1 && - verify_merge file result.1-5 && - verify_parents $c1 $c2 + git reset --hard c1 && + test_tick && + git merge c0 c2 c0 c1 && + verify_merge file result.1-5 && + verify_parents $c1 $c2 ' test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c0, c2, c0, and c1' ' - git reset --hard c1 && - test_tick && - git merge c0 c2 c0 c1 && - verify_merge file result.1-5 && - verify_parents $c1 $c2 + git reset --hard c1 && + test_tick && + git merge c0 c2 c0 c1 && + verify_merge file result.1-5 && + verify_parents $c1 $c2 ' test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c1 and c2' ' - git reset --hard c1 && - test_tick && - git merge c1 c2 && - verify_merge file result.1-5 && - verify_parents $c1 $c2 + git reset --hard c1 && + test_tick && + git merge c1 c2 && + verify_merge file result.1-5 && + verify_parents $c1 $c2 ' test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge fast-forward in a dirty tree' ' - git reset --hard c0 && - mv file file1 && - cat file1 >file && - rm -f file1 && - git merge c2 + git reset --hard c0 && + mv file file1 && + cat file1 >file && + rm -f file1 && + git merge c2 ' test_debug 'git log --graph --decorate --oneline --all' diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index faa739eeb9..27b66807cd 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -10,6 +10,10 @@ test_description='git repack works correctly' commit_and_pack () { test_commit "$@" 1>&2 && incrpackid=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) && + # Remove any loose object(s) created by test_commit, since they have + # already been packed. Leaving these around can create subtly different + # packs with `pack-objects`'s `--unpacked` option. + git prune-packed 1>&2 && echo pack-${incrpackid}.pack } @@ -209,6 +213,8 @@ test_expect_success 'repack --keep-pack' ' test_create_repo keep-pack && ( cd keep-pack && + # avoid producing different packs due to delta/base choices + git config pack.window 0 && P1=$(commit_and_pack 1) && P2=$(commit_and_pack 2) && P3=$(commit_and_pack 3) && @@ -220,10 +226,61 @@ test_expect_success 'repack --keep-pack' ' grep -q $P1 new-counts && grep -q $P4 new-counts && test_line_count = 3 new-counts && + git fsck && + + P5=$(commit_and_pack --no-tag 5) && + git reset --hard HEAD^ && + git reflog expire --all --expire=all && + rm -f ".git/objects/pack/${P5%.pack}.idx" && + rm -f ".git/objects/info/commit-graph" && + for from in $(find .git/objects/pack -type f -name "${P5%.pack}.*") + do + to="$(dirname "$from")/.tmp-1234-$(basename "$from")" && + mv "$from" "$to" || return 1 + done && + + # A .idx file without a .pack should not stop us from + # repacking what we can. + touch .git/objects/pack/pack-does-not-exist.idx && + + git repack --cruft -d --keep-pack $P1 --keep-pack $P4 && + + ls .git/objects/pack/*.pack >newer-counts && + test_cmp new-counts newer-counts && git fsck ) ' +test_expect_success 'repacking fails when missing .pack actually means missing objects' ' + test_create_repo idx-without-pack && + ( + cd idx-without-pack && + + # Avoid producing different packs due to delta/base choices + git config pack.window 0 && + P1=$(commit_and_pack 1) && + P2=$(commit_and_pack 2) && + P3=$(commit_and_pack 3) && + P4=$(commit_and_pack 4) && + ls .git/objects/pack/*.pack >old-counts && + test_line_count = 4 old-counts && + + # Remove one .pack file + rm .git/objects/pack/$P2 && + + ls .git/objects/pack/*.pack >before-pack-dir && + + test_must_fail git fsck && + test_must_fail git repack --cruft -d 2>err && + grep "bad object" err && + + # Before failing, the repack did not modify the + # pack directory. + ls .git/objects/pack/*.pack >after-pack-dir && + test_cmp before-pack-dir after-pack-dir + ) +' + test_expect_success 'bitmaps are created by default in bare repos' ' git clone --bare .git bare.git && rm -f bare.git/objects/pack/*.bitmap && @@ -460,10 +517,10 @@ test_expect_success '--write-midx -b packs non-kept objects' ' ' test_expect_success '--write-midx removes stale pack-based bitmaps' ' - rm -fr repo && - git init repo && - test_when_finished "rm -fr repo" && - ( + rm -fr repo && + git init repo && + test_when_finished "rm -fr repo" && + ( cd repo && test_commit base && GIT_TEST_MULTI_PACK_INDEX=0 git repack -Ab && @@ -477,7 +534,7 @@ test_expect_success '--write-midx removes stale pack-based bitmaps' ' test_path_is_file $midx && test_path_is_file $midx-$(midx_checksum $objdir).bitmap && test_path_is_missing $pack_bitmap - ) + ) ' test_expect_success '--write-midx with --pack-kept-objects' ' diff --git a/t/t7701-repack-unpack-unreachable.sh b/t/t7701-repack-unpack-unreachable.sh index ebb267855f..fe6c3e77a3 100755 --- a/t/t7701-repack-unpack-unreachable.sh +++ b/t/t7701-repack-unpack-unreachable.sh @@ -113,6 +113,48 @@ test_expect_success 'do not bother loosening old objects' ' test_must_fail git cat-file -p $obj2 ' +test_expect_success 'gc.recentObjectsHook' ' + obj1=$(echo one | git hash-object -w --stdin) && + obj2=$(echo two | git hash-object -w --stdin) && + obj3=$(echo three | git hash-object -w --stdin) && + pack1=$(echo $obj1 | git pack-objects .git/objects/pack/pack) && + pack2=$(echo $obj2 | git pack-objects .git/objects/pack/pack) && + pack3=$(echo $obj3 | git pack-objects .git/objects/pack/pack) && + git prune-packed && + + git cat-file -p $obj1 && + git cat-file -p $obj2 && + git cat-file -p $obj3 && + + # make an unreachable annotated tag object to ensure we rescue objects + # which are reachable from non-pruned unreachable objects + obj2_tag="$(git mktag <<-EOF + object $obj2 + type blob + tag obj2-tag + tagger T A Gger <tagger@example.com> 1234567890 -0000 + EOF + )" && + + obj2_tag_pack="$(echo $obj2_tag | git pack-objects .git/objects/pack/pack)" && + git prune-packed && + + write_script precious-objects <<-EOF && + echo $obj2_tag + EOF + git config gc.recentObjectsHook ./precious-objects && + + test-tool chmtime =-86400 .git/objects/pack/pack-$pack2.pack && + test-tool chmtime =-86400 .git/objects/pack/pack-$pack3.pack && + test-tool chmtime =-86400 .git/objects/pack/pack-$obj2_tag_pack.pack && + git repack -A -d --unpack-unreachable=1.hour.ago && + + git cat-file -p $obj1 && + git cat-file -p $obj2 && + git cat-file -p $obj2_tag && + test_must_fail git cat-file -p $obj3 +' + test_expect_success 'keep packed objects found only in index' ' echo my-unique-content >file && git add file && diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh index 8143817b19..d37c83b464 100755 --- a/t/t7814-grep-recurse-submodules.sh +++ b/t/t7814-grep-recurse-submodules.sh @@ -594,4 +594,44 @@ test_expect_success 'grep partially-cloned submodule' ' ) ' +test_expect_success 'check scope of core.useReplaceRefs' ' + git init base && + git init base/sub && + + echo A >base/a && + echo B >base/b && + echo C >base/sub/c && + echo D >base/sub/d && + + git -C base/sub add c d && + git -C base/sub commit -m "Add files" && + + git -C base submodule add ./sub && + git -C base add a b sub && + git -C base commit -m "Add files and submodule" && + + A=$(git -C base rev-parse HEAD:a) && + B=$(git -C base rev-parse HEAD:b) && + C=$(git -C base/sub rev-parse HEAD:c) && + D=$(git -C base/sub rev-parse HEAD:d) && + + git -C base replace $A $B && + git -C base/sub replace $C $D && + + test_must_fail git -C base grep --cached --recurse-submodules A && + test_must_fail git -C base grep --cached --recurse-submodules C && + + git -C base config core.useReplaceRefs false && + git -C base grep --recurse-submodules A && + test_must_fail git -C base grep --cached --recurse-submodules C && + + git -C base/sub config core.useReplaceRefs false && + git -C base grep --cached --recurse-submodules A && + git -C base grep --cached --recurse-submodules C && + + git -C base config --unset core.useReplaceRefs && + test_must_fail git -C base grep --cached --recurse-submodules A && + git -C base grep --cached --recurse-submodules C +' + test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 22fc908024..263db3ad17 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -4,7 +4,7 @@ test_description='git send-email' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME -# no longer TEST_PASSES_SANITIZE_LEAK=true - format-patch --thread leaks +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # May be altered later in the test @@ -61,8 +61,8 @@ test_no_confirm () { --smtp-server="$(pwd)/fake.sendmail" \ $@ \ $patches >stdout && - ! grep "Send this email" stdout && - >no_confirm_okay + ! grep "Send this email" stdout && + >no_confirm_okay } # Exit immediately to prevent hang if a no-confirm test fails @@ -337,13 +337,14 @@ test_expect_success $PREREQ 'Show all headers' ' test_expect_success $PREREQ 'Prompting works' ' clean_fake_sendmail && (echo "to@example.com" && - echo "" + echo "my-message-id@example.com" ) | GIT_SEND_EMAIL_NOTTY=1 git send-email \ --smtp-server="$(pwd)/fake.sendmail" \ $patches \ 2>errors && grep "^From: A U Thor <author@example.com>\$" msgtxt1 && - grep "^To: to@example.com\$" msgtxt1 + grep "^To: to@example.com\$" msgtxt1 && + grep "^In-Reply-To: <my-message-id@example.com>" msgtxt1 ' test_expect_success $PREREQ,AUTOIDENT 'implicit ident is allowed' ' @@ -659,7 +660,6 @@ test_expect_success $PREREQ 'clear message-id before parsing a new message' ' clean_fake_sendmail && echo true | write_script my-hooks/sendemail-validate && test_config core.hooksPath my-hooks && - GIT_SEND_EMAIL_NOTTY=1 \ git send-email --validate --to=recipient@example.com \ --smtp-server="$(pwd)/fake.sendmail" \ $patches $threaded_patches && diff --git a/t/t9004-example.sh b/t/t9004-example.sh index 7e8894a4a7..590aab0304 100755 --- a/t/t9004-example.sh +++ b/t/t9004-example.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='check that example code compiles and runs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'decorate' ' diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index fea41b3c36..af28b01fef 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -21,7 +21,7 @@ test_expect_success 'git svn help works anywhere' ' ' test_expect_success \ - 'initialize git svn' ' + 'initialize git svn' ' mkdir import && ( cd import && @@ -38,9 +38,9 @@ test_expect_success \ rm -rf import && git svn init "$svnrepo"' -test_expect_success \ - 'import an SVN revision into git' \ - 'git svn fetch' +test_expect_success 'import an SVN revision into git' ' + git svn fetch +' test_expect_success "checkout from svn" 'svn co "$svnrepo" "$SVN_TREE"' @@ -233,27 +233,26 @@ test_expect_success POSIXPERM,SYMLINKS "$name" ' ' test_expect_success 'exit if remote refs are ambigious' ' - git config --add svn-remote.svn.fetch \ + git config --add svn-remote.svn.fetch \ bar:refs/remotes/git-svn && test_must_fail git svn migrate ' test_expect_success 'exit if init-ing a would clobber a URL' ' - svnadmin create "${PWD}/svnrepo2" && - svn mkdir -m "mkdir bar" "${svnrepo}2/bar" && - git config --unset svn-remote.svn.fetch \ + svnadmin create "${PWD}/svnrepo2" && + svn mkdir -m "mkdir bar" "${svnrepo}2/bar" && + git config --unset svn-remote.svn.fetch \ "^bar:refs/remotes/git-svn$" && test_must_fail git svn init "${svnrepo}2/bar" ' -test_expect_success \ - 'init allows us to connect to another directory in the same repo' ' - git svn init --minimize-url -i bar "$svnrepo/bar" && - git config --get svn-remote.svn.fetch \ - "^bar:refs/remotes/bar$" && - git config --get svn-remote.svn.fetch \ - "^:refs/remotes/git-svn$" - ' +test_expect_success 'init allows us to connect to another directory in the same repo' ' + git svn init --minimize-url -i bar "$svnrepo/bar" && + git config --get svn-remote.svn.fetch \ + "^bar:refs/remotes/bar$" && + git config --get svn-remote.svn.fetch \ + "^:refs/remotes/git-svn$" +' test_expect_success 'dcommit $rev does not clobber current branch' ' git svn fetch -i bar && diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index 85d735861f..b5845e28fe 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -41,51 +41,51 @@ test_expect_success 'init and fetch a moved directory' ' ' test_expect_success 'init and fetch from one svn-remote' ' - git config svn-remote.svn.url "$svnrepo" && - git config --add svn-remote.svn.fetch \ - trunk:refs/remotes/svn/trunk && - git config --add svn-remote.svn.fetch \ - thunk:refs/remotes/svn/thunk && - git svn fetch -i svn/thunk && + git config svn-remote.svn.url "$svnrepo" && + git config --add svn-remote.svn.fetch \ + trunk:refs/remotes/svn/trunk && + git config --add svn-remote.svn.fetch \ + thunk:refs/remotes/svn/thunk && + git svn fetch -i svn/thunk && test "$(git rev-parse --verify refs/remotes/svn/trunk)" \ - = "$(git rev-parse --verify refs/remotes/svn/thunk~1)" && + = "$(git rev-parse --verify refs/remotes/svn/thunk~1)" && git cat-file blob refs/remotes/svn/thunk:readme >actual && test "$(sed -n -e "3p" actual)" = goodbye - ' +' test_expect_success 'follow deleted parent' ' - (svn_cmd cp -m "resurrecting trunk as junk" \ - "$svnrepo"/trunk@2 "$svnrepo"/junk || - svn cp -m "resurrecting trunk as junk" \ - -r2 "$svnrepo"/trunk "$svnrepo"/junk) && - git config --add svn-remote.svn.fetch \ - junk:refs/remotes/svn/junk && - git svn fetch -i svn/thunk && - git svn fetch -i svn/junk && + (svn_cmd cp -m "resurrecting trunk as junk" \ + "$svnrepo"/trunk@2 "$svnrepo"/junk || + svn cp -m "resurrecting trunk as junk" \ + -r2 "$svnrepo"/trunk "$svnrepo"/junk) && + git config --add svn-remote.svn.fetch \ + junk:refs/remotes/svn/junk && + git svn fetch -i svn/thunk && + git svn fetch -i svn/junk && test -z "$(git diff svn/junk svn/trunk)" && test "$(git merge-base svn/junk svn/trunk)" \ - = "$(git rev-parse svn/trunk)" - ' + = "$(git rev-parse svn/trunk)" +' test_expect_success 'follow larger parent' ' - mkdir -p import/trunk/thunk/bump/thud && - echo hi > import/trunk/thunk/bump/thud/file && - svn import -m "import a larger parent" import "$svnrepo"/larger-parent && - svn cp -m "hi" "$svnrepo"/larger-parent "$svnrepo"/another-larger && - git svn init --minimize-url -i larger \ - "$svnrepo"/larger-parent/trunk/thunk/bump/thud && - git svn fetch -i larger && + mkdir -p import/trunk/thunk/bump/thud && + echo hi > import/trunk/thunk/bump/thud/file && + svn import -m "import a larger parent" import "$svnrepo"/larger-parent && + svn cp -m "hi" "$svnrepo"/larger-parent "$svnrepo"/another-larger && + git svn init --minimize-url -i larger \ + "$svnrepo"/larger-parent/trunk/thunk/bump/thud && + git svn fetch -i larger && git svn init --minimize-url -i larger-parent \ - "$svnrepo"/another-larger/trunk/thunk/bump/thud && + "$svnrepo"/another-larger/trunk/thunk/bump/thud && git svn fetch -i larger-parent && - git rev-parse --verify refs/remotes/larger && - git rev-parse --verify \ - refs/remotes/larger-parent && + git rev-parse --verify refs/remotes/larger && + git rev-parse --verify \ + refs/remotes/larger-parent && test "$(git merge-base \ refs/remotes/larger-parent \ refs/remotes/larger)" = \ - "$(git rev-parse refs/remotes/larger)" - ' + "$(git rev-parse refs/remotes/larger)" +' test_expect_success 'follow higher-level parent' ' svn mkdir -m "follow higher-level parent" "$svnrepo"/blob && diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index c5946cb0b8..a44eabf0d8 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -50,56 +50,56 @@ check_entries () { fi } -test_expect_success \ - 'New file' \ - 'mkdir A B C D E F && - echo hello1 >A/newfile1.txt && - echo hello2 >B/newfile2.txt && - cp "$TEST_DIRECTORY"/test-binary-1.png C/newfile3.png && - cp "$TEST_DIRECTORY"/test-binary-1.png D/newfile4.png && - git add A/newfile1.txt && - git add B/newfile2.txt && - git add C/newfile3.png && - git add D/newfile4.png && - git commit -a -m "Test: New file" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - git cvsexportcommit -c $id && - check_entries A "newfile1.txt/1.1/" && - check_entries B "newfile2.txt/1.1/" && - check_entries C "newfile3.png/1.1/-kb" && - check_entries D "newfile4.png/1.1/-kb" && - test_cmp A/newfile1.txt ../A/newfile1.txt && - test_cmp B/newfile2.txt ../B/newfile2.txt && - test_cmp C/newfile3.png ../C/newfile3.png && - test_cmp D/newfile4.png ../D/newfile4.png - )' +test_expect_success 'New file' ' + mkdir A B C D E F && + echo hello1 >A/newfile1.txt && + echo hello2 >B/newfile2.txt && + cp "$TEST_DIRECTORY"/test-binary-1.png C/newfile3.png && + cp "$TEST_DIRECTORY"/test-binary-1.png D/newfile4.png && + git add A/newfile1.txt && + git add B/newfile2.txt && + git add C/newfile3.png && + git add D/newfile4.png && + git commit -a -m "Test: New file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "newfile1.txt/1.1/" && + check_entries B "newfile2.txt/1.1/" && + check_entries C "newfile3.png/1.1/-kb" && + check_entries D "newfile4.png/1.1/-kb" && + test_cmp A/newfile1.txt ../A/newfile1.txt && + test_cmp B/newfile2.txt ../B/newfile2.txt && + test_cmp C/newfile3.png ../C/newfile3.png && + test_cmp D/newfile4.png ../D/newfile4.png + ) +' -test_expect_success \ - 'Remove two files, add two and update two' \ - 'echo Hello1 >>A/newfile1.txt && - rm -f B/newfile2.txt && - rm -f C/newfile3.png && - echo Hello5 >E/newfile5.txt && - cp "$TEST_DIRECTORY"/test-binary-2.png D/newfile4.png && - cp "$TEST_DIRECTORY"/test-binary-1.png F/newfile6.png && - git add E/newfile5.txt && - git add F/newfile6.png && - git commit -a -m "Test: Remove, add and update" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - git cvsexportcommit -c $id && - check_entries A "newfile1.txt/1.2/" && - check_entries B "" && - check_entries C "" && - check_entries D "newfile4.png/1.2/-kb" && - check_entries E "newfile5.txt/1.1/" && - check_entries F "newfile6.png/1.1/-kb" && - test_cmp A/newfile1.txt ../A/newfile1.txt && - test_cmp D/newfile4.png ../D/newfile4.png && - test_cmp E/newfile5.txt ../E/newfile5.txt && - test_cmp F/newfile6.png ../F/newfile6.png - )' +test_expect_success 'Remove two files, add two and update two' ' + echo Hello1 >>A/newfile1.txt && + rm -f B/newfile2.txt && + rm -f C/newfile3.png && + echo Hello5 >E/newfile5.txt && + cp "$TEST_DIRECTORY"/test-binary-2.png D/newfile4.png && + cp "$TEST_DIRECTORY"/test-binary-1.png F/newfile6.png && + git add E/newfile5.txt && + git add F/newfile6.png && + git commit -a -m "Test: Remove, add and update" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "newfile1.txt/1.2/" && + check_entries B "" && + check_entries C "" && + check_entries D "newfile4.png/1.2/-kb" && + check_entries E "newfile5.txt/1.1/" && + check_entries F "newfile6.png/1.1/-kb" && + test_cmp A/newfile1.txt ../A/newfile1.txt && + test_cmp D/newfile4.png ../D/newfile4.png && + test_cmp E/newfile5.txt ../E/newfile5.txt && + test_cmp F/newfile6.png ../F/newfile6.png + ) +' # Should fail (but only on the git cvsexportcommit stage) test_expect_success \ @@ -129,67 +129,67 @@ test_expect_success \ # This test is here because a patch for only binary files will # fail with gnu patch, so cvsexportcommit must handle that. -test_expect_success \ - 'Remove only binary files' \ - 'git reset --hard HEAD^^ && - rm -f D/newfile4.png && - git commit -a -m "test: remove only a binary file" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - git cvsexportcommit -c $id && - check_entries A "newfile1.txt/1.2/" && - check_entries B "" && - check_entries C "" && - check_entries D "" && - check_entries E "newfile5.txt/1.1/" && - check_entries F "newfile6.png/1.1/-kb" && - test_cmp A/newfile1.txt ../A/newfile1.txt && - test_cmp E/newfile5.txt ../E/newfile5.txt && - test_cmp F/newfile6.png ../F/newfile6.png - )' +test_expect_success 'Remove only binary files' ' + git reset --hard HEAD^^ && + rm -f D/newfile4.png && + git commit -a -m "test: remove only a binary file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "newfile1.txt/1.2/" && + check_entries B "" && + check_entries C "" && + check_entries D "" && + check_entries E "newfile5.txt/1.1/" && + check_entries F "newfile6.png/1.1/-kb" && + test_cmp A/newfile1.txt ../A/newfile1.txt && + test_cmp E/newfile5.txt ../E/newfile5.txt && + test_cmp F/newfile6.png ../F/newfile6.png + ) +' -test_expect_success \ - 'Remove only a text file' \ - 'rm -f A/newfile1.txt && - git commit -a -m "test: remove only a binary file" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - git cvsexportcommit -c $id && - check_entries A "" && - check_entries B "" && - check_entries C "" && - check_entries D "" && - check_entries E "newfile5.txt/1.1/" && - check_entries F "newfile6.png/1.1/-kb" && - test_cmp E/newfile5.txt ../E/newfile5.txt && - test_cmp F/newfile6.png ../F/newfile6.png - )' +test_expect_success 'Remove only a text file' ' + rm -f A/newfile1.txt && + git commit -a -m "test: remove only a binary file" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries A "" && + check_entries B "" && + check_entries C "" && + check_entries D "" && + check_entries E "newfile5.txt/1.1/" && + check_entries F "newfile6.png/1.1/-kb" && + test_cmp E/newfile5.txt ../E/newfile5.txt && + test_cmp F/newfile6.png ../F/newfile6.png + ) +' -test_expect_success \ - 'New file with spaces in file name' \ - 'mkdir "G g" && - echo ok then >"G g/with spaces.txt" && - git add "G g/with spaces.txt" && \ - cp "$TEST_DIRECTORY"/test-binary-1.png "G g/with spaces.png" && \ - git add "G g/with spaces.png" && - git commit -a -m "With spaces" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - git cvsexportcommit -c $id && - check_entries "G g" "with spaces.png/1.1/-kb|with spaces.txt/1.1/" - )' +test_expect_success 'New file with spaces in file name' ' + mkdir "G g" && + echo ok then >"G g/with spaces.txt" && + git add "G g/with spaces.txt" && \ + cp "$TEST_DIRECTORY"/test-binary-1.png "G g/with spaces.png" && \ + git add "G g/with spaces.png" && + git commit -a -m "With spaces" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries "G g" "with spaces.png/1.1/-kb|with spaces.txt/1.1/" + ) +' -test_expect_success \ - 'Update file with spaces in file name' \ - 'echo Ok then >>"G g/with spaces.txt" && - cat "$TEST_DIRECTORY"/test-binary-1.png >>"G g/with spaces.png" && \ - git add "G g/with spaces.png" && - git commit -a -m "Update with spaces" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - git cvsexportcommit -c $id && - check_entries "G g" "with spaces.png/1.2/-kb|with spaces.txt/1.2/" - )' +test_expect_success 'Update file with spaces in file name' ' + echo Ok then >>"G g/with spaces.txt" && + cat "$TEST_DIRECTORY"/test-binary-1.png >>"G g/with spaces.png" && \ + git add "G g/with spaces.png" && + git commit -a -m "Update with spaces" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -c $id && + check_entries "G g" "with spaces.png/1.2/-kb|with spaces.txt/1.2/" + ) +' # Some filesystems mangle pathnames with UTF-8 characters -- # check and skip @@ -202,68 +202,68 @@ if p="Å/goo/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/å/ä/ö" && then # This test contains UTF-8 characters -test_expect_success !MINGW \ - 'File with non-ascii file name' \ - 'mkdir -p Å/goo/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/å/ä/ö && - echo Foo >Å/goo/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/å/ä/ö/gårdetsågårdet.txt && - git add Å/goo/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/å/ä/ö/gårdetsågårdet.txt && - cp "$TEST_DIRECTORY"/test-binary-1.png Å/goo/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/å/ä/ö/gårdetsågårdet.png && - git add Å/goo/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/å/ä/ö/gårdetsågårdet.png && - git commit -a -m "Går det så går det" && \ - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - git cvsexportcommit -v -c $id && - check_entries \ - "Å/goo/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/å/ä/ö" \ - "gårdetsågårdet.png/1.1/-kb|gårdetsågårdet.txt/1.1/" - )' +test_expect_success !MINGW 'File with non-ascii file name' ' + mkdir -p Å/goo/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/å/ä/ö && + echo Foo >Å/goo/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/å/ä/ö/gårdetsågårdet.txt && + git add Å/goo/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/å/ä/ö/gårdetsågårdet.txt && + cp "$TEST_DIRECTORY"/test-binary-1.png Å/goo/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/å/ä/ö/gårdetsågårdet.png && + git add Å/goo/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/å/ä/ö/gårdetsågårdet.png && + git commit -a -m "Går det så går det" && \ + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + git cvsexportcommit -v -c $id && + check_entries \ + "Å/goo/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/å/ä/ö" \ + "gårdetsågårdet.png/1.1/-kb|gårdetsågårdet.txt/1.1/" + ) +' fi rm -fr tst -test_expect_success \ - 'Mismatching patch should fail' \ - 'date >>"E/newfile5.txt" && - git add "E/newfile5.txt" && - git commit -a -m "Update one" && - date >>"E/newfile5.txt" && - git add "E/newfile5.txt" && - git commit -a -m "Update two" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$CVSWORK" && - test_must_fail git cvsexportcommit -c $id - )' - -test_expect_success FILEMODE \ - 'Retain execute bit' \ - 'mkdir G && - echo executeon >G/on && - chmod +x G/on && - echo executeoff >G/off && - git add G/on && - git add G/off && - git commit -a -m "Execute test" && - (cd "$CVSWORK" && - git cvsexportcommit -c HEAD && - test -x G/on && - ! test -x G/off - )' +test_expect_success 'Mismatching patch should fail' ' + date >>"E/newfile5.txt" && + git add "E/newfile5.txt" && + git commit -a -m "Update one" && + date >>"E/newfile5.txt" && + git add "E/newfile5.txt" && + git commit -a -m "Update two" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$CVSWORK" && + test_must_fail git cvsexportcommit -c $id + ) +' + +test_expect_success FILEMODE 'Retain execute bit' ' + mkdir G && + echo executeon >G/on && + chmod +x G/on && + echo executeoff >G/off && + git add G/on && + git add G/off && + git commit -a -m "Execute test" && + (cd "$CVSWORK" && + git cvsexportcommit -c HEAD && + test -x G/on && + ! test -x G/off + ) +' test_expect_success '-w option should work with relative GIT_DIR' ' - mkdir W && - echo foobar >W/file1.txt && - echo bazzle >W/file2.txt && - git add W/file1.txt && - git add W/file2.txt && - git commit -m "More updates" && - id=$(git rev-list --max-count=1 HEAD) && - (cd "$GIT_DIR" && - GIT_DIR=. git cvsexportcommit -w "$CVSWORK" -c $id && - check_entries "$CVSWORK/W" "file1.txt/1.1/|file2.txt/1.1/" && - test_cmp "$CVSWORK/W/file1.txt" ../W/file1.txt && - test_cmp "$CVSWORK/W/file2.txt" ../W/file2.txt - ) + mkdir W && + echo foobar >W/file1.txt && + echo bazzle >W/file2.txt && + git add W/file1.txt && + git add W/file2.txt && + git commit -m "More updates" && + id=$(git rev-list --max-count=1 HEAD) && + (cd "$GIT_DIR" && + GIT_DIR=. git cvsexportcommit -w "$CVSWORK" -c $id && + check_entries "$CVSWORK/W" "file1.txt/1.1/|file2.txt/1.1/" && + test_cmp "$CVSWORK/W/file1.txt" ../W/file1.txt && + test_cmp "$CVSWORK/W/file2.txt" ../W/file2.txt + ) ' test_expect_success 'check files before directories' ' @@ -290,21 +290,20 @@ test_expect_success 'check files before directories' ' ' test_expect_success 're-commit a removed filename which remains in CVS attic' ' - - (cd "$CVSWORK" && - echo >attic_gremlin && - cvs -Q add attic_gremlin && - cvs -Q ci -m "added attic_gremlin" && - rm attic_gremlin && - cvs -Q rm attic_gremlin && - cvs -Q ci -m "removed attic_gremlin") && - - echo > attic_gremlin && - git add attic_gremlin && - git commit -m "Added attic_gremlin" && + (cd "$CVSWORK" && + echo >attic_gremlin && + cvs -Q add attic_gremlin && + cvs -Q ci -m "added attic_gremlin" && + rm attic_gremlin && + cvs -Q rm attic_gremlin && + cvs -Q ci -m "removed attic_gremlin") && + + echo > attic_gremlin && + git add attic_gremlin && + git commit -m "Added attic_gremlin" && git cvsexportcommit -w "$CVSWORK" -c HEAD && - (cd "$CVSWORK" && cvs -Q update -d) && - test -f "$CVSWORK/attic_gremlin" + (cd "$CVSWORK" && cvs -Q update -d) && + test -f "$CVSWORK/attic_gremlin" ' # the state of the CVS sandbox may be indeterminate for ' space' diff --git a/t/t9211-scalar-clone.sh b/t/t9211-scalar-clone.sh index 872ad1c9c2..7869f45ee6 100755 --- a/t/t9211-scalar-clone.sh +++ b/t/t9211-scalar-clone.sh @@ -180,4 +180,16 @@ test_expect_success 'scalar clone warns when background maintenance fails' ' grep "could not turn on maintenance" err ' +test_expect_success '`scalar clone --no-src`' ' + scalar clone --src "file://$(pwd)/to-clone" with-src && + scalar clone --no-src "file://$(pwd)/to-clone" without-src && + + test_path_is_dir with-src/src && + test_path_is_missing without-src/src && + + (cd with-src/src && ls ?*) >with && + (cd without-src && ls ?*) >without && + test_cmp with without +' + test_done diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 379b19f2f8..003c0b61d0 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -66,10 +66,11 @@ test_expect_success 'setup' ' # note that cvs doesn't accept absolute pathnames # as argument to co -d -test_expect_success 'basic checkout' \ - 'GIT_CONFIG="$git_config" cvs -Q co -d cvswork main && - test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | head -n 1))" = "empty/1.1/" && - test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | sed -ne \$p))" = "secondrootfile/1.1/"' +test_expect_success 'basic checkout' ' + GIT_CONFIG="$git_config" cvs -Q co -d cvswork main && + test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | head -n 1))" = "empty/1.1/" && + test "$(echo $(grep -v ^D cvswork/CVS/Entries|cut -d/ -f2,3,5 | sed -ne \$p))" = "secondrootfile/1.1/" +' #------------------------ # PSERVER AUTHENTICATION @@ -115,35 +116,40 @@ Ah<Z:yZZ30 e END VERIFICATION REQUEST EOF -test_expect_success 'pserver authentication' \ - 'cat request-anonymous | git-cvsserver pserver >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'pserver authentication' ' + cat request-anonymous | git-cvsserver pserver >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' -test_expect_success 'pserver authentication failure (non-anonymous user)' \ - 'if cat request-git | git-cvsserver pserver >log 2>&1 - then - false - else - true - fi && - sed -ne \$p log | grep "^I HATE YOU\$"' +test_expect_success 'pserver authentication failure (non-anonymous user)' ' + if cat request-git | git-cvsserver pserver >log 2>&1 + then + false + else + true + fi && + sed -ne \$p log | grep "^I HATE YOU\$" +' -test_expect_success 'pserver authentication success (non-anonymous user with password)' \ - 'cat login-git-ok | git-cvsserver pserver >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'pserver authentication success (non-anonymous user with password)' ' + cat login-git-ok | git-cvsserver pserver >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' -test_expect_success 'pserver authentication (login)' \ - 'cat login-anonymous | git-cvsserver pserver >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'pserver authentication (login)' ' + cat login-anonymous | git-cvsserver pserver >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' -test_expect_success 'pserver authentication failure (login/non-anonymous user)' \ - 'if cat login-git | git-cvsserver pserver >log 2>&1 - then - false - else - true - fi && - sed -ne \$p log | grep "^I HATE YOU\$"' +test_expect_success 'pserver authentication failure (login/non-anonymous user)' ' + if cat login-git | git-cvsserver pserver >log 2>&1 + then + false + else + true + fi && + sed -ne \$p log | grep "^I HATE YOU\$" +' # misuse pserver authentication for testing of req_Root @@ -165,36 +171,40 @@ END AUTH REQUEST Root $WORKDIR EOF -test_expect_success 'req_Root failure (relative pathname)' \ - 'if cat request-relative | git-cvsserver pserver >log 2>&1 - then - echo unexpected success - false - else - true - fi && - tail log | grep "^error 1 Root must be an absolute pathname$"' +test_expect_success 'req_Root failure (relative pathname)' ' + if cat request-relative | git-cvsserver pserver >log 2>&1 + then + echo unexpected success + false + else + true + fi && + tail log | grep "^error 1 Root must be an absolute pathname$" +' -test_expect_success 'req_Root failure (conflicting roots)' \ - 'cat request-conflict | git-cvsserver pserver >log 2>&1 && - tail log | grep "^error 1 Conflicting roots specified$"' +test_expect_success 'req_Root failure (conflicting roots)' ' + cat request-conflict | git-cvsserver pserver >log 2>&1 && + tail log | grep "^error 1 Conflicting roots specified$" +' -test_expect_success 'req_Root (strict paths)' \ - 'cat request-anonymous | git-cvsserver --strict-paths pserver "$SERVERDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'req_Root (strict paths)' ' + cat request-anonymous | git-cvsserver --strict-paths pserver "$SERVERDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' test_expect_success 'req_Root failure (strict-paths)' ' - ! cat request-anonymous | - git-cvsserver --strict-paths pserver "$WORKDIR" >log 2>&1 + ! cat request-anonymous | + git-cvsserver --strict-paths pserver "$WORKDIR" >log 2>&1 ' -test_expect_success 'req_Root (w/o strict-paths)' \ - 'cat request-anonymous | git-cvsserver pserver "$WORKDIR/" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'req_Root (w/o strict-paths)' ' + cat request-anonymous | git-cvsserver pserver "$WORKDIR/" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' test_expect_success 'req_Root failure (w/o strict-paths)' ' - ! cat request-anonymous | - git-cvsserver pserver "$WORKDIR/gitcvs" >log 2>&1 + ! cat request-anonymous | + git-cvsserver pserver "$WORKDIR/gitcvs" >log 2>&1 ' cat >request-base <<EOF @@ -206,27 +216,30 @@ END AUTH REQUEST Root /gitcvs.git EOF -test_expect_success 'req_Root (base-path)' \ - 'cat request-base | git-cvsserver --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'req_Root (base-path)' ' + cat request-base | git-cvsserver --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' test_expect_success 'req_Root failure (base-path)' ' - ! cat request-anonymous | - git-cvsserver --strict-paths --base-path "$WORKDIR" pserver "$SERVERDIR" >log 2>&1 + ! cat request-anonymous | + git-cvsserver --strict-paths --base-path "$WORKDIR" pserver "$SERVERDIR" >log 2>&1 ' GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false || exit 1 -test_expect_success 'req_Root (export-all)' \ - 'cat request-anonymous | git-cvsserver --export-all pserver "$WORKDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'req_Root (export-all)' ' + cat request-anonymous | git-cvsserver --export-all pserver "$WORKDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' -test_expect_success 'req_Root failure (export-all w/o directory list)' \ - '! (cat request-anonymous | git-cvsserver --export-all pserver >log 2>&1 || false)' +test_expect_success 'req_Root failure (export-all w/o directory list)' ' + ! (cat request-anonymous | git-cvsserver --export-all pserver >log 2>&1 || false)' -test_expect_success 'req_Root (everything together)' \ - 'cat request-base | git-cvsserver --export-all --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && - sed -ne \$p log | grep "^I LOVE YOU\$"' +test_expect_success 'req_Root (everything together)' ' + cat request-base | git-cvsserver --export-all --strict-paths --base-path "$WORKDIR/" pserver "$SERVERDIR" >log 2>&1 && + sed -ne \$p log | grep "^I LOVE YOU\$" +' GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true || exit 1 @@ -247,45 +260,49 @@ test_expect_success 'gitcvs.enabled = false' \ test ! -d cvswork2' rm -fr cvswork2 -test_expect_success 'gitcvs.ext.enabled = true' \ - 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && - GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false && - GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 && - test_cmp cvswork cvswork2' +test_expect_success 'gitcvs.ext.enabled = true' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && + GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled false && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 && + test_cmp cvswork cvswork2 +' rm -fr cvswork2 -test_expect_success 'gitcvs.ext.enabled = false' \ - 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled false && - GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && - if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 - then - echo unexpected cvs success - false - else - true - fi && - grep "GITCVS emulation disabled" cvs.log && - test ! -d cvswork2' +test_expect_success 'gitcvs.ext.enabled = false' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled false && + GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && + if GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 + then + echo unexpected cvs success + false + else + true + fi && + grep "GITCVS emulation disabled" cvs.log && + test ! -d cvswork2 +' rm -fr cvswork2 -test_expect_success 'gitcvs.dbname' \ - 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && - GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs.%a.%m.sqlite && - GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 && - test_cmp cvswork cvswork2 && - test -f "$SERVERDIR/gitcvs.ext.main.sqlite" && - cmp "$SERVERDIR/gitcvs.main.sqlite" "$SERVERDIR/gitcvs.ext.main.sqlite"' +test_expect_success 'gitcvs.dbname' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && + GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs.%a.%m.sqlite && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 && + test_cmp cvswork cvswork2 && + test -f "$SERVERDIR/gitcvs.ext.main.sqlite" && + cmp "$SERVERDIR/gitcvs.main.sqlite" "$SERVERDIR/gitcvs.ext.main.sqlite" +' rm -fr cvswork2 -test_expect_success 'gitcvs.ext.dbname' \ - 'GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && - GIT_DIR="$SERVERDIR" git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && - GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && - GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 && - test_cmp cvswork cvswork2 && - test -f "$SERVERDIR/gitcvs1.ext.main.sqlite" && - test ! -f "$SERVERDIR/gitcvs2.ext.main.sqlite" && - cmp "$SERVERDIR/gitcvs.main.sqlite" "$SERVERDIR/gitcvs1.ext.main.sqlite"' +test_expect_success 'gitcvs.ext.dbname' ' + GIT_DIR="$SERVERDIR" git config --bool gitcvs.ext.enabled true && + GIT_DIR="$SERVERDIR" git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite && + GIT_DIR="$SERVERDIR" git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite && + GIT_CONFIG="$git_config" cvs -Q co -d cvswork2 main >cvs.log 2>&1 && + test_cmp cvswork cvswork2 && + test -f "$SERVERDIR/gitcvs1.ext.main.sqlite" && + test ! -f "$SERVERDIR/gitcvs2.ext.main.sqlite" && + cmp "$SERVERDIR/gitcvs.main.sqlite" "$SERVERDIR/gitcvs1.ext.main.sqlite" +' #------------ @@ -299,109 +316,115 @@ GIT_DIR="$SERVERDIR" git config --bool gitcvs.enabled true && GIT_DIR="$SERVERDIR" git config gitcvs.logfile "$SERVERDIR/gitcvs.log" || exit 1 -test_expect_success 'cvs update (create new file)' \ - 'echo testfile1 >testfile1 && - git add testfile1 && - git commit -q -m "Add testfile1" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.1/" && - test_cmp testfile1 ../testfile1' +test_expect_success 'cvs update (create new file)' ' + echo testfile1 >testfile1 && + git add testfile1 && + git commit -q -m "Add testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.1/" && + test_cmp testfile1 ../testfile1 +' cd "$WORKDIR" -test_expect_success 'cvs update (update existing file)' \ - 'echo line 2 >>testfile1 && - git add testfile1 && - git commit -q -m "Append to testfile1" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.2/" && - test_cmp testfile1 ../testfile1' +test_expect_success 'cvs update (update existing file)' ' + echo line 2 >>testfile1 && + git add testfile1 && + git commit -q -m "Append to testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.2/" && + test_cmp testfile1 ../testfile1 +' cd "$WORKDIR" #TODO: cvsserver doesn't support update w/o -d test_expect_failure "cvs update w/o -d doesn't create subdir (TODO)" ' - mkdir test && - echo >test/empty && - git add test && - git commit -q -m "Single Subdirectory" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - test ! -d test + mkdir test && + echo >test/empty && + git add test && + git commit -q -m "Single Subdirectory" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test ! -d test ' cd "$WORKDIR" -test_expect_success 'cvs update (subdirectories)' \ - '(for dir in A A/B A/B/C A/D E; do - mkdir $dir && - echo "test file in $dir" >"$dir/file_in_$(echo $dir|sed -e "s#/# #g")" && - git add $dir || exit 1 - done) && - git commit -q -m "deep sub directory structure" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update -d && - (for dir in A A/B A/B/C A/D E; do - filename="file_in_$(echo $dir|sed -e "s#/# #g")" && - if test "$(echo $(grep -v ^D $dir/CVS/Entries|cut -d/ -f2,3,5))" = "$filename/1.1/" && - test_cmp "$dir/$filename" "../$dir/$filename"; then - : - else - exit 1 - fi - done)' +test_expect_success 'cvs update (subdirectories)' ' + (for dir in A A/B A/B/C A/D E; do + mkdir $dir && + echo "test file in $dir" >"$dir/file_in_$(echo $dir|sed -e "s#/# #g")" && + git add $dir || exit 1 + done) && + git commit -q -m "deep sub directory structure" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update -d && + (for dir in A A/B A/B/C A/D E; do + filename="file_in_$(echo $dir|sed -e "s#/# #g")" && + if test "$(echo $(grep -v ^D $dir/CVS/Entries|cut -d/ -f2,3,5))" = "$filename/1.1/" && + test_cmp "$dir/$filename" "../$dir/$filename"; then + : + else + exit 1 + fi + done) +' cd "$WORKDIR" -test_expect_success 'cvs update (delete file)' \ - 'git rm testfile1 && - git commit -q -m "Remove testfile1" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - test -z "$(grep testfile1 CVS/Entries)" && - test ! -f testfile1' +test_expect_success 'cvs update (delete file)' ' + git rm testfile1 && + git commit -q -m "Remove testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test -z "$(grep testfile1 CVS/Entries)" && + test ! -f testfile1 +' cd "$WORKDIR" -test_expect_success 'cvs update (re-add deleted file)' \ - 'echo readded testfile >testfile1 && - git add testfile1 && - git commit -q -m "Re-Add testfile1" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.4/" && - test_cmp testfile1 ../testfile1' +test_expect_success 'cvs update (re-add deleted file)' ' + echo readded testfile >testfile1 && + git add testfile1 && + git commit -q -m "Re-Add testfile1" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep testfile1 CVS/Entries|cut -d/ -f2,3,5))" = "testfile1/1.4/" && + test_cmp testfile1 ../testfile1 +' cd "$WORKDIR" -test_expect_success 'cvs update (merge)' \ - 'echo Line 0 >expected && - for i in 1 2 3 4 5 6 7 - do - echo Line $i >>merge && - echo Line $i >>expected || return 1 - done && - echo Line 8 >>expected && - git add merge && - git commit -q -m "Merge test (pre-merge)" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - test "$(echo $(grep merge CVS/Entries|cut -d/ -f2,3,5))" = "merge/1.1/" && - test_cmp merge ../merge && - ( echo Line 0 && cat merge ) >merge.tmp && - mv merge.tmp merge && - cd "$WORKDIR" && - echo Line 8 >>merge && - git add merge && - git commit -q -m "Merge test (merge)" && - git push gitcvs.git >/dev/null && - cd cvswork && - sleep 1 && touch merge && - GIT_CONFIG="$git_config" cvs -Q update && - test_cmp merge ../expected' +test_expect_success 'cvs update (merge)' ' + echo Line 0 >expected && + for i in 1 2 3 4 5 6 7 + do + echo Line $i >>merge && + echo Line $i >>expected || return 1 + done && + echo Line 8 >>expected && + git add merge && + git commit -q -m "Merge test (pre-merge)" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test "$(echo $(grep merge CVS/Entries|cut -d/ -f2,3,5))" = "merge/1.1/" && + test_cmp merge ../merge && + ( echo Line 0 && cat merge ) >merge.tmp && + mv merge.tmp merge && + cd "$WORKDIR" && + echo Line 8 >>merge && + git add merge && + git commit -q -m "Merge test (merge)" && + git push gitcvs.git >/dev/null && + cd cvswork && + sleep 1 && touch merge && + GIT_CONFIG="$git_config" cvs -Q update && + test_cmp merge ../expected +' cd "$WORKDIR" @@ -418,55 +441,58 @@ do echo Line $i >>expected.C done -test_expect_success 'cvs update (conflict merge)' \ - '( echo LINE 0 && cat merge ) >merge.tmp && - mv merge.tmp merge && - git add merge && - git commit -q -m "Merge test (conflict)" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update && - test_cmp merge ../expected.C' +test_expect_success 'cvs update (conflict merge)' ' + ( echo LINE 0 && cat merge ) >merge.tmp && + mv merge.tmp merge && + git add merge && + git commit -q -m "Merge test (conflict)" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update && + test_cmp merge ../expected.C +' cd "$WORKDIR" -test_expect_success 'cvs update (-C)' \ - 'cd cvswork && - GIT_CONFIG="$git_config" cvs -Q update -C && - test_cmp merge ../merge' +test_expect_success 'cvs update (-C)' ' + cd cvswork && + GIT_CONFIG="$git_config" cvs -Q update -C && + test_cmp merge ../merge +' cd "$WORKDIR" -test_expect_success 'cvs update (merge no-op)' \ - 'echo Line 9 >>merge && - cp merge cvswork/merge && - git add merge && - git commit -q -m "Merge test (no-op)" && - git push gitcvs.git >/dev/null && - cd cvswork && - sleep 1 && touch merge && - GIT_CONFIG="$git_config" cvs -Q update && - test_cmp merge ../merge' +test_expect_success 'cvs update (merge no-op)' ' + echo Line 9 >>merge && + cp merge cvswork/merge && + git add merge && + git commit -q -m "Merge test (no-op)" && + git push gitcvs.git >/dev/null && + cd cvswork && + sleep 1 && touch merge && + GIT_CONFIG="$git_config" cvs -Q update && + test_cmp merge ../merge +' cd "$WORKDIR" test_expect_success 'cvs update (-p)' ' - touch really-empty && - echo Line 1 > no-lf && - printf "Line 2" >> no-lf && - git add really-empty no-lf && - git commit -q -m "Update -p test" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs update && - for i in merge no-lf empty really-empty; do - GIT_CONFIG="$git_config" cvs update -p "$i" >$i.out && - test_cmp $i.out ../$i || return 1 - done + touch really-empty && + echo Line 1 > no-lf && + printf "Line 2" >> no-lf && + git add really-empty no-lf && + git commit -q -m "Update -p test" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs update && + for i in merge no-lf empty really-empty; do + GIT_CONFIG="$git_config" cvs update -p "$i" >$i.out && + test_cmp $i.out ../$i || return 1 + done ' cd "$WORKDIR" test_expect_success 'cvs update (module list supports packed refs)' ' - GIT_DIR="$SERVERDIR" git pack-refs --all && - GIT_CONFIG="$git_config" cvs -n up -d 2> out && - grep "cvs update: New directory \`main'\''" < out + GIT_DIR="$SERVERDIR" git pack-refs --all && + GIT_CONFIG="$git_config" cvs -n up -d 2> out && + grep "cvs update: New directory \`main'\''" < out ' #------------ @@ -475,30 +501,30 @@ test_expect_success 'cvs update (module list supports packed refs)' ' cd "$WORKDIR" test_expect_success 'cvs status' ' - mkdir status.dir && - echo Line > status.dir/status.file && - echo Line > status.file && - git add status.dir status.file && - git commit -q -m "Status test" && - git push gitcvs.git >/dev/null && - cd cvswork && - GIT_CONFIG="$git_config" cvs update && - GIT_CONFIG="$git_config" cvs status | grep "^File: status.file" >../out && - test_line_count = 2 ../out + mkdir status.dir && + echo Line > status.dir/status.file && + echo Line > status.file && + git add status.dir status.file && + git commit -q -m "Status test" && + git push gitcvs.git >/dev/null && + cd cvswork && + GIT_CONFIG="$git_config" cvs update && + GIT_CONFIG="$git_config" cvs status | grep "^File: status.file" >../out && + test_line_count = 2 ../out ' cd "$WORKDIR" test_expect_success 'cvs status (nonrecursive)' ' - cd cvswork && - GIT_CONFIG="$git_config" cvs status -l | grep "^File: status.file" >../out && - test_line_count = 1 ../out + cd cvswork && + GIT_CONFIG="$git_config" cvs status -l | grep "^File: status.file" >../out && + test_line_count = 1 ../out ' cd "$WORKDIR" test_expect_success 'cvs status (no subdirs in header)' ' - cd cvswork && - GIT_CONFIG="$git_config" cvs status | grep ^File: >../out && - ! grep / <../out + cd cvswork && + GIT_CONFIG="$git_config" cvs status | grep ^File: >../out && + ! grep / <../out ' #------------ @@ -507,9 +533,9 @@ test_expect_success 'cvs status (no subdirs in header)' ' cd "$WORKDIR" test_expect_success 'cvs co -c (shows module database)' ' - GIT_CONFIG="$git_config" cvs co -c > out && - grep "^main[ ][ ]*main$" <out && - ! grep -v "^main[ ][ ]*main$" <out + GIT_CONFIG="$git_config" cvs co -c > out && + grep "^main[ ][ ]*main$" <out && + ! grep -v "^main[ ][ ]*main$" <out ' #------------ @@ -575,11 +601,11 @@ expectStat="$?" cd "$WORKDIR" test_expect_success 'cvs log' ' - cd cvswork && - test x"$expectStat" = x"0" && - GIT_CONFIG="$git_config" cvs log merge >../out && - sed -e "s%2[0-9][0-9][0-9]/[01][0-9]/[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]%__DATE__%" ../out > ../actual && - test_cmp ../expect ../actual + cd cvswork && + test x"$expectStat" = x"0" && + GIT_CONFIG="$git_config" cvs log merge >../out && +sed -e "s%2[0-9][0-9][0-9]/[01][0-9]/[0-3][0-9] [0-2][0-9]:[0-5][0-9]:[0-5][0-9]%__DATE__%" ../out > ../actual && + test_cmp ../expect ../actual ' #------------ @@ -588,11 +614,11 @@ test_expect_success 'cvs log' ' cd "$WORKDIR" test_expect_success 'cvs annotate' ' - cd cvswork && - GIT_CONFIG="$git_config" cvs annotate merge >../out && - sed -e "s/ .*//" ../out >../actual && - printf "1.%d\n" 3 1 1 1 1 1 1 1 2 4 >../expect && - test_cmp ../expect ../actual + cd cvswork && + GIT_CONFIG="$git_config" cvs annotate merge >../out && + sed -e "s/ .*//" ../out >../actual && + printf "1.%d\n" 3 1 1 1 1 1 1 1 2 4 >../expect && + test_cmp ../expect ../actual ' #------------ diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 8835e16e81..47e20fb8b1 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1622,14 +1622,22 @@ test_expect_success 'git checkout - with -d, complete only references' ' ' test_expect_success 'git switch - with --track, complete only remote branches' ' - test_completion "git switch --track " <<-\EOF + test_completion "git switch --track " <<-\EOF && + other/branch-in-other Z + other/main-in-other Z + EOF + test_completion "git switch -t " <<-\EOF other/branch-in-other Z other/main-in-other Z EOF ' test_expect_success 'git checkout - with --track, complete only remote branches' ' - test_completion "git checkout --track " <<-\EOF + test_completion "git checkout --track " <<-\EOF && + other/branch-in-other Z + other/main-in-other Z + EOF + test_completion "git checkout -t " <<-\EOF other/branch-in-other Z other/main-in-other Z EOF diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 6e19ebc922..2f8868caa1 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -542,8 +542,17 @@ test_config () { config_dir=$1 shift fi - test_when_finished "test_unconfig ${config_dir:+-C '$config_dir'} '$1'" && - git ${config_dir:+-C "$config_dir"} config "$@" + + # If --worktree is provided, use it to configure/unconfigure + is_worktree= + if test "$1" = --worktree + then + is_worktree=1 + shift + fi + + test_when_finished "test_unconfig ${config_dir:+-C '$config_dir'} ${is_worktree:+--worktree} '$1'" && + git ${config_dir:+-C "$config_dir"} config ${is_worktree:+--worktree} "$@" } test_config_global () { @@ -901,6 +910,15 @@ test_path_is_symlink () { fi } +test_path_is_executable () { + test "$#" -ne 1 && BUG "1 param" + if ! test -x "$1" + then + echo "$1 is not executable" + false + fi +} + # Check if the directory exists and is empty as expected, barf otherwise. test_dir_is_empty () { test "$#" -ne 1 && BUG "1 param" @@ -1273,6 +1291,39 @@ test_cmp_rev () { fi } +# Tests that a commit message matches the expected text +# +# Usage: test_commit_message <rev> [-m <msg> | <file>] +# +# When using "-m" <msg> will have a line feed appended. If the second +# argument is omitted then the expected message is read from stdin. + +test_commit_message () { + local msg_file=expect.msg + + case $# in + 3) + if test "$2" = "-m" + then + printf "%s\n" "$3" >"$msg_file" + else + BUG "Usage: test_commit_message <rev> [-m <message> | <file>]" + fi + ;; + 2) + msg_file="$2" + ;; + 1) + cat >"$msg_file" + ;; + *) + BUG "Usage: test_commit_message <rev> [-m <message> | <file>]" + ;; + esac + git show --no-patch --pretty=format:%B "$1" -- >actual.msg && + test_cmp "$msg_file" actual.msg +} + # Compare paths respecting core.ignoreCase test_cmp_fspath () { if test "x$1" = "x$2" diff --git a/t/test-lib.sh b/t/test-lib.sh index 5ea5d1d62a..1656c9eed0 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -89,6 +89,9 @@ prepend_var LSAN_OPTIONS : $GIT_SAN_OPTIONS prepend_var LSAN_OPTIONS : fast_unwind_on_malloc=0 export LSAN_OPTIONS +prepend_var UBSAN_OPTIONS : $GIT_SAN_OPTIONS +export UBSAN_OPTIONS + if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS then echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).' |
