diff options
Diffstat (limited to 't')
28 files changed, 961 insertions, 65 deletions
@@ -315,7 +315,7 @@ packs on demand. This normally only happens when the object size is over 2GB. This variable forces the code path on any object larger than <n> bytes. -GIT_TEST_OE_DELTA_SIZE=<n> exercises the uncomon pack-objects code +GIT_TEST_OE_DELTA_SIZE=<n> exercises the uncommon pack-objects code path where deltas larger than this limit require extra memory allocation for bookkeeping. @@ -327,6 +327,22 @@ GIT_TEST_COMMIT_GRAPH=<boolean>, when true, forces the commit-graph to be written after every 'git commit' command, and overrides the 'core.commitGraph' setting to true. +GIT_TEST_FSMONITOR=$PWD/t7519/fsmonitor-all exercises the fsmonitor +code path for utilizing a file system monitor to speed up detecting +new or changed files. + +GIT_TEST_INDEX_VERSION=<n> exercises the index read/write code path +for the index version specified. Can be set to any valid version +(currently 2, 3, or 4). + +GIT_TEST_PRELOAD_INDEX=<boolean> exercises the preload-index code path +by overriding the minimum number of cache entries required per thread. + +GIT_TEST_INDEX_THREADS=<n> enables exercising the multi-threaded loading +of the index for the whole test suite by bypassing the default number of +cache entries and thread minimums. Setting this to 1 will make the +index loading single threaded. + Naming Tests ------------ diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c index 4f8bc75821..625b2dbf82 100644 --- a/t/helper/test-revision-walking.c +++ b/t/helper/test-revision-walking.c @@ -32,7 +32,7 @@ static int run_revision_walk(void) int argc = ARRAY_SIZE(argv) - 1; int got_revision = 0; - init_revisions(&rev, NULL); + repo_init_revisions(the_repository, &rev, NULL); setup_revisions(argc, argv, &rev, NULL); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 6b5836dc1b..5df8b682aa 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -55,13 +55,23 @@ static struct test_cmd cmds[] = { { "write-cache", cmd__write_cache }, }; +static NORETURN void die_usage(void) +{ + size_t i; + + fprintf(stderr, "usage: test-tool <toolname> [args]\n"); + for (i = 0; i < ARRAY_SIZE(cmds); i++) + fprintf(stderr, " %s\n", cmds[i].name); + exit(128); +} + int cmd_main(int argc, const char **argv) { int i; BUG_exit_code = 99; if (argc < 2) - die("I need a test name!"); + die_usage(); for (i = 0; i < ARRAY_SIZE(cmds); i++) { if (!strcmp(cmds[i].name, argv[1])) { @@ -70,5 +80,6 @@ int cmd_main(int argc, const char **argv) return cmds[i].fn(argc, argv); } } - die("There is no test named '%s'", argv[1]); + error("there is no tool named '%s'", argv[1]); + die_usage(); } diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index e4890566da..71f470b871 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -1,5 +1,5 @@ -#ifndef __TEST_TOOL_H__ -#define __TEST_TOOL_H__ +#ifndef TEST_TOOL_H +#define TEST_TOOL_H #include "git-compat-util.h" diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 26601e698b..4d23373526 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -87,6 +87,10 @@ _run_sub_test_lib_test_common () { passing metrics ' + # Tell the framework that we are self-testing to make sure + # it yields a stable result. + GIT_TEST_FRAMEWORK_SELFTEST=t && + # Point to the t/test-lib.sh, which isn't in ../ as usual . "\$TEST_DIRECTORY"/test-lib.sh EOF diff --git a/t/t0012-help.sh b/t/t0012-help.sh index bc27df7f38..e8ef7300ec 100755 --- a/t/t0012-help.sh +++ b/t/t0012-help.sh @@ -29,9 +29,9 @@ test_expect_success "setup" ' # to verify test_expect_success 'basic help commands' ' git help >/dev/null && - git help -a >/dev/null && + git help -a --no-verbose >/dev/null && git help -g >/dev/null && - git help -av >/dev/null + git help -a >/dev/null ' test_expect_success "works for commands and guides by default" ' diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index 3e131c5325..cf932c8514 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -12,10 +12,14 @@ cat >hello-script <<-EOF cat hello-script EOF -test_expect_success 'start_command reports ENOENT' ' +test_expect_success 'start_command reports ENOENT (slash)' ' test-tool run-command start-command-ENOENT ./does-not-exist ' +test_expect_success 'start_command reports ENOENT (no slash)' ' + test-tool run-command start-command-ENOENT does-not-exist +' + test_expect_success 'run_command can run a command' ' cat hello-script >hello.sh && chmod +x hello.sh && @@ -25,6 +29,13 @@ test_expect_success 'run_command can run a command' ' test_must_be_empty err ' +test_expect_success 'run_command is restricted to PATH' ' + write_script should-not-run <<-\EOF && + echo yikes + EOF + test_must_fail test-tool run-command run-command should-not-run +' + test_expect_success !MINGW 'run_command can run a script without a #! line' ' cat >hello <<-\EOF && cat hello-script diff --git a/t/t0410-partial-clone.sh b/t/t0410-partial-clone.sh index cfd0655ea1..ba3887f178 100755 --- a/t/t0410-partial-clone.sh +++ b/t/t0410-partial-clone.sh @@ -182,6 +182,47 @@ test_expect_success 'fetching of missing objects works with ref-in-want enabled' grep "git< fetch=.*ref-in-want" trace ' +test_expect_success 'fetching of missing blobs works' ' + rm -rf server repo && + test_create_repo server && + test_commit -C server foo && + git -C server repack -a -d --write-bitmap-index && + + git clone "file://$(pwd)/server" repo && + git hash-object repo/foo.t >blobhash && + rm -rf repo/.git/objects/* && + + git -C server config uploadpack.allowanysha1inwant 1 && + git -C server config uploadpack.allowfilter 1 && + git -C repo config core.repositoryformatversion 1 && + git -C repo config extensions.partialclone "origin" && + + git -C repo cat-file -p $(cat blobhash) +' + +test_expect_success 'fetching of missing trees does not fetch blobs' ' + rm -rf server repo && + test_create_repo server && + test_commit -C server foo && + git -C server repack -a -d --write-bitmap-index && + + git clone "file://$(pwd)/server" repo && + git -C repo rev-parse foo^{tree} >treehash && + git hash-object repo/foo.t >blobhash && + rm -rf repo/.git/objects/* && + + git -C server config uploadpack.allowanysha1inwant 1 && + git -C server config uploadpack.allowfilter 1 && + git -C repo config core.repositoryformatversion 1 && + git -C repo config extensions.partialclone "origin" && + git -C repo cat-file -p $(cat treehash) && + + # Ensure that the tree, but not the blob, is fetched + git -C repo rev-list --objects --missing=print $(cat treehash) >objects && + grep "^$(cat treehash)" objects && + grep "^[?]$(cat blobhash)" objects +' + test_expect_success 'rev-list stops traversal at missing and promised commit' ' rm -rf repo && test_create_repo repo && @@ -198,6 +239,51 @@ test_expect_success 'rev-list stops traversal at missing and promised commit' ' ! grep $FOO out ' +test_expect_success 'missing tree objects with --missing=allow-promisor and --exclude-promisor-objects' ' + rm -rf repo && + test_create_repo repo && + test_commit -C repo foo && + test_commit -C repo bar && + test_commit -C repo baz && + + promise_and_delete $(git -C repo rev-parse bar^{tree}) && + promise_and_delete $(git -C repo rev-parse foo^{tree}) && + + git -C repo config core.repositoryformatversion 1 && + git -C repo config extensions.partialclone "arbitrary string" && + + git -C repo rev-list --missing=allow-promisor --objects HEAD >objs 2>rev_list_err && + test_must_be_empty rev_list_err && + # 3 commits, 3 blobs, and 1 tree + test_line_count = 7 objs && + + # Do the same for --exclude-promisor-objects, but with all trees gone. + promise_and_delete $(git -C repo rev-parse baz^{tree}) && + git -C repo rev-list --exclude-promisor-objects --objects HEAD >objs 2>rev_list_err && + test_must_be_empty rev_list_err && + # 3 commits, no blobs or trees + test_line_count = 3 objs +' + +test_expect_success 'missing non-root tree object and rev-list' ' + rm -rf repo && + test_create_repo repo && + mkdir repo/dir && + echo foo >repo/dir/foo && + git -C repo add dir/foo && + git -C repo commit -m "commit dir/foo" && + + promise_and_delete $(git -C repo rev-parse HEAD:dir) && + + git -C repo config core.repositoryformatversion 1 && + git -C repo config extensions.partialclone "arbitrary string" && + + git -C repo rev-list --missing=allow-any --objects HEAD >objs 2>rev_list_err && + test_must_be_empty rev_list_err && + # 1 commit and 1 tree + test_line_count = 2 objs +' + test_expect_success 'rev-list stops traversal at missing and promised tree' ' rm -rf repo && test_create_repo repo && diff --git a/t/t1090-sparse-checkout-scope.sh b/t/t1090-sparse-checkout-scope.sh index 25d7c700f6..090b7fc3d3 100755 --- a/t/t1090-sparse-checkout-scope.sh +++ b/t/t1090-sparse-checkout-scope.sh @@ -63,4 +63,37 @@ test_expect_success 'return to full checkout of master' ' test "$(cat b)" = "modified" ' +test_expect_success 'in partial clone, sparse checkout only fetches needed blobs' ' + test_create_repo server && + git clone "file://$(pwd)/server" client && + + test_config -C server uploadpack.allowfilter 1 && + test_config -C server uploadpack.allowanysha1inwant 1 && + echo a >server/a && + echo bb >server/b && + mkdir server/c && + echo ccc >server/c/c && + git -C server add a b c/c && + git -C server commit -m message && + + test_config -C client core.sparsecheckout 1 && + test_config -C client extensions.partialclone origin && + echo "!/*" >client/.git/info/sparse-checkout && + echo "/a" >>client/.git/info/sparse-checkout && + git -C client fetch --filter=blob:none origin && + git -C client checkout FETCH_HEAD && + + git -C client rev-list HEAD \ + --quiet --objects --missing=print >unsorted_actual && + ( + printf "?" && + git hash-object server/b && + printf "?" && + git hash-object server/c/c + ) >unsorted_expect && + sort unsorted_actual >actual && + sort unsorted_expect >expect && + test_cmp expect actual +' + test_done diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh index 5c715fe2cf..01abee533d 100755 --- a/t/t1500-rev-parse.sh +++ b/t/t1500-rev-parse.sh @@ -142,6 +142,22 @@ test_expect_success 'showing the superproject correctly' ' git -C super submodule add ../sub dir/sub && echo $(pwd)/super >expect && git -C super/dir/sub rev-parse --show-superproject-working-tree >out && + test_cmp expect out && + + test_commit -C super submodule_add && + git -C super checkout -b branch1 && + git -C super/dir/sub checkout -b branch1 && + test_commit -C super/dir/sub branch1_commit && + git -C super add dir/sub && + test_commit -C super branch1_commit && + git -C super checkout -b branch2 master && + git -C super/dir/sub checkout -b branch2 master && + test_commit -C super/dir/sub branch2_commit && + git -C super add dir/sub && + test_commit -C super branch2_commit && + test_must_fail git -C super merge branch1 && + + git -C super/dir/sub rev-parse --show-superproject-working-tree >out && test_cmp expect out ' diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh index be22398a85..2ac47aa0e4 100755 --- a/t/t1700-split-index.sh +++ b/t/t1700-split-index.sh @@ -6,7 +6,19 @@ test_description='split index mode tests' # We need total control of index splitting here sane_unset GIT_TEST_SPLIT_INDEX -sane_unset GIT_FSMONITOR_TEST + +# Testing a hard coded SHA against an index with an extension +# that can vary from run to run is problematic so we disable +# those extensions. +sane_unset GIT_TEST_FSMONITOR +sane_unset GIT_TEST_INDEX_THREADS + +# Create a file named as $1 with content read from stdin. +# Set the file's mtime to a few seconds in the past to avoid racy situations. +create_non_racy_file () { + cat >"$1" && + test-tool chmtime =-5 "$1" +} test_expect_success 'enable split index' ' git config splitIndex.maxPercentChange 100 && @@ -15,11 +27,11 @@ test_expect_success 'enable split index' ' indexversion=$(test-tool index-version <.git/index) && if test "$indexversion" = "4" then - own=432ef4b63f32193984f339431fd50ca796493569 - base=508851a7f0dfa8691e9f69c7f055865389012491 + own=3527df833c6c100d3d1d921a9a782d62a8be4b58 + base=746f7ab2ed44fb839efdfbffcf399d0b113fb4cb else - own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339 - base=39d890139ee5356c7ef572216cebcd27aa41f9df + own=5e9b60117ece18da410ddecc8b8d43766a0e4204 + base=4370042739b31cd17a5c5cd6043a77c9a00df113 fi && cat >expect <<-EOF && own $own @@ -31,7 +43,7 @@ test_expect_success 'enable split index' ' ' test_expect_success 'add one file' ' - : >one && + create_non_racy_file one && git update-index --add one && git ls-files --stage >ls-files.actual && cat >ls-files.expect <<-EOF && @@ -83,7 +95,7 @@ test_expect_success 'enable split index again, "one" now belongs to base index"' ' test_expect_success 'modify original file, base index untouched' ' - echo modified >one && + echo modified | create_non_racy_file one && git update-index one && git ls-files --stage >ls-files.actual && cat >ls-files.expect <<-EOF && @@ -102,7 +114,7 @@ test_expect_success 'modify original file, base index untouched' ' ' test_expect_success 'add another file, which stays index' ' - : >two && + create_non_racy_file two && git update-index --add two && git ls-files --stage >ls-files.actual && cat >ls-files.expect <<-EOF && @@ -155,7 +167,7 @@ test_expect_success 'remove file in base index' ' ' test_expect_success 'add original file back' ' - : >one && + create_non_racy_file one && git update-index --add one && git ls-files --stage >ls-files.actual && cat >ls-files.expect <<-EOF && @@ -174,7 +186,7 @@ test_expect_success 'add original file back' ' ' test_expect_success 'add new file' ' - : >two && + create_non_racy_file two && git update-index --add two && git ls-files --stage >actual && cat >expect <<-EOF && @@ -218,7 +230,7 @@ test_expect_success 'rev-parse --shared-index-path' ' test_expect_success 'set core.splitIndex config variable to true' ' git config core.splitIndex true && - : >three && + create_non_racy_file three && git update-index --add three && git ls-files --stage >ls-files.actual && cat >ls-files.expect <<-EOF && @@ -253,9 +265,9 @@ test_expect_success 'set core.splitIndex config variable to false' ' test_cmp expect actual ' -test_expect_success 'set core.splitIndex config variable to true' ' +test_expect_success 'set core.splitIndex config variable back to true' ' git config core.splitIndex true && - : >three && + create_non_racy_file three && git update-index --add three && BASE=$(test-tool dump-split-index .git/index | grep "^base") && test-tool dump-split-index .git/index | sed "/^own/d" >actual && @@ -265,7 +277,7 @@ test_expect_success 'set core.splitIndex config variable to true' ' deletions: EOF test_cmp expect actual && - : >four && + create_non_racy_file four && git update-index --add four && test-tool dump-split-index .git/index | sed "/^own/d" >actual && cat >expect <<-EOF && @@ -279,7 +291,7 @@ test_expect_success 'set core.splitIndex config variable to true' ' test_expect_success 'check behavior with splitIndex.maxPercentChange unset' ' git config --unset splitIndex.maxPercentChange && - : >five && + create_non_racy_file five && git update-index --add five && BASE=$(test-tool dump-split-index .git/index | grep "^base") && test-tool dump-split-index .git/index | sed "/^own/d" >actual && @@ -289,7 +301,7 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' ' deletions: EOF test_cmp expect actual && - : >six && + create_non_racy_file six && git update-index --add six && test-tool dump-split-index .git/index | sed "/^own/d" >actual && cat >expect <<-EOF && @@ -303,7 +315,7 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' ' test_expect_success 'check splitIndex.maxPercentChange set to 0' ' git config splitIndex.maxPercentChange 0 && - : >seven && + create_non_racy_file seven && git update-index --add seven && BASE=$(test-tool dump-split-index .git/index | grep "^base") && test-tool dump-split-index .git/index | sed "/^own/d" >actual && @@ -313,7 +325,7 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' ' deletions: EOF test_cmp expect actual && - : >eight && + create_non_racy_file eight && git update-index --add eight && BASE=$(test-tool dump-split-index .git/index | grep "^base") && test-tool dump-split-index .git/index | sed "/^own/d" >actual && @@ -326,17 +338,17 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' ' ' test_expect_success 'shared index files expire after 2 weeks by default' ' - : >ten && + create_non_racy_file ten && git update-index --add ten && test $(ls .git/sharedindex.* | wc -l) -gt 2 && just_under_2_weeks_ago=$((5-14*86400)) && test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* && - : >eleven && + create_non_racy_file eleven && git update-index --add eleven && test $(ls .git/sharedindex.* | wc -l) -gt 2 && just_over_2_weeks_ago=$((-1-14*86400)) && test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* && - : >twelve && + create_non_racy_file twelve && git update-index --add twelve && test $(ls .git/sharedindex.* | wc -l) -le 2 ' @@ -344,12 +356,12 @@ test_expect_success 'shared index files expire after 2 weeks by default' ' test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' ' git config splitIndex.sharedIndexExpire "16.days.ago" && test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* && - : >thirteen && + create_non_racy_file thirteen && git update-index --add thirteen && test $(ls .git/sharedindex.* | wc -l) -gt 2 && just_over_16_days_ago=$((-1-16*86400)) && test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* && - : >fourteen && + create_non_racy_file fourteen && git update-index --add fourteen && test $(ls .git/sharedindex.* | wc -l) -le 2 ' @@ -358,13 +370,13 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now" git config splitIndex.sharedIndexExpire never && just_10_years_ago=$((-365*10*86400)) && test-tool chmtime =$just_10_years_ago .git/sharedindex.* && - : >fifteen && + create_non_racy_file fifteen && git update-index --add fifteen && test $(ls .git/sharedindex.* | wc -l) -gt 2 && git config splitIndex.sharedIndexExpire now && just_1_second_ago=-1 && test-tool chmtime =$just_1_second_ago .git/sharedindex.* && - : >sixteen && + create_non_racy_file sixteen && git update-index --add sixteen && test $(ls .git/sharedindex.* | wc -l) -le 2 ' @@ -379,7 +391,7 @@ do # Create one new shared index file git config core.sharedrepository "$mode" && git config core.splitIndex true && - : >one && + create_non_racy_file one && git update-index --add one && echo "$modebits" >expect && test_modebits .git/index >actual && diff --git a/t/t1701-racy-split-index.sh b/t/t1701-racy-split-index.sh new file mode 100755 index 0000000000..5dc221ef38 --- /dev/null +++ b/t/t1701-racy-split-index.sh @@ -0,0 +1,214 @@ +#!/bin/sh + +# This test can give false success if your machine is sufficiently +# slow or all trials happened to happen on second boundaries. + +test_description='racy split index' + +. ./test-lib.sh + +test_expect_success 'setup' ' + # Only split the index when the test explicitly says so. + sane_unset GIT_TEST_SPLIT_INDEX && + git config splitIndex.maxPercentChange 100 && + + echo "cached content" >racy-file && + git add racy-file && + git commit -m initial && + + echo something >other-file && + # No raciness with this file. + test-tool chmtime =-20 other-file && + + echo "+cached content" >expect +' + +check_cached_diff () { + git diff-index --patch --cached $EMPTY_TREE racy-file >diff && + tail -1 diff >actual && + test_cmp expect actual +} + +trials="0 1 2 3 4" +for trial in $trials +do + test_expect_success "split the index while adding a racily clean file #$trial" ' + rm -f .git/index .git/sharedindex.* && + + # The next three commands must be run within the same + # second (so both writes to racy-file result in the same + # mtime) to create the interesting racy situation. + echo "cached content" >racy-file && + + # Update and split the index. The cache entry of + # racy-file will be stored only in the shared index. + git update-index --split-index --add racy-file && + + # File size must stay the same. + echo "dirty worktree" >racy-file && + + # Subsequent git commands should notice that racy-file + # and the split index have the same mtime, and check + # the content of the file to see if it is actually + # clean. + check_cached_diff + ' +done + +for trial in $trials +do + test_expect_success "add a racily clean file to an already split index #$trial" ' + rm -f .git/index .git/sharedindex.* && + + git update-index --split-index && + + # The next three commands must be run within the same + # second. + echo "cached content" >racy-file && + + # Update the split index. The cache entry of racy-file + # will be stored only in the split index. + git update-index --add racy-file && + + # File size must stay the same. + echo "dirty worktree" >racy-file && + + # Subsequent git commands should notice that racy-file + # and the split index have the same mtime, and check + # the content of the file to see if it is actually + # clean. + check_cached_diff + ' +done + +for trial in $trials +do + test_expect_success "split the index when the index contains a racily clean cache entry #$trial" ' + rm -f .git/index .git/sharedindex.* && + + # The next three commands must be run within the same + # second. + echo "cached content" >racy-file && + + git update-index --add racy-file && + + # File size must stay the same. + echo "dirty worktree" >racy-file && + + # Now wait a bit to ensure that the split index written + # below will get a more recent mtime than racy-file. + sleep 1 && + + # Update and split the index when the index contains + # the racily clean cache entry of racy-file. + # A corresponding replacement cache entry with smudged + # stat data should be added to the new split index. + git update-index --split-index --add other-file && + + # Subsequent git commands should notice the smudged + # stat data in the replacement cache entry and that it + # doesnt match with the file the worktree. + check_cached_diff + ' +done + +for trial in $trials +do + test_expect_success "update the split index when it contains a new racily clean cache entry #$trial" ' + rm -f .git/index .git/sharedindex.* && + + git update-index --split-index && + + # The next three commands must be run within the same + # second. + echo "cached content" >racy-file && + + # Update the split index. The cache entry of racy-file + # will be stored only in the split index. + git update-index --add racy-file && + + # File size must stay the same. + echo "dirty worktree" >racy-file && + + # Now wait a bit to ensure that the split index written + # below will get a more recent mtime than racy-file. + sleep 1 && + + # Update the split index when the racily clean cache + # entry of racy-file is only stored in the split index. + # An updated cache entry with smudged stat data should + # be added to the new split index. + git update-index --add other-file && + + # Subsequent git commands should notice the smudged + # stat data. + check_cached_diff + ' +done + +for trial in $trials +do + test_expect_success "update the split index when a racily clean cache entry is stored only in the shared index #$trial" ' + rm -f .git/index .git/sharedindex.* && + + # The next three commands must be run within the same + # second. + echo "cached content" >racy-file && + + # Update and split the index. The cache entry of + # racy-file will be stored only in the shared index. + git update-index --split-index --add racy-file && + + # File size must stay the same. + echo "dirty worktree" >racy-file && + + # Now wait a bit to ensure that the split index written + # below will get a more recent mtime than racy-file. + sleep 1 && + + # Update the split index when the racily clean cache + # entry of racy-file is only stored in the shared index. + # A corresponding replacement cache entry with smudged + # stat data should be added to the new split index. + git update-index --add other-file && + + # Subsequent git commands should notice the smudged + # stat data. + check_cached_diff + ' +done + +for trial in $trials +do + test_expect_success "update the split index after unpack trees() copied a racily clean cache entry from the shared index #$trial" ' + rm -f .git/index .git/sharedindex.* && + + # The next three commands must be run within the same + # second. + echo "cached content" >racy-file && + + # Update and split the index. The cache entry of + # racy-file will be stored only in the shared index. + git update-index --split-index --add racy-file && + + # File size must stay the same. + echo "dirty worktree" >racy-file && + + # Now wait a bit to ensure that the split index written + # below will get a more recent mtime than racy-file. + sleep 1 && + + # Update the split index after unpack_trees() copied the + # racily clean cache entry of racy-file from the shared + # index. A corresponding replacement cache entry + # with smudged stat data should be added to the new + # split index. + git read-tree -m HEAD && + + # Subsequent git commands should notice the smudged + # stat data. + check_cached_diff + ' +done + +test_done diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index 045aca1c18..6aae364171 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -122,6 +122,35 @@ test_expect_success 'changed commit' ' test_cmp expected actual ' +test_expect_success 'changed commit with sm config' ' + git range-diff --no-color --submodule=log topic...changed >actual && + cat >expected <<-EOF && + 1: 4de457d = 1: a4b3333 s/5/A/ + 2: fccce22 = 2: f51d370 s/4/A/ + 3: 147e64e ! 3: 0559556 s/11/B/ + @@ -10,7 +10,7 @@ + 9 + 10 + -11 + -+B + ++BB + 12 + 13 + 14 + 4: a63e992 ! 4: d966c5c s/12/B/ + @@ -8,7 +8,7 @@ + @@ + 9 + 10 + - B + + BB + -12 + +B + 13 + EOF + test_cmp expected actual +' + test_expect_success 'no commits on one side' ' git commit --amend -m "new message" && git range-diff master HEAD@{1} HEAD diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 453e6c35eb..6e0dd6f9e5 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -127,4 +127,14 @@ test_expect_success 'diff --no-index from repo subdir respects config (implicit) test_cmp expect actual.head ' +test_expect_success 'diff --no-index from repo subdir with absolute paths' ' + cat <<-EOF >expect && + 1 1 $(pwd)/non/git/{a => b} + EOF + test_expect_code 1 \ + git -C repo/sub diff --numstat \ + "$(pwd)/non/git/a" "$(pwd)/non/git/b" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4214-log-graph-octopus.sh b/t/t4214-log-graph-octopus.sh new file mode 100755 index 0000000000..dab96c89aa --- /dev/null +++ b/t/t4214-log-graph-octopus.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +test_description='git log --graph of skewed left octopus merge.' + +. ./test-lib.sh + +test_expect_success 'set up merge history' ' + cat >expect.uncolored <<-\EOF && + * left + | *---. octopus-merge + | |\ \ \ + |/ / / / + | | | * 4 + | | * | 3 + | | |/ + | * | 2 + | |/ + * | 1 + |/ + * initial + EOF + cat >expect.colors <<-\EOF && + * left + <RED>|<RESET> *<BLUE>-<RESET><BLUE>-<RESET><MAGENTA>-<RESET><MAGENTA>.<RESET> octopus-merge + <RED>|<RESET> <RED>|<RESET><YELLOW>\<RESET> <BLUE>\<RESET> <MAGENTA>\<RESET> + <RED>|<RESET><RED>/<RESET> <YELLOW>/<RESET> <BLUE>/<RESET> <MAGENTA>/<RESET> + <RED>|<RESET> <YELLOW>|<RESET> <BLUE>|<RESET> * 4 + <RED>|<RESET> <YELLOW>|<RESET> * <MAGENTA>|<RESET> 3 + <RED>|<RESET> <YELLOW>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET> + <RED>|<RESET> * <MAGENTA>|<RESET> 2 + <RED>|<RESET> <MAGENTA>|<RESET><MAGENTA>/<RESET> + * <MAGENTA>|<RESET> 1 + <MAGENTA>|<RESET><MAGENTA>/<RESET> + * initial + EOF + test_commit initial && + for i in 1 2 3 4 ; do + git checkout master -b $i || return $? + # Make tag name different from branch name, to avoid + # ambiguity error when calling checkout. + test_commit $i $i $i tag$i || return $? + done && + git checkout 1 -b merge && + test_tick && + git merge -m octopus-merge 1 2 3 4 && + git checkout 1 -b L && + test_commit left +' + +test_expect_success 'log --graph with tricky octopus merge with colors' ' + test_config log.graphColors red,green,yellow,blue,magenta,cyan && + git log --color=always --graph --date-order --pretty=tformat:%s --all >actual.colors.raw && + test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors && + test_cmp expect.colors actual.colors +' + +test_expect_success 'log --graph with tricky octopus merge, no color' ' + git log --color=never --graph --date-order --pretty=tformat:%s --all >actual.raw && + sed "s/ *\$//" actual.raw >actual && + test_cmp expect.uncolored actual +' + +# Repeat the previous two tests with "normal" octopus merge (i.e., +# without the first parent skewing to the "left" branch column). + +test_expect_success 'log --graph with normal octopus merge, no color' ' + cat >expect.uncolored <<-\EOF && + *---. octopus-merge + |\ \ \ + | | | * 4 + | | * | 3 + | | |/ + | * | 2 + | |/ + * | 1 + |/ + * initial + EOF + git log --color=never --graph --date-order --pretty=tformat:%s merge >actual.raw && + sed "s/ *\$//" actual.raw >actual && + test_cmp expect.uncolored actual +' + +test_expect_success 'log --graph with normal octopus merge with colors' ' + cat >expect.colors <<-\EOF && + *<YELLOW>-<RESET><YELLOW>-<RESET><BLUE>-<RESET><BLUE>.<RESET> octopus-merge + <RED>|<RESET><GREEN>\<RESET> <YELLOW>\<RESET> <BLUE>\<RESET> + <RED>|<RESET> <GREEN>|<RESET> <YELLOW>|<RESET> * 4 + <RED>|<RESET> <GREEN>|<RESET> * <BLUE>|<RESET> 3 + <RED>|<RESET> <GREEN>|<RESET> <BLUE>|<RESET><BLUE>/<RESET> + <RED>|<RESET> * <BLUE>|<RESET> 2 + <RED>|<RESET> <BLUE>|<RESET><BLUE>/<RESET> + * <BLUE>|<RESET> 1 + <BLUE>|<RESET><BLUE>/<RESET> + * initial + EOF + test_config log.graphColors red,green,yellow,blue,magenta,cyan && + git log --color=always --graph --date-order --pretty=tformat:%s merge >actual.colors.raw && + test_decode_color <actual.colors.raw | sed "s/ *\$//" >actual.colors && + test_cmp expect.colors actual.colors +' +test_done diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh index 2e718f0bde..24541ea137 100755 --- a/t/t5317-pack-objects-filter-objects.sh +++ b/t/t5317-pack-objects-filter-objects.sh @@ -67,6 +67,47 @@ test_expect_success 'verify normal and blob:none packfiles have same commits/tre test_cmp expected observed ' +test_expect_success 'get an error for missing tree object' ' + git init r5 && + echo foo >r5/foo && + git -C r5 add foo && + git -C r5 commit -m "foo" && + del=$(git -C r5 rev-parse HEAD^{tree} | sed "s|..|&/|") && + rm r5/.git/objects/$del && + test_must_fail git -C r5 pack-objects --rev --stdout 2>bad_tree <<-EOF && + HEAD + EOF + grep "bad tree object" bad_tree +' + +test_expect_success 'setup for tests of tree:0' ' + mkdir r1/subtree && + echo "This is a file in a subtree" >r1/subtree/file && + git -C r1 add subtree/file && + git -C r1 commit -m subtree +' + +test_expect_success 'verify tree:0 packfile has no blobs or trees' ' + git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF && + HEAD + EOF + git -C r1 index-pack ../commitsonly.pack && + git -C r1 verify-pack -v ../commitsonly.pack >objs && + ! grep -E "tree|blob" objs +' + +test_expect_success 'grab tree directly when using tree:0' ' + # We should get the tree specified directly but not its blobs or subtrees. + git -C r1 pack-objects --rev --stdout --filter=tree:0 >commitsonly.pack <<-EOF && + HEAD: + EOF + git -C r1 index-pack ../commitsonly.pack && + git -C r1 verify-pack -v ../commitsonly.pack >objs && + awk "/tree|blob/{print \$1}" objs >trees_and_blobs && + git -C r1 rev-parse HEAD: >expected && + test_cmp expected trees_and_blobs +' + # Test blob:limit=<n>[kmg] filter. # We boundary test around the size parameter. The filter is strictly less than # the value, so size 500 and 1000 should have the same results, but 1001 should diff --git a/t/t5321-pack-large-objects.sh b/t/t5321-pack-large-objects.sh new file mode 100755 index 0000000000..a75eab87d3 --- /dev/null +++ b/t/t5321-pack-large-objects.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# +# Copyright (c) 2018 Johannes Schindelin +# + +test_description='git pack-object with "large" deltas + +' +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-pack.sh + +# Two similar-ish objects that we have computed deltas between. +A=01d7713666f4de822776c7622c10f1b07de280dc +B=e68fe8129b546b101aee9510c5328e7f21ca1d18 + +test_expect_success 'setup' ' + clear_packs && + { + pack_header 2 && + pack_obj $A $B && + pack_obj $B + } >ab.pack && + pack_trailer ab.pack && + git index-pack --stdin <ab.pack +' + +test_expect_success 'repack large deltas' ' + printf "%s\\n" $A $B | + GIT_TEST_OE_DELTA_SIZE=2 git pack-objects tmp-pack +' + +test_done diff --git a/t/t5410-receive-pack-alternates.sh b/t/t5410-receive-pack-alternates.sh new file mode 100755 index 0000000000..f00d0da860 --- /dev/null +++ b/t/t5410-receive-pack-alternates.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +test_description='git receive-pack with alternate ref filtering' + +. ./test-lib.sh + +test_expect_success 'setup' ' + test_commit base && + git clone -s --bare . fork && + git checkout -b public/branch master && + test_commit public && + git checkout -b private/branch master && + test_commit private +' + +extract_haves () { + depacketize | perl -lne '/^(\S+) \.have/ and print $1' +} + +test_expect_success 'with core.alternateRefsCommand' ' + write_script fork/alternate-refs <<-\EOF && + git --git-dir="$1" for-each-ref \ + --format="%(objectname)" \ + refs/heads/public/ + EOF + test_config -C fork core.alternateRefsCommand ./alternate-refs && + git rev-parse public/branch >expect && + printf "0000" | git receive-pack fork >actual && + extract_haves <actual >actual.haves && + test_cmp expect actual.haves +' + +test_expect_success 'with core.alternateRefsPrefixes' ' + test_config -C fork core.alternateRefsPrefixes "refs/heads/private" && + git rev-parse private/branch >expect && + printf "0000" | git receive-pack fork >actual && + extract_haves <actual >actual.haves && + test_cmp expect actual.haves +' + +test_done diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index 3dc8f8ecec..8630b0cc39 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -381,6 +381,21 @@ test_expect_success 'using fetch command in remote-curl updates refs' ' test_cmp expect actual ' +test_expect_success 'fetch by SHA-1 without tag following' ' + SERVER="$HTTPD_DOCUMENT_ROOT_PATH/server" && + rm -rf "$SERVER" client && + + git init "$SERVER" && + test_commit -C "$SERVER" foo && + + git clone $HTTPD_URL/smart/server client && + + test_commit -C "$SERVER" bar && + git -C "$SERVER" rev-parse bar >bar_hash && + git -C client -c protocol.version=0 fetch \ + --no-tags origin $(cat bar_hash) +' + test_expect_success 'GIT_REDACT_COOKIES redacts cookies' ' rm -rf clone && echo "Set-Cookie: Foo=1" >cookies && diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 6ff6146923..336f02a41a 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -166,6 +166,48 @@ test_expect_success 'partial clone with transfer.fsckobjects=1 uses index-pack - grep "git index-pack.*--fsck-objects" trace ' +test_expect_success 'use fsck before and after manually fetching a missing subtree' ' + # push new commit so server has a subtree + mkdir src/dir && + echo "in dir" >src/dir/file.txt && + git -C src add dir/file.txt && + git -C src commit -m "file in dir" && + git -C src push -u srv master && + SUBTREE=$(git -C src rev-parse HEAD:dir) && + + rm -rf dst && + git clone --no-checkout --filter=tree:0 "file://$(pwd)/srv.bare" dst && + git -C dst fsck && + + # Make sure we only have commits, and all trees and blobs are missing. + git -C dst rev-list --missing=allow-any --objects master \ + >fetched_objects && + awk -f print_1.awk fetched_objects | + xargs -n1 git -C dst cat-file -t >fetched_types && + + sort -u fetched_types >unique_types.observed && + echo commit >unique_types.expected && + test_cmp unique_types.expected unique_types.observed && + + # Auto-fetch a tree with cat-file. + git -C dst cat-file -p $SUBTREE >tree_contents && + grep file.txt tree_contents && + + # fsck still works after an auto-fetch of a tree. + git -C dst fsck && + + # Auto-fetch all remaining trees and blobs with --missing=error + git -C dst rev-list --missing=error --objects master >fetched_objects && + test_line_count = 70 fetched_objects && + + awk -f print_1.awk fetched_objects | + xargs -n1 git -C dst cat-file -t >fetched_types && + + sort -u fetched_types >unique_types.observed && + test_write_lines blob commit tree >unique_types.expected && + test_cmp unique_types.expected unique_types.observed +' + test_expect_success 'partial clone fetches blobs pointed to by refs even if normally filtered out' ' rm -rf src dst && git init src && @@ -182,6 +224,23 @@ test_expect_success 'partial clone fetches blobs pointed to by refs even if norm git -C dst fsck ' +test_expect_success 'fetch what is specified on CLI even if already promised' ' + rm -rf src dst.git && + git init src && + test_commit -C src foo && + test_config -C src uploadpack.allowfilter 1 && + test_config -C src uploadpack.allowanysha1inwant 1 && + + git hash-object --stdin <src/foo.t >blob && + + git clone --bare --filter=blob:none "file://$(pwd)/src" dst.git && + git -C dst.git rev-list --objects --quiet --missing=print HEAD >missing_before && + grep "?$(cat blob)" missing_before && + git -C dst.git fetch origin $(cat blob) && + git -C dst.git rev-list --objects --quiet --missing=print HEAD >missing_after && + ! grep "?$(cat blob)" missing_after +' + . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index 98fbf39da3..8360188c01 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -79,6 +79,19 @@ test_expect_success 'fetch with git:// using protocol v2' ' grep "fetch< version 2" log ' +test_expect_success 'fetch by hash without tag following with protocol v2 does not list refs' ' + test_when_finished "rm -f log" && + + test_commit -C "$daemon_parent" two_a && + git -C "$daemon_parent" rev-parse two_a >two_a_hash && + + GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \ + fetch --no-tags origin $(cat two_a_hash) && + + grep "fetch< version 2" log && + ! grep "fetch> command=ls-refs" log +' + test_expect_success 'pull with git:// using protocol v2' ' test_when_finished "rm -f log" && @@ -286,6 +299,10 @@ test_expect_success 'dynamically fetch missing object' ' grep "version 2" trace ' +test_expect_success 'when dynamically fetching missing object, do not list refs' ' + ! grep "git> command=ls-refs" trace +' + test_expect_success 'partial fetch' ' rm -rf client "$(pwd)/trace" && git init client && diff --git a/t/t6112-rev-list-filters-objects.sh b/t/t6112-rev-list-filters-objects.sh index 53975c5724..eb32505a6e 100755 --- a/t/t6112-rev-list-filters-objects.sh +++ b/t/t6112-rev-list-filters-objects.sh @@ -34,6 +34,18 @@ test_expect_success 'verify blob:none omits all 5 blobs' ' test_cmp expected observed ' +test_expect_success 'specify blob explicitly prevents filtering' ' + file_3=$(git -C r1 ls-files -s file.3 | + awk -f print_2.awk) && + + file_4=$(git -C r1 ls-files -s file.4 | + awk -f print_2.awk) && + + git -C r1 rev-list --objects --filter=blob:none HEAD $file_3 >observed && + grep "$file_3" observed && + ! grep "$file_4" observed +' + test_expect_success 'verify emitted+omitted == all' ' git -C r1 rev-list --objects HEAD >revs && awk -f print_1.awk revs | @@ -232,6 +244,56 @@ test_expect_success 'verify sparse:oid=oid-ish omits top-level files' ' test_cmp expected observed ' +test_expect_success 'rev-list W/ --missing=print and --missing=allow-any for trees' ' + TREE=$(git -C r3 rev-parse HEAD:dir1) && + + # Create a spare repo because we will be deleting objects from this one. + git clone r3 r3.b && + + rm r3.b/.git/objects/$(echo $TREE | sed "s|^..|&/|") && + + git -C r3.b rev-list --quiet --missing=print --objects HEAD \ + >missing_objs 2>rev_list_err && + echo "?$TREE" >expected && + test_cmp expected missing_objs && + + # do not complain when a missing tree cannot be parsed + test_must_be_empty rev_list_err && + + git -C r3.b rev-list --missing=allow-any --objects HEAD \ + >objs 2>rev_list_err && + ! grep $TREE objs && + test_must_be_empty rev_list_err +' + +# Test tree:0 filter. + +test_expect_success 'verify tree:0 includes trees in "filtered" output' ' + git -C r3 rev-list --quiet --objects --filter-print-omitted \ + --filter=tree:0 HEAD >revs && + + awk -f print_1.awk revs | + sed s/~// | + xargs -n1 git -C r3 cat-file -t >unsorted_filtered_types && + + sort -u unsorted_filtered_types >filtered_types && + test_write_lines blob tree >expected && + test_cmp expected filtered_types +' + +# Make sure tree:0 does not iterate through any trees. + +test_expect_success 'filter a GIANT tree through tree:0' ' + GIT_TRACE=1 git -C r3 rev-list \ + --objects --filter=tree:0 HEAD 2>filter_trace && + grep "Skipping contents of tree [.][.][.]" filter_trace >actual && + # One line for each commit traversed. + test_line_count = 2 actual && + + # Make sure no other trees were considered besides the root. + ! grep "Skipping contents of tree [^.]" filter_trace +' + # Delete some loose objects and use rev-list, but WITHOUT any filtering. # This models previously omitted objects that we did not receive. diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh index b2ca77b338..5fcf281dfb 100755 --- a/t/t7005-editor.sh +++ b/t/t7005-editor.sh @@ -112,7 +112,7 @@ do done test_expect_success 'editor with a space' ' - echo "echo space >\$1" >"e space.sh" && + echo "echo space >\"\$1\"" >"e space.sh" && chmod a+x "e space.sh" && GIT_EDITOR="./e\ space.sh" git commit --amend && test space = "$(git show -s --pretty=format:%s)" diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 1a6773ee68..f1349af56e 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -99,12 +99,12 @@ test_expect_success '--dry-run with stuff to commit returns ok' ' git commit -m next -a --dry-run ' -test_expect_failure '--short with stuff to commit returns ok' ' +test_expect_success '--short with stuff to commit returns ok' ' echo bongo bongo bongo >>file && git commit -m next -a --short ' -test_expect_failure '--porcelain with stuff to commit returns ok' ' +test_expect_success '--porcelain with stuff to commit returns ok' ' echo bongo bongo bongo >>file && git commit -m next -a --porcelain ' @@ -698,4 +698,10 @@ test_expect_success '--dry-run with conflicts fixed from a merge' ' git commit -m "conflicts fixed from merge." ' +test_expect_success '--dry-run --short' ' + >test-file && + git add test-file && + git commit --dry-run --short +' + test_done diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh index 8384ad258c..3e0a61db23 100755 --- a/t/t7519-status-fsmonitor.sh +++ b/t/t7519-status-fsmonitor.sh @@ -4,13 +4,6 @@ test_description='git status with file system watcher' . ./test-lib.sh -# -# To run the entire git test suite using fsmonitor: -# -# copy t/t7519/fsmonitor-all to a location in your path and then set -# GIT_FSMONITOR_TEST=fsmonitor-all and run your tests. -# - # Note, after "git reset --hard HEAD" no extensions exist other than 'TREE' # "git update-index --fsmonitor" can be used to get the extension written # before testing the results. @@ -245,9 +238,9 @@ do git config core.preloadIndex $preload_val && if test $preload_val = true then - GIT_FORCE_PRELOAD_TEST=$preload_val; export GIT_FORCE_PRELOAD_TEST + GIT_TEST_PRELOAD_INDEX=$preload_val; export GIT_TEST_PRELOAD_INDEX else - unset GIT_FORCE_PRELOAD_TEST + sane_unset GIT_TEST_PRELOAD_INDEX fi ' diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index be5c1bd553..43aa4161cf 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -309,6 +309,8 @@ do echo ${HC}v:1:vvv } >expected && git grep --max-depth -1 -n -e vvv $H >actual && + test_cmp expected actual && + git grep --recursive -n -e vvv $H >actual && test_cmp expected actual ' @@ -317,6 +319,8 @@ do echo ${HC}v:1:vvv } >expected && git grep --max-depth 0 -n -e vvv $H >actual && + test_cmp expected actual && + git grep --no-recursive -n -e vvv $H >actual && test_cmp expected actual ' @@ -327,6 +331,8 @@ do echo ${HC}v:1:vvv } >expected && git grep --max-depth 0 -n -e vvv $H -- "*" >actual && + test_cmp expected actual && + git grep --no-recursive -n -e vvv $H -- "*" >actual && test_cmp expected actual ' @@ -344,6 +350,8 @@ do echo ${HC}t/v:1:vvv } >expected && git grep --max-depth 0 -n -e vvv $H -- t >actual && + test_cmp expected actual && + git grep --no-recursive -n -e vvv $H -- t >actual && test_cmp expected actual ' @@ -353,6 +361,8 @@ do echo ${HC}v:1:vvv } >expected && git grep --max-depth 0 -n -e vvv $H -- . t >actual && + test_cmp expected actual && + git grep --no-recursive -n -e vvv $H -- . t >actual && test_cmp expected actual ' @@ -362,6 +372,8 @@ do echo ${HC}v:1:vvv } >expected && git grep --max-depth 0 -n -e vvv $H -- t . >actual && + test_cmp expected actual && + git grep --no-recursive -n -e vvv $H -- t . >actual && test_cmp expected actual ' test_expect_success "grep $L with grep.extendedRegexp=false" ' diff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh index 48ec7679b8..41c09f11f4 100755 --- a/t/t9832-unshelve.sh +++ b/t/t9832-unshelve.sh @@ -19,8 +19,10 @@ test_expect_success 'init depot' ' p4 add file1 && p4 submit -d "change 1" && : >file_to_delete && + : >file_to_move && p4 add file_to_delete && - p4 submit -d "file to delete" + p4 add file_to_move && + p4 submit -d "add files to delete" ) ' @@ -36,6 +38,8 @@ test_expect_success 'create shelved changelist' ' echo "new file" >file2 && p4 add file2 && p4 delete file_to_delete && + p4 edit file_to_move && + p4 move file_to_move moved_file && p4 opened && p4 shelve -i <<EOF Change: new @@ -47,6 +51,8 @@ Files: //depot/file1 //depot/file2 //depot/file_to_delete + //depot/file_to_move + //depot/moved_file EOF ) && @@ -54,12 +60,14 @@ EOF cd "$git" && change=$(last_shelved_change) && git p4 unshelve $change && - git show refs/remotes/p4/unshelved/$change | grep -q "Further description" && - git cherry-pick refs/remotes/p4/unshelved/$change && + git show refs/remotes/p4-unshelved/$change | grep -q "Further description" && + git cherry-pick refs/remotes/p4-unshelved/$change && test_path_is_file file2 && test_cmp file1 "$cli"/file1 && test_cmp file2 "$cli"/file2 && - test_path_is_missing file_to_delete + test_path_is_missing file_to_delete && + test_path_is_missing file_to_move && + test_path_is_file moved_file ) ' @@ -88,10 +96,22 @@ EOF cd "$git" && change=$(last_shelved_change) && git p4 unshelve $change && - git diff refs/remotes/p4/unshelved/$change.0 refs/remotes/p4/unshelved/$change | grep -q file3 + git diff refs/remotes/p4-unshelved/$change.0 refs/remotes/p4-unshelved/$change | grep -q file3 ) ' +shelve_one_file () { + description="Change to be unshelved" && + file="$1" && + p4 shelve -i <<EOF +Change: new +Description: + $description +Files: + $file +EOF +} + # This is the tricky case where the shelved changelist base revision doesn't # match git-p4's idea of the base revision # @@ -108,29 +128,52 @@ test_expect_success 'create shelved changelist based on p4 change ahead of p4/ma p4 submit -d "change:foo" && p4 edit file1 && echo "bar" >>file1 && - p4 shelve -i <<EOF && -Change: new -Description: - Change to be unshelved -Files: - //depot/file1 -EOF + shelve_one_file //depot/file1 && change=$(last_shelved_change) && - p4 describe -S $change | grep -q "Change to be unshelved" + p4 describe -S $change >out.txt && + grep -q "Change to be unshelved" out.txt ) ' -# Now try to unshelve it. git-p4 should refuse to do so. +# Now try to unshelve it. test_expect_success 'try to unshelve the change' ' test_when_finished cleanup_git && ( change=$(last_shelved_change) && cd "$git" && - test_must_fail git p4 unshelve $change 2>out.txt && - grep -q "cannot unshelve" out.txt + git p4 unshelve $change >out.txt && + grep -q "unshelved changelist $change" out.txt ) ' +# Specify the origin. Create 2 unrelated files, and check that +# we only get the one in HEAD~, not the one in HEAD. + +test_expect_success 'unshelve specifying the origin' ' + ( + cd "$cli" && + : >unrelated_file0 && + p4 add unrelated_file0 && + p4 submit -d "unrelated" && + : >unrelated_file1 && + p4 add unrelated_file1 && + p4 submit -d "unrelated" && + : >file_to_shelve && + p4 add file_to_shelve && + shelve_one_file //depot/file_to_shelve + ) && + test_when_finished cleanup_git && + git p4 clone --dest="$git" //depot/@all && + ( + cd "$git" && + change=$(last_shelved_change) && + git p4 unshelve --origin HEAD~ $change && + git checkout refs/remotes/p4-unshelved/$change && + test_path_is_file unrelated_file0 && + test_path_is_missing unrelated_file1 && + test_path_is_file file_to_shelve + ) +' test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/test-lib.sh b/t/test-lib.sh index 3f95bfda60..897e6fcc94 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -134,9 +134,40 @@ export EDITOR GIT_TRACE_BARE=1 export GIT_TRACE_BARE -if test -n "${TEST_GIT_INDEX_VERSION:+isset}" +check_var_migration () { + # the warnings and hints given from this helper depends + # on end-user settings, which will disrupt the self-test + # done on the test framework itself. + case "$GIT_TEST_FRAMEWORK_SELFTEST" in + t) return ;; + esac + + old_name=$1 new_name=$2 + eval "old_isset=\${${old_name}:+isset}" + eval "new_isset=\${${new_name}:+isset}" + + case "$old_isset,$new_isset" in + isset,) + echo >&2 "warning: $old_name is now $new_name" + echo >&2 "hint: set $new_name too during the transition period" + eval "$new_name=\$$old_name" + ;; + isset,isset) + # do this later + # echo >&2 "warning: $old_name is now $new_name" + # echo >&2 "hint: remove $old_name" + ;; + esac +} + +check_var_migration GIT_FSMONITOR_TEST GIT_TEST_FSMONITOR +check_var_migration TEST_GIT_INDEX_VERSION GIT_TEST_INDEX_VERSION +check_var_migration GIT_FORCE_PRELOAD_TEST GIT_TEST_PRELOAD_INDEX + +# Use specific version of the index file format +if test -n "${GIT_TEST_INDEX_VERSION:+isset}" then - GIT_INDEX_VERSION="$TEST_GIT_INDEX_VERSION" + GIT_INDEX_VERSION="$GIT_TEST_INDEX_VERSION" export GIT_INDEX_VERSION fi |