diff options
Diffstat (limited to 't')
119 files changed, 1810 insertions, 175 deletions
@@ -419,7 +419,7 @@ the --sparse command-line argument. GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path by overriding the minimum number of cache entries required per thread. -GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when true, enables the +GIT_TEST_ADD_I_USE_BUILTIN=<boolean>, when false, disables the built-in version of git add -i. See 'add.interactive.useBuiltin' in git-config(1). diff --git a/t/helper/test-fast-rebase.c b/t/helper/test-fast-rebase.c index fc2d460..4e5553e 100644 --- a/t/helper/test-fast-rebase.c +++ b/t/helper/test-fast-rebase.c @@ -99,6 +99,7 @@ int cmd__fast_rebase(int argc, const char **argv) struct merge_result result; struct strbuf reflog_msg = STRBUF_INIT; struct strbuf branch_name = STRBUF_INIT; + int ret = 0; /* * test-tool stuff doesn't set up the git directory by default; need to @@ -137,13 +138,17 @@ int cmd__fast_rebase(int argc, const char **argv) revs.topo_order = 1; strvec_pushl(&rev_walk_args, "", argv[4], "--not", argv[3], NULL); - if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) - return error(_("unhandled options")); + if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) { + ret = error(_("unhandled options")); + goto cleanup; + } strvec_clear(&rev_walk_args); - if (prepare_revision_walk(&revs) < 0) - return error(_("error preparing revisions")); + if (prepare_revision_walk(&revs) < 0) { + ret = error(_("error preparing revisions")); + goto cleanup; + } init_merge_options(&merge_opt, the_repository); memset(&result, 0, sizeof(result)); @@ -201,8 +206,6 @@ int cmd__fast_rebase(int argc, const char **argv) } if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0) die(_("unable to update HEAD")); - strbuf_release(&reflog_msg); - strbuf_release(&branch_name); prime_cache_tree(the_repository, the_repository->index, result.tree); @@ -221,5 +224,11 @@ int cmd__fast_rebase(int argc, const char **argv) if (write_locked_index(&the_index, &lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write %s"), get_index_file()); - return (result.clean == 0); + + ret = (result.clean == 0); +cleanup: + strbuf_release(&reflog_msg); + strbuf_release(&branch_name); + release_revisions(&revs); + return ret; } diff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c new file mode 100644 index 0000000..f7b79da --- /dev/null +++ b/t/helper/test-pack-mtimes.c @@ -0,0 +1,56 @@ +#include "git-compat-util.h" +#include "test-tool.h" +#include "strbuf.h" +#include "object-store.h" +#include "packfile.h" +#include "pack-mtimes.h" + +static void dump_mtimes(struct packed_git *p) +{ + uint32_t i; + if (load_pack_mtimes(p) < 0) + die("could not load pack .mtimes"); + + for (i = 0; i < p->num_objects; i++) { + struct object_id oid; + if (nth_packed_object_id(&oid, p, i) < 0) + die("could not load object id at position %"PRIu32, i); + + printf("%s %"PRIu32"\n", + oid_to_hex(&oid), nth_packed_mtime(p, i)); + } +} + +static const char *pack_mtimes_usage = "\n" +" test-tool pack-mtimes <pack-name.mtimes>"; + +int cmd__pack_mtimes(int argc, const char **argv) +{ + struct strbuf buf = STRBUF_INIT; + struct packed_git *p; + + setup_git_directory(); + + if (argc != 2) + usage(pack_mtimes_usage); + + for (p = get_all_packs(the_repository); p; p = p->next) { + strbuf_addstr(&buf, basename(p->pack_name)); + strbuf_strip_suffix(&buf, ".pack"); + strbuf_addstr(&buf, ".mtimes"); + + if (!strcmp(buf.buf, argv[1])) + break; + + strbuf_reset(&buf); + } + + strbuf_release(&buf); + + if (!p) + die("could not find pack '%s'", argv[1]); + + dump_mtimes(p); + + return 0; +} diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c index 625b2db..4a45d5b 100644 --- a/t/helper/test-revision-walking.c +++ b/t/helper/test-revision-walking.c @@ -43,6 +43,7 @@ static int run_revision_walk(void) } reset_revision_walk(); + release_revisions(&rev); return got_revision; } diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 0424f7a..d2eacd3 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -48,6 +48,7 @@ static struct test_cmd cmds[] = { { "oidmap", cmd__oidmap }, { "oidtree", cmd__oidtree }, { "online-cpus", cmd__online_cpus }, + { "pack-mtimes", cmd__pack_mtimes }, { "parse-options", cmd__parse_options }, { "parse-pathspec-file", cmd__parse_pathspec_file }, { "partial-clone", cmd__partial_clone }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index c876e82..960cc27 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -38,6 +38,7 @@ int cmd__mktemp(int argc, const char **argv); int cmd__oidmap(int argc, const char **argv); int cmd__oidtree(int argc, const char **argv); int cmd__online_cpus(int argc, const char **argv); +int cmd__pack_mtimes(int argc, const char **argv); int cmd__parse_options(int argc, const char **argv); int cmd__parse_pathspec_file(int argc, const char** argv); int cmd__partial_clone(int argc, const char **argv); diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index 2fde235..ea28971 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -1,3 +1,7 @@ +if test -z "$TEST_FAILS_SANITIZE_LEAK" +then + TEST_PASSES_SANITIZE_LEAK=true +fi . ./test-lib.sh if test -n "$NO_SVN_TESTS" diff --git a/t/lib-sudo.sh b/t/lib-sudo.sh new file mode 100644 index 0000000..b4d7788 --- /dev/null +++ b/t/lib-sudo.sh @@ -0,0 +1,15 @@ +# Helpers for running git commands under sudo. + +# Runs a scriplet passed through stdin under sudo. +run_with_sudo () { + local ret + local RUN="$TEST_DIRECTORY/$$.sh" + write_script "$RUN" "$TEST_SHELL_PATH" + # avoid calling "$RUN" directly so sudo doesn't get a chance to + # override the shell, add aditional restrictions or even reject + # running the script because its security policy deem it unsafe + sudo "$TEST_SHELL_PATH" -c "\"$RUN\"" + ret=$? + rm -f "$RUN" + return $ret +} diff --git a/t/lib-unique-files.sh b/t/lib-unique-files.sh new file mode 100644 index 0000000..a14080f --- /dev/null +++ b/t/lib-unique-files.sh @@ -0,0 +1,34 @@ +# Helper to create files with unique contents + +# Create multiple files with unique contents within this test run. Takes the +# number of directories, the number of files in each directory, and the base +# directory. +# +# test_create_unique_files 2 3 my_dir -- Creates 2 directories with 3 files +# each in my_dir, all with contents +# different from previous invocations +# of this command in this run. + +test_create_unique_files () { + test "$#" -ne 3 && BUG "3 param" + + local dirs="$1" && + local files="$2" && + local basedir="$3" && + local counter="0" && + local i && + local j && + test_tick && + local basedata="$basedir$test_tick" && + rm -rf "$basedir" && + for i in $(test_seq $dirs) + do + local dir="$basedir/dir$i" && + mkdir -p "$dir" && + for j in $(test_seq $files) + do + counter=$((counter + 1)) && + echo "$basedata.$counter">"$dir/file$j.txt" + done + done +} diff --git a/t/perf/p0008-odb-fsync.sh b/t/perf/p0008-odb-fsync.sh new file mode 100755 index 0000000..b3a90f3 --- /dev/null +++ b/t/perf/p0008-odb-fsync.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# +# This test measures the performance of adding new files to the object +# database. The test was originally added to measure the effect of the +# core.fsyncMethod=batch mode, which is why we are testing different values of +# that setting explicitly and creating a lot of unique objects. + +test_description="Tests performance of adding things to the object database" + +. ./perf-lib.sh + +. $TEST_DIRECTORY/lib-unique-files.sh + +test_perf_fresh_repo +test_checkout_worktree + +dir_count=10 +files_per_dir=50 +total_files=$((dir_count * files_per_dir)) + +populate_files () { + test_create_unique_files $dir_count $files_per_dir files +} + +setup_repo () { + (rm -rf .git || 1) && + git init && + test_commit first && + populate_files +} + +test_perf_fsync_cfgs () { + local method && + local cfg && + for method in none fsync batch writeout-only + do + case $method in + none) + cfg="-c core.fsync=none" + ;; + *) + cfg="-c core.fsync=loose-object -c core.fsyncMethod=$method" + esac && + + # Set GIT_TEST_FSYNC=1 explicitly since fsync is normally + # disabled by t/test-lib.sh. + if ! test_perf "$1 (fsyncMethod=$method)" \ + --setup "$2" \ + "GIT_TEST_FSYNC=1 git $cfg $3" + then + break + fi + done +} + +test_perf_fsync_cfgs "add $total_files files" \ + "setup_repo" \ + "add -- files" + +test_perf_fsync_cfgs "stash $total_files files" \ + "setup_repo" \ + "stash push -u -- files" + +test_perf_fsync_cfgs "unpack $total_files files" \ + " + setup_repo && + git -c core.fsync=none add -- files && + git -c core.fsync=none commit -q -m second && + echo HEAD | git pack-objects -q --stdout --revs >test_pack.pack && + setup_repo + " \ + "unpack-objects -q <test_pack.pack" + +test_perf_fsync_cfgs "commit $total_files files" \ + " + setup_repo && + git -c core.fsync=none add -- files && + populate_files + " \ + "commit -q -a -m test" + +test_done diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh index 76710cb..c181110 100755 --- a/t/perf/p2000-sparse-operations.sh +++ b/t/perf/p2000-sparse-operations.sh @@ -112,6 +112,7 @@ test_perf_on_all git add -A test_perf_on_all git add . test_perf_on_all git commit -a -m A test_perf_on_all git checkout -f - +test_perf_on_all "git sparse-checkout add f2/f3/f1 && git sparse-checkout set $SPARSE_CONE" test_perf_on_all git reset test_perf_on_all git reset --hard test_perf_on_all git reset -- does-not-exist diff --git a/t/perf/p4220-log-grep-engines.sh b/t/perf/p4220-log-grep-engines.sh index 2bc47de..03fbfbb 100755 --- a/t/perf/p4220-log-grep-engines.sh +++ b/t/perf/p4220-log-grep-engines.sh @@ -36,7 +36,8 @@ do else prereq="" fi - test_perf $prereq "$engine log$GIT_PERF_4220_LOG_OPTS --grep='$pattern'" " + test_perf "$engine log$GIT_PERF_4220_LOG_OPTS --grep='$pattern'" \ + --prereq "$prereq" " git -c grep.patternType=$engine log --pretty=format:%h$GIT_PERF_4220_LOG_OPTS --grep='$pattern' >'out.$engine' || : " done diff --git a/t/perf/p4221-log-grep-engines-fixed.sh b/t/perf/p4221-log-grep-engines-fixed.sh index 0609712..0a6d6df 100755 --- a/t/perf/p4221-log-grep-engines-fixed.sh +++ b/t/perf/p4221-log-grep-engines-fixed.sh @@ -26,7 +26,8 @@ do else prereq="" fi - test_perf $prereq "$engine log$GIT_PERF_4221_LOG_OPTS --grep='$pattern'" " + test_perf "$engine log$GIT_PERF_4221_LOG_OPTS --grep='$pattern'" \ + --prereq "$prereq" " git -c grep.patternType=$engine log --pretty=format:%h$GIT_PERF_4221_LOG_OPTS --grep='$pattern' >'out.$engine' || : " done diff --git a/t/perf/p5302-pack-index.sh b/t/perf/p5302-pack-index.sh index c16f6a3..14c601b 100755 --- a/t/perf/p5302-pack-index.sh +++ b/t/perf/p5302-pack-index.sh @@ -26,9 +26,8 @@ test_expect_success 'set up thread-counting tests' ' done ' -test_perf PERF_EXTRA 'index-pack 0 threads' ' - rm -rf repo.git && - git init --bare repo.git && +test_perf 'index-pack 0 threads' --prereq PERF_EXTRA \ + --setup 'rm -rf repo.git && git init --bare repo.git' ' GIT_DIR=repo.git git index-pack --threads=1 --stdin < $PACK ' @@ -36,17 +35,15 @@ for t in $threads do THREADS=$t export THREADS - test_perf PERF_EXTRA "index-pack $t threads" ' - rm -rf repo.git && - git init --bare repo.git && + test_perf "index-pack $t threads" --prereq PERF_EXTRA \ + --setup 'rm -rf repo.git && git init --bare repo.git' ' GIT_DIR=repo.git GIT_FORCE_THREADS=1 \ git index-pack --threads=$THREADS --stdin <$PACK ' done -test_perf 'index-pack default number of threads' ' - rm -rf repo.git && - git init --bare repo.git && +test_perf 'index-pack default number of threads' \ + --setup 'rm -rf repo.git && git init --bare repo.git' ' GIT_DIR=repo.git git index-pack --stdin < $PACK ' diff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh index 0b9129c..b1cb238 100755 --- a/t/perf/p7519-fsmonitor.sh +++ b/t/perf/p7519-fsmonitor.sh @@ -60,18 +60,6 @@ then esac fi -if test -n "$GIT_PERF_7519_DROP_CACHE" -then - # When using GIT_PERF_7519_DROP_CACHE, GIT_PERF_REPEAT_COUNT must be 1 to - # generate valid results. Otherwise the caching that happens for the nth - # run will negate the validity of the comparisons. - if test "$GIT_PERF_REPEAT_COUNT" -ne 1 - then - echo "warning: Setting GIT_PERF_REPEAT_COUNT=1" >&2 - GIT_PERF_REPEAT_COUNT=1 - fi -fi - trace_start () { if test -n "$GIT_PERF_7519_TRACE" then @@ -175,10 +163,10 @@ setup_for_fsmonitor_hook () { test_perf_w_drop_caches () { if test -n "$GIT_PERF_7519_DROP_CACHE"; then - test-tool drop-caches + test_perf "$1" --setup "test-tool drop-caches" "$2" + else + test_perf "$@" fi - - test_perf "$@" } test_fsmonitor_suite () { diff --git a/t/perf/p7820-grep-engines.sh b/t/perf/p7820-grep-engines.sh index 8b09c5b..9bfb868 100755 --- a/t/perf/p7820-grep-engines.sh +++ b/t/perf/p7820-grep-engines.sh @@ -49,13 +49,15 @@ do fi if ! test_have_prereq PERF_GREP_ENGINES_THREADS then - test_perf $prereq "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern'" " + test_perf "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern'" \ + --prereq "$prereq" " git -c grep.patternType=$engine grep$GIT_PERF_7820_GREP_OPTS -- '$pattern' >'out.$engine' || : " else for threads in $GIT_PERF_GREP_THREADS do - test_perf PTHREADS,$prereq "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern' with $threads threads" " + test_perf "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern' with $threads threads" + --prereq PTHREADS,$prereq " git -c grep.patternType=$engine -c grep.threads=$threads grep$GIT_PERF_7820_GREP_OPTS -- '$pattern' >'out.$engine.$threads' || : " done diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 932105c..ab3687c 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -189,19 +189,39 @@ exit $ret' >&3 2>&4 } test_wrapper_ () { - test_wrapper_func_=$1; shift + local test_wrapper_func_="$1"; shift + local test_title_="$1"; shift test_start_ - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || - BUG "not 2 or 3 parameters to test-expect-success" + test_prereq= + test_perf_setup_= + while test $# != 0 + do + case $1 in + --prereq) + test_prereq=$2 + shift + ;; + --setup) + test_perf_setup_=$2 + shift + ;; + *) + break + ;; + esac + shift + done + test "$#" = 1 || BUG "test_wrapper_ needs 2 positional parameters" export test_prereq - if ! test_skip "$@" + export test_perf_setup_ + + if ! test_skip "$test_title_" "$@" then base=$(basename "$0" .sh) echo "$test_count" >>"$perf_results_dir"/$base.subtests echo "$1" >"$perf_results_dir"/$base.$test_count.descr base="$perf_results_dir"/"$PERF_RESULTS_PREFIX$(basename "$0" .sh)"."$test_count" - "$test_wrapper_func_" "$@" + "$test_wrapper_func_" "$test_title_" "$@" fi test_finish_ @@ -214,6 +234,16 @@ test_perf_ () { echo "perf $test_count - $1:" fi for i in $(test_seq 1 $GIT_PERF_REPEAT_COUNT); do + if test -n "$test_perf_setup_" + then + say >&3 "setup: $test_perf_setup_" + if ! test_eval_ $test_perf_setup_ + then + test_failure_ "$test_perf_setup_" + break + fi + + fi say >&3 "running: $2" if test_run_perf_ "$2" then @@ -237,11 +267,24 @@ test_perf_ () { rm test_time.* } +# Usage: test_perf 'title' [options] 'perf-test' +# Run the performance test script specified in perf-test with +# optional prerequisite and setup steps. +# Options: +# --prereq prerequisites: Skip the test if prequisites aren't met +# --setup "setup-steps": Run setup steps prior to each measured iteration +# test_perf () { test_wrapper_ test_perf_ "$@" } test_size_ () { + if test -n "$test_perf_setup_" + then + say >&3 "setup: $test_perf_setup_" + test_eval_ $test_perf_setup_ + fi + say >&3 "running: $2" if test_eval_ "$2" 3>"$base".result; then test_ok_ "$1" @@ -250,6 +293,14 @@ test_size_ () { fi } +# Usage: test_size 'title' [options] 'size-test' +# Run the size test script specified in size-test with optional +# prerequisites and setup steps. Returns the numeric value +# returned by size-test. +# Options: +# --prereq prerequisites: Skip the test if prequisites aren't met +# --setup "setup-steps": Run setup steps prior to the size measurement + test_size () { test_wrapper_ test_size_ "$@" } diff --git a/t/t0034-root-safe-directory.sh b/t/t0034-root-safe-directory.sh new file mode 100755 index 0000000..a621f1e --- /dev/null +++ b/t/t0034-root-safe-directory.sh @@ -0,0 +1,106 @@ +#!/bin/sh + +test_description='verify safe.directory checks while running as root' + +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-sudo.sh + +if [ "$GIT_TEST_ALLOW_SUDO" != "YES" ] +then + skip_all="You must set env var GIT_TEST_ALLOW_SUDO=YES in order to run this test" + test_done +fi + +if ! test_have_prereq NOT_ROOT +then + skip_all="These tests do not support running as root" + test_done +fi + +test_lazy_prereq SUDO ' + sudo -n id -u >u && + id -u root >r && + test_cmp u r && + command -v git >u && + sudo command -v git >r && + test_cmp u r +' + +if ! test_have_prereq SUDO +then + skip_all="Your sudo/system configuration is either too strict or unsupported" + test_done +fi + +test_expect_success SUDO 'setup' ' + sudo rm -rf root && + mkdir -p root/r && + ( + cd root/r && + git init + ) +' + +test_expect_success SUDO 'sudo git status as original owner' ' + ( + cd root/r && + git status && + sudo git status + ) +' + +test_expect_success SUDO 'setup root owned repository' ' + sudo mkdir -p root/p && + sudo git init root/p +' + +test_expect_success 'cannot access if owned by root' ' + ( + cd root/p && + test_must_fail git status + ) +' + +test_expect_success 'can access if addressed explicitly' ' + ( + cd root/p && + GIT_DIR=.git GIT_WORK_TREE=. git status + ) +' + +test_expect_failure SUDO 'can access with sudo if root' ' + ( + cd root/p && + sudo git status + ) +' + +test_expect_success SUDO 'can access with sudo if root by removing SUDO_UID' ' + ( + cd root/p && + run_with_sudo <<-END + unset SUDO_UID && + git status + END + ) +' + +test_lazy_prereq SUDO_SUDO ' + sudo sudo id -u >u && + id -u root >r && + test_cmp u r +' + +test_expect_success SUDO_SUDO 'can access with sudo abusing SUDO_UID' ' + ( + cd root/p && + sudo sudo git status + ) +' + +# this MUST be always the last test +test_expect_success SUDO 'cleanup' ' + sudo rm -rf root +' + +test_done diff --git a/t/t0056-git-C.sh b/t/t0056-git-C.sh index 2630e75..752aa8c 100755 --- a/t/t0056-git-C.sh +++ b/t/t0056-git-C.sh @@ -2,6 +2,7 @@ test_description='"-C <path>" option and its effects on other path-related options' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success '"git -C <path>" runs git from the directory <path>' ' diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 2fe6ae6..aa35350 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -542,7 +542,7 @@ test_lazy_prereq CAN_EXEC_IN_PWD ' ./git rev-parse ' -test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' +test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' mkdir -p pretend/bin pretend/libexec/git-core && echo "echo HERE" | write_script pretend/libexec/git-core/git-here && cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && @@ -550,7 +550,7 @@ test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD 'RUNTIME_PREFIX works' ' echo HERE >expect && test_cmp expect actual' -test_expect_success RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' ' +test_expect_success !VALGRIND,RUNTIME_PREFIX,CAN_EXEC_IN_PWD '%(prefix)/ works' ' mkdir -p pretend/bin && cp "$GIT_EXEC_PATH"/git$X pretend/bin/ && git config yes.path "%(prefix)/yes" && diff --git a/t/t0062-revision-walking.sh b/t/t0062-revision-walking.sh index 8e21586..b9480c8 100755 --- a/t/t0062-revision-walking.sh +++ b/t/t0062-revision-walking.sh @@ -5,6 +5,7 @@ test_description='Test revision walking api' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >run_twice_expected <<-EOF diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh index 69beb59..a16cc3d 100755 --- a/t/t0100-previous.sh +++ b/t/t0100-previous.sh @@ -5,6 +5,7 @@ test_description='previous branch syntax @{-n}' 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 'branch -d @{-1}' ' diff --git a/t/t0101-at-syntax.sh b/t/t0101-at-syntax.sh index a1998b5..878aadd 100755 --- a/t/t0101-at-syntax.sh +++ b/t/t0101-at-syntax.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='various @{whatever} syntax tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 0710b1f..516a611 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -21,6 +21,7 @@ In the test, these paths are used: yomin - not in H or M ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index 46cbd55..bd5313c 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -9,6 +9,7 @@ This is identical to t1001, but uses -u to update the work tree as well. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh index 1b85207..dadf3b1 100755 --- a/t/t1006-cat-file.sh +++ b/t/t1006-cat-file.sh @@ -681,7 +681,7 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' ' # Setup and create the empty blob and its path empty_path=$(git rev-parse --git-path objects/$(test_oid_to_path "$EMPTY_BLOB")) && - git hash-object -w --stdin </dev/null && + empty_blob=$(git hash-object -w --stdin </dev/null) && # Create another blob and its path echo other >other.blob && @@ -722,7 +722,13 @@ test_expect_success 'cat-file -t and -s on corrupt loose object' ' # content out as-is. Try to make it zlib-invalid. mv -f other.blob "$empty_path" && test_must_fail git fsck 2>err.fsck && - grep "^error: inflate: data stream error (" err.fsck + cat >expect <<-EOF && + error: inflate: data stream error (incorrect header check) + error: unable to unpack header of ./$empty_path + error: $empty_blob: object corrupt or missing: ./$empty_path + EOF + grep "^error: " err.fsck >actual && + test_cmp expect actual ) ' diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh index bc89371..5b8e47e 100755 --- a/t/t1060-object-corruption.sh +++ b/t/t1060-object-corruption.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='see how we handle various forms of corruption' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # convert "1234abcd" to ".git/objects/12/34abcd" diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 9a90031..de1ec89 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -72,7 +72,7 @@ test_expect_success 'git sparse-checkout list (populated)' ' ' test_expect_success 'git sparse-checkout init' ' - git -C repo sparse-checkout init && + git -C repo sparse-checkout init --no-cone && cat >expect <<-\EOF && /* !/*/ @@ -111,6 +111,7 @@ test_expect_success 'init with existing sparse-checkout' ' test_expect_success 'clone --sparse' ' git clone --sparse "file://$(pwd)/repo" clone && + git -C clone sparse-checkout reapply --no-cone && git -C clone sparse-checkout list >actual && cat >expect <<-\EOF && /* @@ -124,7 +125,7 @@ test_expect_success 'switching to cone mode with non-cone mode patterns' ' git init bad-patterns && ( cd bad-patterns && - git sparse-checkout init && + git sparse-checkout init --no-cone && git sparse-checkout add dir && git config --worktree core.sparseCheckoutCone true && test_must_fail git sparse-checkout add dir 2>err && @@ -402,7 +403,7 @@ test_expect_success 'revert to old sparse-checkout on empty update' ' git sparse-checkout set nothing 2>err && test_i18ngrep ! "Sparse checkout leaves no entry on working directory" err && test_i18ngrep ! ".git/index.lock" err && - git sparse-checkout set file + git sparse-checkout set --no-cone file ) ' @@ -424,7 +425,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' git clone repo dirty && echo dirty >dirty/folder1/a && - git -C dirty sparse-checkout init 2>err && + git -C dirty sparse-checkout init --no-cone 2>err && test_i18ngrep "warning.*The following paths are not up to date" err && git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* 2>err && @@ -435,7 +436,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' test_must_be_empty err && git -C dirty reset --hard && - git -C dirty sparse-checkout init && + git -C dirty sparse-checkout init --no-cone && git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* && test_path_is_missing dirty/folder1/a && git -C dirty sparse-checkout disable && @@ -451,7 +452,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat EOF git -C unmerged update-index --index-info <input && - git -C unmerged sparse-checkout init 2>err && + git -C unmerged sparse-checkout init --no-cone 2>err && test_i18ngrep "warning.*The following paths are unmerged" err && git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* 2>err && @@ -462,7 +463,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat test_i18ngrep "warning.*The following paths are unmerged" err && git -C unmerged reset --hard && - git -C unmerged sparse-checkout init && + git -C unmerged sparse-checkout init --no-cone && git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* && git -C unmerged sparse-checkout disable ' diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 6f778cf..f9f8c98 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -205,36 +205,68 @@ test_sparse_unstaged () { done } -test_expect_success 'sparse-index contents' ' - init_repos && - +# Usage: test_sprase_checkout_set "<c1> ... <cN>" "<s1> ... <sM>" +# Verifies that "git sparse-checkout set <c1> ... <cN>" succeeds and +# leaves the sparse index in a state where <s1> ... <sM> are sparse +# directories (and <c1> ... <cN> are not). +test_sparse_checkout_set () { + CONE_DIRS=$1 && + SPARSE_DIRS=$2 && + git -C sparse-index sparse-checkout set --skip-checks $CONE_DIRS && git -C sparse-index ls-files --sparse --stage >cache && - for dir in folder1 folder2 x + + # Check that the directories outside of the sparse-checkout cone + # have sparse directory entries. + for dir in $SPARSE_DIRS do TREE=$(git -C sparse-index rev-parse HEAD:$dir) && grep "040000 $TREE 0 $dir/" cache \ || return 1 done && - git -C sparse-index sparse-checkout set folder1 && - - git -C sparse-index ls-files --sparse --stage >cache && - for dir in deep folder2 x + # Check that the directories in the sparse-checkout cone + # are not sparse directory entries. + for dir in $CONE_DIRS do - TREE=$(git -C sparse-index rev-parse HEAD:$dir) && - grep "040000 $TREE 0 $dir/" cache \ + # Allow TREE to not exist because + # $dir does not exist at HEAD. + TREE=$(git -C sparse-index rev-parse HEAD:$dir) || + ! grep "040000 $TREE 0 $dir/" cache \ || return 1 - done && + done +} - git -C sparse-index sparse-checkout set deep/deeper1 && +test_expect_success 'sparse-index contents' ' + init_repos && - git -C sparse-index ls-files --sparse --stage >cache && - for dir in deep/deeper2 folder1 folder2 x - do - TREE=$(git -C sparse-index rev-parse HEAD:$dir) && - grep "040000 $TREE 0 $dir/" cache \ - || return 1 - done && + # Remove deep, add three other directories. + test_sparse_checkout_set \ + "folder1 folder2 x" \ + "before deep" && + + # Remove folder1, add deep + test_sparse_checkout_set \ + "deep folder2 x" \ + "before folder1" && + + # Replace deep with deep/deeper2 (dropping deep/deeper1) + # Add folder1 + test_sparse_checkout_set \ + "deep/deeper2 folder1 folder2 x" \ + "before deep/deeper1" && + + # Replace deep/deeper2 with deep/deeper1 + # Replace folder1 with folder1/0/0 + # Replace folder2 with non-existent folder2/2/3 + # Add non-existent "bogus" + test_sparse_checkout_set \ + "bogus deep/deeper1 folder1/0/0 folder2/2/3 x" \ + "before deep/deeper2 folder2/0" && + + # Drop down to only files at root + test_sparse_checkout_set \ + "" \ + "before deep folder1 folder2 x" && # Disabling the sparse-index replaces tree entries with full ones git -C sparse-index sparse-checkout init --no-sparse-index && @@ -1628,6 +1660,31 @@ test_expect_success 'ls-files' ' ensure_not_expanded ls-files --sparse ' +test_expect_success 'sparse index is not expanded: sparse-checkout' ' + init_repos && + + ensure_not_expanded sparse-checkout set deep/deeper2 && + ensure_not_expanded sparse-checkout set deep/deeper1 && + ensure_not_expanded sparse-checkout set deep && + ensure_not_expanded sparse-checkout add folder1 && + ensure_not_expanded sparse-checkout set deep/deeper1 && + ensure_not_expanded sparse-checkout set folder2 && + + # Demonstrate that the checks that "folder1/a" is a file + # do not cause a sparse-index expansion (since it is in the + # sparse-checkout cone). + echo >>sparse-index/folder2/a && + git -C sparse-index add folder2/a && + + ensure_not_expanded sparse-checkout add folder1 && + + # Skip checks here, since deep/deeper1 is inside a sparse directory + # that must be expanded to check whether `deep/deeper1` is a file + # or not. + ensure_not_expanded sparse-checkout set --skip-checks deep/deeper1 && + ensure_not_expanded sparse-checkout set +' + # NEEDSWORK: a sparse-checkout behaves differently from a full checkout # in this scenario, but it shouldn't. test_expect_success 'reset mixed and checkout orphan' ' diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 132a1b8..9fb0b90 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='basic symbolic-ref tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # If the tests munging HEAD fail, they can break detection of diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index 975c4ea..da581ec 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -4,6 +4,7 @@ test_description='Test reflog display routines' 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/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh index 977603f..ff30874 100755 --- a/t/t1412-reflog-loop.sh +++ b/t/t1412-reflog-loop.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='reflog walk shows repeated commits again' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup commits' ' diff --git a/t/t1415-worktree-refs.sh b/t/t1415-worktree-refs.sh index a3e6ea0..3b53184 100755 --- a/t/t1415-worktree-refs.sh +++ b/t/t1415-worktree-refs.sh @@ -2,6 +2,7 @@ test_description='per-worktree refs' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index de50c0e..ab7f31f 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -774,10 +774,19 @@ test_expect_success 'fsck finds problems in duplicate loose objects' ' # no "-d" here, so we end up with duplicates git repack && # now corrupt the loose copy - file=$(sha1_file "$(git rev-parse HEAD)") && + oid="$(git rev-parse HEAD)" && + file=$(sha1_file "$oid") && rm "$file" && echo broken >"$file" && - test_must_fail git fsck + test_must_fail git fsck 2>err && + + cat >expect <<-EOF && + error: inflate: data stream error (incorrect header check) + error: unable to unpack header of $file + error: $oid: object corrupt or missing: $file + EOF + grep "^error: " err >actual && + test_cmp expect actual ) ' diff --git a/t/t2015-checkout-unborn.sh b/t/t2015-checkout-unborn.sh index a972121..9425aae 100755 --- a/t/t2015-checkout-unborn.sh +++ b/t/t2015-checkout-unborn.sh @@ -4,6 +4,7 @@ test_description='checkout from unborn branch' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2016-checkout-patch.sh b/t/t2016-checkout-patch.sh index abfd586..bc3f69b 100755 --- a/t/t2016-checkout-patch.sh +++ b/t/t2016-checkout-patch.sh @@ -4,7 +4,13 @@ test_description='git checkout --patch' . ./lib-patch-mode.sh -test_expect_success PERL 'setup' ' +if ! test_bool_env GIT_TEST_ADD_I_USE_BUILTIN true && ! test_have_prereq PERL +then + skip_all='skipping interactive add tests, PERL not set' + test_done +fi + +test_expect_success 'setup' ' mkdir dir && echo parent > dir/foo && echo dummy > bar && @@ -18,44 +24,40 @@ test_expect_success PERL 'setup' ' # note: bar sorts before dir/foo, so the first 'n' is always to skip 'bar' -# NEEDSWORK: Since the builtin add-p is used when $GIT_TEST_ADD_I_USE_BUILTIN -# is given, we should replace the PERL prerequisite with an ADD_I prerequisite -# which first checks if $GIT_TEST_ADD_I_USE_BUILTIN is defined before checking -# PERL. -test_expect_success PERL 'saying "n" does nothing' ' +test_expect_success 'saying "n" does nothing' ' set_and_save_state dir/foo work head && test_write_lines n n | git checkout -p && verify_saved_state bar && verify_saved_state dir/foo ' -test_expect_success PERL 'git checkout -p' ' +test_expect_success 'git checkout -p' ' test_write_lines n y | git checkout -p && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success PERL 'git checkout -p with staged changes' ' +test_expect_success 'git checkout -p with staged changes' ' set_state dir/foo work index && test_write_lines n y | git checkout -p && verify_saved_state bar && verify_state dir/foo index index ' -test_expect_success PERL 'git checkout -p HEAD with NO staged changes: abort' ' +test_expect_success 'git checkout -p HEAD with NO staged changes: abort' ' set_and_save_state dir/foo work head && test_write_lines n y n | git checkout -p HEAD && verify_saved_state bar && verify_saved_state dir/foo ' -test_expect_success PERL 'git checkout -p HEAD with NO staged changes: apply' ' +test_expect_success 'git checkout -p HEAD with NO staged changes: apply' ' test_write_lines n y y | git checkout -p HEAD && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success PERL 'git checkout -p HEAD with change already staged' ' +test_expect_success 'git checkout -p HEAD with change already staged' ' set_state dir/foo index index && # the third n is to get out in case it mistakenly does not apply test_write_lines n y n | git checkout -p HEAD && @@ -63,21 +65,21 @@ test_expect_success PERL 'git checkout -p HEAD with change already staged' ' verify_state dir/foo head head ' -test_expect_success PERL 'git checkout -p HEAD^...' ' +test_expect_success 'git checkout -p HEAD^...' ' # the third n is to get out in case it mistakenly does not apply test_write_lines n y n | git checkout -p HEAD^... && verify_saved_state bar && verify_state dir/foo parent parent ' -test_expect_success PERL 'git checkout -p HEAD^' ' +test_expect_success 'git checkout -p HEAD^' ' # the third n is to get out in case it mistakenly does not apply test_write_lines n y n | git checkout -p HEAD^ && verify_saved_state bar && verify_state dir/foo parent parent ' -test_expect_success PERL 'git checkout -p handles deletion' ' +test_expect_success 'git checkout -p handles deletion' ' set_state dir/foo work index && rm dir/foo && test_write_lines n y | git checkout -p && @@ -90,28 +92,28 @@ test_expect_success PERL 'git checkout -p handles deletion' ' # dir/foo. There's always an extra 'n' to reject edits to dir/foo in # the failure case (and thus get out of the loop). -test_expect_success PERL 'path limiting works: dir' ' +test_expect_success 'path limiting works: dir' ' set_state dir/foo work head && test_write_lines y n | git checkout -p dir && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success PERL 'path limiting works: -- dir' ' +test_expect_success 'path limiting works: -- dir' ' set_state dir/foo work head && test_write_lines y n | git checkout -p -- dir && verify_saved_state bar && verify_state dir/foo head head ' -test_expect_success PERL 'path limiting works: HEAD^ -- dir' ' +test_expect_success 'path limiting works: HEAD^ -- dir' ' # the third n is to get out in case it mistakenly does not apply test_write_lines y n n | git checkout -p HEAD^ -- dir && verify_saved_state bar && verify_state dir/foo parent parent ' -test_expect_success PERL 'path limiting works: foo inside dir' ' +test_expect_success 'path limiting works: foo inside dir' ' set_state dir/foo work head && # the third n is to get out in case it mistakenly does not apply test_write_lines y n n | (cd dir && git checkout -p foo) && @@ -119,11 +121,11 @@ test_expect_success PERL 'path limiting works: foo inside dir' ' verify_state dir/foo head head ' -test_expect_success PERL 'none of this moved HEAD' ' +test_expect_success 'none of this moved HEAD' ' verify_saved_head ' -test_expect_success PERL 'empty tree can be handled' ' +test_expect_success 'empty tree can be handled' ' test_when_finished "git reset --hard" && git checkout -p $(test_oid empty_tree) -- ' diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 0c38f8e..be394f1 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -14,6 +14,7 @@ only the updates to dir/sub. Also tested are "git add -u" without limiting, and "git add -u" without contents changes, and other conditions' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t2203-add-intent.sh b/t/t2203-add-intent.sh index db7ca55..ebf58db 100755 --- a/t/t2203-add-intent.sh +++ b/t/t2203-add-intent.sh @@ -2,6 +2,7 @@ test_description='Intent to add' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'intent to add' ' diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index e12db59..9723c28 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -886,6 +886,41 @@ test_expect_success 'branch from tag w/--track causes failure' ' test_must_fail git branch --track my11 foobar ' +test_expect_success 'simple tracking works when remote branch name matches' ' + test_when_finished "rm -rf otherserver" && + git init otherserver && + test_commit -C otherserver my_commit 1 && + git -C otherserver branch feature && + test_config branch.autosetupmerge simple && + test_config remote.otherserver.url otherserver && + test_config remote.otherserver.fetch refs/heads/*:refs/remotes/otherserver/* && + git fetch otherserver && + git branch feature otherserver/feature && + test_cmp_config otherserver branch.feature.remote && + test_cmp_config refs/heads/feature branch.feature.merge +' + +test_expect_success 'simple tracking skips when remote branch name does not match' ' + test_config branch.autosetupmerge simple && + test_config remote.local.url . && + test_config remote.local.fetch refs/heads/*:refs/remotes/local/* && + git fetch local && + git branch my-other local/main && + test_cmp_config "" --default "" branch.my-other.remote && + test_cmp_config "" --default "" branch.my-other.merge +' + +test_expect_success 'simple tracking skips when remote ref is not a branch' ' + test_config branch.autosetupmerge simple && + test_config remote.localtags.url . && + test_config remote.localtags.fetch refs/tags/*:refs/remotes/localtags/* && + git tag mytag12 main && + git fetch localtags && + git branch mytag12 localtags/mytag12 && + test_cmp_config "" --default "" branch.mytag12.remote && + test_cmp_config "" --default "" branch.mytag12.merge +' + test_expect_success '--set-upstream-to fails on multiple branches' ' echo "fatal: too many arguments to set new upstream" >expect && test_must_fail git branch --set-upstream-to main a b c 2>err && diff --git a/t/t3202-show-branch.sh b/t/t3202-show-branch.sh index 7a1be73..f2b9199 100755 --- a/t/t3202-show-branch.sh +++ b/t/t3202-show-branch.sh @@ -161,4 +161,18 @@ test_expect_success 'show branch --reflog=2' ' test_cmp actual expect ' +# incompatible options +while read combo +do + test_expect_success "show-branch $combo (should fail)" ' + test_must_fail git show-branch $combo 2>error && + grep -e "cannot be used together" -e "usage:" error + ' +done <<\EOF +--all --reflog +--merge-base --reflog +--list --merge-base +--reflog --current +EOF + test_done diff --git a/t/t3302-notes-index-expensive.sh b/t/t3302-notes-index-expensive.sh index bb5fea0..d0c4d38 100755 --- a/t/t3302-notes-index-expensive.sh +++ b/t/t3302-notes-index-expensive.sh @@ -8,6 +8,7 @@ test_description='Test commit notes index (expensive!)' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_repo () { diff --git a/t/t3303-notes-subtrees.sh b/t/t3303-notes-subtrees.sh index eac1937..bc9b791 100755 --- a/t/t3303-notes-subtrees.sh +++ b/t/t3303-notes-subtrees.sh @@ -5,6 +5,7 @@ test_description='Test commit notes organized in subtrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh number_of_commits=100 diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh index 9976d78..64a9915 100755 --- a/t/t3305-notes-fanout.sh +++ b/t/t3305-notes-fanout.sh @@ -2,6 +2,7 @@ test_description='Test that adding/removing many notes triggers automatic fanout restructuring' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh path_has_fanout() { diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh index cde3562..7b4607d 100755 --- a/t/t3408-rebase-multi-line.sh +++ b/t/t3408-rebase-multi-line.sh @@ -5,6 +5,7 @@ test_description='rebasing a commit with multi-line first paragraph.' 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/t3602-rm-sparse-checkout.sh b/t/t3602-rm-sparse-checkout.sh index 034ec01..08580fd 100755 --- a/t/t3602-rm-sparse-checkout.sh +++ b/t/t3602-rm-sparse-checkout.sh @@ -30,7 +30,7 @@ test_expect_success 'setup' " for opt in "" -f --dry-run do test_expect_success "rm${opt:+ $opt} does not remove sparse entries" ' - git sparse-checkout set a && + git sparse-checkout set --no-cone a && test_must_fail git rm $opt b 2>stderr && test_cmp b_error_and_hint stderr && git ls-files --error-unmatch b @@ -118,7 +118,7 @@ test_expect_success 'can remove files from non-sparse dir' ' test_commit w/f && test_commit x/y/f && - git sparse-checkout set w !/x y/ && + git sparse-checkout set --no-cone w !/x y/ && git rm w/f.t x/y/f.t 2>stderr && test_must_be_empty stderr ' @@ -128,7 +128,7 @@ test_expect_success 'refuse to remove non-skip-worktree file from sparse dir' ' git sparse-checkout disable && mkdir -p x/y/z && test_commit x/y/z/f && - git sparse-checkout set !/x y/ !x/y/z && + git sparse-checkout set --no-cone !/x y/ !x/y/z && git update-index --no-skip-worktree x/y/z/f.t && test_must_fail git rm x/y/z/f.t 2>stderr && diff --git a/t/t3700-add.sh b/t/t3700-add.sh index b1f90ba..8979c8a 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -8,6 +8,8 @@ test_description='Test of git add, including the -- option.' TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +. $TEST_DIRECTORY/lib-unique-files.sh + # Test the file mode "$1" of the file "$2" in the index. test_mode_in_index () { case "$(git ls-files -s "$2")" in @@ -34,6 +36,32 @@ 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' + +test_expect_success 'git add: core.fsyncmethod=batch' " + test_create_unique_files 2 4 files_base_dir1 && + GIT_TEST_FSYNC=1 git $BATCH_CONFIGURATION add -- ./files_base_dir1/ && + git ls-files --stage files_base_dir1/ | + test_parse_ls_files_stage_oids >added_files_oids && + + # We created 2 subdirs with 4 files each (8 files total) above + test_line_count = 8 added_files_oids && + git cat-file --batch-check='%(objectname)' <added_files_oids >added_files_actual && + test_cmp added_files_oids added_files_actual +" + +test_expect_success 'git update-index: core.fsyncmethod=batch' " + test_create_unique_files 2 4 files_base_dir2 && + find files_base_dir2 ! -type d -print | xargs git $BATCH_CONFIGURATION update-index --add -- && + git ls-files --stage files_base_dir2 | + test_parse_ls_files_stage_oids >added_files2_oids && + + # We created 2 subdirs with 4 files each (8 files total) above + test_line_count = 8 added_files2_oids && + git cat-file --batch-check='%(objectname)' <added_files2_oids >added_files2_actual && + test_cmp added_files2_oids added_files2_actual +" + test_expect_success \ 'git add: Test that executable bit is not used if core.filemode=0' \ 'git config core.filemode 0 && diff --git a/t/t3705-add-sparse-checkout.sh b/t/t3705-add-sparse-checkout.sh index 9560904..2bade9e 100755 --- a/t/t3705-add-sparse-checkout.sh +++ b/t/t3705-add-sparse-checkout.sh @@ -166,7 +166,7 @@ test_expect_success 'do not warn when pathspec matches dense entries' ' test_expect_success 'git add fails outside of sparse-checkout definition' ' test_when_finished git sparse-checkout disable && test_commit a && - git sparse-checkout init && + git sparse-checkout init --no-cone && git sparse-checkout set a && echo >>sparse_entry && @@ -208,7 +208,7 @@ test_expect_success 'add obeys advice.updateSparsePath' ' ' test_expect_success 'add allows sparse entries with --sparse' ' - git sparse-checkout set a && + git sparse-checkout set --no-cone a && echo modified >sparse_entry && test_must_fail git add sparse_entry && test_sparse_entry_unchanged && diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 4abbc8f..20e9488 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -9,6 +9,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +. $TEST_DIRECTORY/lib-unique-files.sh test_expect_success 'usage on cmd and subcommand invalid option' ' test_expect_code 129 git stash --invalid-option 2>usage && @@ -1410,6 +1411,25 @@ test_expect_success 'stash handles skip-worktree entries nicely' ' git rev-parse --verify refs/stash:A.t ' + +BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch' + +test_expect_success 'stash with core.fsyncmethod=batch' " + test_create_unique_files 2 4 files_base_dir && + GIT_TEST_FSYNC=1 git $BATCH_CONFIGURATION stash push -u -- ./files_base_dir/ && + + # The files were untracked, so use the third parent, + # which contains the untracked files + git ls-tree -r stash^3 -- ./files_base_dir/ | + test_parse_ls_tree_oids >stashed_files_oids && + + # We created 2 dirs with 4 files each (8 files total) above + test_line_count = 8 stashed_files_oids && + git cat-file --batch-check='%(objectname)' <stashed_files_oids >stashed_files_actual && + test_cmp stashed_files_oids stashed_files_actual +" + + test_expect_success 'git stash succeeds despite directory/file change' ' test_create_repo directory_file_switch_v1 && ( diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh index 9be65fd..1219aa2 100755 --- a/t/t4021-format-patch-numbered.sh +++ b/t/t4021-format-patch-numbered.sh @@ -5,6 +5,7 @@ test_description='Format-patch numbering options' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 295da98..40164ae 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -2,6 +2,7 @@ test_description='difference in submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4028-format-patch-mime-headers.sh b/t/t4028-format-patch-mime-headers.sh index 204ba67..60cb819 100755 --- a/t/t4028-format-patch-mime-headers.sh +++ b/t/t4028-format-patch-mime-headers.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='format-patch mime headers and extra headers do not conflict' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create commit with utf-8 body' ' diff --git a/t/t4036-format-patch-signer-mime.sh b/t/t4036-format-patch-signer-mime.sh index 98d9713..48655bc 100755 --- a/t/t4036-format-patch-signer-mime.sh +++ b/t/t4036-format-patch-signer-mime.sh @@ -2,6 +2,7 @@ test_description='format-patch -s should force MIME encoding as needed' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4039-diff-assume-unchanged.sh b/t/t4039-diff-assume-unchanged.sh index 0eb0314..78090e6 100755 --- a/t/t4039-diff-assume-unchanged.sh +++ b/t/t4039-diff-assume-unchanged.sh @@ -2,6 +2,7 @@ test_description='diff with assume-unchanged entries' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # external diff has been tested in t4020-diff-external.sh diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index 741e080..73048d0 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -5,6 +5,7 @@ test_description='diff.context configuration' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4066-diff-emit-delay.sh b/t/t4066-diff-emit-delay.sh index a1de63b..0ecb391 100755 --- a/t/t4066-diff-emit-delay.sh +++ b/t/t4066-diff-emit-delay.sh @@ -4,6 +4,7 @@ test_description='test combined/stat/moved interaction' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test covers a weird 3-way interaction between "--cc -p", which will run diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh index aa52de4..9696537 100755 --- a/t/t4122-apply-symlink-inside.sh +++ b/t/t4122-apply-symlink-inside.sh @@ -4,6 +4,7 @@ test_description='apply to deeper directory without getting fooled with symlink' 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/t4126-apply-empty.sh b/t/t4126-apply-empty.sh index 33860d3..ece9fae 100755 --- a/t/t4126-apply-empty.sh +++ b/t/t4126-apply-empty.sh @@ -2,7 +2,6 @@ test_description='apply empty' - TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh index f6db5a7..ed94c90 100755 --- a/t/t4128-apply-root.sh +++ b/t/t4128-apply-root.sh @@ -2,6 +2,7 @@ test_description='apply same filename' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4202-log.sh b/t/t4202-log.sh index be07407..6e66352 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -1992,10 +1992,13 @@ test_expect_success GPG 'log --show-signature for merged tag with GPG failure' ' git tag -s -m signed_tag_msg signed_tag_fail && git checkout plain-fail && git merge --no-ff -m msg signed_tag_fail && - TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual && - grep "^merged tag" actual && - grep "^No signature" actual && - ! grep "^gpg: Signature made" actual + if ! test_have_prereq VALGRIND + then + TMPDIR="$(pwd)/bogus" git log --show-signature -n1 plain-fail >actual && + grep "^merged tag" actual && + grep "^No signature" actual && + ! grep "^gpg: Signature made" actual + fi ' test_expect_success GPGSM 'log --graph --show-signature for merged tag x509' ' diff --git a/t/t4206-log-follow-harder-copies.sh b/t/t4206-log-follow-harder-copies.sh index 4871a5d..33ecf82 100755 --- a/t/t4206-log-follow-harder-copies.sh +++ b/t/t4206-log-follow-harder-copies.sh @@ -6,6 +6,8 @@ test_description='Test --follow should always find copies hard in git log. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh index b870942..36ac6af 100755 --- a/t/t4207-log-decoration-colors.sh +++ b/t/t4207-log-decoration-colors.sh @@ -8,6 +8,7 @@ test_description='Test for "git log --decorate" colors' 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/t4212-log-corrupt.sh b/t/t4212-log-corrupt.sh index 0244888..30a2198 100755 --- a/t/t4212-log-corrupt.sh +++ b/t/t4212-log-corrupt.sh @@ -2,6 +2,7 @@ test_description='git log with invalid commit headers' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index a11d612..f8a0f30 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -161,22 +161,27 @@ test_expect_success 'pack-objects with bogus arguments' ' ' check_unpack () { + local packname="$1" && + local object_list="$2" && + local git_config="$3" && test_when_finished "rm -rf git2" && - git init --bare git2 && - git -C git2 unpack-objects -n <"$1".pack && - git -C git2 unpack-objects <"$1".pack && - (cd .git && find objects -type f -print) | - while read path - do - cmp git2/$path .git/$path || { - echo $path differs. - return 1 - } - done + git $git_config init --bare git2 && + ( + git $git_config -C git2 unpack-objects -n <"$packname".pack && + git $git_config -C git2 unpack-objects <"$packname".pack && + git $git_config -C git2 cat-file --batch-check="%(objectname)" + ) <"$object_list" >current && + cmp "$object_list" current } test_expect_success 'unpack without delta' ' - check_unpack test-1-${packname_1} + check_unpack test-1-${packname_1} obj-list +' + +BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch' + +test_expect_success 'unpack without delta (core.fsyncmethod=batch)' ' + check_unpack test-1-${packname_1} obj-list "$BATCH_CONFIGURATION" ' test_expect_success 'pack with REF_DELTA' ' @@ -185,7 +190,11 @@ test_expect_success 'pack with REF_DELTA' ' ' test_expect_success 'unpack with REF_DELTA' ' - check_unpack test-2-${packname_2} + check_unpack test-2-${packname_2} obj-list +' + +test_expect_success 'unpack with REF_DELTA (core.fsyncmethod=batch)' ' + check_unpack test-2-${packname_2} obj-list "$BATCH_CONFIGURATION" ' test_expect_success 'pack with OFS_DELTA' ' @@ -195,7 +204,11 @@ test_expect_success 'pack with OFS_DELTA' ' ' test_expect_success 'unpack with OFS_DELTA' ' - check_unpack test-3-${packname_3} + check_unpack test-3-${packname_3} obj-list +' + +test_expect_success 'unpack with OFS_DELTA (core.fsyncmethod=batch)' ' + check_unpack test-3-${packname_3} obj-list "$BATCH_CONFIGURATION" ' test_expect_success 'compare delta flavors' ' diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 76f9798..3ccaaeb 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -4,6 +4,8 @@ # test_description='mmap sliding window tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh index 535313e..cc4cfaa 100755 --- a/t/t5313-pack-bounds-checks.sh +++ b/t/t5313-pack-bounds-checks.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='bounds-checking of access to mmapped on-disk file formats' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh clear_base () { diff --git a/t/t5316-pack-delta-depth.sh b/t/t5316-pack-delta-depth.sh index e904500..eb4ef3d 100755 --- a/t/t5316-pack-delta-depth.sh +++ b/t/t5316-pack-delta-depth.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='pack-objects breaks long cross-pack delta chains' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This mirrors a repeated push setup: diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh index 33b740ce..bb633c9 100755 --- a/t/t5317-pack-objects-filter-objects.sh +++ b/t/t5317-pack-objects-filter-objects.sh @@ -10,9 +10,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME # Test blob:none filter. test_expect_success 'setup r1' ' - echo "{print \$1}" >print_1.awk && - echo "{print \$2}" >print_2.awk && - git init r1 && for n in 1 2 3 4 5 do @@ -22,10 +19,13 @@ test_expect_success 'setup r1' ' done ' +parse_verify_pack_blob_oid () { + awk '{print $1}' - +} + test_expect_success 'verify blob count in normal packfile' ' - git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 | + test_parse_ls_files_stage_oids | sort >expected && git -C r1 pack-objects --revs --stdout >all.pack <<-EOF && @@ -35,7 +35,7 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r1 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -54,12 +54,12 @@ test_expect_success 'verify blob:none packfile has no blobs' ' test_expect_success 'verify normal and blob:none packfiles have same commits/trees' ' git -C r1 verify-pack -v ../all.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >expected && git -C r1 verify-pack -v ../filter.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -123,8 +123,8 @@ test_expect_success 'setup r2' ' ' test_expect_success 'verify blob count in normal packfile' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout >all.pack <<-EOF && @@ -134,7 +134,7 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r2 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -161,8 +161,8 @@ test_expect_success 'verify blob:limit=1000' ' ' test_expect_success 'verify blob:limit=1001' ' - git -C r2 ls-files -s large.1000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=1001 >filter.pack <<-EOF && @@ -172,15 +172,15 @@ test_expect_success 'verify blob:limit=1001' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify blob:limit=10001' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=10001 >filter.pack <<-EOF && @@ -190,15 +190,15 @@ test_expect_success 'verify blob:limit=10001' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify blob:limit=1k' ' - git -C r2 ls-files -s large.1000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k >filter.pack <<-EOF && @@ -208,15 +208,15 @@ test_expect_success 'verify blob:limit=1k' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify explicitly specifying oversized blob in input' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && echo HEAD >objects && @@ -226,15 +226,15 @@ test_expect_success 'verify explicitly specifying oversized blob in input' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify blob:limit=1m' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=1m >filter.pack <<-EOF && @@ -244,7 +244,7 @@ test_expect_success 'verify blob:limit=1m' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -253,12 +253,12 @@ test_expect_success 'verify blob:limit=1m' ' test_expect_success 'verify normal and blob:limit packfiles have same commits/trees' ' git -C r2 verify-pack -v ../all.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >expected && git -C r2 verify-pack -v ../filter.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -289,9 +289,8 @@ test_expect_success 'setup r3' ' ' test_expect_success 'verify blob count in normal packfile' ' - git -C r3 ls-files -s sparse1 sparse2 dir1/sparse1 dir1/sparse2 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r3 ls-files -s sparse1 sparse2 dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r3 pack-objects --revs --stdout >all.pack <<-EOF && @@ -301,7 +300,7 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r3 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -342,9 +341,8 @@ test_expect_success 'setup r4' ' ' test_expect_success 'verify blob count in normal packfile' ' - git -C r4 ls-files -s pattern sparse1 sparse2 dir1/sparse1 dir1/sparse2 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r4 ls-files -s pattern sparse1 sparse2 dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r4 pack-objects --revs --stdout >all.pack <<-EOF && @@ -354,19 +352,19 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r4 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify sparse:oid=OID' ' - git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r4 ls-files -s pattern >staged && - oid=$(awk -f print_2.awk staged) && + oid=$(test_parse_ls_files_stage_oids <staged) && git -C r4 pack-objects --revs --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF && HEAD EOF @@ -374,15 +372,15 @@ test_expect_success 'verify sparse:oid=OID' ' git -C r4 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify sparse:oid=oid-ish' ' - git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r4 pack-objects --revs --stdout --filter=sparse:oid=main:pattern >filter.pack <<-EOF && @@ -392,7 +390,7 @@ test_expect_success 'verify sparse:oid=oid-ish' ' git -C r4 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -402,9 +400,8 @@ test_expect_success 'verify sparse:oid=oid-ish' ' # This models previously omitted objects that we did not receive. test_expect_success 'setup r1 - delete loose blobs' ' - git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 | + test_parse_ls_files_stage_oids | sort >expected && for id in `cat expected | sed "s|..|&/|"` diff --git a/t/t5320-delta-islands.sh b/t/t5320-delta-islands.sh index fea92a5..124d476 100755 --- a/t/t5320-delta-islands.sh +++ b/t/t5320-delta-islands.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='exercise delta islands' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # returns true iff $1 is a delta based on $2 diff --git a/t/t5322-pack-objects-sparse.sh b/t/t5322-pack-objects-sparse.sh index d39958c..770695c 100755 --- a/t/t5322-pack-objects-sparse.sh +++ b/t/t5322-pack-objects-sparse.sh @@ -4,6 +4,7 @@ test_description='pack-objects object selection using sparse algorithm' 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 repo' ' diff --git a/t/t5329-pack-objects-cruft.sh b/t/t5329-pack-objects-cruft.sh new file mode 100755 index 0000000..b481224 --- /dev/null +++ b/t/t5329-pack-objects-cruft.sh @@ -0,0 +1,739 @@ +#!/bin/sh + +test_description='cruft pack related pack-objects tests' +. ./test-lib.sh + +objdir=.git/objects +packdir=$objdir/pack + +basic_cruft_pack_tests () { + expire="$1" + + test_expect_success "unreachable loose objects are packed (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + git repack -Ad && + test_commit loose && + + test-tool chmtime +2000 "$objdir/$(test_oid_to_path \ + $(git rev-parse loose:loose.t))" && + test-tool chmtime +1000 "$objdir/$(test_oid_to_path \ + $(git rev-parse loose^{tree}))" && + + ( + git rev-list --objects --no-object-names base..loose | + while read oid + do + path="$objdir/$(test_oid_to_path "$oid")" && + printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" + done | + sort -k1 + ) >expect && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration="$expire" $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual && + + test_cmp expect actual + ) + ' + + test_expect_success "unreachable packed objects are packed (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + test_commit other && + + git rev-list --objects --no-object-names packed.. >objects && + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + other="$(git pack-objects --delta-base-offset \ + $packdir/pack <objects)" && + git prune-packed && + + test-tool chmtime --get -100 "$packdir/pack-$other.pack" >expect && + + cruft="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF + $keep + -pack-$other.pack + EOF + )" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + + cut -d" " -f2 <actual.raw | sort -u >actual && + + test_cmp expect actual + ) + ' + + test_expect_success "unreachable cruft objects are repacked (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + test_commit other && + + git rev-list --objects --no-object-names packed.. >objects && + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + + cruft_a="$(echo $keep | git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack)" && + git prune-packed && + cruft_b="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF + $keep + -pack-$cruft_a.pack + EOF + )" && + + test-tool pack-mtimes "pack-$cruft_a.mtimes" >expect.raw && + test-tool pack-mtimes "pack-$cruft_b.mtimes" >actual.raw && + + sort <expect.raw >expect && + sort <actual.raw >actual && + + test_cmp expect actual + ) + ' + + test_expect_success "multiple cruft packs (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + + test_commit cruft && + loose="$objdir/$(test_oid_to_path $(git rev-parse cruft))" && + + # generate three copies of the cruft object in different + # cruft packs, each with a unique mtime: + # - one expired (1000 seconds ago) + # - two non-expired (one 1000 seconds in the future, + # one 1500 seconds in the future) + test-tool chmtime =-1000 "$loose" && + git pack-objects --cruft $packdir/pack-A <<-EOF && + $keep + EOF + test-tool chmtime =+1000 "$loose" && + git pack-objects --cruft $packdir/pack-B <<-EOF && + $keep + -$(basename $(ls $packdir/pack-A-*.pack)) + EOF + test-tool chmtime =+1500 "$loose" && + git pack-objects --cruft $packdir/pack-C <<-EOF && + $keep + -$(basename $(ls $packdir/pack-A-*.pack)) + -$(basename $(ls $packdir/pack-B-*.pack)) + EOF + + # ensure the resulting cruft pack takes the most recent + # mtime among all copies + cruft="$(git pack-objects --cruft \ + --cruft-expiration="$expire" \ + $packdir/pack <<-EOF + $keep + -$(basename $(ls $packdir/pack-A-*.pack)) + -$(basename $(ls $packdir/pack-B-*.pack)) + -$(basename $(ls $packdir/pack-C-*.pack)) + EOF + )" && + + test-tool pack-mtimes "$(basename $(ls $packdir/pack-C-*.mtimes))" >expect.raw && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + + sort expect.raw >expect && + sort actual.raw >actual && + test_cmp expect actual + ) + ' + + test_expect_success "cruft packs tolerate missing trees (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + test_commit cruft && + + tree="$(git rev-parse cruft^{tree})" && + + git reset --hard reachable && + git tag -d cruft && + git reflog expire --all --expire=all && + + # remove the unreachable tree, but leave the commit + # which has it as its root tree intact + rm -fr "$objdir/$(test_oid_to_path "$tree")" && + + git repack -Ad && + basename $(ls $packdir/pack-*.pack) >in && + git pack-objects --cruft --cruft-expiration="$expire" \ + $packdir/pack <in + ) + ' + + test_expect_success "cruft packs tolerate missing blobs (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + test_commit cruft && + + blob="$(git rev-parse cruft:cruft.t)" && + + git reset --hard reachable && + git tag -d cruft && + git reflog expire --all --expire=all && + + # remove the unreachable blob, but leave the commit (and + # the root tree of that commit) intact + rm -fr "$objdir/$(test_oid_to_path "$blob")" && + + git repack -Ad && + basename $(ls $packdir/pack-*.pack) >in && + git pack-objects --cruft --cruft-expiration="$expire" \ + $packdir/pack <in + ) + ' +} + +basic_cruft_pack_tests never +basic_cruft_pack_tests 2.weeks.ago + +test_expect_success 'cruft tags rescue tagged objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + test_commit tagged && + git tag -a annotated -m tag && + + git rev-list --objects --no-object-names packed.. >objects && + while read oid + do + test-tool chmtime -1000 \ + "$objdir/$(test_oid_to_path $oid)" + done <objects && + + test-tool chmtime -500 \ + "$objdir/$(test_oid_to_path $(git rev-parse annotated))" && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + cut -f1 -d" " <actual.raw | sort >actual && + + ( + cat objects && + git rev-parse annotated + ) >expect.raw && + sort <expect.raw >expect && + + test_cmp expect actual && + cat actual + ) +' + +test_expect_success 'cruft commits rescue parents, trees' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + test_commit old && + test_commit new && + + git rev-list --objects --no-object-names packed..new >objects && + while read object + do + test-tool chmtime -1000 \ + "$objdir/$(test_oid_to_path $object)" + done <objects && + test-tool chmtime +500 "$objdir/$(test_oid_to_path \ + $(git rev-parse HEAD))" && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + + cut -d" " -f1 <actual.raw | sort >actual && + sort <objects >expect && + + test_cmp expect actual + ) +' + +test_expect_success 'cruft trees rescue sub-trees, blobs' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + mkdir -p dir/sub && + echo foo >foo && + echo bar >dir/bar && + echo baz >dir/sub/baz && + + test_tick && + git add . && + git commit -m "pruned" && + + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD^{tree}))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:foo))" && + test-tool chmtime -500 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/bar))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub/baz))" && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + cut -f1 -d" " <actual.raw | sort >actual && + + git rev-parse HEAD:dir HEAD:dir/bar HEAD:dir/sub HEAD:dir/sub/baz >expect.raw && + sort <expect.raw >expect && + + test_cmp expect actual + ) +' + +test_expect_success 'expired objects are pruned' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + test_commit pruned && + + git rev-list --objects --no-object-names packed..pruned >objects && + while read object + do + test-tool chmtime -1000 \ + "$objdir/$(test_oid_to_path $object)" + done <objects && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + + test-tool pack-mtimes "pack-$cruft.mtimes" >actual && + test_must_be_empty actual + ) +' + +test_expect_success 'repack --cruft generates a cruft pack' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git branch -M main && + git checkout --orphan other && + test_commit unreachable && + + git checkout main && + git branch -D other && + git tag -d unreachable && + # objects are not cruft if they are contained in the reflogs + git reflog expire --all --expire=all && + + git rev-list --objects --all --no-object-names >reachable.raw && + git cat-file --batch-all-objects --batch-check="%(objectname)" >objects && + sort <reachable.raw >reachable && + comm -13 reachable objects >unreachable && + + git repack --cruft -d && + + cruft=$(basename $(ls $packdir/pack-*.mtimes) .mtimes) && + pack=$(basename $(ls $packdir/pack-*.pack | grep -v $cruft) .pack) && + + git show-index <$packdir/$pack.idx >actual.raw && + cut -f2 -d" " actual.raw | sort >actual && + test_cmp reachable actual && + + git show-index <$packdir/$cruft.idx >actual.raw && + cut -f2 -d" " actual.raw | sort >actual && + test_cmp unreachable actual + ) +' + +test_expect_success 'loose objects mtimes upsert others' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + git branch -M main && + + git checkout --orphan other && + test_commit cruft && + # incremental repack, leaving existing objects loose (so + # they can be "freshened") + git repack && + + tip="$(git rev-parse cruft)" && + path="$objdir/$(test_oid_to_path "$tip")" && + test-tool chmtime --get +1000 "$path" >expect && + + git checkout main && + git branch -D other && + git tag -d cruft && + git reflog expire --all --expire=all && + + git repack --cruft -d && + + mtimes="$(basename $(ls $packdir/pack-*.mtimes))" && + test-tool pack-mtimes "$mtimes" >actual.raw && + grep "$tip" actual.raw | cut -d" " -f2 >actual && + test_cmp expect actual + ) +' + +test_expect_success 'expiring cruft objects with git gc' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git branch -M main && + git checkout --orphan other && + test_commit unreachable && + + git checkout main && + git branch -D other && + git tag -d unreachable && + # objects are not cruft if they are contained in the reflogs + git reflog expire --all --expire=all && + + git rev-list --objects --all --no-object-names >reachable.raw && + git cat-file --batch-all-objects --batch-check="%(objectname)" >objects && + sort <reachable.raw >reachable && + comm -13 reachable objects >unreachable && + + git repack --cruft -d && + + mtimes=$(ls .git/objects/pack/pack-*.mtimes) && + test_path_is_file $mtimes && + + git gc --cruft --prune=now && + + git cat-file --batch-all-objects --batch-check="%(objectname)" >objects && + + comm -23 unreachable objects >removed && + test_cmp unreachable removed && + test_path_is_missing $mtimes + ) +' + +test_expect_success 'cruft packs are not included in geometric repack' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + git branch -M main && + + git checkout --orphan other && + test_commit cruft && + git repack -d && + + git checkout main && + git branch -D other && + git tag -d cruft && + git reflog expire --all --expire=all && + + git repack --cruft && + + find $packdir -type f | sort >before && + git repack --geometric=2 -d && + find $packdir -type f | sort >after && + + test_cmp before after + ) +' + +test_expect_success 'repack --geometric collects once-cruft objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + git branch -M main && + + git checkout --orphan other && + git rm -rf . && + test_commit --no-tag cruft && + cruft="$(git rev-parse HEAD)" && + + git checkout main && + git branch -D other && + git reflog expire --all --expire=all && + + # Pack the objects created in the previous step into a cruft + # pack. Intentionally leave loose copies of those objects + # around so we can pick them up in a subsequent --geometric + # reapack. + git repack --cruft && + + # Now make those objects reachable, and ensure that they are + # packed into the new pack created via a --geometric repack. + git update-ref refs/heads/other $cruft && + + # Without this object, the set of unpacked objects is exactly + # the set of objects already in the cruft pack. Tweak that set + # to ensure we do not overwrite the cruft pack entirely. + test_commit reachable2 && + + find $packdir -name "pack-*.idx" | sort >before && + git repack --geometric=2 -d && + find $packdir -name "pack-*.idx" | sort >after && + + { + git rev-list --objects --no-object-names $cruft && + git rev-list --objects --no-object-names reachable..reachable2 + } >want.raw && + sort want.raw >want && + + pack=$(comm -13 before after) && + git show-index <$pack >objects.raw && + + cut -d" " -f2 objects.raw | sort >got && + + test_cmp want got + ) +' + +test_expect_success 'cruft repack with no reachable objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + git repack -ad && + + base="$(git rev-parse base)" && + + git for-each-ref --format="delete %(refname)" >in && + git update-ref --stdin <in && + git reflog expire --all --expire=all && + rm -fr .git/index && + + git repack --cruft -d && + + git cat-file -t $base + ) +' + +test_expect_success 'cruft repack ignores --max-pack-size' ' + git init max-pack-size && + ( + cd max-pack-size && + test_commit base && + # two cruft objects which exceed the maximum pack size + test-tool genrandom foo 1048576 | git hash-object --stdin -w && + test-tool genrandom bar 1048576 | git hash-object --stdin -w && + git repack --cruft --max-pack-size=1M && + find $packdir -name "*.mtimes" >cruft && + test_line_count = 1 cruft && + test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects && + test_line_count = 2 objects + ) +' + +test_expect_success 'cruft repack ignores pack.packSizeLimit' ' + ( + cd max-pack-size && + # repack everything back together to remove the existing cruft + # pack (but to keep its objects) + git repack -adk && + git -c pack.packSizeLimit=1M repack --cruft && + # ensure the same post condition is met when --max-pack-size + # would otherwise be inferred from the configuration + find $packdir -name "*.mtimes" >cruft && + test_line_count = 1 cruft && + test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects && + test_line_count = 2 objects + ) +' + +test_expect_success 'cruft repack respects repack.cruftWindow' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + + GIT_TRACE2_EVENT=$(pwd)/event.trace \ + git -c pack.window=1 -c repack.cruftWindow=2 repack \ + --cruft --window=3 && + + grep "pack-objects.*--window=2.*--cruft" event.trace + ) +' + +test_expect_success 'cruft repack respects --window by default' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + + GIT_TRACE2_EVENT=$(pwd)/event.trace \ + git -c pack.window=2 repack --cruft --window=3 && + + grep "pack-objects.*--window=3.*--cruft" event.trace + ) +' + +test_expect_success 'cruft repack respects --quiet' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + GIT_PROGRESS_DELAY=0 git repack --cruft --quiet 2>err && + test_must_be_empty err + ) +' + +test_expect_success 'cruft --local drops unreachable objects' ' + git init alternate && + git init repo && + test_when_finished "rm -fr alternate repo" && + + test_commit -C alternate base && + # Pack all objects in alterate so that the cruft repack in "repo" sees + # the object it dropped due to `--local` as packed. Otherwise this + # object would not appear packed anywhere (since it is not packed in + # alternate and likewise not part of the cruft pack in the other repo + # because of `--local`). + git -C alternate repack -ad && + + ( + cd repo && + + object="$(git -C ../alternate rev-parse HEAD:base.t)" && + git -C ../alternate cat-file -p $object >contents && + + # Write some reachable objects and two unreachable ones: one + # that the alternate has and another that is unique. + test_commit other && + git hash-object -w -t blob contents && + cruft="$(echo cruft | git hash-object -w -t blob --stdin)" && + + ( cd ../alternate/.git/objects && pwd ) \ + >.git/objects/info/alternates && + + test_path_is_file $objdir/$(test_oid_to_path $cruft) && + test_path_is_file $objdir/$(test_oid_to_path $object) && + + git repack -d --cruft --local && + + test-tool pack-mtimes "$(basename $(ls $packdir/pack-*.mtimes))" \ + >objects && + ! grep $object objects && + grep $cruft objects + ) +' + +test_expect_success 'MIDX bitmaps tolerate reachable cruft objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + test_commit cruft && + unreachable="$(git rev-parse cruft)" && + + git reset --hard $unreachable^ && + git tag -d cruft && + git reflog expire --all --expire=all && + + git repack --cruft -d && + + # resurrect the unreachable object via a new commit. the + # new commit will get selected for a bitmap, but be + # missing one of its parents from the selected packs. + git reset --hard $unreachable && + test_commit resurrect && + + git repack --write-midx --write-bitmap-index --geometric=2 -d + ) +' + +test_expect_success 'cruft objects are freshend via loose' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + echo "cruft" >contents && + blob="$(git hash-object -w -t blob contents)" && + loose="$objdir/$(test_oid_to_path $blob)" && + + test_commit base && + + git repack --cruft -d && + + test_path_is_missing "$loose" && + test-tool pack-mtimes "$(basename "$(ls $packdir/pack-*.mtimes)")" >cruft && + grep "$blob" cruft && + + # write the same object again + git hash-object -w -t blob contents && + + test_path_is_file "$loose" + ) +' + +test_done diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index c90cf47..fff14e1 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -78,6 +78,40 @@ test_expect_success 'add another remote' ' ) ' +test_expect_success 'setup bare clone for server' ' + git clone --bare "file://$(pwd)/one" srv.bare && + git -C srv.bare config --local uploadpack.allowfilter 1 && + git -C srv.bare config --local uploadpack.allowanysha1inwant 1 +' + +test_expect_success 'filters for promisor remotes are listed by git remote -v' ' + test_when_finished "rm -rf pc" && + git clone --filter=blob:none "file://$(pwd)/srv.bare" pc && + git -C pc remote -v >out && + grep "srv.bare (fetch) \[blob:none\]" out && + + git -C pc config remote.origin.partialCloneFilter object:type=commit && + git -C pc remote -v >out && + grep "srv.bare (fetch) \[object:type=commit\]" out +' + +test_expect_success 'filters should not be listed for non promisor remotes (remote -v)' ' + test_when_finished "rm -rf pc" && + git clone one pc && + git -C pc remote -v >out && + ! grep "(fetch) \[.*\]" out +' + +test_expect_success 'filters are listed by git remote -v only' ' + test_when_finished "rm -rf pc" && + git clone --filter=blob:none "file://$(pwd)/srv.bare" pc && + git -C pc remote >out && + ! grep "\[blob:none\]" out && + + git -C pc remote show >out && + ! grep "\[blob:none\]" out +' + test_expect_success 'check remote-tracking' ' ( cd test && diff --git a/t/t5506-remote-groups.sh b/t/t5506-remote-groups.sh index 8f150c0..5bac03e 100755 --- a/t/t5506-remote-groups.sh +++ b/t/t5506-remote-groups.sh @@ -4,6 +4,7 @@ test_description='git remote group handling' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh mark() { diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index f53f588..20d063f 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -15,6 +15,10 @@ generate_references () { done } +test_expect_success 'dies when no remote found' ' + test_must_fail git ls-remote +' + test_expect_success setup ' >file && git add file && @@ -30,7 +34,8 @@ test_expect_success setup ' git show-ref -d >refs && sed -e "s/ / /" refs >>expected.all && - git remote add self "$(pwd)/.git" + git remote add self "$(pwd)/.git" && + git remote add self2 "." ' test_expect_success 'ls-remote --tags .git' ' @@ -83,11 +88,17 @@ test_expect_success 'ls-remote --sort="-refname" --tags self' ' test_cmp expect actual ' -test_expect_success 'dies when no remote specified and no default remotes found' ' +test_expect_success 'dies when no remote specified, multiple remotes found, and no default specified' ' test_must_fail git ls-remote ' -test_expect_success 'use "origin" when no remote specified' ' +test_expect_success 'succeeds when no remote specified but only one found' ' + test_when_finished git remote add self2 "." && + git remote remove self2 && + git ls-remote +' + +test_expect_success 'use "origin" when no remote specified and multiple found' ' URL="$(pwd)/.git" && echo "From $URL" >exp_err && diff --git a/t/t5513-fetch-track.sh b/t/t5513-fetch-track.sh index 65d1e05..c46c4db 100755 --- a/t/t5513-fetch-track.sh +++ b/t/t5513-fetch-track.sh @@ -2,6 +2,7 @@ test_description='fetch follows remote-tracking branches correctly' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh index 320d267..c100a80 100755 --- a/t/t5515-fetch-merge-logic.sh +++ b/t/t5515-fetch-merge-logic.sh @@ -14,6 +14,7 @@ export GIT_TEST_PROTOCOL_VERSION GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh build_script () { diff --git a/t/t5518-fetch-exit-status.sh b/t/t5518-fetch-exit-status.sh index 5c4ac25..c131200 100755 --- a/t/t5518-fetch-exit-status.sh +++ b/t/t5518-fetch-exit-status.sh @@ -8,6 +8,7 @@ test_description='fetch exit status test' 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/t5526-fetch-submodules.sh b/t/t5526-fetch-submodules.sh index 43dada8..a301b56 100755 --- a/t/t5526-fetch-submodules.sh +++ b/t/t5526-fetch-submodules.sh @@ -1125,4 +1125,31 @@ test_expect_success 'fetch --recurse-submodules updates name-conflicted, unpopul ) ' +test_expect_success 'fetch --all with --recurse-submodules' ' + test_when_finished "rm -fr src_clone" && + git clone --recurse-submodules src src_clone && + ( + cd src_clone && + git config submodule.recurse true && + git config fetch.parallel 0 && + git fetch --all 2>../fetch-log + ) && + grep "^Fetching submodule sub$" fetch-log >fetch-subs && + test_line_count = 1 fetch-subs +' + +test_expect_success 'fetch --all with --recurse-submodules with multiple' ' + test_when_finished "rm -fr src_clone" && + git clone --recurse-submodules src src_clone && + ( + cd src_clone && + git remote add secondary ../src && + git config submodule.recurse true && + git config fetch.parallel 0 && + git fetch --all 2>../fetch-log + ) && + grep "Fetching submodule sub" fetch-log >fetch-subs && + test_line_count = 2 fetch-subs +' + test_done diff --git a/t/t5528-push-default.sh b/t/t5528-push-default.sh index f280e00..284e20f 100755 --- a/t/t5528-push-default.sh +++ b/t/t5528-push-default.sh @@ -94,13 +94,88 @@ test_expect_success '"upstream" does not push when remotes do not match' ' test_must_fail git push parent2 ' -test_expect_success 'push from/to new branch with upstream, matching and simple' ' +test_expect_success '"current" does not push when multiple remotes and none origin' ' + git checkout main && + test_config push.default current && + test_commit current-multi && + test_must_fail git push +' + +test_expect_success '"current" pushes when remote explicitly specified' ' + git checkout main && + test_config push.default current && + test_commit current-specified && + git push parent1 +' + +test_expect_success '"current" pushes to origin when no remote specified among multiple' ' + git checkout main && + test_config remote.origin.url repo1 && + test_config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" && + test_commit current-origin && + test_push_success current main +' + +test_expect_success '"current" pushes to single remote even when not specified' ' + git checkout main && + test_when_finished git remote add parent1 repo1 && + git remote remove parent1 && + test_commit current-implied && + test_push_success current main repo2 +' + +test_expect_success 'push from/to new branch with non-defaulted remote fails with upstream, matching, current and simple ' ' git checkout -b new-branch && test_push_failure simple && test_push_failure matching && + test_push_failure upstream && + test_push_failure current +' + +test_expect_success 'push from/to new branch fails with upstream and simple ' ' + git checkout -b new-branch-1 && + test_config branch.new-branch-1.remote parent1 && + test_push_failure simple && test_push_failure upstream ' +# The behavior here is surprising but not entirely wrong: +# - the current branch is used to determine the target remote +# - the "matching" push default pushes matching branches, *ignoring* the +# current new branch as it does not have upstream tracking +# - the default push succeeds +# +# A previous test expected this to fail, but for the wrong reasons: +# it expected a fail becaause the branch is new and cannot be pushed, but +# in fact it was failing because of an ambiguous remote +# +test_expect_failure 'push from/to new branch fails with matching ' ' + git checkout -b new-branch-2 && + test_config branch.new-branch-2.remote parent1 && + test_push_failure matching +' + +test_expect_success 'push from/to branch with tracking fails with nothing ' ' + git checkout -b tracked-branch && + test_config branch.tracked-branch.remote parent1 && + test_config branch.tracked-branch.merge refs/heads/tracked-branch && + test_push_failure nothing +' + +test_expect_success 'push from/to new branch succeeds with upstream if push.autoSetupRemote' ' + git checkout -b new-branch-a && + test_config push.autoSetupRemote true && + test_config branch.new-branch-a.remote parent1 && + test_push_success upstream new-branch-a +' + +test_expect_success 'push from/to new branch succeeds with simple if push.autoSetupRemote' ' + git checkout -b new-branch-c && + test_config push.autoSetupRemote true && + test_config branch.new-branch-c.remote parent1 && + test_push_success simple new-branch-c +' + test_expect_success '"matching" fails if none match' ' git init --bare empty && test_must_fail git push empty : 2>actual && diff --git a/t/t5532-fetch-proxy.sh b/t/t5532-fetch-proxy.sh index 9c27986..d664912 100755 --- a/t/t5532-fetch-proxy.sh +++ b/t/t5532-fetch-proxy.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='fetching via git:// using core.gitproxy' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup remote repo' ' diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index f92c79c..b9351a7 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -567,4 +567,11 @@ test_expect_success 'client falls back from v2 to v0 to match server' ' grep symref=HEAD:refs/heads/ trace ' +test_expect_success 'passing hostname resolution information works' ' + BOGUS_HOST=gitbogusexamplehost.invalid && + BOGUS_HTTPD_URL=$HTTPD_PROTO://$BOGUS_HOST:$LIB_HTTPD_PORT && + test_must_fail git ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null && + git -c "http.curloptResolve=$BOGUS_HOST:$LIB_HTTPD_PORT:127.0.0.1" ls-remote "$BOGUS_HTTPD_URL/smart/repo.git" >/dev/null +' + test_done diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh index 34b3df4..c814afa 100755 --- a/t/t5600-clone-fail-cleanup.sh +++ b/t/t5600-clone-fail-cleanup.sh @@ -13,6 +13,7 @@ Unless the directory already exists, in which case we clean up only what we wrote. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh corrupt_repo () { diff --git a/t/t5900-repo-selection.sh b/t/t5900-repo-selection.sh index 14e59c5..a84faac 100755 --- a/t/t5900-repo-selection.sh +++ b/t/t5900-repo-selection.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='selecting remote repo in ambiguous cases' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh reset() { diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index b95a021..162cf50 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -4,6 +4,7 @@ # test_description='Tests git rev-list --bisect functionality' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions diff --git a/t/t6003-rev-list-topo-order.sh b/t/t6003-rev-list-topo-order.sh index 24d1836..1f7d7dd 100755 --- a/t/t6003-rev-list-topo-order.sh +++ b/t/t6003-rev-list-topo-order.sh @@ -5,6 +5,7 @@ test_description='Tests git rev-list --topo-order functionality' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions diff --git a/t/t6005-rev-list-count.sh b/t/t6005-rev-list-count.sh index e960049..0729f80 100755 --- a/t/t6005-rev-list-count.sh +++ b/t/t6005-rev-list-count.sh @@ -2,6 +2,7 @@ test_description='git rev-list --max-count and --skip test' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index 24b34ad..e1abc5c 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -5,6 +5,7 @@ test_description='rev-list/rev-parse --glob' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit () { diff --git a/t/t6100-rev-list-in-order.sh b/t/t6100-rev-list-in-order.sh index e934bc2..88ed7bd 100755 --- a/t/t6100-rev-list-in-order.sh +++ b/t/t6100-rev-list-in-order.sh @@ -2,6 +2,7 @@ test_description='rev-list testing in-commit-order' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a commit history with trees, blobs' ' diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index c571fa5..a3a41c7 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -8,6 +8,7 @@ test_description='Test git rev-parse with different parent options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_cmp_rev_output () { diff --git a/t/t6110-rev-list-sparse.sh b/t/t6110-rev-list-sparse.sh index 13c1da5..ddefc7f 100755 --- a/t/t6110-rev-list-sparse.sh +++ b/t/t6110-rev-list-sparse.sh @@ -4,6 +4,7 @@ test_description='operations that cull histories in unusual ways' 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/t6114-keep-packs.sh b/t/t6114-keep-packs.sh index 9239d8a..44246f8 100755 --- a/t/t6114-keep-packs.sh +++ b/t/t6114-keep-packs.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='rev-list with .keep packs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6131-pathspec-icase.sh b/t/t6131-pathspec-icase.sh index 39fc3f6..770cce0 100755 --- a/t/t6131-pathspec-icase.sh +++ b/t/t6131-pathspec-icase.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test case insensitive pathspec limiting' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if test_have_prereq CASE_INSENSITIVE_FS diff --git a/t/t6424-merge-unrelated-index-changes.sh b/t/t6424-merge-unrelated-index-changes.sh index 89dd544..b6e424a 100755 --- a/t/t6424-merge-unrelated-index-changes.sh +++ b/t/t6424-merge-unrelated-index-changes.sh @@ -71,7 +71,9 @@ test_expect_success 'ff update' ' git merge E^0 && test_must_fail git rev-parse HEAD:random_file && - test "$(git diff --name-only --cached E)" = "random_file" + test "$(git diff --name-only --cached E)" = "random_file" && + test_path_is_file random_file && + git rev-parse --verify :random_file ' test_expect_success 'ff update, important file modified' ' @@ -83,6 +85,8 @@ test_expect_success 'ff update, important file modified' ' git add subdir/e && test_must_fail git merge E^0 && + test_path_is_file subdir/e && + git rev-parse --verify :subdir/e && test_path_is_missing .git/MERGE_HEAD ' @@ -93,6 +97,8 @@ test_expect_success 'resolve, trivial' ' touch random_file && git add random_file && test_must_fail git merge -s resolve C^0 && + test_path_is_file random_file && + git rev-parse --verify :random_file && test_path_is_missing .git/MERGE_HEAD ' @@ -103,6 +109,8 @@ test_expect_success 'resolve, non-trivial' ' touch random_file && git add random_file && test_must_fail git merge -s resolve D^0 && + test_path_is_file random_file && + git rev-parse --verify :random_file && test_path_is_missing .git/MERGE_HEAD ' @@ -113,6 +121,8 @@ test_expect_success 'recursive' ' touch random_file && git add random_file && test_must_fail git merge -s recursive C^0 && + test_path_is_file random_file && + git rev-parse --verify :random_file && test_path_is_missing .git/MERGE_HEAD ' @@ -145,9 +155,12 @@ test_expect_success 'recursive, when file has staged changes not matching HEAD n mkdir subdir && test_seq 1 10 >subdir/a && git add subdir/a && + git rev-parse --verify :subdir/a >expect && # We have staged changes; merge should error out test_must_fail git merge -s recursive E^0 2>err && + git rev-parse --verify :subdir/a >actual && + test_cmp expect actual && test_i18ngrep "changes to the following files would be overwritten" err ' @@ -158,9 +171,12 @@ test_expect_success 'recursive, when file has staged changes matching what a mer mkdir subdir && test_seq 1 11 >subdir/a && git add subdir/a && + git rev-parse --verify :subdir/a >expect && # We have staged changes; merge should error out test_must_fail git merge -s recursive E^0 2>err && + git rev-parse --verify :subdir/a >actual && + test_cmp expect actual && test_i18ngrep "changes to the following files would be overwritten" err ' @@ -171,7 +187,9 @@ test_expect_success 'octopus, unrelated file touched' ' touch random_file && git add random_file && test_must_fail git merge C^0 D^0 && - test_path_is_missing .git/MERGE_HEAD + test_path_is_missing .git/MERGE_HEAD && + git rev-parse --verify :random_file && + test_path_exists random_file ' test_expect_success 'octopus, related file removed' ' @@ -181,6 +199,8 @@ test_expect_success 'octopus, related file removed' ' git rm b && test_must_fail git merge C^0 D^0 && + test_path_is_missing b && + test_must_fail git rev-parse --verify :b && test_path_is_missing .git/MERGE_HEAD ' @@ -189,8 +209,12 @@ test_expect_success 'octopus, related file modified' ' git checkout B^0 && echo 12 >>a && git add a && + git rev-parse --verify :a >expect && test_must_fail git merge C^0 D^0 && + test_path_is_file a && + git rev-parse --verify :a >actual && + test_cmp expect actual && test_path_is_missing .git/MERGE_HEAD ' @@ -201,6 +225,8 @@ test_expect_success 'ours' ' touch random_file && git add random_file && test_must_fail git merge -s ours C^0 && + test_path_is_file random_file && + git rev-parse --verify :random_file && test_path_is_missing .git/MERGE_HEAD ' @@ -211,6 +237,8 @@ test_expect_success 'subtree' ' touch random_file && git add random_file && test_must_fail git merge -s subtree E^0 && + test_path_is_file random_file && + git rev-parse --verify :random_file && test_path_is_missing .git/MERGE_HEAD ' diff --git a/t/t6428-merge-conflicts-sparse.sh b/t/t6428-merge-conflicts-sparse.sh index 142c9aa..064be1b 100755 --- a/t/t6428-merge-conflicts-sparse.sh +++ b/t/t6428-merge-conflicts-sparse.sh @@ -87,7 +87,7 @@ test_expect_success 'conflicting entries written to worktree even if sparse' ' test_path_is_file numerals && git sparse-checkout init && - git sparse-checkout set README && + git sparse-checkout set --no-cone README && test_path_is_file README && test_path_is_missing numerals && @@ -123,7 +123,7 @@ test_expect_success 'present-despite-SKIP_WORKTREE handled reasonably' ' test_path_is_file numerals && git sparse-checkout init && - git sparse-checkout set README && + git sparse-checkout set --no-cone README && test_path_is_file README && test_path_is_missing numerals && diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh index 1d3d2ac..f0f7cbf 100755 --- a/t/t7002-mv-sparse-checkout.sh +++ b/t/t7002-mv-sparse-checkout.sh @@ -27,7 +27,7 @@ test_expect_success 'setup' " test_expect_success 'mv refuses to move sparse-to-sparse' ' test_when_finished rm -f e && git reset --hard && - git sparse-checkout set a && + git sparse-checkout set --no-cone a && touch b && test_must_fail git mv b e 2>stderr && cat sparse_error_header >expect && diff --git a/t/t7008-filter-branch-null-sha1.sh b/t/t7008-filter-branch-null-sha1.sh index 9ba9f24..93fbc92 100755 --- a/t/t7008-filter-branch-null-sha1.sh +++ b/t/t7008-filter-branch-null-sha1.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='filter-branch removal of trees with null sha1' + . ./test-lib.sh test_expect_success 'setup: base commits' ' diff --git a/t/t7011-skip-worktree-reading.sh b/t/t7011-skip-worktree-reading.sh index 1761a2b..4adac5a 100755 --- a/t/t7011-skip-worktree-reading.sh +++ b/t/t7011-skip-worktree-reading.sh @@ -5,6 +5,7 @@ test_description='skip-worktree bit test' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >expect.full <<EOF diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh index cb9f1a6..cd5c20f 100755 --- a/t/t7012-skip-worktree-writing.sh +++ b/t/t7012-skip-worktree-writing.sh @@ -151,7 +151,7 @@ test_expect_success 'stash restore in sparse checkout' ' git stash push && - git sparse-checkout set subdir && + git sparse-checkout set --no-cone subdir && # Ensure after sparse-checkout we only have expected files cat >expect <<-EOF && diff --git a/t/t7702-repack-cyclic-alternate.sh b/t/t7702-repack-cyclic-alternate.sh index 93b7486..f3cdb98 100755 --- a/t/t7702-repack-cyclic-alternate.sh +++ b/t/t7702-repack-cyclic-alternate.sh @@ -4,6 +4,8 @@ # test_description='repack involving cyclic alternate' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh index bdbbcbf..da87f8b 100755 --- a/t/t7703-repack-geometric.sh +++ b/t/t7703-repack-geometric.sh @@ -7,6 +7,7 @@ test_description='git repack --geometric works correctly' GIT_TEST_MULTI_PACK_INDEX=0 objdir=.git/objects +packdir=$objdir/pack midx=$objdir/pack/multi-pack-index test_expect_success '--geometric with no packs' ' @@ -180,6 +181,34 @@ test_expect_success '--geometric ignores kept packs' ' ) ' +test_expect_success '--geometric ignores --keep-pack packs' ' + git init geometric && + test_when_finished "rm -fr geometric" && + ( + cd geometric && + + # Create two equal-sized packs + test_commit kept && # 3 objects + git repack -d && + test_commit pack && # 3 objects + git repack -d && + + find $objdir/pack -type f -name "*.pack" | sort >packs.before && + git repack --geometric 2 -dm \ + --keep-pack="$(basename "$(head -n 1 packs.before)")" >out && + find $objdir/pack -type f -name "*.pack" | sort >packs.after && + + # Packs should not have changed (only one non-kept pack, no + # loose objects), but $midx should now exist. + grep "Nothing new to pack" out && + test_path_is_file $midx && + + test_cmp packs.before packs.after && + + git fsck + ) +' + test_expect_success '--geometric chooses largest MIDX preferred pack' ' git init geometric && test_when_finished "rm -fr geometric" && @@ -202,4 +231,50 @@ test_expect_success '--geometric chooses largest MIDX preferred pack' ' ) ' +test_expect_success '--geometric with pack.packSizeLimit' ' + git init pack-rewrite && + test_when_finished "rm -fr pack-rewrite" && + ( + cd pack-rewrite && + + test-tool genrandom foo 1048576 >foo && + test-tool genrandom bar 1048576 >bar && + + git add foo bar && + test_tick && + git commit -m base && + + git rev-parse HEAD:foo HEAD:bar >p1.objects && + git rev-parse HEAD HEAD^{tree} >p2.objects && + + # These two packs each contain two objects, so the following + # `--geometric` repack will try to combine them. + p1="$(git pack-objects $packdir/pack <p1.objects)" && + p2="$(git pack-objects $packdir/pack <p2.objects)" && + + # Remove any loose objects in packs, since we do not want extra + # copies around (which would mask over potential object + # corruption issues). + git prune-packed && + + # Both p1 and p2 will be rolled up, but pack-objects will write + # three packs: + # + # - one containing object "foo", + # - another containing object "bar", + # - a final pack containing the commit and tree objects + # (identical to p2 above) + git repack --geometric 2 -d --max-pack-size=1048576 && + + # Ensure `repack` can detect that the third pack it wrote + # (containing just the tree and commit objects) was identical to + # one that was below the geometric split, so that we can save it + # from deletion. + # + # If `repack` fails to do that, we will incorrectly delete p2, + # causing object corruption. + git fsck + ) +' + test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 42694fe..01c74b8 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -4,6 +4,7 @@ test_description='git send-email' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # May be altered later in the test diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index fea41b3..7c5b847 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -8,6 +8,7 @@ test_description='git svn basic tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh prepare_utf8_locale diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index 8b5681d..d043e80 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -4,6 +4,8 @@ # test_description='git svn property tests' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh mkdir import diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index c7d8e0b..5cf2ef4 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -4,6 +4,8 @@ # test_description='git svn fetching' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh index aec45bc..3cab0b9 100755 --- a/t/t9106-git-svn-commit-diff-clobber.sh +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -2,6 +2,8 @@ # # Copyright (c) 2006 Eric Wong test_description='git svn commit-diff clobber' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh index 743fbe1..419f055 100755 --- a/t/t9115-git-svn-dcommit-funky-renames.sh +++ b/t/t9115-git-svn-dcommit-funky-renames.sh @@ -5,6 +5,7 @@ test_description='git svn dcommit can commit renames of files with ugly names' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'load repository with strange names' ' diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh index 0a9f1ef..d74d7b2 100755 --- a/t/t9116-git-svn-log.sh +++ b/t/t9116-git-svn-log.sh @@ -4,6 +4,7 @@ # test_description='git svn log tests' + . ./lib-git-svn.sh test_expect_success 'setup repository and import' ' diff --git a/t/t9122-git-svn-author.sh b/t/t9122-git-svn-author.sh index 9e8fe38..527ba3d 100755 --- a/t/t9122-git-svn-author.sh +++ b/t/t9122-git-svn-author.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git svn authorship' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'setup svn repository' ' diff --git a/t/t9127-git-svn-partial-rebuild.sh b/t/t9127-git-svn-partial-rebuild.sh index 2e4789d..97f495b 100755 --- a/t/t9127-git-svn-partial-rebuild.sh +++ b/t/t9127-git-svn-partial-rebuild.sh @@ -4,6 +4,7 @@ # test_description='git svn partial-rebuild tests' + . ./lib-git-svn.sh test_expect_success 'initialize svnrepo' ' diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 01e1e8a..185248a 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -4,6 +4,7 @@ test_description='git svn honors i18n.commitEncoding in config' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh compare_git_head_with () { diff --git a/t/t9132-git-svn-broken-symlink.sh b/t/t9132-git-svn-broken-symlink.sh index aeceffa..4d8d058 100755 --- a/t/t9132-git-svn-broken-symlink.sh +++ b/t/t9132-git-svn-broken-symlink.sh @@ -2,6 +2,7 @@ test_description='test that git handles an svn repository with empty symlinks' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'load svn dumpfile' ' svnadmin load "$rawsvnrepo" <<EOF diff --git a/t/t9139-git-svn-non-utf8-commitencoding.sh b/t/t9139-git-svn-non-utf8-commitencoding.sh index 22d80b0..b7f756b 100755 --- a/t/t9139-git-svn-non-utf8-commitencoding.sh +++ b/t/t9139-git-svn-non-utf8-commitencoding.sh @@ -4,6 +4,7 @@ test_description='git svn refuses to dcommit non-UTF8 messages' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh # ISO-2022-JP can pass for valid UTF-8, so skipping that in this test diff --git a/t/t9146-git-svn-empty-dirs.sh b/t/t9146-git-svn-empty-dirs.sh index 80cb55f..79c26ed 100755 --- a/t/t9146-git-svn-empty-dirs.sh +++ b/t/t9146-git-svn-empty-dirs.sh @@ -3,6 +3,8 @@ # Copyright (c) 2009 Eric Wong test_description='git svn creates empty directories' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9148-git-svn-propset.sh b/t/t9148-git-svn-propset.sh index aebb289..6cc76a0 100755 --- a/t/t9148-git-svn-propset.sh +++ b/t/t9148-git-svn-propset.sh @@ -5,6 +5,7 @@ test_description='git svn propset tests' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'setup propset via import' ' diff --git a/t/t9160-git-svn-preserve-empty-dirs.sh b/t/t9160-git-svn-preserve-empty-dirs.sh index 36c6b1a..9cf7a14 100755 --- a/t/t9160-git-svn-preserve-empty-dirs.sh +++ b/t/t9160-git-svn-preserve-empty-dirs.sh @@ -9,6 +9,7 @@ This test uses git to clone a Subversion repository that contains empty directories, and checks that corresponding directories are created in the local Git repository with placeholder files.' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh GIT_REPO=git-svn-repo diff --git a/t/t9162-git-svn-dcommit-interactive.sh b/t/t9162-git-svn-dcommit-interactive.sh index e38d9fa..e2aa8ed 100755 --- a/t/t9162-git-svn-dcommit-interactive.sh +++ b/t/t9162-git-svn-dcommit-interactive.sh @@ -3,6 +3,8 @@ # Copyright (c) 2011 Frédéric Heitzmann test_description='git svn dcommit --interactive series' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9164-git-svn-dcommit-concurrent.sh b/t/t9164-git-svn-dcommit-concurrent.sh index 8466269..1465156 100755 --- a/t/t9164-git-svn-dcommit-concurrent.sh +++ b/t/t9164-git-svn-dcommit-concurrent.sh @@ -4,6 +4,8 @@ # test_description='concurrent git svn dcommit' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh index 32814e7..c900231 100755 --- a/t/t9501-gitweb-standalone-http-status.sh +++ b/t/t9501-gitweb-standalone-http-status.sh @@ -13,6 +13,7 @@ code and message.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gitweb.sh # diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 89a5e14..6da7273 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -1784,6 +1784,16 @@ test_oid_to_path () { echo "${1%$basename}/$basename" } +# Parse oids from git ls-files --staged output +test_parse_ls_files_stage_oids () { + awk '{print $2}' - +} + +# Parse oids from git ls-tree output +test_parse_ls_tree_oids () { + awk '{print $3}' - +} + # Choose a port number based on the test script's number and store it in # the given variable name, unless that variable already contains a number. test_set_port () { diff --git a/t/test-lib.sh b/t/test-lib.sh index 9e410a5..736c644 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1579,6 +1579,7 @@ test -n "$USE_LIBPCRE2" && test_set_prereq PCRE test -n "$USE_LIBPCRE2" && test_set_prereq LIBPCRE2 test -z "$NO_GETTEXT" && test_set_prereq GETTEXT test -n "$SANITIZE_LEAK" && test_set_prereq SANITIZE_LEAK +test -n "$GIT_VALGRIND_ENABLED" && test_set_prereq VALGRIND if test -z "$GIT_TEST_CHECK_CACHE_TREE" then |