|
| 1 | +#!/bin/sh |
| 2 | + |
| 3 | +test_description='parallel-checkout basics |
| 4 | +
|
| 5 | +Ensure that parallel-checkout basically works on clone and checkout, spawning |
| 6 | +the required number of workers and correctly populating both the index and |
| 7 | +working tree. |
| 8 | +' |
| 9 | + |
| 10 | +TEST_NO_CREATE_REPO=1 |
| 11 | +. ./test-lib.sh |
| 12 | +. "$TEST_DIRECTORY/lib-parallel-checkout.sh" |
| 13 | + |
| 14 | +# NEEDSWORK: cloning a SHA1 repo with GIT_TEST_DEFAULT_HASH set to "sha256" |
| 15 | +# currently produces a wrong result (See |
| 16 | +# https://lore.kernel.org/git/[email protected]/). |
| 17 | +# So we skip the "parallel-checkout during clone" tests when this test flag is |
| 18 | +# set to "sha256". Remove this when the bug is fixed. |
| 19 | +# |
| 20 | +if test "$GIT_TEST_DEFAULT_HASH" = "sha256" |
| 21 | +then |
| 22 | + skip_all="t2080 currently don't work with GIT_TEST_DEFAULT_HASH=sha256" |
| 23 | + test_done |
| 24 | +fi |
| 25 | + |
| 26 | +R_BASE=$GIT_BUILD_DIR |
| 27 | + |
| 28 | +test_expect_success 'sequential clone' ' |
| 29 | + git_pc 1 0 0 clone --quiet -- $R_BASE r_sequential && |
| 30 | + verify_checkout r_sequential |
| 31 | +' |
| 32 | + |
| 33 | +test_expect_success 'parallel clone' ' |
| 34 | + git_pc 2 0 2 clone --quiet -- $R_BASE r_parallel && |
| 35 | + verify_checkout r_parallel |
| 36 | +' |
| 37 | + |
| 38 | +test_expect_success 'fallback to sequential clone (threshold)' ' |
| 39 | + git -C $R_BASE ls-files >files && |
| 40 | + nr_files=$(wc -l <files) && |
| 41 | + threshold=$(($nr_files + 1)) && |
| 42 | +
|
| 43 | + git_pc 2 $threshold 0 clone --quiet -- $R_BASE r_sequential_fallback && |
| 44 | + verify_checkout r_sequential_fallback |
| 45 | +' |
| 46 | + |
| 47 | +# Just to be paranoid, actually compare the contents of the worktrees directly. |
| 48 | +test_expect_success 'compare working trees from clones' ' |
| 49 | + rm -rf r_sequential/.git && |
| 50 | + rm -rf r_parallel/.git && |
| 51 | + rm -rf r_sequential_fallback/.git && |
| 52 | + diff -qr r_sequential r_parallel && |
| 53 | + diff -qr r_sequential r_sequential_fallback |
| 54 | +' |
| 55 | + |
| 56 | +# Test parallel-checkout with different operations (creation, deletion, |
| 57 | +# modification) and entry types. A branch switch from B1 to B2 will contain: |
| 58 | +# |
| 59 | +# - a (file): modified |
| 60 | +# - e/x (file): deleted |
| 61 | +# - b (symlink): deleted |
| 62 | +# - b/f (file): created |
| 63 | +# - e (symlink): created |
| 64 | +# - d (submodule): created |
| 65 | +# |
| 66 | +test_expect_success SYMLINKS 'setup repo for checkout with various operations' ' |
| 67 | + git init various && |
| 68 | + ( |
| 69 | + cd various && |
| 70 | + git checkout -b B1 && |
| 71 | + echo a>a && |
| 72 | + mkdir e && |
| 73 | + echo e/x >e/x && |
| 74 | + ln -s e b && |
| 75 | + git add -A && |
| 76 | + git commit -m B1 && |
| 77 | +
|
| 78 | + git checkout -b B2 && |
| 79 | + echo modified >a && |
| 80 | + rm -rf e && |
| 81 | + rm b && |
| 82 | + mkdir b && |
| 83 | + echo b/f >b/f && |
| 84 | + ln -s b e && |
| 85 | + git init d && |
| 86 | + test_commit -C d f && |
| 87 | + git submodule add ./d && |
| 88 | + git add -A && |
| 89 | + git commit -m B2 && |
| 90 | +
|
| 91 | + git checkout --recurse-submodules B1 |
| 92 | + ) |
| 93 | +' |
| 94 | + |
| 95 | +test_expect_success SYMLINKS 'sequential checkout' ' |
| 96 | + cp -R various various_sequential && |
| 97 | + git_pc 1 0 0 -C various_sequential checkout --recurse-submodules B2 && |
| 98 | + verify_checkout various_sequential |
| 99 | +' |
| 100 | + |
| 101 | +test_expect_success SYMLINKS 'parallel checkout' ' |
| 102 | + cp -R various various_parallel && |
| 103 | + git_pc 2 0 2 -C various_parallel checkout --recurse-submodules B2 && |
| 104 | + verify_checkout various_parallel |
| 105 | +' |
| 106 | + |
| 107 | +test_expect_success SYMLINKS 'fallback to sequential checkout (threshold)' ' |
| 108 | + cp -R various various_sequential_fallback && |
| 109 | + git_pc 2 100 0 -C various_sequential_fallback checkout --recurse-submodules B2 && |
| 110 | + verify_checkout various_sequential_fallback |
| 111 | +' |
| 112 | + |
| 113 | +test_expect_success SYMLINKS 'compare working trees from checkouts' ' |
| 114 | + rm -rf various_sequential/.git && |
| 115 | + rm -rf various_parallel/.git && |
| 116 | + rm -rf various_sequential_fallback/.git && |
| 117 | + diff -qr various_sequential various_parallel && |
| 118 | + diff -qr various_sequential various_sequential_fallback |
| 119 | +' |
| 120 | + |
| 121 | +test_cmp_str() |
| 122 | +{ |
| 123 | + echo "$1" >tmp && |
| 124 | + test_cmp tmp "$2" |
| 125 | +} |
| 126 | + |
| 127 | +test_expect_success 'parallel checkout respects --[no]-force' ' |
| 128 | + git init dirty && |
| 129 | + ( |
| 130 | + cd dirty && |
| 131 | + mkdir D && |
| 132 | + test_commit D/F && |
| 133 | + test_commit F && |
| 134 | +
|
| 135 | + echo changed >F.t && |
| 136 | + rm -rf D && |
| 137 | + echo changed >D && |
| 138 | +
|
| 139 | + # We expect 0 workers because there is nothing to be updated |
| 140 | + git_pc 2 0 0 checkout HEAD && |
| 141 | + test_path_is_file D && |
| 142 | + test_cmp_str changed D && |
| 143 | + test_cmp_str changed F.t && |
| 144 | +
|
| 145 | + git_pc 2 0 2 checkout --force HEAD && |
| 146 | + test_path_is_dir D && |
| 147 | + test_cmp_str D/F D/F.t && |
| 148 | + test_cmp_str F F.t |
| 149 | + ) |
| 150 | +' |
| 151 | + |
| 152 | +test_expect_success SYMLINKS 'parallel checkout checks for symlinks in leading dirs' ' |
| 153 | + git init symlinks && |
| 154 | + ( |
| 155 | + cd symlinks && |
| 156 | + mkdir D E && |
| 157 | +
|
| 158 | + # Create two entries in D to have enough work for 2 parallel |
| 159 | + # workers |
| 160 | + test_commit D/A && |
| 161 | + test_commit D/B && |
| 162 | + test_commit E/C && |
| 163 | + rm -rf D && |
| 164 | + ln -s E D && |
| 165 | +
|
| 166 | + git_pc 2 0 2 checkout --force HEAD && |
| 167 | + ! test -L D && |
| 168 | + test_cmp_str D/A D/A.t && |
| 169 | + test_cmp_str D/B D/B.t |
| 170 | + ) |
| 171 | +' |
| 172 | + |
| 173 | +test_expect_success SYMLINKS,CASE_INSENSITIVE_FS 'symlink colliding with leading dir' ' |
| 174 | + git init colliding-symlink && |
| 175 | + ( |
| 176 | + cd colliding-symlink && |
| 177 | + file_hex=$(git hash-object -w --stdin </dev/null) && |
| 178 | + file_oct=$(echo $file_hex | hex2oct) && |
| 179 | +
|
| 180 | + sym_hex=$(echo "./D" | git hash-object -w --stdin) && |
| 181 | + sym_oct=$(echo $sym_hex | hex2oct) && |
| 182 | +
|
| 183 | + printf "100644 D/A\0${file_oct}" >tree && |
| 184 | + printf "100644 E/B\0${file_oct}" >>tree && |
| 185 | + printf "120000 e\0${sym_oct}" >>tree && |
| 186 | +
|
| 187 | + tree_hex=$(git hash-object -w -t tree --stdin <tree) && |
| 188 | + commit_hex=$(git commit-tree -m collisions $tree_hex) && |
| 189 | + git update-ref refs/heads/colliding-symlink $commit_hex && |
| 190 | +
|
| 191 | + git_pc 2 0 2 checkout colliding-symlink && |
| 192 | + test_path_is_dir D && |
| 193 | + test_path_is_missing D/B |
| 194 | + ) |
| 195 | +' |
| 196 | + |
| 197 | +test_done |
0 commit comments