diff options
Diffstat (limited to 't')
76 files changed, 2620 insertions, 335 deletions
diff --git a/t/.gitignore b/t/.gitignore index 91cf5772fe..3e6b0f2cc5 100644 --- a/t/.gitignore +++ b/t/.gitignore @@ -2,4 +2,5 @@ /test-results /.prove /chainlinttmp +/mesontmp /out/ diff --git a/t/Makefile b/t/Makefile index 131ffd778f..daa5fcae86 100644 --- a/t/Makefile +++ b/t/Makefile @@ -59,7 +59,7 @@ CHAINLINTSUPPRESS = GIT_TEST_EXT_CHAIN_LINT=0 && export GIT_TEST_EXT_CHAIN_LINT all:: $(DEFAULT_TEST_TARGET) -test: pre-clean check-chainlint $(TEST_LINT) +test: pre-clean check-chainlint check-meson $(TEST_LINT) $(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup failed: @@ -103,6 +103,7 @@ clean-except-prove-cache: clean-chainlint clean: clean-except-prove-cache $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' + $(RM) -r mesontmp $(RM) .prove clean-chainlint: @@ -114,6 +115,23 @@ check-chainlint: { $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \ diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual +check-meson: + @# awk acts up when trying to match single quotes, so we use \047 instead. + @mkdir -p mesontmp && \ + printf "%s\n" \ + "integration_tests t[0-9][0-9][0-9][0-9]-*.sh" \ + "unit_test_programs unit-tests/t-*.c" \ + "clar_test_suites unit-tests/u-*.c" | \ + while read -r variable pattern; do \ + awk "/^$$variable = \[\$$/ {flag=1 ; next } /^]$$/ { flag=0 } flag { gsub(/^ \047/, \"\"); gsub(/\047,\$$/, \"\"); print }" meson.build >mesontmp/meson.txt && \ + ls $$pattern >mesontmp/actual.txt && \ + if ! cmp mesontmp/meson.txt mesontmp/actual.txt; then \ + echo "Meson tests differ from actual tests:"; \ + diff -u mesontmp/meson.txt mesontmp/actual.txt; \ + exit 1; \ + fi; \ + done + test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \ test-lint-filenames ifneq ($(GIT_TEST_CHAIN_LINT),0) diff --git a/t/helper/meson.build b/t/helper/meson.build new file mode 100644 index 0000000000..5e83884246 --- /dev/null +++ b/t/helper/meson.build @@ -0,0 +1,91 @@ +test_tool_sources = [ + '../unit-tests/test-lib.c', + 'test-advise.c', + 'test-bitmap.c', + 'test-bloom.c', + 'test-bundle-uri.c', + 'test-cache-tree.c', + 'test-chmtime.c', + 'test-config.c', + 'test-crontab.c', + 'test-csprng.c', + 'test-date.c', + 'test-delete-gpgsig.c', + 'test-delta.c', + 'test-dir-iterator.c', + 'test-drop-caches.c', + 'test-dump-cache-tree.c', + 'test-dump-fsmonitor.c', + 'test-dump-split-index.c', + 'test-dump-untracked-cache.c', + 'test-env-helper.c', + 'test-example-tap.c', + 'test-find-pack.c', + 'test-fsmonitor-client.c', + 'test-genrandom.c', + 'test-genzeros.c', + 'test-getcwd.c', + 'test-hash-speed.c', + 'test-hash.c', + 'test-hashmap.c', + 'test-hexdump.c', + 'test-json-writer.c', + 'test-lazy-init-name-hash.c', + 'test-match-trees.c', + 'test-mergesort.c', + 'test-mktemp.c', + 'test-online-cpus.c', + 'test-pack-mtimes.c', + 'test-parse-options.c', + 'test-parse-pathspec-file.c', + 'test-partial-clone.c', + 'test-path-utils.c', + 'test-pcre2-config.c', + 'test-pkt-line.c', + 'test-proc-receive.c', + 'test-progress.c', + 'test-reach.c', + 'test-read-cache.c', + 'test-read-graph.c', + 'test-read-midx.c', + 'test-ref-store.c', + 'test-reftable.c', + 'test-regex.c', + 'test-repository.c', + 'test-revision-walking.c', + 'test-rot13-filter.c', + 'test-run-command.c', + 'test-scrap-cache-tree.c', + 'test-serve-v2.c', + 'test-sha1.c', + 'test-sha256.c', + 'test-sigchain.c', + 'test-simple-ipc.c', + 'test-string-list.c', + 'test-submodule-config.c', + 'test-submodule-nested-repo-config.c', + 'test-submodule.c', + 'test-subprocess.c', + 'test-tool.c', + 'test-trace2.c', + 'test-truncate.c', + 'test-userdiff.c', + 'test-wildmatch.c', + 'test-windows-named-pipe.c', + 'test-write-cache.c', + 'test-xml-encode.c', +] + +test_tool = executable('test-tool', + sources: test_tool_sources, + dependencies: [libgit, common_main], +) +bin_wrappers += test_tool +test_dependencies += test_tool + +test_fake_ssh = executable('test-fake-ssh', + sources: 'test-fake-ssh.c', + dependencies: [libgit, common_main], +) +bin_wrappers += test_fake_ssh +test_dependencies += test_fake_ssh diff --git a/t/helper/test-read-midx.c b/t/helper/test-read-midx.c index 438fb9fc61..fc63236961 100644 --- a/t/helper/test-read-midx.c +++ b/t/helper/test-read-midx.c @@ -18,7 +18,7 @@ static int read_midx_file(const char *object_dir, const char *checksum, struct multi_pack_index *m; setup_git_directory(); - m = load_multi_pack_index(object_dir, 1); + m = load_multi_pack_index(the_repository, object_dir, 1); if (!m) return 1; @@ -82,7 +82,7 @@ static int read_midx_checksum(const char *object_dir) struct multi_pack_index *m; setup_git_directory(); - m = load_multi_pack_index(object_dir, 1); + m = load_multi_pack_index(the_repository, object_dir, 1); if (!m) return 1; printf("%s\n", hash_to_hex(get_midx_checksum(m))); @@ -98,7 +98,7 @@ static int read_midx_preferred_pack(const char *object_dir) setup_git_directory(); - midx = load_multi_pack_index(object_dir, 1); + midx = load_multi_pack_index(the_repository, object_dir, 1); if (!midx) return 1; @@ -121,7 +121,7 @@ static int read_midx_bitmapped_packs(const char *object_dir) setup_git_directory(); - midx = load_multi_pack_index(object_dir, 1); + midx = load_multi_pack_index(the_repository, object_dir, 1); if (!midx) return 1; diff --git a/t/helper/test-reftable.c b/t/helper/test-reftable.c index 5c8849d115..3c72ed985b 100644 --- a/t/helper/test-reftable.c +++ b/t/helper/test-reftable.c @@ -156,7 +156,7 @@ int cmd__dump_reftable(int argc, const char **argv) int opt_dump_blocks = 0; int opt_dump_table = 0; int opt_dump_stack = 0; - uint32_t opt_hash_id = GIT_SHA1_FORMAT_ID; + uint32_t opt_hash_id = REFTABLE_HASH_SHA1; const char *arg = NULL, *argv0 = argv[0]; for (; argc > 1; argv++, argc--) @@ -167,7 +167,7 @@ int cmd__dump_reftable(int argc, const char **argv) else if (!strcmp("-t", argv[1])) opt_dump_table = 1; else if (!strcmp("-6", argv[1])) - opt_hash_id = GIT_SHA256_FORMAT_ID; + opt_hash_id = REFTABLE_HASH_SHA256; else if (!strcmp("-s", argv[1])) opt_dump_stack = 1; else if (!strcmp("-?", argv[1]) || !strcmp("-h", argv[1])) { diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh index cc6bb2cdea..7a734c6973 100644 --- a/t/lib-gettext.sh +++ b/t/lib-gettext.sh @@ -6,8 +6,8 @@ . ./test-lib.sh -GIT_TEXTDOMAINDIR="$GIT_BUILD_DIR/po/build/locale" -GIT_PO_PATH="$GIT_BUILD_DIR/po" +GIT_TEXTDOMAINDIR="$GIT_TEST_TEXTDOMAINDIR" +GIT_PO_PATH="$GIT_TEST_POPATH" export GIT_TEXTDOMAINDIR GIT_PO_PATH if test -n "$GIT_TEST_INSTALLED" diff --git a/t/lib-gitweb.sh b/t/lib-gitweb.sh index 7f9808ec20..a6e3dd11b3 100644 --- a/t/lib-gitweb.sh +++ b/t/lib-gitweb.sh @@ -105,6 +105,11 @@ if ! test_have_prereq PERL; then test_done fi +if ! test_have_prereq GITWEB; then + skip_all='skipping gitweb tests, gitweb not available' + test_done +fi + perl -MEncode -e '$e="";decode_utf8($e, Encode::FB_CROAK)' >/dev/null 2>&1 || { skip_all='skipping gitweb tests, perl version is too old' test_done diff --git a/t/meson.build b/t/meson.build new file mode 100644 index 0000000000..602ebfe6a2 --- /dev/null +++ b/t/meson.build @@ -0,0 +1,1150 @@ +clar_test_suites = [ + 'unit-tests/u-ctype.c', + 'unit-tests/u-strvec.c', +] + +clar_sources = [ + 'unit-tests/clar/clar.c', + 'unit-tests/unit-test.c', +] + +clar_decls_h = custom_target( + input: clar_test_suites, + output: 'clar-decls.h', + command : [ + shell, + meson.current_source_dir() + '/unit-tests/generate-clar-decls.sh', + '@OUTPUT@', + '@INPUT@', + ], + env: script_environment, +) +clar_sources += clar_decls_h + +clar_sources += custom_target( + input: clar_decls_h, + output: 'clar.suite', + command : [ + shell, + meson.current_source_dir() + '/unit-tests/generate-clar-suites.sh', + '@INPUT@', + '@OUTPUT@', + ], + env: script_environment, +) + +clar_unit_tests = executable('unit-tests', + sources: clar_sources + clar_test_suites, + dependencies: [libgit, common_main], +) +test('unit-tests', clar_unit_tests) + +unit_test_programs = [ + 'unit-tests/t-example-decorate.c', + 'unit-tests/t-hash.c', + 'unit-tests/t-hashmap.c', + 'unit-tests/t-mem-pool.c', + 'unit-tests/t-oid-array.c', + 'unit-tests/t-oidmap.c', + 'unit-tests/t-oidtree.c', + 'unit-tests/t-prio-queue.c', + 'unit-tests/t-reftable-basics.c', + 'unit-tests/t-reftable-block.c', + 'unit-tests/t-reftable-merged.c', + 'unit-tests/t-reftable-pq.c', + 'unit-tests/t-reftable-reader.c', + 'unit-tests/t-reftable-readwrite.c', + 'unit-tests/t-reftable-record.c', + 'unit-tests/t-reftable-stack.c', + 'unit-tests/t-reftable-tree.c', + 'unit-tests/t-strbuf.c', + 'unit-tests/t-strcmp-offset.c', + 'unit-tests/t-trailer.c', + 'unit-tests/t-urlmatch-normalization.c', +] + +foreach unit_test_program : unit_test_programs + unit_test_name = fs.stem(unit_test_program) + unit_test = executable(unit_test_name, + sources: [ + 'unit-tests/test-lib.c', + 'unit-tests/lib-oid.c', + 'unit-tests/lib-reftable.c', + unit_test_program, + ], + dependencies: [libgit, common_main], + ) + test(unit_test_name, unit_test, + workdir: meson.current_source_dir(), + timeout: 0, + ) +endforeach + +subdir('helper') + +integration_tests = [ + 't0000-basic.sh', + 't0001-init.sh', + 't0002-gitfile.sh', + 't0003-attributes.sh', + 't0004-unwritable.sh', + 't0005-signals.sh', + 't0006-date.sh', + 't0007-git-var.sh', + 't0008-ignores.sh', + 't0010-racy-git.sh', + 't0012-help.sh', + 't0013-sha1dc.sh', + 't0014-alias.sh', + 't0017-env-helper.sh', + 't0018-advice.sh', + 't0019-json-writer.sh', + 't0020-crlf.sh', + 't0021-conversion.sh', + 't0022-crlf-rename.sh', + 't0023-crlf-am.sh', + 't0024-crlf-archive.sh', + 't0025-crlf-renormalize.sh', + 't0026-eol-config.sh', + 't0027-auto-crlf.sh', + 't0028-working-tree-encoding.sh', + 't0029-core-unsetenvvars.sh', + 't0030-stripspace.sh', + 't0033-safe-directory.sh', + 't0034-root-safe-directory.sh', + 't0035-safe-bare-repository.sh', + 't0040-parse-options.sh', + 't0041-usage.sh', + 't0050-filesystem.sh', + 't0051-windows-named-pipe.sh', + 't0052-simple-ipc.sh', + 't0055-beyond-symlinks.sh', + 't0056-git-C.sh', + 't0060-path-utils.sh', + 't0061-run-command.sh', + 't0062-revision-walking.sh', + 't0063-string-list.sh', + 't0066-dir-iterator.sh', + 't0067-parse_pathspec_file.sh', + 't0068-for-each-repo.sh', + 't0070-fundamental.sh', + 't0071-sort.sh', + 't0080-unit-test-output.sh', + 't0081-find-pack.sh', + 't0090-cache-tree.sh', + 't0091-bugreport.sh', + 't0092-diagnose.sh', + 't0095-bloom.sh', + 't0100-previous.sh', + 't0101-at-syntax.sh', + 't0200-gettext-basic.sh', + 't0201-gettext-fallbacks.sh', + 't0202-gettext-perl.sh', + 't0203-gettext-setlocale-sanity.sh', + 't0204-gettext-reencode-sanity.sh', + 't0210-trace2-normal.sh', + 't0211-trace2-perf.sh', + 't0212-trace2-event.sh', + 't0300-credentials.sh', + 't0301-credential-cache.sh', + 't0302-credential-store.sh', + 't0303-credential-external.sh', + 't0410-partial-clone.sh', + 't0411-clone-from-partial.sh', + 't0450-txt-doc-vs-help.sh', + 't0500-progress-display.sh', + 't0600-reffiles-backend.sh', + 't0601-reffiles-pack-refs.sh', + 't0602-reffiles-fsck.sh', + 't0610-reftable-basics.sh', + 't0611-reftable-httpd.sh', + 't0612-reftable-jgit-compatibility.sh', + 't0613-reftable-write-options.sh', + 't1000-read-tree-m-3way.sh', + 't1001-read-tree-m-2way.sh', + 't1002-read-tree-m-u-2way.sh', + 't1003-read-tree-prefix.sh', + 't1004-read-tree-m-u-wf.sh', + 't1005-read-tree-reset.sh', + 't1006-cat-file.sh', + 't1007-hash-object.sh', + 't1008-read-tree-overlay.sh', + 't1009-read-tree-new-index.sh', + 't1010-mktree.sh', + 't1011-read-tree-sparse-checkout.sh', + 't1012-read-tree-df.sh', + 't1013-read-tree-submodule.sh', + 't1014-read-tree-confusing.sh', + 't1015-read-index-unmerged.sh', + 't1016-compatObjectFormat.sh', + 't1020-subdirectory.sh', + 't1021-rerere-in-workdir.sh', + 't1022-read-tree-partial-clone.sh', + 't1050-large.sh', + 't1051-large-conversion.sh', + 't1060-object-corruption.sh', + 't1090-sparse-checkout-scope.sh', + 't1091-sparse-checkout-builtin.sh', + 't1092-sparse-checkout-compatibility.sh', + 't1100-commit-tree-options.sh', + 't1300-config.sh', + 't1301-shared-repo.sh', + 't1302-repo-version.sh', + 't1303-wacky-config.sh', + 't1304-default-acl.sh', + 't1305-config-include.sh', + 't1306-xdg-files.sh', + 't1307-config-blob.sh', + 't1308-config-set.sh', + 't1309-early-config.sh', + 't1310-config-default.sh', + 't1350-config-hooks-path.sh', + 't1400-update-ref.sh', + 't1401-symbolic-ref.sh', + 't1402-check-ref-format.sh', + 't1403-show-ref.sh', + 't1404-update-ref-errors.sh', + 't1405-main-ref-store.sh', + 't1406-submodule-ref-store.sh', + 't1407-worktree-ref-store.sh', + 't1408-packed-refs.sh', + 't1409-avoid-packing-refs.sh', + 't1410-reflog.sh', + 't1411-reflog-show.sh', + 't1412-reflog-loop.sh', + 't1413-reflog-detach.sh', + 't1414-reflog-walk.sh', + 't1415-worktree-refs.sh', + 't1416-ref-transaction-hooks.sh', + 't1417-reflog-updateref.sh', + 't1418-reflog-exists.sh', + 't1419-exclude-refs.sh', + 't1420-lost-found.sh', + 't1430-bad-ref-name.sh', + 't1450-fsck.sh', + 't1451-fsck-buffer.sh', + 't1460-refs-migrate.sh', + 't1500-rev-parse.sh', + 't1501-work-tree.sh', + 't1502-rev-parse-parseopt.sh', + 't1503-rev-parse-verify.sh', + 't1504-ceiling-dirs.sh', + 't1505-rev-parse-last.sh', + 't1506-rev-parse-diagnosis.sh', + 't1507-rev-parse-upstream.sh', + 't1508-at-combinations.sh', + 't1509-root-work-tree.sh', + 't1510-repo-setup.sh', + 't1511-rev-parse-caret.sh', + 't1512-rev-parse-disambiguation.sh', + 't1513-rev-parse-prefix.sh', + 't1514-rev-parse-push.sh', + 't1515-rev-parse-outside-repo.sh', + 't1517-outside-repo.sh', + 't1600-index.sh', + 't1601-index-bogus.sh', + 't1700-split-index.sh', + 't1701-racy-split-index.sh', + 't1800-hook.sh', + 't2000-conflict-when-checking-files-out.sh', + 't2002-checkout-cache-u.sh', + 't2003-checkout-cache-mkdir.sh', + 't2004-checkout-cache-temp.sh', + 't2005-checkout-index-symlinks.sh', + 't2006-checkout-index-basic.sh', + 't2007-checkout-symlink.sh', + 't2008-checkout-subdir.sh', + 't2009-checkout-statinfo.sh', + 't2010-checkout-ambiguous.sh', + 't2011-checkout-invalid-head.sh', + 't2012-checkout-last.sh', + 't2013-checkout-submodule.sh', + 't2014-checkout-switch.sh', + 't2015-checkout-unborn.sh', + 't2016-checkout-patch.sh', + 't2017-checkout-orphan.sh', + 't2018-checkout-branch.sh', + 't2019-checkout-ambiguous-ref.sh', + 't2020-checkout-detach.sh', + 't2021-checkout-overwrite.sh', + 't2022-checkout-paths.sh', + 't2023-checkout-m.sh', + 't2024-checkout-dwim.sh', + 't2025-checkout-no-overlay.sh', + 't2026-checkout-pathspec-file.sh', + 't2027-checkout-track.sh', + 't2030-unresolve-info.sh', + 't2050-git-dir-relative.sh', + 't2060-switch.sh', + 't2070-restore.sh', + 't2071-restore-patch.sh', + 't2072-restore-pathspec-file.sh', + 't2080-parallel-checkout-basics.sh', + 't2081-parallel-checkout-collisions.sh', + 't2082-parallel-checkout-attributes.sh', + 't2100-update-cache-badpath.sh', + 't2101-update-index-reupdate.sh', + 't2102-update-index-symlinks.sh', + 't2103-update-index-ignore-missing.sh', + 't2104-update-index-skip-worktree.sh', + 't2105-update-index-gitfile.sh', + 't2106-update-index-assume-unchanged.sh', + 't2107-update-index-basic.sh', + 't2108-update-index-refresh-racy.sh', + 't2200-add-update.sh', + 't2201-add-update-typechange.sh', + 't2202-add-addremove.sh', + 't2203-add-intent.sh', + 't2204-add-ignored.sh', + 't2205-add-worktree-config.sh', + 't2300-cd-to-toplevel.sh', + 't2400-worktree-add.sh', + 't2401-worktree-prune.sh', + 't2402-worktree-list.sh', + 't2403-worktree-move.sh', + 't2404-worktree-config.sh', + 't2405-worktree-submodule.sh', + 't2406-worktree-repair.sh', + 't2407-worktree-heads.sh', + 't2500-untracked-overwriting.sh', + 't2501-cwd-empty.sh', + 't3000-ls-files-others.sh', + 't3001-ls-files-others-exclude.sh', + 't3002-ls-files-dashpath.sh', + 't3003-ls-files-exclude.sh', + 't3004-ls-files-basic.sh', + 't3005-ls-files-relative.sh', + 't3006-ls-files-long.sh', + 't3007-ls-files-recurse-submodules.sh', + 't3008-ls-files-lazy-init-name-hash.sh', + 't3009-ls-files-others-nonsubmodule.sh', + 't3010-ls-files-killed-modified.sh', + 't3011-common-prefixes-and-directory-traversal.sh', + 't3012-ls-files-dedup.sh', + 't3013-ls-files-format.sh', + 't3020-ls-files-error-unmatch.sh', + 't3040-subprojects-basic.sh', + 't3050-subprojects-fetch.sh', + 't3060-ls-files-with-tree.sh', + 't3070-wildmatch.sh', + 't3100-ls-tree-restrict.sh', + 't3101-ls-tree-dirname.sh', + 't3102-ls-tree-wildcards.sh', + 't3103-ls-tree-misc.sh', + 't3104-ls-tree-format.sh', + 't3105-ls-tree-output.sh', + 't3200-branch.sh', + 't3201-branch-contains.sh', + 't3202-show-branch.sh', + 't3203-branch-output.sh', + 't3204-branch-name-interpretation.sh', + 't3205-branch-color.sh', + 't3206-range-diff.sh', + 't3207-branch-submodule.sh', + 't3211-peel-ref.sh', + 't3300-funny-names.sh', + 't3301-notes.sh', + 't3302-notes-index-expensive.sh', + 't3303-notes-subtrees.sh', + 't3304-notes-mixed.sh', + 't3305-notes-fanout.sh', + 't3306-notes-prune.sh', + 't3307-notes-man.sh', + 't3308-notes-merge.sh', + 't3309-notes-merge-auto-resolve.sh', + 't3310-notes-merge-manual-resolve.sh', + 't3311-notes-merge-fanout.sh', + 't3320-notes-merge-worktrees.sh', + 't3321-notes-stripspace.sh', + 't3400-rebase.sh', + 't3401-rebase-and-am-rename.sh', + 't3402-rebase-merge.sh', + 't3403-rebase-skip.sh', + 't3404-rebase-interactive.sh', + 't3405-rebase-malformed.sh', + 't3406-rebase-message.sh', + 't3407-rebase-abort.sh', + 't3408-rebase-multi-line.sh', + 't3409-rebase-environ.sh', + 't3412-rebase-root.sh', + 't3413-rebase-hook.sh', + 't3415-rebase-autosquash.sh', + 't3416-rebase-onto-threedots.sh', + 't3417-rebase-whitespace-fix.sh', + 't3418-rebase-continue.sh', + 't3419-rebase-patch-id.sh', + 't3420-rebase-autostash.sh', + 't3421-rebase-topology-linear.sh', + 't3422-rebase-incompatible-options.sh', + 't3423-rebase-reword.sh', + 't3424-rebase-empty.sh', + 't3425-rebase-topology-merges.sh', + 't3426-rebase-submodule.sh', + 't3427-rebase-subtree.sh', + 't3428-rebase-signoff.sh', + 't3429-rebase-edit-todo.sh', + 't3430-rebase-merges.sh', + 't3431-rebase-fork-point.sh', + 't3432-rebase-fast-forward.sh', + 't3433-rebase-across-mode-change.sh', + 't3434-rebase-i18n.sh', + 't3435-rebase-gpg-sign.sh', + 't3436-rebase-more-options.sh', + 't3437-rebase-fixup-options.sh', + 't3438-rebase-broken-files.sh', + 't3500-cherry.sh', + 't3501-revert-cherry-pick.sh', + 't3502-cherry-pick-merge.sh', + 't3503-cherry-pick-root.sh', + 't3504-cherry-pick-rerere.sh', + 't3505-cherry-pick-empty.sh', + 't3506-cherry-pick-ff.sh', + 't3507-cherry-pick-conflict.sh', + 't3508-cherry-pick-many-commits.sh', + 't3509-cherry-pick-merge-df.sh', + 't3510-cherry-pick-sequence.sh', + 't3511-cherry-pick-x.sh', + 't3512-cherry-pick-submodule.sh', + 't3513-revert-submodule.sh', + 't3514-cherry-pick-revert-gpg.sh', + 't3600-rm.sh', + 't3601-rm-pathspec-file.sh', + 't3602-rm-sparse-checkout.sh', + 't3650-replay-basics.sh', + 't3700-add.sh', + 't3701-add-interactive.sh', + 't3702-add-edit.sh', + 't3703-add-magic-pathspec.sh', + 't3704-add-pathspec-file.sh', + 't3705-add-sparse-checkout.sh', + 't3800-mktag.sh', + 't3900-i18n-commit.sh', + 't3901-i18n-patch.sh', + 't3902-quoted.sh', + 't3903-stash.sh', + 't3904-stash-patch.sh', + 't3905-stash-include-untracked.sh', + 't3906-stash-submodule.sh', + 't3907-stash-show-config.sh', + 't3908-stash-in-worktree.sh', + 't3909-stash-pathspec-file.sh', + 't3910-mac-os-precompose.sh', + 't3920-crlf-messages.sh', + 't4000-diff-format.sh', + 't4001-diff-rename.sh', + 't4002-diff-basic.sh', + 't4003-diff-rename-1.sh', + 't4004-diff-rename-symlink.sh', + 't4005-diff-rename-2.sh', + 't4006-diff-mode.sh', + 't4007-rename-3.sh', + 't4008-diff-break-rewrite.sh', + 't4009-diff-rename-4.sh', + 't4010-diff-pathspec.sh', + 't4011-diff-symlink.sh', + 't4012-diff-binary.sh', + 't4013-diff-various.sh', + 't4014-format-patch.sh', + 't4015-diff-whitespace.sh', + 't4016-diff-quote.sh', + 't4017-diff-retval.sh', + 't4018-diff-funcname.sh', + 't4019-diff-wserror.sh', + 't4020-diff-external.sh', + 't4021-format-patch-numbered.sh', + 't4022-diff-rewrite.sh', + 't4023-diff-rename-typechange.sh', + 't4024-diff-optimize-common.sh', + 't4025-hunk-header.sh', + 't4026-color.sh', + 't4027-diff-submodule.sh', + 't4028-format-patch-mime-headers.sh', + 't4029-diff-trailing-space.sh', + 't4030-diff-textconv.sh', + 't4031-diff-rewrite-binary.sh', + 't4032-diff-inter-hunk-context.sh', + 't4033-diff-patience.sh', + 't4034-diff-words.sh', + 't4035-diff-quiet.sh', + 't4036-format-patch-signer-mime.sh', + 't4037-diff-r-t-dirs.sh', + 't4038-diff-combined.sh', + 't4039-diff-assume-unchanged.sh', + 't4040-whitespace-status.sh', + 't4041-diff-submodule-option.sh', + 't4042-diff-textconv-caching.sh', + 't4043-diff-rename-binary.sh', + 't4044-diff-index-unique-abbrev.sh', + 't4045-diff-relative.sh', + 't4046-diff-unmerged.sh', + 't4047-diff-dirstat.sh', + 't4048-diff-combined-binary.sh', + 't4049-diff-stat-count.sh', + 't4050-diff-histogram.sh', + 't4051-diff-function-context.sh', + 't4052-stat-output.sh', + 't4053-diff-no-index.sh', + 't4054-diff-bogus-tree.sh', + 't4055-diff-context.sh', + 't4056-diff-order.sh', + 't4057-diff-combined-paths.sh', + 't4058-diff-duplicates.sh', + 't4059-diff-submodule-not-initialized.sh', + 't4060-diff-submodule-option-diff-format.sh', + 't4061-diff-indent.sh', + 't4062-diff-pickaxe.sh', + 't4063-diff-blobs.sh', + 't4064-diff-oidfind.sh', + 't4065-diff-anchored.sh', + 't4066-diff-emit-delay.sh', + 't4067-diff-partial-clone.sh', + 't4068-diff-symmetric-merge-base.sh', + 't4069-remerge-diff.sh', + 't4100-apply-stat.sh', + 't4101-apply-nonl.sh', + 't4102-apply-rename.sh', + 't4103-apply-binary.sh', + 't4104-apply-boundary.sh', + 't4105-apply-fuzz.sh', + 't4106-apply-stdin.sh', + 't4107-apply-ignore-whitespace.sh', + 't4108-apply-threeway.sh', + 't4109-apply-multifrag.sh', + 't4110-apply-scan.sh', + 't4111-apply-subdir.sh', + 't4112-apply-renames.sh', + 't4113-apply-ending.sh', + 't4114-apply-typechange.sh', + 't4115-apply-symlink.sh', + 't4116-apply-reverse.sh', + 't4117-apply-reject.sh', + 't4118-apply-empty-context.sh', + 't4119-apply-config.sh', + 't4120-apply-popt.sh', + 't4121-apply-diffs.sh', + 't4122-apply-symlink-inside.sh', + 't4123-apply-shrink.sh', + 't4124-apply-ws-rule.sh', + 't4125-apply-ws-fuzz.sh', + 't4126-apply-empty.sh', + 't4127-apply-same-fn.sh', + 't4128-apply-root.sh', + 't4129-apply-samemode.sh', + 't4130-apply-criss-cross-rename.sh', + 't4131-apply-fake-ancestor.sh', + 't4132-apply-removal.sh', + 't4133-apply-filenames.sh', + 't4134-apply-submodule.sh', + 't4135-apply-weird-filenames.sh', + 't4136-apply-check.sh', + 't4137-apply-submodule.sh', + 't4138-apply-ws-expansion.sh', + 't4139-apply-escape.sh', + 't4140-apply-ita.sh', + 't4141-apply-too-large.sh', + 't4150-am.sh', + 't4151-am-abort.sh', + 't4152-am-subjects.sh', + 't4153-am-resume-override-opts.sh', + 't4200-rerere.sh', + 't4201-shortlog.sh', + 't4202-log.sh', + 't4203-mailmap.sh', + 't4204-patch-id.sh', + 't4205-log-pretty-formats.sh', + 't4206-log-follow-harder-copies.sh', + 't4207-log-decoration-colors.sh', + 't4208-log-magic-pathspec.sh', + 't4209-log-pickaxe.sh', + 't4210-log-i18n.sh', + 't4211-line-log.sh', + 't4212-log-corrupt.sh', + 't4213-log-tabexpand.sh', + 't4214-log-graph-octopus.sh', + 't4215-log-skewed-merges.sh', + 't4216-log-bloom.sh', + 't4217-log-limit.sh', + 't4252-am-options.sh', + 't4253-am-keep-cr-dos.sh', + 't4254-am-corrupt.sh', + 't4255-am-submodule.sh', + 't4256-am-format-flowed.sh', + 't4257-am-interactive.sh', + 't4258-am-quoted-cr.sh', + 't4300-merge-tree.sh', + 't4301-merge-tree-write-tree.sh', + 't5000-tar-tree.sh', + 't5001-archive-attr.sh', + 't5002-archive-attr-pattern.sh', + 't5003-archive-zip.sh', + 't5004-archive-corner-cases.sh', + 't5100-mailinfo.sh', + 't5150-request-pull.sh', + 't5200-update-server-info.sh', + 't5300-pack-object.sh', + 't5301-sliding-window.sh', + 't5302-pack-index.sh', + 't5303-pack-corruption-resilience.sh', + 't5304-prune.sh', + 't5305-include-tag.sh', + 't5306-pack-nobase.sh', + 't5307-pack-missing-commit.sh', + 't5308-pack-detect-duplicates.sh', + 't5309-pack-delta-cycles.sh', + 't5310-pack-bitmaps.sh', + 't5311-pack-bitmaps-shallow.sh', + 't5312-prune-corruption.sh', + 't5313-pack-bounds-checks.sh', + 't5314-pack-cycle-detection.sh', + 't5315-pack-objects-compression.sh', + 't5316-pack-delta-depth.sh', + 't5317-pack-objects-filter-objects.sh', + 't5318-commit-graph.sh', + 't5319-multi-pack-index.sh', + 't5320-delta-islands.sh', + 't5321-pack-large-objects.sh', + 't5322-pack-objects-sparse.sh', + 't5323-pack-redundant.sh', + 't5324-split-commit-graph.sh', + 't5325-reverse-index.sh', + 't5326-multi-pack-bitmaps.sh', + 't5327-multi-pack-bitmaps-rev.sh', + 't5328-commit-graph-64bit-time.sh', + 't5329-pack-objects-cruft.sh', + 't5330-no-lazy-fetch-with-commit-graph.sh', + 't5331-pack-objects-stdin.sh', + 't5332-multi-pack-reuse.sh', + 't5333-pseudo-merge-bitmaps.sh', + 't5334-incremental-multi-pack-index.sh', + 't5351-unpack-large-objects.sh', + 't5400-send-pack.sh', + 't5401-update-hooks.sh', + 't5402-post-merge-hook.sh', + 't5403-post-checkout-hook.sh', + 't5404-tracking-branches.sh', + 't5405-send-pack-rewind.sh', + 't5406-remote-rejects.sh', + 't5407-post-rewrite-hook.sh', + 't5408-send-pack-stdin.sh', + 't5409-colorize-remote-messages.sh', + 't5410-receive-pack-alternates.sh', + 't5411-proc-receive-hook.sh', + 't5500-fetch-pack.sh', + 't5501-fetch-push-alternates.sh', + 't5502-quickfetch.sh', + 't5503-tagfollow.sh', + 't5504-fetch-receive-strict.sh', + 't5505-remote.sh', + 't5506-remote-groups.sh', + 't5507-remote-environment.sh', + 't5509-fetch-push-namespaces.sh', + 't5510-fetch.sh', + 't5511-refspec.sh', + 't5512-ls-remote.sh', + 't5513-fetch-track.sh', + 't5514-fetch-multiple.sh', + 't5515-fetch-merge-logic.sh', + 't5516-fetch-push.sh', + 't5517-push-mirror.sh', + 't5518-fetch-exit-status.sh', + 't5519-push-alternates.sh', + 't5520-pull.sh', + 't5521-pull-options.sh', + 't5522-pull-symlink.sh', + 't5523-push-upstream.sh', + 't5524-pull-msg.sh', + 't5525-fetch-tagopt.sh', + 't5526-fetch-submodules.sh', + 't5527-fetch-odd-refs.sh', + 't5528-push-default.sh', + 't5529-push-errors.sh', + 't5530-upload-pack-error.sh', + 't5531-deep-submodule-push.sh', + 't5532-fetch-proxy.sh', + 't5533-push-cas.sh', + 't5534-push-signed.sh', + 't5535-fetch-push-symref.sh', + 't5536-fetch-conflicts.sh', + 't5537-fetch-shallow.sh', + 't5538-push-shallow.sh', + 't5539-fetch-http-shallow.sh', + 't5540-http-push-webdav.sh', + 't5541-http-push-smart.sh', + 't5542-push-http-shallow.sh', + 't5543-atomic-push.sh', + 't5544-pack-objects-hook.sh', + 't5545-push-options.sh', + 't5546-receive-limits.sh', + 't5547-push-quarantine.sh', + 't5548-push-porcelain.sh', + 't5549-fetch-push-http.sh', + 't5550-http-fetch-dumb.sh', + 't5551-http-fetch-smart.sh', + 't5552-skipping-fetch-negotiator.sh', + 't5553-set-upstream.sh', + 't5554-noop-fetch-negotiator.sh', + 't5555-http-smart-common.sh', + 't5557-http-get.sh', + 't5558-clone-bundle-uri.sh', + 't5559-http-fetch-smart-http2.sh', + 't5560-http-backend-noserver.sh', + 't5561-http-backend.sh', + 't5562-http-backend-content-length.sh', + 't5563-simple-http-auth.sh', + 't5564-http-proxy.sh', + 't5570-git-daemon.sh', + 't5571-pre-push-hook.sh', + 't5572-pull-submodule.sh', + 't5573-pull-verify-signatures.sh', + 't5574-fetch-output.sh', + 't5580-unc-paths.sh', + 't5581-http-curl-verbose.sh', + 't5582-fetch-negative-refspec.sh', + 't5583-push-branches.sh', + 't5600-clone-fail-cleanup.sh', + 't5601-clone.sh', + 't5602-clone-remote-exec.sh', + 't5603-clone-dirname.sh', + 't5604-clone-reference.sh', + 't5605-clone-local.sh', + 't5606-clone-options.sh', + 't5607-clone-bundle.sh', + 't5608-clone-2gb.sh', + 't5609-clone-branch.sh', + 't5610-clone-detached.sh', + 't5611-clone-config.sh', + 't5612-clone-refspec.sh', + 't5613-info-alternate.sh', + 't5614-clone-submodules-shallow.sh', + 't5615-alternate-env.sh', + 't5616-partial-clone.sh', + 't5617-clone-submodules-remote.sh', + 't5618-alternate-refs.sh', + 't5619-clone-local-ambiguous-transport.sh', + 't5700-protocol-v1.sh', + 't5701-git-serve.sh', + 't5702-protocol-v2.sh', + 't5703-upload-pack-ref-in-want.sh', + 't5704-protocol-violations.sh', + 't5705-session-id-in-capabilities.sh', + 't5730-protocol-v2-bundle-uri-file.sh', + 't5731-protocol-v2-bundle-uri-git.sh', + 't5732-protocol-v2-bundle-uri-http.sh', + 't5750-bundle-uri-parse.sh', + 't5801-remote-helpers.sh', + 't5802-connect-helper.sh', + 't5810-proto-disable-local.sh', + 't5811-proto-disable-git.sh', + 't5812-proto-disable-http.sh', + 't5813-proto-disable-ssh.sh', + 't5814-proto-disable-ext.sh', + 't5815-submodule-protos.sh', + 't5900-repo-selection.sh', + 't6000-rev-list-misc.sh', + 't6001-rev-list-graft.sh', + 't6002-rev-list-bisect.sh', + 't6003-rev-list-topo-order.sh', + 't6004-rev-list-path-optim.sh', + 't6005-rev-list-count.sh', + 't6006-rev-list-format.sh', + 't6007-rev-list-cherry-pick-file.sh', + 't6008-rev-list-submodule.sh', + 't6009-rev-list-parent.sh', + 't6010-merge-base.sh', + 't6011-rev-list-with-bad-commit.sh', + 't6012-rev-list-simplify.sh', + 't6013-rev-list-reverse-parents.sh', + 't6014-rev-list-all.sh', + 't6016-rev-list-graph-simplify-history.sh', + 't6017-rev-list-stdin.sh', + 't6018-rev-list-glob.sh', + 't6019-rev-list-ancestry-path.sh', + 't6020-bundle-misc.sh', + 't6021-rev-list-exclude-hidden.sh', + 't6022-rev-list-missing.sh', + 't6030-bisect-porcelain.sh', + 't6040-tracking-info.sh', + 't6041-bisect-submodule.sh', + 't6050-replace.sh', + 't6060-merge-index.sh', + 't6100-rev-list-in-order.sh', + 't6101-rev-parse-parents.sh', + 't6102-rev-list-unexpected-objects.sh', + 't6110-rev-list-sparse.sh', + 't6111-rev-list-treesame.sh', + 't6112-rev-list-filters-objects.sh', + 't6113-rev-list-bitmap-filters.sh', + 't6114-keep-packs.sh', + 't6115-rev-list-du.sh', + 't6120-describe.sh', + 't6130-pathspec-noglob.sh', + 't6131-pathspec-icase.sh', + 't6132-pathspec-exclude.sh', + 't6133-pathspec-rev-dwim.sh', + 't6134-pathspec-in-submodule.sh', + 't6135-pathspec-with-attrs.sh', + 't6136-pathspec-in-bare.sh', + 't6200-fmt-merge-msg.sh', + 't6300-for-each-ref.sh', + 't6301-for-each-ref-errors.sh', + 't6302-for-each-ref-filter.sh', + 't6400-merge-df.sh', + 't6401-merge-criss-cross.sh', + 't6402-merge-rename.sh', + 't6403-merge-file.sh', + 't6404-recursive-merge.sh', + 't6405-merge-symlinks.sh', + 't6406-merge-attr.sh', + 't6407-merge-binary.sh', + 't6408-merge-up-to-date.sh', + 't6409-merge-subtree.sh', + 't6411-merge-filemode.sh', + 't6412-merge-large-rename.sh', + 't6413-merge-crlf.sh', + 't6414-merge-rename-nocruft.sh', + 't6415-merge-dir-to-symlink.sh', + 't6416-recursive-corner-cases.sh', + 't6417-merge-ours-theirs.sh', + 't6418-merge-text-auto.sh', + 't6419-merge-ignorecase.sh', + 't6421-merge-partial-clone.sh', + 't6422-merge-rename-corner-cases.sh', + 't6423-merge-rename-directories.sh', + 't6424-merge-unrelated-index-changes.sh', + 't6425-merge-rename-delete.sh', + 't6426-merge-skip-unneeded-updates.sh', + 't6427-diff3-conflict-markers.sh', + 't6428-merge-conflicts-sparse.sh', + 't6429-merge-sequence-rename-caching.sh', + 't6430-merge-recursive.sh', + 't6431-merge-criscross.sh', + 't6432-merge-recursive-space-options.sh', + 't6433-merge-toplevel.sh', + 't6434-merge-recursive-rename-options.sh', + 't6435-merge-sparse.sh', + 't6436-merge-overwrite.sh', + 't6437-submodule-merge.sh', + 't6438-submodule-directory-file-conflicts.sh', + 't6439-merge-co-error-msgs.sh', + 't6500-gc.sh', + 't6501-freshen-objects.sh', + 't6600-test-reach.sh', + 't6700-tree-depth.sh', + 't7001-mv.sh', + 't7002-mv-sparse-checkout.sh', + 't7003-filter-branch.sh', + 't7004-tag.sh', + 't7005-editor.sh', + 't7006-pager.sh', + 't7007-show.sh', + 't7008-filter-branch-null-sha1.sh', + 't7010-setup.sh', + 't7011-skip-worktree-reading.sh', + 't7012-skip-worktree-writing.sh', + 't7030-verify-tag.sh', + 't7031-verify-tag-signed-ssh.sh', + 't7060-wtstatus.sh', + 't7061-wtstatus-ignore.sh', + 't7062-wtstatus-ignorecase.sh', + 't7063-status-untracked-cache.sh', + 't7064-wtstatus-pv2.sh', + 't7101-reset-empty-subdirs.sh', + 't7102-reset.sh', + 't7103-reset-bare.sh', + 't7104-reset-hard.sh', + 't7105-reset-patch.sh', + 't7106-reset-unborn-branch.sh', + 't7107-reset-pathspec-file.sh', + 't7110-reset-merge.sh', + 't7111-reset-table.sh', + 't7112-reset-submodule.sh', + 't7113-post-index-change-hook.sh', + 't7201-co.sh', + 't7300-clean.sh', + 't7301-clean-interactive.sh', + 't7400-submodule-basic.sh', + 't7401-submodule-summary.sh', + 't7402-submodule-rebase.sh', + 't7403-submodule-sync.sh', + 't7406-submodule-update.sh', + 't7407-submodule-foreach.sh', + 't7408-submodule-reference.sh', + 't7409-submodule-detached-work-tree.sh', + 't7411-submodule-config.sh', + 't7412-submodule-absorbgitdirs.sh', + 't7413-submodule-is-active.sh', + 't7414-submodule-mistakes.sh', + 't7416-submodule-dash-url.sh', + 't7417-submodule-path-url.sh', + 't7418-submodule-sparse-gitmodules.sh', + 't7419-submodule-set-branch.sh', + 't7420-submodule-set-url.sh', + 't7421-submodule-summary-add.sh', + 't7422-submodule-output.sh', + 't7423-submodule-symlinks.sh', + 't7424-submodule-mixed-ref-formats.sh', + 't7450-bad-git-dotfiles.sh', + 't7500-commit-template-squash-signoff.sh', + 't7501-commit-basic-functionality.sh', + 't7502-commit-porcelain.sh', + 't7503-pre-commit-and-pre-merge-commit-hooks.sh', + 't7504-commit-msg-hook.sh', + 't7505-prepare-commit-msg-hook.sh', + 't7506-status-submodule.sh', + 't7507-commit-verbose.sh', + 't7508-status.sh', + 't7509-commit-authorship.sh', + 't7510-signed-commit.sh', + 't7511-status-index.sh', + 't7512-status-help.sh', + 't7513-interpret-trailers.sh', + 't7514-commit-patch.sh', + 't7515-status-symlinks.sh', + 't7516-commit-races.sh', + 't7517-per-repo-email.sh', + 't7518-ident-corner-cases.sh', + 't7519-status-fsmonitor.sh', + 't7520-ignored-hook-warning.sh', + 't7521-ignored-mode.sh', + 't7524-commit-summary.sh', + 't7525-status-rename.sh', + 't7526-commit-pathspec-file.sh', + 't7527-builtin-fsmonitor.sh', + 't7528-signed-commit-ssh.sh', + 't7600-merge.sh', + 't7601-merge-pull-config.sh', + 't7602-merge-octopus-many.sh', + 't7603-merge-reduce-heads.sh', + 't7604-merge-custom-message.sh', + 't7605-merge-resolve.sh', + 't7606-merge-custom.sh', + 't7607-merge-state.sh', + 't7608-merge-messages.sh', + 't7609-mergetool--lib.sh', + 't7610-mergetool.sh', + 't7611-merge-abort.sh', + 't7612-merge-verify-signatures.sh', + 't7614-merge-signoff.sh', + 't7615-diff-algo-with-mergy-operations.sh', + 't7700-repack.sh', + 't7701-repack-unpack-unreachable.sh', + 't7702-repack-cyclic-alternate.sh', + 't7703-repack-geometric.sh', + 't7704-repack-cruft.sh', + 't7800-difftool.sh', + 't7810-grep.sh', + 't7811-grep-open.sh', + 't7812-grep-icase-non-ascii.sh', + 't7813-grep-icase-iso.sh', + 't7814-grep-recurse-submodules.sh', + 't7815-grep-binary.sh', + 't7816-grep-binary-pattern.sh', + 't7817-grep-sparse-checkout.sh', + 't7900-maintenance.sh', + 't8001-annotate.sh', + 't8002-blame.sh', + 't8003-blame-corner-cases.sh', + 't8004-blame-with-conflicts.sh', + 't8005-blame-i18n.sh', + 't8006-blame-textconv.sh', + 't8007-cat-file-textconv.sh', + 't8008-blame-formats.sh', + 't8009-blame-vs-topicbranches.sh', + 't8010-cat-file-filters.sh', + 't8011-blame-split-file.sh', + 't8012-blame-colors.sh', + 't8013-blame-ignore-revs.sh', + 't8014-blame-ignore-fuzzy.sh', + 't9001-send-email.sh', + 't9002-column.sh', + 't9003-help-autocorrect.sh', + 't9100-git-svn-basic.sh', + 't9101-git-svn-props.sh', + 't9102-git-svn-deep-rmdir.sh', + 't9103-git-svn-tracked-directory-removed.sh', + 't9104-git-svn-follow-parent.sh', + 't9105-git-svn-commit-diff.sh', + 't9106-git-svn-commit-diff-clobber.sh', + 't9107-git-svn-migrate.sh', + 't9108-git-svn-glob.sh', + 't9109-git-svn-multi-glob.sh', + 't9110-git-svn-use-svm-props.sh', + 't9111-git-svn-use-svnsync-props.sh', + 't9112-git-svn-md5less-file.sh', + 't9113-git-svn-dcommit-new-file.sh', + 't9114-git-svn-dcommit-merge.sh', + 't9115-git-svn-dcommit-funky-renames.sh', + 't9116-git-svn-log.sh', + 't9117-git-svn-init-clone.sh', + 't9118-git-svn-funky-branch-names.sh', + 't9119-git-svn-info.sh', + 't9120-git-svn-clone-with-percent-escapes.sh', + 't9121-git-svn-fetch-renamed-dir.sh', + 't9122-git-svn-author.sh', + 't9123-git-svn-rebuild-with-rewriteroot.sh', + 't9124-git-svn-dcommit-auto-props.sh', + 't9125-git-svn-multi-glob-branch-names.sh', + 't9126-git-svn-follow-deleted-readded-directory.sh', + 't9127-git-svn-partial-rebuild.sh', + 't9128-git-svn-cmd-branch.sh', + 't9129-git-svn-i18n-commitencoding.sh', + 't9130-git-svn-authors-file.sh', + 't9131-git-svn-empty-symlink.sh', + 't9132-git-svn-broken-symlink.sh', + 't9133-git-svn-nested-git-repo.sh', + 't9134-git-svn-ignore-paths.sh', + 't9135-git-svn-moved-branch-empty-file.sh', + 't9136-git-svn-recreated-branch-empty-file.sh', + 't9137-git-svn-dcommit-clobber-series.sh', + 't9138-git-svn-authors-prog.sh', + 't9139-git-svn-non-utf8-commitencoding.sh', + 't9140-git-svn-reset.sh', + 't9141-git-svn-multiple-branches.sh', + 't9142-git-svn-shallow-clone.sh', + 't9143-git-svn-gc.sh', + 't9144-git-svn-old-rev_map.sh', + 't9145-git-svn-master-branch.sh', + 't9146-git-svn-empty-dirs.sh', + 't9147-git-svn-include-paths.sh', + 't9148-git-svn-propset.sh', + 't9150-svk-mergetickets.sh', + 't9151-svn-mergeinfo.sh', + 't9152-svn-empty-dirs-after-gc.sh', + 't9153-git-svn-rewrite-uuid.sh', + 't9154-git-svn-fancy-glob.sh', + 't9155-git-svn-fetch-deleted-tag.sh', + 't9156-git-svn-fetch-deleted-tag-2.sh', + 't9157-git-svn-fetch-merge.sh', + 't9158-git-svn-mergeinfo.sh', + 't9159-git-svn-no-parent-mergeinfo.sh', + 't9160-git-svn-preserve-empty-dirs.sh', + 't9161-git-svn-mergeinfo-push.sh', + 't9162-git-svn-dcommit-interactive.sh', + 't9163-git-svn-reset-clears-caches.sh', + 't9164-git-svn-dcommit-concurrent.sh', + 't9165-git-svn-fetch-merge-branch-of-branch.sh', + 't9166-git-svn-fetch-merge-branch-of-branch2.sh', + 't9167-git-svn-cmd-branch-subproject.sh', + 't9168-git-svn-partially-globbed-names.sh', + 't9169-git-svn-dcommit-crlf.sh', + 't9200-git-cvsexportcommit.sh', + 't9210-scalar.sh', + 't9211-scalar-clone.sh', + 't9300-fast-import.sh', + 't9301-fast-import-notes.sh', + 't9302-fast-import-unpack-limit.sh', + 't9303-fast-import-compression.sh', + 't9304-fast-import-marks.sh', + 't9350-fast-export.sh', + 't9351-fast-export-anonymize.sh', + 't9400-git-cvsserver-server.sh', + 't9401-git-cvsserver-crlf.sh', + 't9402-git-cvsserver-refs.sh', + 't9500-gitweb-standalone-no-errors.sh', + 't9501-gitweb-standalone-http-status.sh', + 't9502-gitweb-standalone-parse-output.sh', + 't9600-cvsimport.sh', + 't9601-cvsimport-vendor-branch.sh', + 't9602-cvsimport-branches-tags.sh', + 't9603-cvsimport-patchsets.sh', + 't9604-cvsimport-timestamps.sh', + 't9700-perl-git.sh', + 't9800-git-p4-basic.sh', + 't9801-git-p4-branch.sh', + 't9802-git-p4-filetype.sh', + 't9803-git-p4-shell-metachars.sh', + 't9804-git-p4-label.sh', + 't9805-git-p4-skip-submit-edit.sh', + 't9806-git-p4-options.sh', + 't9807-git-p4-submit.sh', + 't9808-git-p4-chdir.sh', + 't9809-git-p4-client-view.sh', + 't9810-git-p4-rcs.sh', + 't9811-git-p4-label-import.sh', + 't9812-git-p4-wildcards.sh', + 't9813-git-p4-preserve-users.sh', + 't9814-git-p4-rename.sh', + 't9815-git-p4-submit-fail.sh', + 't9816-git-p4-locked.sh', + 't9817-git-p4-exclude.sh', + 't9818-git-p4-block.sh', + 't9819-git-p4-case-folding.sh', + 't9820-git-p4-editor-handling.sh', + 't9821-git-p4-path-variations.sh', + 't9822-git-p4-path-encoding.sh', + 't9823-git-p4-mock-lfs.sh', + 't9824-git-p4-git-lfs.sh', + 't9825-git-p4-handle-utf16-without-bom.sh', + 't9826-git-p4-keep-empty-commits.sh', + 't9827-git-p4-change-filetype.sh', + 't9828-git-p4-map-user.sh', + 't9829-git-p4-jobs.sh', + 't9830-git-p4-symlink-dir.sh', + 't9831-git-p4-triggers.sh', + 't9832-unshelve.sh', + 't9833-errors.sh', + 't9834-git-p4-file-dir-bug.sh', + 't9835-git-p4-metadata-encoding-python2.sh', + 't9836-git-p4-metadata-encoding-python3.sh', + 't9850-shell.sh', + 't9901-git-web--browse.sh', + 't9902-completion.sh', + 't9903-bash-prompt.sh', +] + +# Sanity check that we are not missing any tests present in 't/'. This check +# only runs once at configure time and is thus best-effort, only. It is +# sufficient to catch missing test suites in our CI though. +foreach glob, tests : { + 't[0-9][0-9][0-9][0-9]-*.sh': integration_tests, + 'unit-tests/t-*.c': unit_test_programs, + 'unit-tests/u-*.c': clar_test_suites, +} + actual_tests = run_command(shell, '-c', 'ls ' + glob, + check: true, + env: script_environment, + ).stdout().strip().split('\n') + + if tests != actual_tests + missing_tests = [ ] + foreach actual_test : actual_tests + if actual_test not in tests + missing_tests += actual_test + endif + endforeach + if missing_tests.length() > 0 + error('Test files found, but not configured:\n\n - ' + '\n - '.join(missing_tests)) + endif + + superfluous_tests = [ ] + foreach integration_test : tests + if integration_test not in actual_tests + superfluous_tests += integration_test + endif + endforeach + if superfluous_tests.length() > 0 + error('Test files configured, but not found:\n\n - ' + '\n - '.join(superfluous_tests)) + endif + endif +endforeach + +# GIT_BUILD_DIR needs to be Unix-style without drive prefixes as it get added +# to the PATH variable. And given that drive prefixes contain a colon we'd +# otherwise end up with a broken PATH if we didn't convert it. +git_build_dir = meson.project_build_root() +if cygpath.found() + git_build_dir = run_command(cygpath, git_build_dir, check: true).stdout().strip() +endif + +test_environment = script_environment +test_environment.set('GIT_BUILD_DIR', git_build_dir) + +foreach integration_test : integration_tests + test(fs.stem(integration_test), shell, + args: [ integration_test ], + workdir: meson.current_source_dir(), + env: test_environment, + depends: test_dependencies + bin_wrappers, + timeout: 0, + ) +endforeach diff --git a/t/perf/p6100-describe.sh b/t/perf/p6100-describe.sh new file mode 100755 index 0000000000..069f91ce49 --- /dev/null +++ b/t/perf/p6100-describe.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +test_description='performance of git-describe' +. ./perf-lib.sh + +test_perf_default_repo + +# clear out old tags and give us a known state +test_expect_success 'set up tags' ' + git for-each-ref --format="delete %(refname)" refs/tags >to-delete && + git update-ref --stdin <to-delete && + new=$(git rev-list -1000 HEAD | tail -n 1) && + git tag -m new new $new && + old=$(git rev-list HEAD | tail -n 1) && + git tag -m old old $old +' + +test_perf 'describe HEAD' ' + git describe HEAD +' + +test_perf 'describe HEAD with one max candidate' ' + git describe --candidates=1 HEAD +' + +test_perf 'describe HEAD with one tag' ' + git describe --match=new HEAD +' + +test_done diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 4890dff4b2..72a0c2e7d4 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -433,6 +433,12 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' ' sep_git_dir_worktree () { test_when_finished "rm -rf mainwt linkwt seprepo" && git init mainwt && + if test "relative" = $2 + then + test_config -C mainwt worktree.useRelativePaths true + else + test_config -C mainwt worktree.useRelativePaths false + fi test_commit -C mainwt gumby && git -C mainwt worktree add --detach ../linkwt && git -C "$1" init --separate-git-dir ../seprepo && @@ -441,12 +447,20 @@ sep_git_dir_worktree () { test_cmp expect actual } -test_expect_success 're-init to move gitdir with linked worktrees' ' - sep_git_dir_worktree mainwt +test_expect_success 're-init to move gitdir with linked worktrees (absolute)' ' + sep_git_dir_worktree mainwt absolute +' + +test_expect_success 're-init to move gitdir within linked worktree (absolute)' ' + sep_git_dir_worktree linkwt absolute +' + +test_expect_success 're-init to move gitdir with linked worktrees (relative)' ' + sep_git_dir_worktree mainwt relative ' -test_expect_success 're-init to move gitdir within linked worktree' ' - sep_git_dir_worktree linkwt +test_expect_success 're-init to move gitdir within linked worktree (relative)' ' + sep_git_dir_worktree linkwt relative ' test_expect_success MINGW '.git hidden' ' diff --git a/t/t0018-advice.sh b/t/t0018-advice.sh index 9a3db02fde..f68e08d0b1 100755 --- a/t/t0018-advice.sh +++ b/t/t0018-advice.sh @@ -10,7 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME test_expect_success 'advice should be printed when config variable is unset' ' cat >expect <<-\EOF && hint: This is a piece of advice - hint: Disable this message with "git config advice.nestedTag false" + hint: Disable this message with "git config set advice.nestedTag false" EOF test-tool advise "This is a piece of advice" 2>actual && test_cmp expect actual diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh index c98d501869..196fc61784 100755 --- a/t/t0411-clone-from-partial.sh +++ b/t/t0411-clone-from-partial.sh @@ -28,7 +28,6 @@ test_expect_success 'local clone must not fetch from promisor remote and execute test_must_fail git clone \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ evil clone1 2>err && - test_grep "detected dubious ownership" err && test_grep ! "fake-upload-pack running" err && test_path_is_missing script-executed ' @@ -38,7 +37,6 @@ test_expect_success 'clone from file://... must not fetch from promisor remote a test_must_fail git clone \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ "file://$(pwd)/evil" clone2 2>err && - test_grep "detected dubious ownership" err && test_grep ! "fake-upload-pack running" err && test_path_is_missing script-executed ' @@ -48,7 +46,6 @@ test_expect_success 'fetch from file://... must not fetch from promisor remote a test_must_fail git fetch \ --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ "file://$(pwd)/evil" 2>err && - test_grep "detected dubious ownership" err && test_grep ! "fake-upload-pack running" err && test_path_is_missing script-executed ' diff --git a/t/t1460-refs-migrate.sh b/t/t1460-refs-migrate.sh index 1bfff3a7af..f59bc4860f 100755 --- a/t/t1460-refs-migrate.sh +++ b/t/t1460-refs-migrate.sh @@ -7,23 +7,44 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +# Migrate the provided repository from one format to the other and +# verify that the references and logs are migrated over correctly. +# Usage: test_migration <repo> <format> <skip_reflog_verify> +# <repo> is the relative path to the repo to be migrated. +# <format> is the ref format to be migrated to. +# <skip_reflog_verify> (true or false) whether to skip reflog verification. test_migration () { - git -C "$1" for-each-ref --include-root-refs \ + repo=$1 && + format=$2 && + skip_reflog_verify=${3:-false} && + git -C "$repo" for-each-ref --include-root-refs \ --format='%(refname) %(objectname) %(symref)' >expect && - git -C "$1" refs migrate --ref-format="$2" && - git -C "$1" for-each-ref --include-root-refs \ + if ! $skip_reflog_verify + then + git -C "$repo" reflog --all >expect_logs && + git -C "$repo" reflog list >expect_log_list + fi && + + git -C "$repo" refs migrate --ref-format="$2" && + + git -C "$repo" for-each-ref --include-root-refs \ --format='%(refname) %(objectname) %(symref)' >actual && test_cmp expect actual && + if ! $skip_reflog_verify + then + git -C "$repo" reflog --all >actual_logs && + git -C "$repo" reflog list >actual_log_list && + test_cmp expect_logs actual_logs && + test_cmp expect_log_list actual_log_list + fi && - git -C "$1" rev-parse --show-ref-format >actual && - echo "$2" >expect && + git -C "$repo" rev-parse --show-ref-format >actual && + echo "$format" >expect && test_cmp expect actual } test_expect_success 'setup' ' - rm -rf .git && - # The migration does not yet support reflogs. - git config --global core.logAllRefUpdates false + rm -rf .git ' test_expect_success "superfluous arguments" ' @@ -78,19 +99,6 @@ do test_cmp expect err ' - test_expect_success "$from_format -> $to_format: migration with reflog fails" ' - test_when_finished "rm -rf repo" && - git init --ref-format=$from_format repo && - test_config -C repo core.logAllRefUpdates true && - test_commit -C repo logged && - test_must_fail git -C repo refs migrate \ - --ref-format=$to_format 2>err && - cat >expect <<-EOF && - error: migrating reflogs is not supported yet - EOF - test_cmp expect err - ' - test_expect_success "$from_format -> $to_format: migration with worktree fails" ' test_when_finished "rm -rf repo" && git init --ref-format=$from_format repo && @@ -141,7 +149,7 @@ do test_commit -C repo initial && test-tool -C repo ref-store main update-ref "" refs/heads/broken \ "$(test_oid 001)" "$ZERO_OID" REF_SKIP_CREATE_REFLOG,REF_SKIP_OID_VERIFICATION && - test_migration repo "$to_format" && + test_migration repo "$to_format" true && test_oid 001 >expect && git -C repo rev-parse refs/heads/broken >actual && test_cmp expect actual @@ -195,6 +203,27 @@ do git -C repo rev-parse --show-ref-format >actual && test_cmp expect actual ' + + test_expect_success "$from_format -> $to_format: reflogs of symrefs with target deleted" ' + test_when_finished "rm -rf repo" && + git init --ref-format=$from_format repo && + test_commit -C repo initial && + git -C repo branch branch-1 HEAD && + git -C repo symbolic-ref refs/heads/symref refs/heads/branch-1 && + cat >input <<-EOF && + delete refs/heads/branch-1 + EOF + git -C repo update-ref --stdin <input && + test_migration repo "$to_format" + ' + + test_expect_success "$from_format -> $to_format: reflogs order is retained" ' + test_when_finished "rm -rf repo" && + git init --ref-format=$from_format repo && + test_commit --date "100005000 +0700" --no-tag -C repo initial && + test_commit --date "100003000 +0700" --no-tag -C repo second && + test_migration repo "$to_format" + ' done done diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index bf2a90df94..58a4583088 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -309,4 +309,19 @@ test_expect_success '--short= truncates to the actual hash length' ' test_cmp expect actual ' +test_expect_success ':/ and HEAD^{/} favor more recent matching commits' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit common-old && + test_commit --no-tag common-new && + git rev-parse HEAD >expect && + git rev-parse :/common >actual && + test_cmp expect actual && + git rev-parse HEAD^{/common} >actual && + test_cmp expect actual + ) +' + test_done diff --git a/t/t2400-worktree-add.sh b/t/t2400-worktree-add.sh index ba320dc417..90638fa886 100755 --- a/t/t2400-worktree-add.sh +++ b/t/t2400-worktree-add.sh @@ -1206,4 +1206,50 @@ test_expect_success '"add" with initialized submodule, with submodule.recurse se git -C project-clone -c submodule.recurse worktree add ../project-5 ' +test_expect_success 'can create worktrees with relative paths' ' + test_when_finished "git worktree remove relative" && + test_config worktree.useRelativePaths false && + git worktree add --relative-paths ./relative && + echo "gitdir: ../.git/worktrees/relative" >expect && + test_cmp expect relative/.git && + echo "../../../relative/.git" >expect && + test_cmp expect .git/worktrees/relative/gitdir +' + +test_expect_success 'can create worktrees with absolute paths' ' + test_config worktree.useRelativePaths true && + git worktree add ./relative && + echo "gitdir: ../.git/worktrees/relative" >expect && + test_cmp expect relative/.git && + git worktree add --no-relative-paths ./absolute && + echo "gitdir: $(pwd)/.git/worktrees/absolute" >expect && + test_cmp expect absolute/.git && + echo "$(pwd)/absolute/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir +' + +test_expect_success 'move repo without breaking relative internal links' ' + test_when_finished rm -rf repo moved && + git init repo && + ( + cd repo && + test_commit initial && + git worktree add --relative-paths wt1 && + cd .. && + mv repo moved && + cd moved/wt1 && + git worktree list >out 2>err && + test_must_be_empty err + ) +' + +test_expect_success 'relative worktree sets extension config' ' + test_when_finished "rm -rf repo" && + git init repo && + git -C repo commit --allow-empty -m base && + git -C repo worktree add --relative-paths ./foo && + test_cmp_config -C repo 1 core.repositoryformatversion && + test_cmp_config -C repo true extensions.relativeworktrees +' + test_done diff --git a/t/t2401-worktree-prune.sh b/t/t2401-worktree-prune.sh index aa5b42c0f7..fe671d4197 100755 --- a/t/t2401-worktree-prune.sh +++ b/t/t2401-worktree-prune.sh @@ -119,11 +119,12 @@ test_expect_success 'prune duplicate (main/linked)' ' ! test -d .git/worktrees/wt ' -test_expect_success 'not prune proper worktrees when run inside linked worktree' ' +test_expect_success 'not prune proper worktrees inside linked worktree with relative paths' ' test_when_finished rm -rf repo wt_ext && git init repo && ( cd repo && + git config worktree.useRelativePaths true && echo content >file && git add file && git commit -m msg && diff --git a/t/t2402-worktree-list.sh b/t/t2402-worktree-list.sh index cb125ec226..8ef1cad7f2 100755 --- a/t/t2402-worktree-list.sh +++ b/t/t2402-worktree-list.sh @@ -260,6 +260,7 @@ test_expect_success 'broken main worktree still at the top' ' ' test_expect_success 'linked worktrees are sorted' ' + test_when_finished "rm -rf sorted" && mkdir sorted && git init sorted/main && ( @@ -279,6 +280,27 @@ test_expect_success 'linked worktrees are sorted' ' test_cmp expected sorted/main/actual ' +test_expect_success 'linked worktrees with relative paths are shown with absolute paths' ' + test_when_finished "rm -rf sorted" && + mkdir sorted && + git init sorted/main && + ( + cd sorted/main && + test_tick && + test_commit new && + git worktree add --relative-paths ../first && + git worktree add ../second && + git worktree list --porcelain >out && + grep ^worktree out >actual + ) && + cat >expected <<-EOF && + worktree $(pwd)/sorted/main + worktree $(pwd)/sorted/first + worktree $(pwd)/sorted/second + EOF + test_cmp expected sorted/main/actual +' + test_expect_success 'worktree path when called in .git directory' ' git worktree list >list1 && git -C .git worktree list >list2 && diff --git a/t/t2403-worktree-move.sh b/t/t2403-worktree-move.sh index 08531deb5b..0bb33e8b1b 100755 --- a/t/t2403-worktree-move.sh +++ b/t/t2403-worktree-move.sh @@ -246,4 +246,29 @@ test_expect_success 'not remove a repo with initialized submodule' ' ) ' +test_expect_success 'move worktree with absolute path to relative path' ' + test_config worktree.useRelativePaths false && + git worktree add ./absolute && + git worktree move --relative-paths absolute relative && + echo "gitdir: ../.git/worktrees/absolute" >expect && + test_cmp expect relative/.git && + echo "../../../relative/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir && + test_config worktree.useRelativePaths true && + git worktree move relative relative2 && + echo "gitdir: ../.git/worktrees/absolute" >expect && + test_cmp expect relative2/.git && + echo "../../../relative2/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir +' + +test_expect_success 'move worktree with relative path to absolute path' ' + test_config worktree.useRelativePaths true && + git worktree move --no-relative-paths relative2 absolute && + echo "gitdir: $(pwd)/.git/worktrees/absolute" >expect && + test_cmp expect absolute/.git && + echo "$(pwd)/absolute/.git" >expect && + test_cmp expect .git/worktrees/absolute/gitdir +' + test_done diff --git a/t/t2406-worktree-repair.sh b/t/t2406-worktree-repair.sh index bf340b8772..f5f19b3169 100755 --- a/t/t2406-worktree-repair.sh +++ b/t/t2406-worktree-repair.sh @@ -215,4 +215,43 @@ test_expect_success 'repair copied main and linked worktrees' ' test_cmp dup/linked.expect dup/linked/.git ' +test_expect_success 'repair worktree with relative path with missing gitfile' ' + test_when_finished "rm -rf main wt" && + test_create_repo main && + git -C main config worktree.useRelativePaths true && + test_commit -C main init && + git -C main worktree add --detach ../wt && + rm wt/.git && + test_path_is_missing wt/.git && + git -C main worktree repair && + echo "gitdir: ../main/.git/worktrees/wt" >expect && + test_cmp expect wt/.git +' + +test_expect_success 'repair absolute worktree to use relative paths' ' + test_when_finished "rm -rf main side sidemoved" && + test_create_repo main && + test_commit -C main init && + git -C main worktree add --detach ../side && + echo "../../../../sidemoved/.git" >expect-gitdir && + echo "gitdir: ../main/.git/worktrees/side" >expect-gitfile && + mv side sidemoved && + git -C main worktree repair --relative-paths ../sidemoved && + test_cmp expect-gitdir main/.git/worktrees/side/gitdir && + test_cmp expect-gitfile sidemoved/.git +' + +test_expect_success 'repair relative worktree to use absolute paths' ' + test_when_finished "rm -rf main side sidemoved" && + test_create_repo main && + test_commit -C main init && + git -C main worktree add --relative-paths --detach ../side && + echo "$(pwd)/sidemoved/.git" >expect-gitdir && + echo "gitdir: $(pwd)/main/.git/worktrees/side" >expect-gitfile && + mv side sidemoved && + git -C main worktree repair ../sidemoved && + test_cmp expect-gitdir main/.git/worktrees/side/gitdir && + test_cmp expect-gitfile sidemoved/.git +' + test_done diff --git a/t/t2408-worktree-relative.sh b/t/t2408-worktree-relative.sh deleted file mode 100755 index d51cc8c5ab..0000000000 --- a/t/t2408-worktree-relative.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh - -test_description='test worktrees linked with relative paths' - -. ./test-lib.sh - -test_expect_success 'links worktrees with relative paths' ' - test_when_finished rm -rf repo && - git init repo && - ( - cd repo && - test_commit initial && - git worktree add wt1 && - echo "../../../wt1/.git" >expected_gitdir && - cat .git/worktrees/wt1/gitdir >actual_gitdir && - echo "gitdir: ../.git/worktrees/wt1" >expected_git && - cat wt1/.git >actual_git && - test_cmp expected_gitdir actual_gitdir && - test_cmp expected_git actual_git - ) -' - -test_expect_success 'move repo without breaking relative internal links' ' - test_when_finished rm -rf repo moved && - git init repo && - ( - cd repo && - test_commit initial && - git worktree add wt1 && - cd .. && - mv repo moved && - cd moved/wt1 && - git status >out 2>err && - test_must_be_empty err - ) -' - -test_done diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index 2295db3dcb..a3a21c54cf 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -1696,7 +1696,7 @@ test_expect_success 'errors if given a bad branch name' ' cat <<-\EOF >expect && fatal: '\''foo..bar'\'' is not a valid branch name hint: See `man git check-ref-format` - hint: Disable this message with "git config advice.refSyntax false" + hint: Disable this message with "git config set advice.refSyntax false" EOF test_must_fail git branch foo..bar >actual 2>&1 && test_cmp expect actual diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index d2ca43d6aa..e091df6d01 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -908,4 +908,20 @@ test_expect_success 'submodule changes are shown irrespective of diff.submodule' test_cmp expect actual ' +test_expect_success '--diff-merges' ' + renamed_oid=$(git rev-parse --short renamed-file) && + tree=$(git merge-tree unmodified renamed-file) && + clean=$(git commit-tree -m merge -p unmodified -p renamed-file $tree) && + clean_oid=$(git rev-parse --short $clean) && + conflict=$(git commit-tree -m merge -p unmodified -p renamed-file^ $tree) && + conflict_oid=$(git rev-parse --short $conflict) && + + git range-diff --diff-merges=1 $clean...$conflict >actual && + cat >expect <<-EOF && + 1: $renamed_oid < -: ------- s/12/B/ + 2: $clean_oid = 1: $conflict_oid merge + EOF + test_cmp expect actual +' + test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index b11f04eb33..ecfc02062c 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -2258,20 +2258,20 @@ test_expect_success 'non-merge commands reject merge commits' ' error: ${SQ}pick${SQ} does not accept merge commits hint: ${SQ}pick${SQ} does not take a merge commit. If you wanted to hint: replay the merge, use ${SQ}merge -C${SQ} on the commit. - hint: Disable this message with "git config advice.rebaseTodoError false" + hint: Disable this message with "git config set advice.rebaseTodoError false" error: invalid line 1: pick $oid error: ${SQ}reword${SQ} does not accept merge commits hint: ${SQ}reword${SQ} does not take a merge commit. If you wanted to hint: replay the merge and reword the commit message, use hint: ${SQ}merge -c${SQ} on the commit - hint: Disable this message with "git config advice.rebaseTodoError false" + hint: Disable this message with "git config set advice.rebaseTodoError false" error: invalid line 2: reword $oid error: ${SQ}edit${SQ} does not accept merge commits hint: ${SQ}edit${SQ} does not take a merge commit. If you wanted to hint: replay the merge, use ${SQ}merge -C${SQ} on the commit, and then hint: ${SQ}break${SQ} to give the control back to you so that you can hint: do ${SQ}git commit --amend && git rebase --continue${SQ}. - hint: Disable this message with "git config advice.rebaseTodoError false" + hint: Disable this message with "git config set advice.rebaseTodoError false" error: invalid line 3: edit $oid error: cannot squash merge commit into another commit error: invalid line 4: fixup $oid diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh index 9e8c51b4e2..8025a28cfd 100755 --- a/t/t3501-revert-cherry-pick.sh +++ b/t/t3501-revert-cherry-pick.sh @@ -177,7 +177,7 @@ test_expect_success 'advice from failed revert' ' hint: You can instead skip this commit with "git revert --skip". hint: To abort and get back to the state before "git revert", hint: run "git revert --abort". - hint: Disable this message with "git config advice.mergeConflict false" + hint: Disable this message with "git config set advice.mergeConflict false" EOF test_commit --append --no-tag "double-add dream" dream dream && test_must_fail git revert HEAD^ 2>actual && diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh index f3947b400a..44596cb1e8 100755 --- a/t/t3507-cherry-pick-conflict.sh +++ b/t/t3507-cherry-pick-conflict.sh @@ -34,7 +34,7 @@ test_expect_success setup ' git commit --allow-empty --allow-empty-message && git tag empty && git checkout main && - git config advice.detachedhead false + git config set advice.detachedhead false ' @@ -60,7 +60,7 @@ test_expect_success 'advice from failed cherry-pick' ' hint: You can instead skip this commit with "git cherry-pick --skip". hint: To abort and get back to the state before "git cherry-pick", hint: run "git cherry-pick --abort". - hint: Disable this message with "git config advice.mergeConflict false" + hint: Disable this message with "git config set advice.mergeConflict false" EOF test_must_fail git cherry-pick picked 2>actual && @@ -75,7 +75,7 @@ test_expect_success 'advice from failed cherry-pick --no-commit' " error: could not apply \$picked... picked hint: after resolving the conflicts, mark the corrected paths hint: with 'git add <paths>' or 'git rm <paths>' - hint: Disable this message with \"git config advice.mergeConflict false\" + hint: Disable this message with \"git config set advice.mergeConflict false\" EOF test_must_fail git cherry-pick --no-commit picked 2>actual && diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh index 7eb52b12ed..66ff9db270 100755 --- a/t/t3510-cherry-pick-sequence.sh +++ b/t/t3510-cherry-pick-sequence.sh @@ -25,7 +25,7 @@ pristine_detach () { } test_expect_success setup ' - git config advice.detachedhead false && + git config set advice.detachedhead false && echo unrelated >unrelated && git add unrelated && test_commit initial foo a && diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh index 84a587daf3..98ef13f0a3 100755 --- a/t/t3511-cherry-pick-x.sh +++ b/t/t3511-cherry-pick-x.sh @@ -51,7 +51,7 @@ trailing empty lines " test_expect_success setup ' - git config advice.detachedhead false && + git config set advice.detachedhead false && echo unrelated >unrelated && git add unrelated && test_commit initial foo a && diff --git a/t/t3602-rm-sparse-checkout.sh b/t/t3602-rm-sparse-checkout.sh index 08580fd3dc..02c7acd617 100755 --- a/t/t3602-rm-sparse-checkout.sh +++ b/t/t3602-rm-sparse-checkout.sh @@ -20,7 +20,7 @@ test_expect_success 'setup' " hint: If you intend to update such entries, try one of the following: hint: * Use the --sparse option. hint: * Disable or modify the sparsity rules. - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF echo b | cat sparse_error_header - >sparse_entry_b_error && diff --git a/t/t3700-add.sh b/t/t3700-add.sh index 4c543a1a7e..df580a5806 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -31,7 +31,7 @@ test_expect_success 'Test with no pathspecs' ' cat >expect <<-EOF && Nothing specified, nothing added. hint: Maybe you wanted to say ${SQ}git add .${SQ}? - hint: Disable this message with "git config advice.addEmptyPathspec false" + hint: Disable this message with "git config set advice.addEmptyPathspec false" EOF git add 2>actual && test_cmp expect actual @@ -375,7 +375,7 @@ test_expect_success '"git add" a embedded repository' ' hint: git rm --cached inner1 hint: hint: See "git help submodule" for more information. - hint: Disable this message with "git config advice.addEmbeddedRepo false" + hint: Disable this message with "git config set advice.addEmbeddedRepo false" warning: adding embedded git repository: inner2 EOF test_cmp expect actual @@ -413,7 +413,7 @@ cat >expect.err <<\EOF The following paths are ignored by one of your .gitignore files: ignored-file hint: Use -f if you really want to add them. -hint: Disable this message with "git config advice.addIgnoredFile false" +hint: Disable this message with "git config set advice.addIgnoredFile false" EOF cat >expect.out <<\EOF add 'track-this' diff --git a/t/t3705-add-sparse-checkout.sh b/t/t3705-add-sparse-checkout.sh index 2bade9e804..53a4782267 100755 --- a/t/t3705-add-sparse-checkout.sh +++ b/t/t3705-add-sparse-checkout.sh @@ -54,7 +54,7 @@ test_expect_success 'setup' " hint: If you intend to update such entries, try one of the following: hint: * Use the --sparse option. hint: * Disable or modify the sparsity rules. - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF echo sparse_entry | cat sparse_error_header - >sparse_entry_error && diff --git a/t/t4069-remerge-diff.sh b/t/t4069-remerge-diff.sh index ca8f999cab..c6c94aef14 100755 --- a/t/t4069-remerge-diff.sh +++ b/t/t4069-remerge-diff.sh @@ -352,4 +352,11 @@ test_expect_success 'remerge-diff turns off history simplification' ' test_cmp expect actual ' +test_expect_success 'remerge-diff with --reverse' ' + git log -1 --remerge-diff --oneline ab_resolution^ >expect && + git log -1 --remerge-diff --oneline ab_resolution >>expect && + git log -2 --remerge-diff --oneline ab_resolution --reverse >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh index 0614511656..2e83cc820a 100755 --- a/t/t4207-log-decoration-colors.sh +++ b/t/t4207-log-decoration-colors.sh @@ -58,7 +58,8 @@ ${c_reset}${c_tag}tag: ${c_reset}${c_tag}v1.0${c_reset}${c_commit}, \ ${c_reset}${c_tag}tag: ${c_reset}${c_tag}B${c_reset}${c_commit})${c_reset} B ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ ${c_tag}tag: ${c_reset}${c_tag}A1${c_reset}${c_commit}, \ -${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit})${c_reset} A1 +${c_reset}${c_remoteBranch}other/main${c_reset}${c_commit}, \ +${c_reset}${c_remoteBranch}other/HEAD${c_reset}${c_commit})${c_reset} A1 ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ ${c_stash}refs/stash${c_reset}${c_commit})${c_reset} On main: Changes to A.t ${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_reset}\ diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index 53dc3cbf90..d1d6248558 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -525,6 +525,24 @@ test_expect_success 'index-pack --strict <pack> works in non-repo' ' test_path_is_file foo.idx ' +test_expect_success SHA1 'show-index works OK outside a repository' ' + nongit git show-index <foo.idx +' + +for hash in sha1 sha256 +do + test_expect_success 'show-index works OK outside a repository with hash algo passed in via --object-format' ' + test_when_finished "rm -rf explicit-hash-$hash" && + git init --object-format=$hash explicit-hash-$hash && + test_commit -C explicit-hash-$hash one && + git -C explicit-hash-$hash rev-parse one >in && + git -C explicit-hash-$hash pack-objects explicit-hash-$hash <in && + idx=$(echo explicit-hash-$hash/explicit-hash-$hash*.idx) && + nongit git show-index --object-format=$hash <"$idx" >actual && + test_line_count = 1 actual + ' +done + test_expect_success !PTHREADS,!FAIL_PREREQS \ 'index-pack --threads=N or pack.threads=N warns when no pthreads' ' test_must_fail git index-pack --threads=2 2>err && diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index 53dbc8ce3a..8212a70be8 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -170,7 +170,7 @@ test_expect_success 'fsck with invalid or bogus skipList input' ' test_must_fail git -c fsck.skipList=does-not-exist -c fsck.missingEmail=ignore fsck 2>err && test_grep "could not open.*: does-not-exist" err && test_must_fail git -c fsck.skipList=.git/config -c fsck.missingEmail=ignore fsck 2>err && - test_grep "invalid object name: \[core\]" err + test_grep "invalid object name: " err ' test_expect_success 'fsck with other accepted skipList input (comments & empty lines)' ' @@ -233,7 +233,7 @@ test_expect_success 'push with receive.fsck.skipList' ' test_grep "could not open.*: does-not-exist" err && git --git-dir=dst/.git config receive.fsck.skipList config && test_must_fail git push --porcelain dst bogus 2>err && - test_grep "invalid object name: \[core\]" err && + test_grep "invalid object name: " err && git --git-dir=dst/.git config receive.fsck.skipList SKIP && git push --porcelain dst bogus @@ -262,7 +262,7 @@ test_expect_success 'fetch with fetch.fsck.skipList' ' test_grep "could not open.*: does-not-exist" err && git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/config && test_must_fail git --git-dir=dst/.git fetch "file://$(pwd)" $refspec 2>err && - test_grep "invalid object name: \[core\]" err && + test_grep "invalid object name: " err && git --git-dir=dst/.git config fetch.fsck.skipList dst/.git/SKIP && git --git-dir=dst/.git fetch "file://$(pwd)" $refspec diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 08424e878e..519f7973e3 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -2,6 +2,9 @@ test_description='git remote porcelain-ish' +GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main +export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME + . ./test-lib.sh setup_repository () { @@ -70,7 +73,7 @@ test_expect_success 'add another remote' ' cd test && git remote add -f second ../two && tokens_match "origin second" "$(git remote)" && - check_tracking_branch second main side another && + check_tracking_branch second main side another HEAD && git for-each-ref "--format=%(refname)" refs/remotes | sed -e "/^refs\/remotes\/origin\//d" \ -e "/^refs\/remotes\/second\//d" >actual && @@ -428,16 +431,90 @@ test_expect_success 'set-head --auto' ' ) ' +test_expect_success REFFILES 'set-head --auto failure' ' + test_when_finished "rm -f test/.git/refs/remotes/origin/HEAD.lock" && + ( + cd test && + touch .git/refs/remotes/origin/HEAD.lock && + test_must_fail git remote set-head --auto origin 2>err && + tail -n1 err >output && + echo "error: Could not set up refs/remotes/origin/HEAD" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects creation' ' + ( + cd test && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} is now created and points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto to update a non symbolic ref' ' + ( + cd test && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git update-ref refs/remotes/origin/HEAD HEAD && + HEAD=$(git log --pretty="%H") && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} was detached at ${SQ}${HEAD}${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects no change' ' + ( + cd test && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} is unchanged and points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects change' ' + ( + cd test && + git symbolic-ref refs/remotes/origin/HEAD refs/remotes/origin/ahead && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} has changed from ${SQ}ahead${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + +test_expect_success 'set-head --auto detects strange ref' ' + ( + cd test && + git symbolic-ref refs/remotes/origin/HEAD refs/heads/main && + git remote set-head --auto origin >output && + echo "${SQ}origin/HEAD${SQ} used to point to ${SQ}refs/heads/main${SQ} (which is not a remote branch), but now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + test_expect_success 'set-head --auto has no problem w/multiple HEADs' ' ( cd test && git fetch two "refs/heads/*:refs/remotes/two/*" && git remote set-head --auto two >output 2>&1 && - echo "two/HEAD set to main" >expect && + echo "${SQ}two/HEAD${SQ} is unchanged and points to ${SQ}main${SQ}" >expect && test_cmp expect output ) ' +test_expect_success 'set-head changes followRemoteHEAD always to warn' ' + ( + cd test && + git config set remote.origin.followRemoteHEAD "always" && + git remote set-head --auto origin && + git config get remote.origin.followRemoteHEAD >actual && + echo "warn" >expect && + test_cmp expect actual + ) +' + cat >test/expect <<\EOF refs/remotes/origin/side2 EOF @@ -452,6 +529,16 @@ test_expect_success 'set-head explicit' ' ) ' +test_expect_success 'set-head --auto reports change' ' + ( + cd test && + git remote set-head origin side2 && + git remote set-head --auto origin >output 2>&1 && + echo "${SQ}origin/HEAD${SQ} has changed from ${SQ}side2${SQ} and now points to ${SQ}main${SQ}" >expect && + test_cmp expect output + ) +' + cat >test/expect <<EOF Pruning origin URL: $(pwd)/one @@ -492,6 +579,16 @@ test_expect_success 'add --mirror && prune' ' ) ' +test_expect_success 'add --mirror setting HEAD' ' + mkdir headmirror && + ( + cd headmirror && + git init --bare -b notmain && + git remote add --mirror -f origin ../one && + test "$(git symbolic-ref HEAD)" = "refs/heads/main" + ) +' + test_expect_success 'add --mirror=fetch' ' mkdir mirror-fetch && git init -b main mirror-fetch/parent && @@ -711,8 +808,10 @@ test_expect_success 'reject --no-no-tags' ' ' cat >one/expect <<\EOF + apis/HEAD -> apis/main apis/main apis/side + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side @@ -730,11 +829,14 @@ test_expect_success 'update' ' ' cat >one/expect <<\EOF + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side + manduca/HEAD -> manduca/main manduca/main manduca/side + megaloprepus/HEAD -> megaloprepus/main megaloprepus/main megaloprepus/side EOF @@ -742,7 +844,7 @@ EOF test_expect_success 'update with arguments' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -774,10 +876,13 @@ test_expect_success 'update --prune' ' ' cat >one/expect <<-\EOF + apis/HEAD -> apis/main apis/main apis/side + manduca/HEAD -> manduca/main manduca/main manduca/side + megaloprepus/HEAD -> megaloprepus/main megaloprepus/main megaloprepus/side EOF @@ -785,7 +890,7 @@ EOF test_expect_success 'update default' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -797,6 +902,7 @@ test_expect_success 'update default' ' ' cat >one/expect <<\EOF + drosophila/HEAD -> drosophila/main drosophila/another drosophila/main drosophila/side @@ -805,7 +911,7 @@ EOF test_expect_success 'update default (overridden, with funny whitespace)' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -819,7 +925,7 @@ test_expect_success 'update default (overridden, with funny whitespace)' ' test_expect_success 'update (with remotes.default defined)' ' ( cd one && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 3b3991ab86..2d9587059f 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -74,6 +74,168 @@ test_expect_success "fetch test for-merge" ' cut -f -2 .git/FETCH_HEAD >actual && test_cmp expected actual' +test_expect_success "fetch test remote HEAD" ' + cd "$D" && + cd two && + git fetch && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch"' + +test_expect_success "fetch test remote HEAD change" ' + cd "$D" && + cd two && + git switch -c other && + git push -u origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git fetch && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch"' + +test_expect_success "fetch test followRemoteHEAD never" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git config set remote.origin.followRemoteHEAD "never" && + git fetch && + test_must_fail git rev-parse --verify refs/remotes/origin/HEAD + ) +' + +test_expect_success "fetch test followRemoteHEAD warn no change" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn" && + git fetch >output && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have ${SQ}other${SQ} locally." >expect && + test_cmp expect output && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn create" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git config set remote.origin.followRemoteHEAD "warn" && + git rev-parse --verify refs/remotes/origin/main && + output=$(git fetch) && + test "z" = "z$output" && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn detached" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git update-ref --no-deref -d refs/remotes/origin/HEAD && + git update-ref refs/remotes/origin/HEAD HEAD && + HEAD=$(git log --pretty="%H") && + git config set remote.origin.followRemoteHEAD "warn" && + git fetch >output && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have a detached HEAD pointing to" \ + "${SQ}${HEAD}${SQ} locally." >expect && + test_cmp expect output + ) +' + +test_expect_success "fetch test followRemoteHEAD warn quiet" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn" && + output=$(git fetch --quiet) && + test "z" = "z$output" && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is same" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn-if-not-main" && + actual=$(git fetch) && + test "z" = "z$actual" && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is different" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "warn-if-not-some/different-branch" && + git fetch >actual && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have ${SQ}other${SQ} locally." >expect && + test_cmp expect actual && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" + ) +' + +test_expect_success "fetch test followRemoteHEAD always" ' + test_when_finished "git config unset remote.origin.followRemoteHEAD" && + ( + cd "$D" && + cd two && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + git config set remote.origin.followRemoteHEAD "always" && + git fetch && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch" + ) +' + test_expect_success 'fetch --prune on its own works as expected' ' cd "$D" && git clone . prune && @@ -164,6 +326,23 @@ test_expect_success 'fetch --prune --tags with refspec prunes based on refspec' git rev-parse sometag ' +test_expect_success 'fetch --tags gets tags even without a configured remote' ' + REMOTE="$(pwd)/test_tag_1" && + git init test_tag_1 && + ( + cd test_tag_1 && + test_commit foo + ) && + git init test_tag_2 && + ( + cd test_tag_2 && + git fetch --tags "file://$REMOTE" && + echo "foo" >expect && + git tag >actual && + test_cmp expect actual + ) +' + test_expect_success REFFILES 'fetch --prune fails to delete branches' ' cd "$D" && git clone . prune-fail && diff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh index 3a67992a7d..5930f55186 100755 --- a/t/t5512-ls-remote.sh +++ b/t/t5512-ls-remote.sh @@ -292,6 +292,8 @@ test_expect_success 'ls-remote with filtered symref (refname)' ' cat >expect <<-EOF && ref: refs/heads/main HEAD $rev HEAD + ref: refs/remotes/origin/main refs/remotes/origin/HEAD + $rev refs/remotes/origin/HEAD EOF git ls-remote --symref . HEAD >actual && test_cmp expect actual diff --git a/t/t5514-fetch-multiple.sh b/t/t5514-fetch-multiple.sh index 25772c85c5..523aff6268 100755 --- a/t/t5514-fetch-multiple.sh +++ b/t/t5514-fetch-multiple.sh @@ -44,14 +44,17 @@ test_expect_success setup ' ' cat > test/expect << EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -96,6 +99,7 @@ cat > expect << EOF origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side @@ -111,8 +115,10 @@ test_expect_success 'git fetch --multiple (but only one remote)' ' ' cat > expect << EOF + one/HEAD -> one/main one/main one/side + two/HEAD -> two/main two/another two/main two/side @@ -140,7 +146,7 @@ test_expect_success 'git fetch --multiple (bad remote names)' ' test_expect_success 'git fetch --all (skipFetchAll)' ' (cd test4 && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -152,11 +158,14 @@ test_expect_success 'git fetch --all (skipFetchAll)' ' ' cat > expect << EOF + one/HEAD -> one/main one/main one/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -164,7 +173,7 @@ EOF test_expect_success 'git fetch --multiple (ignoring skipFetchAll)' ' (cd test4 && - for b in $(git branch -r) + for b in $(git branch -r | grep -v HEAD) do git branch -r -d $b || exit 1 done && @@ -220,14 +229,17 @@ test_expect_success 'git fetch --multiple --jobs=0 picks a default' ' create_fetch_all_expect () { cat >expect <<-\EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main origin/main origin/side + three/HEAD -> three/main three/another three/main three/side + two/HEAD -> two/main two/another two/main two/side @@ -264,6 +276,7 @@ test_expect_success 'git fetch (fetch all remotes with fetch.all = true)' ' create_fetch_one_expect () { cat >expect <<-\EOF + one/HEAD -> one/main one/main one/side origin/HEAD -> origin/main diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 9d693eb57f..041d7d806f 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1394,7 +1394,8 @@ test_expect_success 'fetch follows tags by default' ' git tag -m "annotated" tag && git for-each-ref >tmp1 && sed -n "p; s|refs/heads/main$|refs/remotes/origin/main|p" tmp1 | - sort -k 3 >../expect + sed -n "p; s|refs/heads/main$|refs/remotes/origin/HEAD|p" | + sort -k 4 >../expect ) && test_when_finished "rm -rf dst" && git init dst && diff --git a/t/t5527-fetch-odd-refs.sh b/t/t5527-fetch-odd-refs.sh index e2770e4541..0de8eb5b6f 100755 --- a/t/t5527-fetch-odd-refs.sh +++ b/t/t5527-fetch-odd-refs.sh @@ -51,7 +51,8 @@ test_expect_success LONG_REF 'fetch handles extremely long refname' ' long main EOF - git for-each-ref --format="%(subject)" refs/remotes/long >actual && + git for-each-ref --format="%(subject)" refs/remotes/long \ + --exclude=refs/remotes/long/HEAD >actual && test_cmp expect actual ' diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index fa5ca4f522..470bfb610c 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -130,7 +130,7 @@ test_expect_success 'cloning with multiple references drops duplicates' ' test_expect_success 'clone with reference from a tagged repository' ' ( - cd A && git tag -a -m tagged HEAD + cd A && git tag -a -m tagged foo ) && git clone --reference=A A I ' @@ -155,10 +155,10 @@ test_expect_success 'fetch with incomplete alternates' ' git remote add J "file://$base_dir/J" && GIT_TRACE_PACKET=$U.K git fetch J ) && - main_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/main) && + main_object=$(git -C A rev-parse --verify refs/heads/main) && test -s "$U.K" && ! grep " want $main_object" "$U.K" && - tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) && + tag_object=$(git -C A rev-parse --verify refs/tags/foo) && ! grep " want $tag_object" "$U.K" ' diff --git a/t/t5605-clone-local.sh b/t/t5605-clone-local.sh index 339d8c786f..4605703496 100755 --- a/t/t5605-clone-local.sh +++ b/t/t5605-clone-local.sh @@ -153,6 +153,16 @@ test_expect_success 'cloning a local path with --no-local does not hardlink' ' ! repo_is_hardlinked force-nonlocal ' +test_expect_success 'cloning a local path with --no-local from a different user succeeds' ' + git clone --upload-pack="GIT_TEST_ASSUME_DIFFERENT_OWNER=true git-upload-pack" \ + --no-local a nonlocal-otheruser 2>err && + ! repo_is_hardlinked nonlocal-otheruser && + # Verify that this is a git repository. + git -C nonlocal-otheruser rev-parse --show-toplevel && + ! test_grep "detected dubious ownership" err + +' + test_expect_success 'cloning locally respects "-u" for fetching refs' ' test_must_fail git clone --bare -u false a should_not_work.git ' diff --git a/t/t5607-clone-bundle.sh b/t/t5607-clone-bundle.sh index 489c6570da..82e3621ec5 100755 --- a/t/t5607-clone-bundle.sh +++ b/t/t5607-clone-bundle.sh @@ -170,6 +170,13 @@ test_expect_success 'clone bundle with different fsckObjects configurations' ' test_must_fail git -c transfer.fsckObjects=true \ clone bundle-fsck/bad.bundle bundle-transfer-fsck 2>err && + test_grep "missingEmail" err && + + git -c fetch.fsckObjects=true -c fetch.fsck.missingEmail=ignore \ + clone bundle-fsck/bad.bundle bundle-fsck-ignore && + + test_must_fail git -c fetch.fsckObjects=true -c fetch.fsck.missingEmail=error \ + clone bundle-fsck/bad.bundle bundle-fsck-error 2>err && test_grep "missingEmail" err ' diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh index 5d444bfe20..4ce62feaa2 100755 --- a/t/t6020-bundle-misc.sh +++ b/t/t6020-bundle-misc.sh @@ -504,6 +504,50 @@ test_expect_success 'unfiltered bundle with --objects' ' test_cmp expect actual ' +test_expect_success 'full bundle upto annotated tag' ' + git bundle create v2.bdl \ + v2 && + + git bundle verify v2.bdl | + make_user_friendly_and_stable_output >actual && + + format_and_save_expect <<-EOF && + The bundle contains this ref: + <TAG-2> refs/tags/v2 + The bundle records a complete history. + $HASH_MESSAGE + EOF + test_cmp expect actual +' + +test_expect_success 'clone from full bundle upto annotated tag' ' + git clone --mirror v2.bdl tag-clone.git && + git -C tag-clone.git show-ref | + make_user_friendly_and_stable_output >actual && + cat >expect <<-\EOF && + <TAG-2> refs/tags/v2 + EOF + test_cmp expect actual +' + +test_expect_success 'incremental bundle between two annotated tags' ' + git bundle create v1-v2.bdl \ + v1..v2 && + + git bundle verify v1-v2.bdl | + make_user_friendly_and_stable_output >actual && + + format_and_save_expect <<-EOF && + The bundle contains this ref: + <TAG-2> refs/tags/v2 + The bundle requires these 2 refs: + <COMMIT-E> Z + <COMMIT-B> Z + $HASH_MESSAGE + EOF + test_cmp expect actual +' + for filter in "blob:none" "tree:0" "tree:1" "blob:limit=100" do test_expect_success "filtered bundle: $filter" ' diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 79e0f19deb..3f6160d702 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -18,6 +18,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME check_describe () { indir= && + outcome=success && while test $# != 0 do case "$1" in @@ -25,6 +26,9 @@ check_describe () { indir="$2" shift ;; + --expect-failure) + outcome=failure + ;; *) break ;; @@ -35,7 +39,7 @@ check_describe () { expect="$1" shift describe_opts="$@" - test_expect_success "describe $describe_opts" ' + test_expect_${outcome} "describe $describe_opts" ' git ${indir:+ -C "$indir"} describe $describe_opts >raw && sed -e "s/-g[0-9a-f]*\$/-gHASH/" <raw >actual && echo "$expect" >expect && @@ -616,7 +620,7 @@ test_expect_success 'name-rev --annotate-stdin works with commitGraph' ' # B # o -# \ +# H \ # o-----o---o----x # A # @@ -626,6 +630,7 @@ test_expect_success 'setup: describe commits with disjoint bases' ' cd disjoint1 && echo o >> file && git add file && git commit -m o && + git tag H -a -m H && echo A >> file && git add file && git commit -m A && git tag A -a -m A && echo o >> file && git add file && git commit -m o && @@ -638,8 +643,9 @@ test_expect_success 'setup: describe commits with disjoint bases' ' ' check_describe -C disjoint1 "A-3-gHASH" HEAD +check_describe -C disjoint1 --expect-failure "A-3-gHASH" --candidates=2 HEAD -# B +# H B # o---o---o------------. # \ # o---o---x @@ -657,6 +663,7 @@ test_expect_success 'setup: describe commits with disjoint bases 2' ' git checkout --orphan branch && echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:00" git commit -m o && echo o >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:01" git commit -m o && + git tag H -a -m H && echo B >> file2 && git add file2 && GIT_COMMITTER_DATE="2020-01-01 15:02" git commit -m B && git tag B -a -m B && git merge --no-ff --allow-unrelated-histories main -m x @@ -664,6 +671,7 @@ test_expect_success 'setup: describe commits with disjoint bases 2' ' ' check_describe -C disjoint2 "B-3-gHASH" HEAD +check_describe -C disjoint2 --expect-failure "B-3-gHASH" --candidates=2 HEAD test_expect_success 'setup misleading taggerdates' ' GIT_COMMITTER_DATE="2006-12-12 12:31" git tag -a -m "another tag" newer-tag-older-commit unique-file~1 @@ -707,4 +715,14 @@ test_expect_success 'describe --broken --dirty with a file with changed stat' ' ) ' +test_expect_success '--always with no refs falls back to commit hash' ' + git rev-parse HEAD >expect && + git describe --no-abbrev --always --match=no-such-tag >actual && + test_cmp expect actual +' + +test_expect_success '--exact-match does not show --always fallback' ' + test_must_fail git describe --exact-match --always +' + test_done diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh index 26582ae4e5..4d3f221224 100755 --- a/t/t7002-mv-sparse-checkout.sh +++ b/t/t7002-mv-sparse-checkout.sh @@ -32,7 +32,7 @@ test_expect_success 'setup' " hint: If you intend to update such entries, try one of the following: hint: * Use the --sparse option. hint: * Disable or modify the sparsity rules. - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF cat >dirty_error_header <<-EOF && @@ -45,7 +45,7 @@ test_expect_success 'setup' " hint: To correct the sparsity of these paths, do the following: hint: * Use \"git add --sparse <paths>\" to update the index hint: * Use \"git sparse-checkout reapply\" to apply the sparsity rules - hint: Disable this message with \"git config advice.updateSparsePath false\" + hint: Disable this message with \"git config set advice.updateSparsePath false\" EOF " diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index b1316e62f4..10835631ca 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -91,6 +91,18 @@ test_expect_success 'creating a tag using default HEAD should succeed' ' test_must_fail git reflog exists refs/tags/mytag ' +test_expect_success 'HEAD is forbidden as a tagname' ' + test_when_finished "git update-ref --no-deref -d refs/tags/HEAD || :" && + test_must_fail git tag HEAD && + test_must_fail git tag -a -m "useless" HEAD +' + +test_expect_success '"git tag" can remove a tag named HEAD' ' + test_when_finished "git update-ref --no-deref -d refs/tags/HEAD || :" && + git update-ref refs/tags/HEAD HEAD && + git tag -d HEAD +' + test_expect_success 'creating a tag with --create-reflog should create reflog' ' git log -1 \ --format="format:tag: tagging %h (%s, %cd)%n" \ @@ -1850,7 +1862,7 @@ test_expect_success 'recursive tagging should give advice' ' hint: already a tag. If you meant to tag the object that it points to, use: hint: hint: git tag -f nested annotated-v4.0^{} - hint: Disable this message with "git config advice.nestedTag false" + hint: Disable this message with "git config set advice.nestedTag false" EOF git tag -m nested nested annotated-v4.0 2>actual && test_cmp expect actual diff --git a/t/t7201-co.sh b/t/t7201-co.sh index 793da6e64e..9bcf7c0b40 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -224,7 +224,7 @@ test_expect_success 'switch to another branch while carrying a deletion' ' ' test_expect_success 'checkout to detach HEAD (with advice declined)' ' - git config advice.detachedHead false && + git config set advice.detachedHead false && rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && @@ -244,7 +244,7 @@ test_expect_success 'checkout to detach HEAD (with advice declined)' ' ' test_expect_success 'checkout to detach HEAD' ' - git config advice.detachedHead true && + git config set advice.detachedHead true && rev=$(git rev-parse --short renamer^) && git checkout -f renamer && git clean -f && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 981488885f..d6a501d453 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -212,7 +212,7 @@ test_expect_success 'submodule add to .gitignored path fails' ' The following paths are ignored by one of your .gitignore files: submod hint: Use -f if you really want to add them. - hint: Disable this message with "git config advice.addIgnoredFile false" + hint: Disable this message with "git config set advice.addIgnoredFile false" EOF # Does not use test_commit due to the ignore echo "*" > .gitignore && diff --git a/t/t7508-status.sh b/t/t7508-status.sh index f9a5c98f3f..b2070d4e39 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -1699,7 +1699,7 @@ test_expect_success 'setup slow status advice' ' EOF git add .gitignore && git commit -m "Add .gitignore" && - git config advice.statusuoption true + git config set advice.statusuoption true ) ' diff --git a/t/t7609-mergetool--lib.sh b/t/t7609-mergetool--lib.sh index 330d6d603d..e8e205707e 100755 --- a/t/t7609-mergetool--lib.sh +++ b/t/t7609-mergetool--lib.sh @@ -7,7 +7,7 @@ Testing basic merge tools options' . ./test-lib.sh test_expect_success 'mergetool --tool=vimdiff creates the expected layout' ' - . "$GIT_BUILD_DIR"/mergetools/vimdiff && + . "$GIT_TEST_MERGE_TOOLS_DIR"/vimdiff && run_unit_tests ' diff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh index 22b3a85b3e..c077aba7ce 100755 --- a/t/t7610-mergetool.sh +++ b/t/t7610-mergetool.sh @@ -898,4 +898,12 @@ test_expect_success 'mergetool with guiDefault' ' git commit -m "branch1 resolved with mergetool" ' +test_expect_success 'mergetool with non-existent tool' ' + test_when_finished "git reset --hard" && + git checkout -b test$test_count branch1 && + test_must_fail git merge main && + yes "" | test_must_fail git mergetool --tool=absent >out 2>&1 && + test_grep "mergetool.absent.cmd not set for tool" out +' + test_done diff --git a/t/t7611-merge-abort.sh b/t/t7611-merge-abort.sh index d6975ca48d..1a251485e1 100755 --- a/t/t7611-merge-abort.sh +++ b/t/t7611-merge-abort.sh @@ -54,13 +54,13 @@ test_expect_success 'fails without MERGE_HEAD (unstarted merge)' ' ' test_expect_success 'fails without MERGE_HEAD (unstarted merge): .git/MERGE_HEAD sanity' ' - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" ' test_expect_success 'fails without MERGE_HEAD (completed merge)' ' git merge clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && # Merge successfully completed post_merge_head="$(git rev-parse HEAD)" && test_must_fail git merge --abort 2>output && @@ -68,7 +68,7 @@ test_expect_success 'fails without MERGE_HEAD (completed merge)' ' ' test_expect_success 'fails without MERGE_HEAD (completed merge): .git/MERGE_HEAD sanity' ' - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$post_merge_head" = "$(git rev-parse HEAD)" ' @@ -79,10 +79,10 @@ test_expect_success 'Forget previous merge' ' test_expect_success 'Abort after --no-commit' ' # Redo merge, but stop before creating merge commit git merge --no-commit clean_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort non-conflicting merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && test -z "$(git diff --staged)" @@ -91,10 +91,10 @@ test_expect_success 'Abort after --no-commit' ' test_expect_success 'Abort after conflicts' ' # Create conflicting merge test_must_fail git merge conflict_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort conflicting merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && test -z "$(git diff --staged)" @@ -105,7 +105,7 @@ test_expect_success 'Clean merge with dirty index fails' ' git add foo && git diff --staged > expect && test_must_fail git merge clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && git diff --staged > actual && @@ -114,7 +114,7 @@ test_expect_success 'Clean merge with dirty index fails' ' test_expect_success 'Conflicting merge with dirty index fails' ' test_must_fail git merge conflict_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff)" && git diff --staged > actual && @@ -129,10 +129,10 @@ test_expect_success 'Reset index (but preserve worktree changes)' ' test_expect_success 'Abort clean merge with non-conflicting dirty worktree' ' git merge --no-commit clean_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -141,10 +141,10 @@ test_expect_success 'Abort clean merge with non-conflicting dirty worktree' ' test_expect_success 'Abort conflicting merge with non-conflicting dirty worktree' ' test_must_fail git merge conflict_branch && - test -f .git/MERGE_HEAD && + test_path_is_file .git/MERGE_HEAD && # Abort merge git merge --abort && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -159,7 +159,7 @@ test_expect_success 'Fail clean merge with conflicting dirty worktree' ' echo xyzzy >> bar && git diff > expect && test_must_fail git merge --no-commit clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -168,7 +168,7 @@ test_expect_success 'Fail clean merge with conflicting dirty worktree' ' test_expect_success 'Fail conflicting merge with conflicting dirty worktree' ' test_must_fail git merge conflict_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -183,7 +183,7 @@ test_expect_success 'Fail clean merge with matching dirty worktree' ' echo bart > bar && git diff > expect && test_must_fail git merge --no-commit clean_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && @@ -194,7 +194,7 @@ test_expect_success 'Fail conflicting merge with matching dirty worktree' ' echo barf > bar && git diff > expect && test_must_fail git merge conflict_branch && - test ! -f .git/MERGE_HEAD && + test_path_is_missing .git/MERGE_HEAD && test "$pre_merge_head" = "$(git rev-parse HEAD)" && test -z "$(git diff --staged)" && git diff > actual && diff --git a/t/t7900-maintenance.sh b/t/t7900-maintenance.sh index 0ce4ba1cbe..1909aed95e 100755 --- a/t/t7900-maintenance.sh +++ b/t/t7900-maintenance.sh @@ -328,7 +328,8 @@ test_expect_success 'incremental-repack task' ' # Delete refs that have not been repacked in these packs. git for-each-ref --format="delete %(refname)" \ - refs/prefetch refs/tags refs/remotes >refs && + refs/prefetch refs/tags refs/remotes \ + --exclude=refs/remotes/*/HEAD >refs && git update-ref --stdin <refs && # Replace the object directory with this pack layout. diff --git a/t/t9210-scalar.sh b/t/t9210-scalar.sh index 027235d61a..a81662713e 100755 --- a/t/t9210-scalar.sh +++ b/t/t9210-scalar.sh @@ -150,7 +150,8 @@ test_expect_success 'scalar clone' ' "$(pwd)" && git for-each-ref --format="%(refname)" refs/remotes/origin/ >actual && - echo "refs/remotes/origin/parallel" >expect && + echo "refs/remotes/origin/HEAD" >>expect && + echo "refs/remotes/origin/parallel" >>expect && test_cmp expect actual && test_path_is_missing 1/2 && @@ -219,7 +220,7 @@ test_expect_success 'scalar reconfigure --all with includeIf.onbranch' ' done ' - test_expect_success 'scalar reconfigure --all with detached HEADs' ' +test_expect_success 'scalar reconfigure --all with detached HEADs' ' repos="two three four" && for num in $repos do diff --git a/t/t9211-scalar-clone.sh b/t/t9211-scalar-clone.sh index 7869f45ee6..01f71910f5 100755 --- a/t/t9211-scalar-clone.sh +++ b/t/t9211-scalar-clone.sh @@ -31,7 +31,7 @@ test_expect_success 'set up repository to clone' ' ) ' -cleanup_clone () { +cleanup_clone() { rm -rf "$1" } @@ -127,7 +127,7 @@ test_expect_success '--single-branch clones HEAD only' ' ( cd $enlistment/src && git for-each-ref refs/remotes/origin >out && - test_line_count = 1 out && + test_line_count = 2 out && grep "refs/remotes/origin/base" out ) && @@ -141,7 +141,7 @@ test_expect_success '--no-single-branch clones all branches' ' ( cd $enlistment/src && git for-each-ref refs/remotes/origin >out && - test_line_count = 2 out && + test_line_count = 3 out && grep "refs/remotes/origin/base" out && grep "refs/remotes/origin/parallel" out ) && diff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh index 27b2025f40..b258dbf1df 100755 --- a/t/t9300-fast-import.sh +++ b/t/t9300-fast-import.sh @@ -521,6 +521,113 @@ test_expect_success 'B: fail on invalid committer (5)' ' test_must_fail git fast-import <input ' +test_expect_success 'B: fail on invalid file path of ..' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 100644 :1 ../invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: fail on invalid file path of .' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Good path + COMMIT + M 100644 :1 ok-path + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Bad path + COMMIT + R ok-path ./invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success WINDOWS 'B: fail on invalid file path of C:' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 100644 :1 C:/invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: fail on invalid file path of .git' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 100644 :1 .git/invalid-path + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + +test_expect_success 'B: fail on invalid file path of .gitmodules' ' + cat >input <<-INPUT_END && + blob + mark :1 + data <<EOF + File contents + EOF + + commit refs/heads/badpath + committer Name <email> $GIT_COMMITTER_DATE + data <<COMMIT + Commit Message + COMMIT + M 120000 :1 .gitmodules + INPUT_END + + test_when_finished "git update-ref -d refs/heads/badpath" && + test_must_fail git fast-import <input +' + ### ### series C ### @@ -945,7 +1052,7 @@ test_expect_success 'L: verify internal tree sorting' ' :100644 100644 M ba EXPECT_END - git fast-import <input && + git -c core.protectNTFS=false fast-import <input && GIT_PRINT_SHA1_ELLIPSIS="yes" git diff-tree --abbrev --raw L^ L >output && cut -d" " -f1,2,5 output >actual && test_cmp expect actual @@ -3096,7 +3203,7 @@ test_path_eol_success () { test_expect_success "S: paths at EOL with $test must work" ' test_when_finished "git branch -D S-path-eol" && - git fast-import --export-marks=marks.out <<-EOF >out 2>err && + git -c core.protectNTFS=false fast-import --export-marks=marks.out <<-EOF >out 2>err && blob mark :401 data <<BLOB @@ -3205,7 +3312,7 @@ test_path_space_success () { test_expect_success "S: paths before space with $test must work" ' test_when_finished "git branch -D S-path-space" && - git fast-import --export-marks=marks.out <<-EOF 2>err && + git -c core.protectNTFS=false fast-import --export-marks=marks.out <<-EOF 2>err && blob mark :401 data <<BLOB diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index aa33791b77..40427883ec 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -631,7 +631,7 @@ test_expect_success 'fast-export quotes pathnames' ' git rev-list HEAD >expect && git init result && cd result && - git fast-import <../export.out && + git -c core.protectNTFS=false fast-import <../export.out && git rev-list HEAD >actual && test_cmp ../expect actual ) diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh index 036bf79c66..6116f806f6 100755 --- a/t/t9835-git-p4-metadata-encoding-python2.sh +++ b/t/t9835-git-p4-metadata-encoding-python2.sh @@ -8,29 +8,29 @@ failing, and produces maximally sane output in git.' . ./lib-git-p4.sh -python_target_version='2' - ############################### ## SECTION REPEATED IN t9836 ## ############################### -# Please note: this test calls "git-p4.py" rather than "git-p4", because the -# latter references a specific path so we can't easily force it to run under -# the python version we need to. - -python_major_version=$(python -V 2>&1 | cut -c 8) -python_target_binary=$(which python$python_target_version) -if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary" +# These tests are specific to Python 2. Write a custom script that executes +# git-p4 directly with the Python 2 interpreter to ensure that we use that +# version even if Git was compiled with Python 3. +python_target_binary=$(which python2) +if test -n "$python_target_binary" then mkdir temp_python - PATH="$(pwd)/temp_python:$PATH" && export PATH - ln -s $python_target_binary temp_python/python + PATH="$(pwd)/temp_python:$PATH" + export PATH + + write_script temp_python/git-p4-python2 <<-EOF + exec "$python_target_binary" "$(git --exec-path)/git-p4" "\$@" + EOF fi -python_major_version=$(python -V 2>&1 | cut -c 8) -if ! test "$python_major_version" = "$python_target_version" +git p4-python2 >err +if ! grep 'valid commands' err then - skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available" + skip_all="skipping python2 git p4 tests; python2 not available" test_done fi @@ -81,14 +81,14 @@ test_expect_success 'init depot' ' test_expect_success 'clone non-utf8 repo with strict encoding' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err && + test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python2 clone --dest="$git" //depot@all 2>err && grep "Decoding perforce metadata failed!" err ' test_expect_success 'check utf-8 contents with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -100,7 +100,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' ' test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -114,7 +114,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st test_expect_success 'check utf-8 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -126,7 +126,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' ' test_expect_success 'check latin-1 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -138,7 +138,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' ' test_expect_success 'check cp-1252 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -150,7 +150,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' ' test_expect_success 'check cp850 contents parsed with correct fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -162,7 +162,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' ' test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -174,7 +174,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest="$git" //depot@all && ( cd "$cli" && P4USER=cp1252_author && @@ -186,7 +186,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb ( cd "$git" && - git p4.py sync --branch=master && + git p4-python2 sync --branch=master && git log p4/master >actual && grep "sÅ“me more cp-1252 tæxt" actual && @@ -201,7 +201,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb test_expect_success 'passthrough (latin-1 contents corrupted in git) is the default with python2' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && diff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh index 63350dc4b5..5e5217a66b 100755 --- a/t/t9836-git-p4-metadata-encoding-python3.sh +++ b/t/t9836-git-p4-metadata-encoding-python3.sh @@ -8,29 +8,29 @@ failing, and produces maximally sane output in git.' . ./lib-git-p4.sh -python_target_version='3' - ############################### ## SECTION REPEATED IN t9835 ## ############################### -# Please note: this test calls "git-p4.py" rather than "git-p4", because the -# latter references a specific path so we can't easily force it to run under -# the python version we need to. - -python_major_version=$(python -V 2>&1 | cut -c 8) -python_target_binary=$(which python$python_target_version) -if ! test "$python_major_version" = "$python_target_version" && test "$python_target_binary" +# These tests are specific to Python 3. Write a custom script that executes +# git-p4 directly with the Python 3 interpreter to ensure that we use that +# version even if Git was compiled with Python 2. +python_target_binary=$(which python3) +if test -n "$python_target_binary" then mkdir temp_python - PATH="$(pwd)/temp_python:$PATH" && export PATH - ln -s $python_target_binary temp_python/python + PATH="$(pwd)/temp_python:$PATH" + export PATH + + write_script temp_python/git-p4-python3 <<-EOF + exec "$python_target_binary" "$(git --exec-path)/git-p4" "\$@" + EOF fi -python_major_version=$(python -V 2>&1 | cut -c 8) -if ! test "$python_major_version" = "$python_target_version" +git p4-python3 >err +if ! grep 'valid commands' err then - skip_all="skipping python$python_target_version-specific git p4 tests; python$python_target_version not available" + skip_all="skipping python3 git p4 tests; python3 not available" test_done fi @@ -81,14 +81,14 @@ test_expect_success 'init depot' ' test_expect_success 'clone non-utf8 repo with strict encoding' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest="$git" //depot@all 2>err && + test_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python3 clone --dest="$git" //depot@all 2>err && grep "Decoding perforce metadata failed!" err ' test_expect_success 'check utf-8 contents with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -100,7 +100,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' ' test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -114,7 +114,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st test_expect_success 'check utf-8 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -126,7 +126,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' ' test_expect_success 'check latin-1 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -138,7 +138,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' ' test_expect_success 'check cp-1252 contents with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -150,7 +150,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' ' test_expect_success 'check cp850 contents parsed with correct fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -162,7 +162,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' ' test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && @@ -174,7 +174,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest="$git" //depot@all && + git -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest="$git" //depot@all && ( cd "$cli" && P4USER=cp1252_author && @@ -186,7 +186,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb ( cd "$git" && - git p4.py sync --branch=master && + git p4-python3 sync --branch=master && git log p4/master >actual && grep "sÅ“me more cp-1252 tæxt" actual && @@ -202,7 +202,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb test_expect_success 'fallback (both utf-8 and cp-1252 contents handled) is the default with python3' ' test_when_finished cleanup_git && test_when_finished remove_user_cache && - git p4.py clone --dest="$git" //depot@all && + git p4-python3 clone --dest="$git" //depot@all && ( cd "$git" && git log >actual && diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 932d5ad759..51bd750837 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -657,6 +657,7 @@ test_expect_success '__git_refs - simple' ' HEAD main matching-branch + other/HEAD other/branch-in-other other/main-in-other matching-tag @@ -672,6 +673,7 @@ test_expect_success '__git_refs - full refs' ' cat >expected <<-EOF && refs/heads/main refs/heads/matching-branch + refs/remotes/other/HEAD refs/remotes/other/branch-in-other refs/remotes/other/main-in-other refs/tags/matching-tag @@ -728,6 +730,7 @@ test_expect_success '__git_refs - remote on local file system - full refs' ' test_expect_success '__git_refs - configured remote' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -755,6 +758,7 @@ test_expect_success '__git_refs - configured remote - full refs' ' test_expect_success '__git_refs - configured remote - repo given on the command line' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -786,6 +790,7 @@ test_expect_success '__git_refs - configured remote - full refs - repo given on test_expect_success '__git_refs - configured remote - remote name matches a directory' ' cat >expected <<-EOF && HEAD + HEAD branch-in-other main-in-other EOF @@ -874,12 +879,14 @@ test_expect_success '__git_refs - unique remote branches for git checkout DWIMer HEAD main matching-branch + other/HEAD other/ambiguous other/branch-in-other other/main-in-other remote/ambiguous remote/branch-in-remote matching-tag + HEAD branch-in-other branch-in-remote main-in-other @@ -903,6 +910,7 @@ test_expect_success '__git_refs - after --opt=' ' HEAD main matching-branch + other/HEAD other/branch-in-other other/main-in-other matching-tag @@ -918,6 +926,7 @@ test_expect_success '__git_refs - after --opt= - full refs' ' cat >expected <<-EOF && refs/heads/main refs/heads/matching-branch + refs/remotes/other/HEAD refs/remotes/other/branch-in-other refs/remotes/other/main-in-other refs/tags/matching-tag @@ -934,6 +943,7 @@ test_expect_success '__git refs - excluding refs' ' ^HEAD ^main ^matching-branch + ^other/HEAD ^other/branch-in-other ^other/main-in-other ^matching-tag @@ -949,6 +959,7 @@ test_expect_success '__git refs - excluding full refs' ' cat >expected <<-EOF && ^refs/heads/main ^refs/heads/matching-branch + ^refs/remotes/other/HEAD ^refs/remotes/other/branch-in-other ^refs/remotes/other/main-in-other ^refs/tags/matching-tag @@ -974,6 +985,7 @@ test_expect_success '__git_refs - do not filter refs unless told so' ' main matching-branch matching/branch + other/HEAD other/branch-in-other other/main-in-other other/matching/branch-in-other @@ -1094,6 +1106,7 @@ test_expect_success '__git_complete_refs - simple' ' HEAD Z main Z matching-branch Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z matching-tag Z @@ -1122,6 +1135,7 @@ test_expect_success '__git_complete_refs - matching' ' test_expect_success '__git_complete_refs - remote' ' sed -e "s/Z$//" >expected <<-EOF && HEAD Z + HEAD Z branch-in-other Z main-in-other Z EOF @@ -1138,9 +1152,11 @@ test_expect_success '__git_complete_refs - track' ' HEAD Z main Z matching-branch Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z matching-tag Z + HEAD Z branch-in-other Z main-in-other Z EOF @@ -1183,6 +1199,7 @@ test_expect_success '__git_complete_refs - suffix' ' HEAD. main. matching-branch. + other/HEAD. other/branch-in-other. other/main-in-other. matching-tag. @@ -1198,6 +1215,7 @@ test_expect_success '__git_complete_refs - suffix' ' test_expect_success '__git_complete_fetch_refspecs - simple' ' sed -e "s/Z$//" >expected <<-EOF && HEAD:HEAD Z + HEAD:HEAD Z branch-in-other:branch-in-other Z main-in-other:main-in-other Z EOF @@ -1224,6 +1242,7 @@ test_expect_success '__git_complete_fetch_refspecs - matching' ' test_expect_success '__git_complete_fetch_refspecs - prefix' ' sed -e "s/Z$//" >expected <<-EOF && +HEAD:HEAD Z + +HEAD:HEAD Z +branch-in-other:branch-in-other Z +main-in-other:main-in-other Z EOF @@ -1288,6 +1307,7 @@ test_expect_success '__git_complete_worktree_paths with -C' ' test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' ' test_completion "git switch " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1434,11 +1454,13 @@ test_expect_success 'git-bisect - existing view subcommand is recognized and ena test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' ' test_completion "git checkout " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1460,6 +1482,7 @@ test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, compl test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' ' GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1469,6 +1492,7 @@ test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_G test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' ' test_completion "git switch --no-guess --guess " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1489,6 +1513,7 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1497,11 +1522,13 @@ test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only complete test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' ' GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1513,6 +1540,7 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1521,11 +1549,13 @@ test_expect_success 'git checkout - with --no-guess, only completes refs' ' test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' ' test_completion "git checkout --no-guess --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1537,6 +1567,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous --gues main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1549,6 +1580,7 @@ test_expect_success 'git checkout - with checkout.guess = false, only completes main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1558,11 +1590,13 @@ test_expect_success 'git checkout - with checkout.guess = true, completes refs a test_config checkout.guess true && test_completion "git checkout " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1572,11 +1606,13 @@ test_expect_success 'git checkout - a later --guess overrides previous checkout. test_config checkout.guess false && test_completion "git checkout --guess " <<-\EOF HEAD Z + HEAD Z branch-in-other Z main Z main-in-other Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1589,6 +1625,7 @@ test_expect_success 'git checkout - a later --no-guess overrides previous checko main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1600,6 +1637,7 @@ test_expect_success 'git switch - with --detach, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1611,6 +1649,7 @@ test_expect_success 'git checkout - with --detach, complete only references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1782,6 +1821,7 @@ test_expect_success 'git switch - with -d, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1793,6 +1833,7 @@ test_expect_success 'git checkout - with -d, complete only references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1800,10 +1841,12 @@ test_expect_success 'git checkout - with -d, complete only references' ' test_expect_success 'git switch - with --track, complete only remote branches' ' test_completion "git switch --track " <<-\EOF && + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF test_completion "git switch -t " <<-\EOF + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1811,10 +1854,12 @@ test_expect_success 'git switch - with --track, complete only remote branches' ' test_expect_success 'git checkout - with --track, complete only remote branches' ' test_completion "git checkout --track " <<-\EOF && + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF test_completion "git checkout -t " <<-\EOF + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1833,6 +1878,7 @@ test_expect_success 'git checkout - with --no-track, complete only local referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1844,6 +1890,7 @@ test_expect_success 'git switch - with -c, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1855,6 +1902,7 @@ test_expect_success 'git switch - with -C, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1866,6 +1914,7 @@ test_expect_success 'git switch - with -c and --track, complete all references' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1877,6 +1926,7 @@ test_expect_success 'git switch - with -C and --track, complete all references' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1888,6 +1938,7 @@ test_expect_success 'git switch - with -c and --no-track, complete all reference main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1899,6 +1950,7 @@ test_expect_success 'git switch - with -C and --no-track, complete all reference main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1910,6 +1962,7 @@ test_expect_success 'git checkout - with -b, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1921,6 +1974,7 @@ test_expect_success 'git checkout - with -B, complete all references' ' main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1932,6 +1986,7 @@ test_expect_success 'git checkout - with -b and --track, complete all references main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1943,6 +1998,7 @@ test_expect_success 'git checkout - with -B and --track, complete all references main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1954,6 +2010,7 @@ test_expect_success 'git checkout - with -b and --no-track, complete all referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1965,6 +2022,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF @@ -1972,6 +2030,7 @@ test_expect_success 'git checkout - with -B and --no-track, complete all referen test_expect_success 'git switch - for -c, complete local branches and unique remote branches' ' test_completion "git switch -c " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -1981,6 +2040,7 @@ test_expect_success 'git switch - for -c, complete local branches and unique rem test_expect_success 'git switch - for -C, complete local branches and unique remote branches' ' test_completion "git switch -C " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2018,6 +2078,7 @@ test_expect_success 'git switch - for -C with --no-track, complete local branche test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' ' test_completion "git checkout -b " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2027,6 +2088,7 @@ test_expect_success 'git checkout - for -b, complete local branches and unique r test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' ' test_completion "git checkout -B " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2064,6 +2126,7 @@ test_expect_success 'git checkout - for -B with --no-track, complete local branc test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' ' test_completion "git switch --orphan " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2079,6 +2142,7 @@ test_expect_success 'git switch - --orphan with branch already provided complete test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' ' test_completion "git checkout --orphan " <<-\EOF + HEAD Z branch-in-other Z main Z main-in-other Z @@ -2092,6 +2156,7 @@ test_expect_success 'git checkout - --orphan with branch already provided comple main Z matching-branch Z matching-tag Z + other/HEAD Z other/branch-in-other Z other/main-in-other Z EOF diff --git a/t/test-lib.sh b/t/test-lib.sh index 426036b33a..d1f62adbf8 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -35,13 +35,7 @@ else # needing to exist. TEST_DIRECTORY=$(cd "$TEST_DIRECTORY" && pwd) || exit 1 fi -if test -z "$TEST_OUTPUT_DIRECTORY" -then - # Similarly, override this to store the test-results subdir - # elsewhere - TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY -fi -GIT_BUILD_DIR="${TEST_DIRECTORY%/t}" +GIT_BUILD_DIR="${GIT_BUILD_DIR:-${TEST_DIRECTORY%/t}}" if test "$TEST_DIRECTORY" = "$GIT_BUILD_DIR" then echo "PANIC: Running in a $TEST_DIRECTORY that doesn't end in '/t'?" >&2 @@ -86,12 +80,22 @@ prepend_var ASAN_OPTIONS : detect_leaks=0 export ASAN_OPTIONS prepend_var LSAN_OPTIONS : $GIT_SAN_OPTIONS +prepend_var LSAN_OPTIONS : exitcode=0 prepend_var LSAN_OPTIONS : fast_unwind_on_malloc=0 export LSAN_OPTIONS prepend_var UBSAN_OPTIONS : $GIT_SAN_OPTIONS export UBSAN_OPTIONS +# The TEST_OUTPUT_DIRECTORY will be overwritten via GIT-BUILD-OPTIONS. So in +# case the caller has manually set up this variable via the environment we must +# make sure to not overwrite that value, and thus we save it into +# TEST_OUTPUT_DIRECTORY_OVERRIDE here. +if test -n "$TEST_OUTPUT_DIRECTORY" && test -z "$TEST_OUTPUT_DIRECTORY_OVERRIDE" +then + TEST_OUTPUT_DIRECTORY_OVERRIDE=$TEST_OUTPUT_DIRECTORY +fi + if test ! -f "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS then echo >&2 'error: GIT-BUILD-OPTIONS missing (has Git been built?).' @@ -100,6 +104,13 @@ fi . "$GIT_BUILD_DIR"/GIT-BUILD-OPTIONS export PERL_PATH SHELL_PATH +if test -z "$TEST_OUTPUT_DIRECTORY" +then + # Similarly, override this to store the test-results subdir + # elsewhere + TEST_OUTPUT_DIRECTORY=$TEST_DIRECTORY +fi + # In t0000, we need to override test directories of nested testcases. In case # the developer has TEST_OUTPUT_DIRECTORY part of his build options, then we'd # reset this value to instead contain what the developer has specified. We thus @@ -321,7 +332,7 @@ TEST_RESULTS_BASE="$TEST_RESULTS_DIR/$TEST_NAME$TEST_STRESS_JOB_SFX" TEST_RESULTS_SAN_FILE_PFX=trace TEST_RESULTS_SAN_DIR_SFX=leak TEST_RESULTS_SAN_FILE= -TEST_RESULTS_SAN_DIR="$TEST_RESULTS_DIR/$TEST_NAME.$TEST_RESULTS_SAN_DIR_SFX" +TEST_RESULTS_SAN_DIR="$TEST_RESULTS_BASE.$TEST_RESULTS_SAN_DIR_SFX" TRASH_DIRECTORY="trash directory.$TEST_NAME$TEST_STRESS_JOB_SFX" test -n "$root" && TRASH_DIRECTORY="$root/$TRASH_DIRECTORY" case "$TRASH_DIRECTORY" in @@ -329,17 +340,6 @@ case "$TRASH_DIRECTORY" in *) TRASH_DIRECTORY="$TEST_OUTPUT_DIRECTORY/$TRASH_DIRECTORY" ;; esac -# Utility functions using $TEST_RESULTS_* variables -nr_san_dir_leaks_ () { - # stderr piped to /dev/null because the directory may have - # been "rmdir"'d already. - find "$TEST_RESULTS_SAN_DIR" \ - -type f \ - -name "$TEST_RESULTS_SAN_FILE_PFX.*" 2>/dev/null | - xargs grep -lv "Unable to get registers from thread" | - wc -l -} - # If --stress was passed, run this test repeatedly in several parallel loops. if test "$GIT_TEST_STRESS_STARTED" = "done" then @@ -512,6 +512,7 @@ unset VISUAL EMAIL LANGUAGE $("$PERL_PATH" -e ' PERF_ CURL_VERBOSE TRACE_CURL + BUILD_DIR )); my @vars = grep(/^GIT_/ && !/^GIT_($ok)/o, @env); print join("\n", @vars); @@ -1169,8 +1170,15 @@ test_atexit_handler () { } check_test_results_san_file_empty_ () { - test -z "$TEST_RESULTS_SAN_FILE" || - test "$(nr_san_dir_leaks_)" = 0 + test -z "$TEST_RESULTS_SAN_FILE" && return 0 + + # stderr piped to /dev/null because the directory may have + # been "rmdir"'d already. + ! find "$TEST_RESULTS_SAN_DIR" \ + -type f \ + -name "$TEST_RESULTS_SAN_FILE_PFX.*" 2>/dev/null | + xargs grep ^DEDUP_TOKEN | + grep -qv sanitizer::GetThreadStackTopAndBottom } check_test_results_san_file_ () { @@ -1409,7 +1417,7 @@ else # normal case, use ../bin-wrappers only unless $with_dashes: PATH="$GIT_BUILD_DIR:$GIT_BUILD_DIR/t/helper:$PATH" fi fi -GIT_TEMPLATE_DIR="$GIT_BUILD_DIR"/templates/blt +GIT_TEMPLATE_DIR="$GIT_TEST_TEMPLATE_DIR" GIT_CONFIG_NOSYSTEM=1 GIT_ATTR_NOSYSTEM=1 GIT_CEILING_DIRECTORIES="$TRASH_DIRECTORY/.." @@ -1475,9 +1483,9 @@ then fi fi -GITPERLLIB="$GIT_BUILD_DIR"/perl/build/lib +GITPERLLIB="$GIT_TEST_GITPERLLIB" export GITPERLLIB -test -d "$GIT_BUILD_DIR"/templates/blt || { +test -d "$GIT_TEMPLATE_DIR" || { BAIL_OUT "You haven't built things yet, have you?" } @@ -1676,6 +1684,7 @@ esac ( COLUMNS=1 && test $COLUMNS = 1 ) && test_set_prereq COLUMNS_CAN_BE_1 test -z "$NO_CURL" && test_set_prereq LIBCURL +test -z "$NO_GITWEB" && test_set_prereq GITWEB test -z "$NO_ICONV" && test_set_prereq ICONV test -z "$NO_PERL" && test_set_prereq PERL test -z "$NO_PTHREADS" && test_set_prereq PTHREADS diff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh index 688e0885f4..3b315c64b3 100755 --- a/t/unit-tests/generate-clar-decls.sh +++ b/t/unit-tests/generate-clar-decls.sh @@ -11,6 +11,9 @@ shift for suite in "$@" do - sed -ne "s/^\(void test_$(basename "${suite%.c}")__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\)$/extern \1;/p" "$suite" || + suite_name=$(basename "$suite") + suite_name=${suite_name%.c} + suite_name=${suite_name#u-} + sed -ne "s/^\(void test_${suite_name}__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\)$/extern \1;/p" "$suite" || exit 1 done >"$OUTPUT" diff --git a/t/unit-tests/lib-reftable.c b/t/unit-tests/lib-reftable.c index 7bc742e4f7..8a69612266 100644 --- a/t/unit-tests/lib-reftable.c +++ b/t/unit-tests/lib-reftable.c @@ -4,8 +4,9 @@ #include "test-lib.h" #include "reftable/constants.h" #include "reftable/writer.h" +#include "strbuf.h" -void t_reftable_set_hash(uint8_t *p, int i, uint32_t id) +void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id) { memset(p, (uint8_t)i, hash_size(id)); } @@ -84,7 +85,7 @@ void t_reftable_write_to_buf(struct reftable_buf *buf, size_t off = i * (opts.block_size ? opts.block_size : DEFAULT_BLOCK_SIZE); if (!off) - off = header_size(opts.hash_id == GIT_SHA256_FORMAT_ID ? 2 : 1); + off = header_size(opts.hash_id == REFTABLE_HASH_SHA256 ? 2 : 1); check_char(buf->buf[off], ==, 'r'); } diff --git a/t/unit-tests/lib-reftable.h b/t/unit-tests/lib-reftable.h index d4950fed3d..e4c360fa7e 100644 --- a/t/unit-tests/lib-reftable.h +++ b/t/unit-tests/lib-reftable.h @@ -6,7 +6,7 @@ struct reftable_buf; -void t_reftable_set_hash(uint8_t *p, int i, uint32_t id); +void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id); struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf, struct reftable_write_options *opts); diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c index 65d50df091..1d640b280f 100644 --- a/t/unit-tests/t-reftable-basics.c +++ b/t/unit-tests/t-reftable-basics.c @@ -20,6 +20,11 @@ static int integer_needle_lesseq(size_t i, void *_args) return args->needle <= args->haystack[i]; } +static void *realloc_stub(void *p UNUSED, size_t size UNUSED) +{ + return NULL; +} + int cmd_main(int argc UNUSED, const char *argv[] UNUSED) { if_test ("binary search with binsearch works") { @@ -141,5 +146,56 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) check_int(in, ==, out); } + if_test ("REFTABLE_ALLOC_GROW works") { + int *arr = NULL, *old_arr; + size_t alloc = 0, old_alloc; + + check(!REFTABLE_ALLOC_GROW(arr, 1, alloc)); + check(arr != NULL); + check_uint(alloc, >=, 1); + arr[0] = 42; + + old_alloc = alloc; + old_arr = arr; + reftable_set_alloc(NULL, realloc_stub, NULL); + check(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc)); + check(arr == old_arr); + check_uint(alloc, ==, old_alloc); + + old_alloc = alloc; + reftable_set_alloc(NULL, NULL, NULL); + check(!REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc)); + check(arr != NULL); + check_uint(alloc, >, old_alloc); + arr[alloc - 1] = 42; + + reftable_free(arr); + } + + if_test ("REFTABLE_ALLOC_GROW_OR_NULL works") { + int *arr = NULL; + size_t alloc = 0, old_alloc; + + REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc); + check(arr != NULL); + check_uint(alloc, >=, 1); + arr[0] = 42; + + old_alloc = alloc; + REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); + check(arr != NULL); + check_uint(alloc, >, old_alloc); + arr[alloc - 1] = 42; + + old_alloc = alloc; + reftable_set_alloc(NULL, realloc_stub, NULL); + REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); + check(arr == NULL); + check_uint(alloc, ==, 0); + reftable_set_alloc(NULL, NULL, NULL); + + reftable_free(arr); + } + return test_done(); } diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/t-reftable-block.c index f9af907117..22040aeefa 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/t-reftable-block.c @@ -11,6 +11,7 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable/blocksource.h" #include "reftable/constants.h" #include "reftable/reftable-error.h" +#include "strbuf.h" static void t_ref_block_read_write(void) { @@ -36,7 +37,7 @@ static void t_ref_block_read_write(void) block.len = block_size; block_source_from_buf(&block.source ,&buf); ret = block_writer_init(&bw, BLOCK_TYPE_REF, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + header_off, hash_size(REFTABLE_HASH_SHA1)); check(!ret); rec.u.ref.refname = (char *) ""; @@ -47,7 +48,7 @@ static void t_ref_block_read_write(void) for (i = 0; i < N; i++) { rec.u.ref.refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); rec.u.ref.value_type = REFTABLE_REF_VAL1; - memset(rec.u.ref.value.val1, i, GIT_SHA1_RAWSZ); + memset(rec.u.ref.value.val1, i, REFTABLE_HASH_SIZE_SHA1); recs[i] = rec; ret = block_writer_add(&bw, &rec); @@ -61,7 +62,7 @@ static void t_ref_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -72,7 +73,7 @@ static void t_ref_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { @@ -85,7 +86,7 @@ static void t_ref_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); want.len--; ret = block_iter_seek_key(&it, &br, &want); @@ -93,7 +94,7 @@ static void t_ref_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); @@ -130,7 +131,7 @@ static void t_log_block_read_write(void) block.len = block_size; block_source_from_buf(&block.source ,&buf); ret = block_writer_init(&bw, BLOCK_TYPE_LOG, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + header_off, hash_size(REFTABLE_HASH_SHA1)); check(!ret); for (i = 0; i < N; i++) { @@ -150,7 +151,7 @@ static void t_log_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -161,7 +162,7 @@ static void t_log_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { @@ -175,7 +176,7 @@ static void t_log_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); want.len--; ret = block_iter_seek_key(&it, &br, &want); @@ -183,7 +184,7 @@ static void t_log_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); @@ -220,7 +221,7 @@ static void t_obj_block_read_write(void) block.len = block_size; block_source_from_buf(&block.source, &buf); ret = block_writer_init(&bw, BLOCK_TYPE_OBJ, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + header_off, hash_size(REFTABLE_HASH_SHA1)); check(!ret); for (i = 0; i < N; i++) { @@ -242,7 +243,7 @@ static void t_obj_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -253,7 +254,7 @@ static void t_obj_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { @@ -266,7 +267,7 @@ static void t_obj_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); @@ -304,7 +305,7 @@ static void t_index_block_read_write(void) block.len = block_size; block_source_from_buf(&block.source, &buf); ret = block_writer_init(&bw, BLOCK_TYPE_INDEX, block.data, block_size, - header_off, hash_size(GIT_SHA1_FORMAT_ID)); + header_off, hash_size(REFTABLE_HASH_SHA1)); check(!ret); for (i = 0; i < N; i++) { @@ -326,7 +327,7 @@ static void t_index_block_read_write(void) block_writer_release(&bw); - block_reader_init(&br, &block, header_off, block_size, GIT_SHA1_RAWSZ); + block_reader_init(&br, &block, header_off, block_size, REFTABLE_HASH_SIZE_SHA1); block_iter_seek_start(&it, &br); @@ -337,7 +338,7 @@ static void t_index_block_read_write(void) check_int(i, ==, N); break; } - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); } for (i = 0; i < N; i++) { @@ -350,7 +351,7 @@ static void t_index_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[i], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); want.len--; ret = block_iter_seek_key(&it, &br, &want); @@ -358,7 +359,7 @@ static void t_index_block_read_write(void) ret = block_iter_next(&it, &rec); check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); } block_reader_release(&br); diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c index 4c25ee5334..60836f80d6 100644 --- a/t/unit-tests/t-reftable-merged.c +++ b/t/unit-tests/t-reftable-merged.c @@ -42,7 +42,7 @@ merged_table_from_records(struct reftable_ref_record **refs, check(!err); } - err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&mt, *readers, n, REFTABLE_HASH_SHA1); check(!err); return mt; } @@ -91,7 +91,7 @@ static void t_merged_single_record(void) err = reftable_iterator_next_ref(&it, &ref); check(!err); - check(reftable_ref_record_equal(&r2[0], &ref, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&r2[0], &ref, REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); readers_destroy(readers, 3); @@ -168,7 +168,7 @@ static void t_merged_refs(void) check(!err); err = reftable_iterator_seek_ref(&it, "a"); check(!err); - check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID); + check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1); check_int(reftable_merged_table_min_update_index(mt), ==, 1); check_int(reftable_merged_table_max_update_index(mt), ==, 3); @@ -178,7 +178,7 @@ static void t_merged_refs(void) if (err > 0) break; - REFTABLE_ALLOC_GROW(out, len + 1, cap); + check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); out[len++] = ref; } reftable_iterator_destroy(&it); @@ -186,7 +186,7 @@ static void t_merged_refs(void) check_int(ARRAY_SIZE(want), ==, len); for (i = 0; i < len; i++) check(reftable_ref_record_equal(want[i], &out[i], - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); for (i = 0; i < len; i++) reftable_ref_record_release(&out[i]); reftable_free(out); @@ -252,12 +252,12 @@ static void t_merged_seek_multiple_times(void) err = reftable_iterator_next_ref(&it, &rec); check(!err); - err = reftable_ref_record_equal(&rec, &r1[1], GIT_SHA1_RAWSZ); + err = reftable_ref_record_equal(&rec, &r1[1], REFTABLE_HASH_SIZE_SHA1); check(err == 1); err = reftable_iterator_next_ref(&it, &rec); check(!err); - err = reftable_ref_record_equal(&rec, &r2[1], GIT_SHA1_RAWSZ); + err = reftable_ref_record_equal(&rec, &r2[1], REFTABLE_HASH_SIZE_SHA1); check(err == 1); err = reftable_iterator_next_ref(&it, &rec); @@ -273,6 +273,78 @@ static void t_merged_seek_multiple_times(void) reftable_free(sources); } +static void t_merged_seek_multiple_times_without_draining(void) +{ + struct reftable_ref_record r1[] = { + { + .refname = (char *) "a", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 1 }, + }, + { + .refname = (char *) "c", + .update_index = 1, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 2 }, + } + }; + struct reftable_ref_record r2[] = { + { + .refname = (char *) "b", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 3 }, + }, + { + .refname = (char *) "d", + .update_index = 2, + .value_type = REFTABLE_REF_VAL1, + .value.val1 = { 4 }, + }, + }; + struct reftable_ref_record *refs[] = { + r1, r2, + }; + size_t sizes[] = { + ARRAY_SIZE(r1), ARRAY_SIZE(r2), + }; + struct reftable_buf bufs[] = { + REFTABLE_BUF_INIT, REFTABLE_BUF_INIT, + }; + struct reftable_block_source *sources = NULL; + struct reftable_reader **readers = NULL; + struct reftable_ref_record rec = { 0 }; + struct reftable_iterator it = { 0 }; + struct reftable_merged_table *mt; + int err; + + mt = merged_table_from_records(refs, &sources, &readers, sizes, bufs, 2); + merged_table_init_iter(mt, &it, BLOCK_TYPE_REF); + + err = reftable_iterator_seek_ref(&it, "b"); + check(!err); + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r2[0], REFTABLE_HASH_SIZE_SHA1); + check(err == 1); + + err = reftable_iterator_seek_ref(&it, "a"); + check(!err); + err = reftable_iterator_next_ref(&it, &rec); + check(!err); + err = reftable_ref_record_equal(&rec, &r1[0], REFTABLE_HASH_SIZE_SHA1); + check(err == 1); + + for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) + reftable_buf_release(&bufs[i]); + readers_destroy(readers, ARRAY_SIZE(refs)); + reftable_ref_record_release(&rec); + reftable_iterator_destroy(&it); + reftable_merged_table_free(mt); + reftable_free(sources); +} + static struct reftable_merged_table * merged_table_from_log_records(struct reftable_log_record **logs, struct reftable_block_source **source, @@ -300,7 +372,7 @@ merged_table_from_log_records(struct reftable_log_record **logs, check(!err); } - err = reftable_merged_table_new(&mt, *readers, n, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&mt, *readers, n, REFTABLE_HASH_SHA1); check(!err); return mt; } @@ -377,7 +449,7 @@ static void t_merged_logs(void) check(!err); err = reftable_iterator_seek_log(&it, "a"); check(!err); - check_int(reftable_merged_table_hash_id(mt), ==, GIT_SHA1_FORMAT_ID); + check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1); check_int(reftable_merged_table_min_update_index(mt), ==, 1); check_int(reftable_merged_table_max_update_index(mt), ==, 3); @@ -387,7 +459,7 @@ static void t_merged_logs(void) if (err > 0) break; - REFTABLE_ALLOC_GROW(out, len + 1, cap); + check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); out[len++] = log; } reftable_iterator_destroy(&it); @@ -395,7 +467,7 @@ static void t_merged_logs(void) check_int(ARRAY_SIZE(want), ==, len); for (i = 0; i < len; i++) check(reftable_log_record_equal(want[i], &out[i], - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); err = merged_table_init_iter(mt, &it, BLOCK_TYPE_LOG); check(!err); @@ -404,7 +476,7 @@ static void t_merged_logs(void) reftable_log_record_release(&out[0]); err = reftable_iterator_next_log(&it, &out[0]); check(!err); - check(reftable_log_record_equal(&out[0], &r3[0], GIT_SHA1_RAWSZ)); + check(reftable_log_record_equal(&out[0], &r3[0], REFTABLE_HASH_SIZE_SHA1)); reftable_iterator_destroy(&it); for (i = 0; i < len; i++) @@ -448,11 +520,11 @@ static void t_default_write_opts(void) check(!err); hash_id = reftable_reader_hash_id(rd); - check_int(hash_id, ==, GIT_SHA1_FORMAT_ID); + check_int(hash_id, ==, REFTABLE_HASH_SHA1); - err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA256_FORMAT_ID); + err = reftable_merged_table_new(&merged, &rd, 1, REFTABLE_HASH_SHA256); check_int(err, ==, REFTABLE_FORMAT_ERROR); - err = reftable_merged_table_new(&merged, &rd, 1, GIT_SHA1_FORMAT_ID); + err = reftable_merged_table_new(&merged, &rd, 1, REFTABLE_HASH_SHA1); check(!err); reftable_reader_decref(rd); @@ -467,6 +539,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_merged_logs(), "merged table with multiple log updates for same ref"); TEST(t_merged_refs(), "merged table with multiple updates to same ref"); TEST(t_merged_seek_multiple_times(), "merged table can seek multiple times"); + TEST(t_merged_seek_multiple_times_without_draining(), "merged table can seek multiple times without draining"); TEST(t_merged_single_record(), "ref occurring in only one record can be fetched"); return test_done(); diff --git a/t/unit-tests/t-reftable-pq.c b/t/unit-tests/t-reftable-pq.c index ada4c19f18..f3f8a0cdf3 100644 --- a/t/unit-tests/t-reftable-pq.c +++ b/t/unit-tests/t-reftable-pq.c @@ -9,6 +9,7 @@ https://developers.google.com/open-source/licenses/bsd #include "test-lib.h" #include "reftable/constants.h" #include "reftable/pq.h" +#include "strbuf.h" static void merged_iter_pqueue_check(const struct merged_iter_pqueue *pq) { @@ -132,7 +133,7 @@ static void t_merged_iter_pqueue_top(void) merged_iter_pqueue_check(&pq); check(pq_entry_equal(&top, &e)); - check(reftable_record_equal(top.rec, &recs[i], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(top.rec, &recs[i], REFTABLE_HASH_SIZE_SHA1)); for (size_t j = 0; i < pq.len; j++) { check(pq_less(&top, &pq.heap[j])); check_int(top.index, >, j); diff --git a/t/unit-tests/t-reftable-reader.c b/t/unit-tests/t-reftable-reader.c index 19cb53b641..546df6005e 100644 --- a/t/unit-tests/t-reftable-reader.c +++ b/t/unit-tests/t-reftable-reader.c @@ -31,7 +31,7 @@ static int t_reader_seek_once(void) ret = reftable_iterator_next_ref(&it, &ref); check(!ret); - ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ); + ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1); check_int(ret, ==, 1); ret = reftable_iterator_next_ref(&it, &ref); @@ -74,7 +74,7 @@ static int t_reader_reseek(void) ret = reftable_iterator_next_ref(&it, &ref); check(!ret); - ret = reftable_ref_record_equal(&ref, &records[0], GIT_SHA1_RAWSZ); + ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1); check_int(ret, ==, 1); ret = reftable_iterator_next_ref(&it, &ref); diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/t-reftable-readwrite.c index d38092ff83..6b75a419b9 100644 --- a/t/unit-tests/t-reftable-readwrite.c +++ b/t/unit-tests/t-reftable-readwrite.c @@ -15,6 +15,7 @@ https://developers.google.com/open-source/licenses/bsd #include "reftable/reader.h" #include "reftable/reftable-error.h" #include "reftable/reftable-writer.h" +#include "strbuf.h" static const int update_index = 5; @@ -43,7 +44,7 @@ static void t_buffer(void) } static void write_table(char ***names, struct reftable_buf *buf, int N, - int block_size, uint32_t hash_id) + int block_size, enum reftable_hash hash_id) { struct reftable_write_options opts = { .block_size = block_size, @@ -64,7 +65,7 @@ static void write_table(char ***names, struct reftable_buf *buf, int N, refs[i].refname = (*names)[i] = xstrfmt("refs/heads/branch%02d", i); refs[i].update_index = update_index; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); } for (i = 0; i < N; i++) { @@ -72,7 +73,7 @@ static void write_table(char ***names, struct reftable_buf *buf, int N, logs[i].update_index = update_index; logs[i].value_type = REFTABLE_LOG_UPDATE; t_reftable_set_hash(logs[i].value.update.new_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); logs[i].value.update.message = (char *) "message"; } @@ -92,7 +93,7 @@ static void t_log_buffer_size(void) int i; struct reftable_log_record log = { .refname = (char *) "refs/heads/master", - .update_index = 0xa, + .update_index = update_index, .value_type = REFTABLE_LOG_UPDATE, .value = { .update = { .name = (char *) "Han-Wen Nienhuys", @@ -106,7 +107,7 @@ static void t_log_buffer_size(void) /* This tests buffer extension for log compression. Must use a random hash, to ensure that the compressed part is larger than the original. */ - for (i = 0; i < GIT_SHA1_RAWSZ; i++) { + for (i = 0; i < REFTABLE_HASH_SIZE_SHA1; i++) { log.value.update.old_hash[i] = (uint8_t)(git_rand() % 256); log.value.update.new_hash[i] = (uint8_t)(git_rand() % 256); } @@ -129,7 +130,7 @@ static void t_log_overflow(void) int err; struct reftable_log_record log = { .refname = (char *) "refs/heads/master", - .update_index = 0xa, + .update_index = update_index, .value_type = REFTABLE_LOG_UPDATE, .value = { .update = { @@ -153,6 +154,48 @@ static void t_log_overflow(void) reftable_buf_release(&buf); } +static void t_log_write_limits(void) +{ + struct reftable_write_options opts = { 0 }; + struct reftable_buf buf = REFTABLE_BUF_INIT; + struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_log_record log = { + .refname = (char *)"refs/head/master", + .update_index = 0, + .value_type = REFTABLE_LOG_UPDATE, + .value = { + .update = { + .old_hash = { 1 }, + .new_hash = { 2 }, + .name = (char *)"Han-Wen Nienhuys", + .email = (char *)"hanwen@google.com", + .tz_offset = 100, + .time = 0x5e430672, + }, + }, + }; + int err; + + reftable_writer_set_limits(w, 1, 1); + + /* write with update_index (0) below set limits (1, 1) */ + err = reftable_writer_add_log(w, &log); + check_int(err, ==, 0); + + /* write with update_index (1) in the set limits (1, 1) */ + log.update_index = 1; + err = reftable_writer_add_log(w, &log); + check_int(err, ==, 0); + + /* write with update_index (3) above set limits (1, 1) */ + log.update_index = 3; + err = reftable_writer_add_log(w, &log); + check_int(err, ==, REFTABLE_API_ERROR); + + reftable_writer_free(w); + reftable_buf_release(&buf); +} + static void t_log_write_read(void) { struct reftable_write_options opts = { @@ -193,9 +236,9 @@ static void t_log_write_read(void) log.update_index = i; log.value_type = REFTABLE_LOG_UPDATE; t_reftable_set_hash(log.value.update.old_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); t_reftable_set_hash(log.value.update.new_hash, i + 1, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); err = reftable_writer_add_log(w, &log); check(!err); @@ -328,7 +371,7 @@ static void t_table_read_write_sequential(void) int err = 0; int j = 0; - write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID); + write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1); block_source_from_buf(&source, &buf); @@ -363,7 +406,7 @@ static void t_table_write_small_table(void) char **names; struct reftable_buf buf = REFTABLE_BUF_INIT; int N = 1; - write_table(&names, &buf, N, 4096, GIT_SHA1_FORMAT_ID); + write_table(&names, &buf, N, 4096, REFTABLE_HASH_SHA1); check_int(buf.len, <, 200); reftable_buf_release(&buf); free_names(names); @@ -380,7 +423,7 @@ static void t_table_read_api(void) struct reftable_log_record log = { 0 }; struct reftable_iterator it = { 0 }; - write_table(&names, &buf, N, 256, GIT_SHA1_FORMAT_ID); + write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1); block_source_from_buf(&source, &buf); @@ -402,7 +445,7 @@ static void t_table_read_api(void) reftable_buf_release(&buf); } -static void t_table_read_write_seek(int index, int hash_id) +static void t_table_read_write_seek(int index, enum reftable_hash hash_id) { char **names; struct reftable_buf buf = REFTABLE_BUF_INIT; @@ -469,24 +512,24 @@ static void t_table_read_write_seek(int index, int hash_id) static void t_table_read_write_seek_linear(void) { - t_table_read_write_seek(0, GIT_SHA1_FORMAT_ID); + t_table_read_write_seek(0, REFTABLE_HASH_SHA1); } static void t_table_read_write_seek_linear_sha256(void) { - t_table_read_write_seek(0, GIT_SHA256_FORMAT_ID); + t_table_read_write_seek(0, REFTABLE_HASH_SHA256); } static void t_table_read_write_seek_index(void) { - t_table_read_write_seek(1, GIT_SHA1_FORMAT_ID); + t_table_read_write_seek(1, REFTABLE_HASH_SHA1); } static void t_table_refs_for(int indexed) { char **want_names; int want_names_len = 0; - uint8_t want_hash[GIT_SHA1_RAWSZ]; + uint8_t want_hash[REFTABLE_HASH_SIZE_SHA1]; struct reftable_write_options opts = { .block_size = 256, @@ -502,10 +545,10 @@ static void t_table_refs_for(int indexed) want_names = reftable_calloc(N + 1, sizeof(*want_names)); check(want_names != NULL); - t_reftable_set_hash(want_hash, 4, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(want_hash, 4, REFTABLE_HASH_SHA1); for (i = 0; i < N; i++) { - uint8_t hash[GIT_SHA1_RAWSZ]; + uint8_t hash[REFTABLE_HASH_SIZE_SHA1]; char fill[51] = { 0 }; char name[100]; struct reftable_ref_record ref = { 0 }; @@ -519,9 +562,9 @@ static void t_table_refs_for(int indexed) ref.value_type = REFTABLE_REF_VAL2; t_reftable_set_hash(ref.value.val2.value, i / 4, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); t_reftable_set_hash(ref.value.val2.target_value, 3 + i / 4, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); /* 80 bytes / entry, so 3 entries per block. Yields 17 */ @@ -529,8 +572,8 @@ static void t_table_refs_for(int indexed) n = reftable_writer_add_ref(w, &ref); check_int(n, ==, 0); - if (!memcmp(ref.value.val2.value, want_hash, GIT_SHA1_RAWSZ) || - !memcmp(ref.value.val2.target_value, want_hash, GIT_SHA1_RAWSZ)) + if (!memcmp(ref.value.val2.value, want_hash, REFTABLE_HASH_SIZE_SHA1) || + !memcmp(ref.value.val2.target_value, want_hash, REFTABLE_HASH_SIZE_SHA1)) want_names[want_names_len++] = xstrdup(name); } @@ -919,6 +962,7 @@ int cmd_main(int argc UNUSED, const char *argv[] UNUSED) TEST(t_corrupt_table_empty(), "read-write on an empty table"); TEST(t_log_buffer_size(), "buffer extension for log compression"); TEST(t_log_overflow(), "log overflow returns expected error"); + TEST(t_log_write_limits(), "writer limits for writing log records"); TEST(t_log_write_read(), "read-write on log records"); TEST(t_log_zlib_corruption(), "reading corrupted log record returns expected error"); TEST(t_table_read_api(), "read on a table"); diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/t-reftable-record.c index eb98bf2da9..42bc64cec8 100644 --- a/t/unit-tests/t-reftable-record.c +++ b/t/unit-tests/t-reftable-record.c @@ -7,6 +7,7 @@ */ #include "test-lib.h" +#include "reftable/basics.h" #include "reftable/constants.h" #include "reftable/record.h" @@ -17,10 +18,10 @@ static void t_copy(struct reftable_record *rec) typ = reftable_record_type(rec); reftable_record_init(©, typ); - reftable_record_copy_from(©, rec, GIT_SHA1_RAWSZ); + reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1); /* do it twice to catch memory leaks */ - reftable_record_copy_from(©, rec, GIT_SHA1_RAWSZ); - check(reftable_record_equal(rec, ©, GIT_SHA1_RAWSZ)); + reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1); + check(reftable_record_equal(rec, ©, REFTABLE_HASH_SIZE_SHA1)); reftable_record_release(©); } @@ -59,7 +60,7 @@ static void t_varint_roundtrip(void) static void set_hash(uint8_t *h, int j) { - for (int i = 0; i < hash_size(GIT_SHA1_FORMAT_ID); i++) + for (int i = 0; i < hash_size(REFTABLE_HASH_SHA1); i++) h[i] = (j >> i) & 0xff; } @@ -84,14 +85,14 @@ static void t_reftable_ref_record_comparison(void) }, }; - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); in[1].u.ref.value_type = in[0].u.ref.value_type; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); } @@ -155,15 +156,15 @@ static void t_reftable_ref_record_roundtrip(void) check_int(reftable_record_is_deletion(&in), ==, i == REFTABLE_REF_DELETION); reftable_record_key(&in, &key); - n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ); + n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >, 0); /* decode into a non-zero reftable_record to test for leaks. */ - m = reftable_record_decode(&out, key, i, dest, GIT_SHA1_RAWSZ, &scratch); + m = reftable_record_decode(&out, key, i, dest, REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(n, ==, m); check(reftable_ref_record_equal(&in.u.ref, &out.u.ref, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_record_release(&in); reftable_buf_release(&key); @@ -193,15 +194,15 @@ static void t_reftable_log_record_comparison(void) }, }; - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); /* comparison should be reversed for equal keys, because * comparison is now performed on the basis of update indices */ check_int(reftable_record_cmp(&in[0], &in[1]), <, 0); in[1].u.log.update_index = in[0].u.log.update_index; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); } @@ -303,15 +304,15 @@ static void t_reftable_log_record_roundtrip(void) reftable_record_key(&rec, &key); - n = reftable_record_encode(&rec, dest, GIT_SHA1_RAWSZ); + n = reftable_record_encode(&rec, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >=, 0); valtype = reftable_record_val_type(&rec); m = reftable_record_decode(&out, key, valtype, dest, - GIT_SHA1_RAWSZ, &scratch); + REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(n, ==, m); check(reftable_log_record_equal(&in[i], &out.u.log, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_log_record_release(&in[i]); reftable_buf_release(&key); reftable_record_release(&out); @@ -380,20 +381,20 @@ static void t_reftable_obj_record_comparison(void) }, }; - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); in[1].u.obj.offset_len = in[0].u.obj.offset_len; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); } static void t_reftable_obj_record_roundtrip(void) { - uint8_t testHash1[GIT_SHA1_RAWSZ] = { 1, 2, 3, 4, 0 }; + uint8_t testHash1[REFTABLE_HASH_SIZE_SHA1] = { 1, 2, 3, 4, 0 }; uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 }; struct reftable_obj_record recs[3] = { { @@ -435,14 +436,14 @@ static void t_reftable_obj_record_roundtrip(void) check(!reftable_record_is_deletion(&in)); t_copy(&in); reftable_record_key(&in, &key); - n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ); + n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >, 0); extra = reftable_record_val_type(&in); m = reftable_record_decode(&out, key, extra, dest, - GIT_SHA1_RAWSZ, &scratch); + REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(n, ==, m); - check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1)); reftable_buf_release(&key); reftable_record_release(&out); } @@ -473,14 +474,14 @@ static void t_reftable_index_record_comparison(void) check(!reftable_buf_addstr(&in[1].u.idx.last_key, "refs/heads/master")); check(!reftable_buf_addstr(&in[2].u.idx.last_key, "refs/heads/branch")); - check(!reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); - check(!reftable_record_equal(&in[1], &in[2], GIT_SHA1_RAWSZ)); + check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); check_int(reftable_record_cmp(&in[1], &in[2]), >, 0); in[1].u.idx.offset = in[0].u.idx.offset; - check(reftable_record_equal(&in[0], &in[1], GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); check(!reftable_record_cmp(&in[0], &in[1])); for (size_t i = 0; i < ARRAY_SIZE(in); i++) @@ -516,15 +517,15 @@ static void t_reftable_index_record_roundtrip(void) check(!reftable_record_is_deletion(&in)); check(!reftable_buf_cmp(&key, &in.u.idx.last_key)); - n = reftable_record_encode(&in, dest, GIT_SHA1_RAWSZ); + n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); check_int(n, >, 0); extra = reftable_record_val_type(&in); - m = reftable_record_decode(&out, key, extra, dest, GIT_SHA1_RAWSZ, + m = reftable_record_decode(&out, key, extra, dest, REFTABLE_HASH_SIZE_SHA1, &scratch); check_int(m, ==, n); - check(reftable_record_equal(&in, &out, GIT_SHA1_RAWSZ)); + check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1)); reftable_record_release(&out); reftable_buf_release(&key); diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/t-reftable-stack.c index 4377c0af1b..aeec195b2b 100644 --- a/t/unit-tests/t-reftable-stack.c +++ b/t/unit-tests/t-reftable-stack.c @@ -10,10 +10,13 @@ https://developers.google.com/open-source/licenses/bsd #include "test-lib.h" #include "lib-reftable.h" +#include "dir.h" #include "reftable/merged.h" #include "reftable/reader.h" #include "reftable/reftable-error.h" #include "reftable/stack.h" +#include "strbuf.h" +#include "tempfile.h" #include <dirent.h> static void clear_dir(const char *dirname) @@ -122,7 +125,7 @@ static void write_n_ref_tables(struct reftable_stack *st, snprintf(buf, sizeof(buf), "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i); ref.refname = buf; - t_reftable_set_hash(ref.value.val1, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1); err = reftable_stack_add(st, &write_test_ref, &ref); check(!err); @@ -170,7 +173,7 @@ static void t_reftable_stack_add_one(void) err = reftable_stack_read_ref(st, ref.refname, &dest); check(!err); - check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); check_int(st->readers_len, >, 0); #ifndef GIT_WINDOWS_NATIVE @@ -281,7 +284,7 @@ static void t_reftable_stack_transaction_api(void) err = reftable_stack_read_ref(st, ref.refname, &dest); check(!err); check_int(REFTABLE_REF_SYMREF, ==, dest.value_type); - check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&dest); reftable_stack_destroy(st); @@ -341,7 +344,7 @@ static void t_reftable_stack_transaction_with_reload(void) for (size_t i = 0; i < ARRAY_SIZE(refs); i++) { err = reftable_stack_read_ref(st2, refs[i].refname, &ref); check(!err); - check(reftable_ref_record_equal(&refs[i], &ref, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&refs[i], &ref, REFTABLE_HASH_SIZE_SHA1)); } reftable_ref_record_release(&ref); @@ -531,13 +534,13 @@ static void t_reftable_stack_add(void) refs[i].refname = xstrdup(buf); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); logs[i].refname = xstrdup(buf); logs[i].update_index = N + i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("identity@invalid"); - t_reftable_set_hash(logs[i].value.update.new_hash, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1); } for (i = 0; i < N; i++) { @@ -563,7 +566,7 @@ static void t_reftable_stack_add(void) int err = reftable_stack_read_ref(st, refs[i].refname, &dest); check(!err); check(reftable_ref_record_equal(&dest, refs + i, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&dest); } @@ -572,7 +575,7 @@ static void t_reftable_stack_add(void) int err = reftable_stack_read_log(st, refs[i].refname, &dest); check(!err); check(reftable_log_record_equal(&dest, logs + i, - GIT_SHA1_RAWSZ)); + REFTABLE_HASH_SIZE_SHA1)); reftable_log_record_release(&dest); } @@ -623,14 +626,14 @@ static void t_reftable_stack_iterator(void) refs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); logs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); logs[i].update_index = i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("johndoe@invalid"); logs[i].value.update.message = xstrdup("commit\n"); - t_reftable_set_hash(logs[i].value.update.new_hash, i, GIT_SHA1_FORMAT_ID); + t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1); } for (i = 0; i < N; i++) { @@ -657,7 +660,7 @@ static void t_reftable_stack_iterator(void) if (err > 0) break; check(!err); - check(reftable_ref_record_equal(&ref, &refs[i], GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &refs[i], REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&ref); } check_int(i, ==, N); @@ -675,7 +678,7 @@ static void t_reftable_stack_iterator(void) if (err > 0) break; check(!err); - check(reftable_log_record_equal(&log, &logs[i], GIT_SHA1_RAWSZ)); + check(reftable_log_record_equal(&log, &logs[i], REFTABLE_HASH_SIZE_SHA1)); reftable_log_record_release(&log); } check_int(i, ==, N); @@ -768,16 +771,20 @@ static void t_reftable_stack_tombstone(void) if (i % 2 == 0) { refs[i].value_type = REFTABLE_REF_VAL1; t_reftable_set_hash(refs[i].value.val1, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); } logs[i].refname = xstrdup(buf); - /* update_index is part of the key. */ - logs[i].update_index = 42; + /* + * update_index is part of the key so should be constant. + * The value itself should be less than the writer's upper + * limit. + */ + logs[i].update_index = 1; if (i % 2 == 0) { logs[i].value_type = REFTABLE_LOG_UPDATE; t_reftable_set_hash(logs[i].value.update.new_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); logs[i].value.update.email = xstrdup("identity@invalid"); } @@ -837,7 +844,7 @@ static void t_reftable_stack_hash_id(void) .value.symref = (char *) "target", .update_index = 1, }; - struct reftable_write_options opts32 = { .hash_id = GIT_SHA256_FORMAT_ID }; + struct reftable_write_options opts32 = { .hash_id = REFTABLE_HASH_SHA256 }; struct reftable_stack *st32 = NULL; struct reftable_write_options opts_default = { 0 }; struct reftable_stack *st_default = NULL; @@ -860,7 +867,7 @@ static void t_reftable_stack_hash_id(void) err = reftable_stack_read_ref(st_default, "master", &dest); check(!err); - check(reftable_ref_record_equal(&ref, &dest, GIT_SHA1_RAWSZ)); + check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); reftable_ref_record_release(&dest); reftable_stack_destroy(st); reftable_stack_destroy(st_default); @@ -910,7 +917,7 @@ static void t_reflog_expire(void) logs[i].value.update.time = i; logs[i].value.update.email = xstrdup("identity@invalid"); t_reftable_set_hash(logs[i].value.update.new_hash, i, - GIT_SHA1_FORMAT_ID); + REFTABLE_HASH_SHA1); } for (i = 1; i <= N; i++) { diff --git a/t/unit-tests/ctype.c b/t/unit-tests/u-ctype.c index 32e65867cd..32e65867cd 100644 --- a/t/unit-tests/ctype.c +++ b/t/unit-tests/u-ctype.c diff --git a/t/unit-tests/strvec.c b/t/unit-tests/u-strvec.c index 855b602337..e66b7bbfae 100644 --- a/t/unit-tests/strvec.c +++ b/t/unit-tests/u-strvec.c @@ -88,6 +88,16 @@ void test_strvec__pushv(void) strvec_clear(&vec); } +void test_strvec__splice_just_initialized_strvec(void) +{ + struct strvec vec = STRVEC_INIT; + const char *replacement[] = { "foo" }; + + strvec_splice(&vec, 0, 0, replacement, ARRAY_SIZE(replacement)); + check_strvec(&vec, "foo", NULL); + strvec_clear(&vec); +} + void test_strvec__splice_with_same_size_replacement(void) { struct strvec vec = STRVEC_INIT; diff --git a/t/unit-tests/unit-test.c b/t/unit-tests/unit-test.c index a474cdcfd3..fa8818842a 100644 --- a/t/unit-tests/unit-test.c +++ b/t/unit-tests/unit-test.c @@ -18,8 +18,25 @@ int cmd_main(int argc, const char **argv) N_("immediately exit upon the first failed test")), OPT_STRING_LIST('r', "run", &run_args, N_("suite[::test]"), N_("run only test suite or individual test <suite[::test]>")), - OPT_STRING_LIST('x', "exclude", &exclude_args, N_("suite"), + OPT_STRING_LIST(0, "exclude", &exclude_args, N_("suite"), N_("exclude test suite <suite>")), + /* + * Compatibility wrappers so that we don't have to filter + * options understood by integration tests. + */ + OPT_NOOP_NOARG('d', "debug"), + OPT_NOOP_NOARG(0, "github-workflow-markup"), + OPT_NOOP_NOARG(0, "no-bin-wrappers"), + OPT_NOOP_ARG(0, "root"), + OPT_NOOP_ARG(0, "stress"), + OPT_NOOP_NOARG(0, "tee"), + OPT_NOOP_NOARG(0, "with-dashes"), + OPT_NOOP_ARG(0, "valgrind"), + OPT_NOOP_ARG(0, "valgrind-only"), + OPT_NOOP_NOARG('v', "verbose"), + OPT_NOOP_NOARG('V', "verbose-log"), + OPT_NOOP_ARG(0, "verbose-only"), + OPT_NOOP_NOARG('x', NULL), OPT_END(), }; struct strvec args = STRVEC_INIT; |
