Git fork
at reftables-rust 277 lines 7.5 kB view raw
1#!/bin/sh 2 3test_description='parallel-checkout basics 4 5Ensure that parallel-checkout basically works on clone and checkout, spawning 6the required number of workers and correctly populating both the index and the 7working tree. 8' 9 10TEST_NO_CREATE_REPO=1 11. ./test-lib.sh 12. "$TEST_DIRECTORY/lib-parallel-checkout.sh" 13 14# Test parallel-checkout with a branch switch containing a variety of file 15# creations, deletions, and modifications, involving different entry types. 16# The branches B1 and B2 have the following paths: 17# 18# B1 B2 19# a/a (file) a (file) 20# b (file) b/b (file) 21# 22# c/c (file) c (symlink) 23# d (symlink) d/d (file) 24# 25# e/e (file) e (submodule) 26# f (submodule) f/f (file) 27# 28# g (submodule) g (symlink) 29# h (symlink) h (submodule) 30# 31# Additionally, the following paths are present on both branches, but with 32# different contents: 33# 34# i (file) i (file) 35# j (symlink) j (symlink) 36# k (submodule) k (submodule) 37# 38# And the following paths are only present in one of the branches: 39# 40# l/l (file) - 41# - m/m (file) 42# 43test_expect_success 'setup repo for checkout with various types of changes' ' 44 test_config_global protocol.file.allow always && 45 46 git init sub && 47 ( 48 cd sub && 49 git checkout -b B2 && 50 echo B2 >file && 51 git add file && 52 git commit -m file && 53 54 git checkout -b B1 && 55 echo B1 >file && 56 git add file && 57 git commit -m file 58 ) && 59 60 git init various && 61 ( 62 cd various && 63 64 git checkout -b B1 && 65 mkdir a c e && 66 echo a/a >a/a && 67 echo b >b && 68 echo c/c >c/c && 69 test_ln_s_add c d && 70 echo e/e >e/e && 71 git submodule add ../sub f && 72 git submodule add ../sub g && 73 test_ln_s_add c h && 74 75 echo "B1 i" >i && 76 test_ln_s_add c j && 77 git submodule add -b B1 ../sub k && 78 mkdir l && 79 echo l/l >l/l && 80 81 git add . && 82 git commit -m B1 && 83 84 git checkout -b B2 && 85 git rm -rf :^.gitmodules :^k && 86 mkdir b d f && 87 echo a >a && 88 echo b/b >b/b && 89 test_ln_s_add b c && 90 echo d/d >d/d && 91 git submodule add ../sub e && 92 echo f/f >f/f && 93 test_ln_s_add b g && 94 git submodule add ../sub h && 95 96 echo "B2 i" >i && 97 test_ln_s_add b j && 98 git -C k checkout B2 && 99 mkdir m && 100 echo m/m >m/m && 101 102 git add . && 103 git commit -m B2 && 104 105 git checkout --recurse-submodules B1 106 ) 107' 108 109for mode in sequential parallel sequential-fallback 110do 111 case $mode in 112 sequential) workers=1 threshold=0 expected_workers=0 ;; 113 parallel) workers=2 threshold=0 expected_workers=2 ;; 114 sequential-fallback) workers=2 threshold=100 expected_workers=0 ;; 115 esac 116 117 test_expect_success "$mode checkout" ' 118 repo=various_$mode && 119 cp -R -P various $repo && 120 121 # The just copied files have more recent timestamps than their 122 # associated index entries. So refresh the cached timestamps 123 # to avoid an "entry not up-to-date" error from `git checkout`. 124 # We only have to do this for the submodules as `git checkout` 125 # will already refresh the superproject index before performing 126 # the up-to-date check. 127 # 128 git -C $repo submodule foreach "git update-index --refresh" && 129 130 set_checkout_config $workers $threshold && 131 test_checkout_workers $expected_workers \ 132 git -C $repo checkout --recurse-submodules B2 && 133 verify_checkout $repo 134 ' 135done 136 137for mode in parallel sequential-fallback 138do 139 case $mode in 140 parallel) workers=2 threshold=0 expected_workers=2 ;; 141 sequential-fallback) workers=2 threshold=100 expected_workers=0 ;; 142 esac 143 144 test_expect_success "$mode checkout on clone" ' 145 test_config_global protocol.file.allow always && 146 repo=various_${mode}_clone && 147 set_checkout_config $workers $threshold && 148 test_checkout_workers $expected_workers \ 149 git clone --recurse-submodules --branch B2 various $repo && 150 verify_checkout $repo 151 ' 152done 153 154# Just to be paranoid, actually compare the working trees' contents directly. 155test_expect_success 'compare the working trees' ' 156 rm -rf various_*/.git && 157 rm -rf various_*/*/.git && 158 159 # We use `git diff` instead of `diff -r` because the latter would 160 # follow symlinks, and not all `diff` implementations support the 161 # `--no-dereference` option. 162 # 163 git diff --no-index various_sequential various_parallel && 164 git diff --no-index various_sequential various_parallel_clone && 165 git diff --no-index various_sequential various_sequential-fallback && 166 git diff --no-index various_sequential various_sequential-fallback_clone 167' 168 169# Currently, each submodule is checked out in a separated child process, but 170# these subprocesses must also be able to use parallel checkout workers to 171# write the submodules' entries. 172test_expect_success 'submodules can use parallel checkout' ' 173 set_checkout_config 2 0 && 174 git init super && 175 ( 176 cd super && 177 git init sub && 178 test_commit -C sub A && 179 test_commit -C sub B && 180 git submodule add ./sub && 181 git commit -m sub && 182 rm sub/* && 183 test_checkout_workers 2 git checkout --recurse-submodules . 184 ) 185' 186 187test_expect_success 'parallel checkout respects --[no]-force' ' 188 set_checkout_config 2 0 && 189 git init dirty && 190 ( 191 cd dirty && 192 mkdir D && 193 test_commit D/F && 194 test_commit F && 195 196 rm -rf D && 197 echo changed >D && 198 echo changed >F.t && 199 200 # We expect 0 workers because there is nothing to be done 201 test_checkout_workers 0 git checkout HEAD && 202 test_path_is_file D && 203 grep changed D && 204 grep changed F.t && 205 206 test_checkout_workers 2 git checkout --force HEAD && 207 test_path_is_dir D && 208 grep D/F D/F.t && 209 grep F F.t 210 ) 211' 212 213test_expect_success SYMLINKS 'parallel checkout checks for symlinks in leading dirs' ' 214 set_checkout_config 2 0 && 215 git init symlinks && 216 ( 217 cd symlinks && 218 mkdir D untracked && 219 # Commit 2 files to have enough work for 2 parallel workers 220 test_commit D/A && 221 test_commit D/B && 222 rm -rf D && 223 ln -s untracked D && 224 225 test_checkout_workers 2 git checkout --force HEAD && 226 ! test -h D && 227 grep D/A D/A.t && 228 grep D/B D/B.t 229 ) 230' 231 232# This test is here (and not in e.g. t2022-checkout-paths.sh), because we 233# check the final report including sequential, parallel, and delayed entries 234# all at the same time. So we must have finer control of the parallel checkout 235# variables. 236test_expect_success '"git checkout ." report should not include failed entries' ' 237 test_config_global filter.delay.process \ 238 "test-tool rot13-filter --always-delay --log=delayed.log clean smudge delay" && 239 test_config_global filter.delay.required true && 240 test_config_global filter.cat.clean cat && 241 test_config_global filter.cat.smudge cat && 242 test_config_global filter.cat.required true && 243 244 set_checkout_config 2 0 && 245 git init failed_entries && 246 ( 247 cd failed_entries && 248 cat >.gitattributes <<-EOF && 249 *delay* filter=delay 250 parallel-ineligible* filter=cat 251 EOF 252 echo a >missing-delay.a && 253 echo a >parallel-ineligible.a && 254 echo a >parallel-eligible.a && 255 echo b >success-delay.b && 256 echo b >parallel-ineligible.b && 257 echo b >parallel-eligible.b && 258 git add -A && 259 git commit -m files && 260 261 a_blob="$(git rev-parse :parallel-ineligible.a)" && 262 rm .git/objects/$(test_oid_to_path $a_blob) && 263 rm *.a *.b && 264 265 test_checkout_workers 2 test_must_fail git checkout . 2>err && 266 267 # All *.b entries should succeed and all *.a entries should fail: 268 # - missing-delay.a: the delay filter will drop this path 269 # - parallel-*.a: the blob will be missing 270 # 271 grep "Updated 3 paths from the index" err && 272 test_stdout_line_count = 3 ls *.b && 273 ! ls *.a 274 ) 275' 276 277test_done