3 test_description='compare full workdir to sparse workdir'
5 # The verify_cache_tree() check is not sparse-aware (yet).
6 # So, disable the check until that integration is complete.
7 GIT_TEST_CHECK_CACHE_TREE=0
13 test_expect_success 'setup' '
14 git init initial-repo &&
16 GIT_TEST_SPARSE_INDEX=0 &&
19 echo "after deep" >e &&
20 echo "after folder1" >g &&
22 mkdir folder1 folder2 deep x &&
23 mkdir deep/deeper1 deep/deeper2 &&
24 mkdir deep/deeper1/deepest &&
25 echo "after deeper1" >deep/e &&
26 echo "after deepest" >deep/deeper1/e &&
33 cp a deep/deeper1/deepest &&
34 cp -r deep/deeper1/deepest deep/deeper2 &&
36 git commit -m "initial commit" &&
37 git checkout -b base &&
38 for dir in folder1 folder2 deep
40 git checkout -b update-$dir &&
41 echo "updated $dir" >$dir/a &&
42 git commit -a -m "update $dir" || return 1
45 git checkout -b rename-base base &&
46 echo >folder1/larger-content <<-\EOF &&
53 cp folder1/larger-content folder2/ &&
54 cp folder1/larger-content deep/deeper1/ &&
56 git commit -m "add interesting rename content" &&
58 git checkout -b rename-out-to-out rename-base &&
59 mv folder1/a folder2/b &&
60 mv folder1/larger-content folder2/edited-content &&
61 echo >>folder2/edited-content &&
63 git commit -m "rename folder1/... to folder2/..." &&
65 git checkout -b rename-out-to-in rename-base &&
66 mv folder1/a deep/deeper1/b &&
67 mv folder1/larger-content deep/deeper1/edited-content &&
68 echo >>deep/deeper1/edited-content &&
70 git commit -m "rename folder1/... to deep/deeper1/..." &&
72 git checkout -b rename-in-to-out rename-base &&
73 mv deep/deeper1/a folder1/b &&
74 mv deep/deeper1/larger-content folder1/edited-content &&
75 echo >>folder1/edited-content &&
77 git commit -m "rename deep/deeper1/... to folder1/..." &&
79 git checkout -b deepest base &&
80 echo "updated deepest" >deep/deeper1/deepest/a &&
81 git commit -a -m "update deepest" &&
83 git checkout -f base &&
89 rm -rf full-checkout sparse-checkout sparse-index &&
91 # create repos in initial state
92 cp -r initial-repo full-checkout &&
93 git -C full-checkout reset --hard &&
95 cp -r initial-repo sparse-checkout &&
96 git -C sparse-checkout reset --hard &&
98 cp -r initial-repo sparse-index &&
99 git -C sparse-index reset --hard &&
101 # initialize sparse-checkout definitions
102 git -C sparse-checkout sparse-checkout init --cone &&
103 git -C sparse-checkout sparse-checkout set deep &&
104 git -C sparse-index sparse-checkout init --cone --sparse-index &&
105 test_cmp_config -C sparse-index true index.sparse &&
106 git -C sparse-index sparse-checkout set deep
111 cd sparse-checkout &&
112 "$@" >../sparse-checkout-out 2>../sparse-checkout-err
116 "$@" >../sparse-index-out 2>../sparse-index-err
123 "$@" >../full-checkout-out 2>../full-checkout-err
130 test_cmp full-checkout-out sparse-checkout-out &&
131 test_cmp full-checkout-out sparse-index-out &&
132 test_cmp full-checkout-err sparse-checkout-err &&
133 test_cmp full-checkout-err sparse-index-err
136 test_sparse_match () {
137 run_on_sparse "$@" &&
138 test_cmp sparse-checkout-out sparse-index-out &&
139 test_cmp sparse-checkout-err sparse-index-err
142 test_expect_success 'sparse-index contents' '
145 test-tool -C sparse-index read-cache --table >cache &&
146 for dir in folder1 folder2 x
148 TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
149 grep "040000 tree $TREE $dir/" cache \
153 git -C sparse-index sparse-checkout set folder1 &&
155 test-tool -C sparse-index read-cache --table >cache &&
156 for dir in deep folder2 x
158 TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
159 grep "040000 tree $TREE $dir/" cache \
163 git -C sparse-index sparse-checkout set deep/deeper1 &&
165 test-tool -C sparse-index read-cache --table >cache &&
166 for dir in deep/deeper2 folder1 folder2 x
168 TREE=$(git -C sparse-index rev-parse HEAD:$dir) &&
169 grep "040000 tree $TREE $dir/" cache \
173 # Disabling the sparse-index removes tree entries with full ones
174 git -C sparse-index sparse-checkout init --no-sparse-index &&
176 test-tool -C sparse-index read-cache --table >cache &&
177 ! grep "040000 tree" cache &&
178 test_sparse_match test-tool read-cache --table
181 test_expect_success 'expanded in-memory index matches full index' '
183 test_sparse_match test-tool read-cache --expand --table
186 test_expect_success 'status with options' '
188 test_sparse_match ls &&
189 test_all_match git status --porcelain=v2 &&
190 test_all_match git status --porcelain=v2 -z -u &&
191 test_all_match git status --porcelain=v2 -uno &&
192 run_on_all touch README.md &&
193 test_all_match git status --porcelain=v2 &&
194 test_all_match git status --porcelain=v2 -z -u &&
195 test_all_match git status --porcelain=v2 -uno &&
196 test_all_match git add README.md &&
197 test_all_match git status --porcelain=v2 &&
198 test_all_match git status --porcelain=v2 -z -u &&
199 test_all_match git status --porcelain=v2 -uno
202 test_expect_success 'add, commit, checkout' '
205 write_script edit-contents <<-\EOF &&
208 run_on_all ../edit-contents README.md &&
210 test_all_match git add README.md &&
211 test_all_match git status --porcelain=v2 &&
212 test_all_match git commit -m "Add README.md" &&
214 test_all_match git checkout HEAD~1 &&
215 test_all_match git checkout - &&
217 run_on_all ../edit-contents README.md &&
219 test_all_match git add -A &&
220 test_all_match git status --porcelain=v2 &&
221 test_all_match git commit -m "Extend README.md" &&
223 test_all_match git checkout HEAD~1 &&
224 test_all_match git checkout - &&
226 run_on_all ../edit-contents deep/newfile &&
228 test_all_match git status --porcelain=v2 -uno &&
229 test_all_match git status --porcelain=v2 &&
230 test_all_match git add . &&
231 test_all_match git status --porcelain=v2 &&
232 test_all_match git commit -m "add deep/newfile" &&
234 test_all_match git checkout HEAD~1 &&
235 test_all_match git checkout -
238 test_expect_success 'checkout and reset --hard' '
241 test_all_match git checkout update-folder1 &&
242 test_all_match git status --porcelain=v2 &&
244 test_all_match git checkout update-deep &&
245 test_all_match git status --porcelain=v2 &&
247 test_all_match git checkout -b reset-test &&
248 test_all_match git reset --hard deepest &&
249 test_all_match git reset --hard update-folder1 &&
250 test_all_match git reset --hard update-folder2
253 test_expect_success 'diff --staged' '
256 write_script edit-contents <<-\EOF &&
257 echo text >>README.md
259 run_on_all ../edit-contents &&
261 test_all_match git diff &&
262 test_all_match git diff --staged &&
263 test_all_match git add README.md &&
264 test_all_match git diff &&
265 test_all_match git diff --staged
268 test_expect_success 'diff with renames' '
271 for branch in rename-out-to-out rename-out-to-in rename-in-to-out
273 test_all_match git checkout rename-base &&
274 test_all_match git checkout $branch -- .&&
275 test_all_match git diff --staged --no-renames &&
276 test_all_match git diff --staged --find-renames || return 1
280 test_expect_success 'log with pathspec outside sparse definition' '
283 test_all_match git log -- a &&
284 test_all_match git log -- folder1/a &&
285 test_all_match git log -- folder2/a &&
286 test_all_match git log -- deep/a &&
287 test_all_match git log -- deep/deeper1/a &&
288 test_all_match git log -- deep/deeper1/deepest/a &&
290 test_all_match git checkout update-folder1 &&
291 test_all_match git log -- folder1/a
294 test_expect_success 'blame with pathspec inside sparse definition' '
297 test_all_match git blame a &&
298 test_all_match git blame deep/a &&
299 test_all_match git blame deep/deeper1/a &&
300 test_all_match git blame deep/deeper1/deepest/a
303 # TODO: blame currently does not support blaming files outside of the
304 # sparse definition. It complains that the file doesn't exist locally.
305 test_expect_failure 'blame with pathspec outside sparse definition' '
308 test_all_match git blame folder1/a &&
309 test_all_match git blame folder2/a &&
310 test_all_match git blame deep/deeper2/a &&
311 test_all_match git blame deep/deeper2/deepest/a
314 # TODO: reset currently does not behave as expected when in a
316 test_expect_failure 'checkout and reset (mixed)' '
319 test_all_match git checkout -b reset-test update-deep &&
320 test_all_match git reset deepest &&
321 test_all_match git reset update-folder1 &&
322 test_all_match git reset update-folder2
325 # Ensure that sparse-index behaves identically to
326 # sparse-checkout with a full index.
327 test_expect_success 'checkout and reset (mixed) [sparse]' '
330 test_sparse_match git checkout -b reset-test update-deep &&
331 test_sparse_match git reset deepest &&
332 test_sparse_match git reset update-folder1 &&
333 test_sparse_match git reset update-folder2
336 test_expect_success 'merge' '
339 test_all_match git checkout -b merge update-deep &&
340 test_all_match git merge -m "folder1" update-folder1 &&
341 test_all_match git rev-parse HEAD^{tree} &&
342 test_all_match git merge -m "folder2" update-folder2 &&
343 test_all_match git rev-parse HEAD^{tree}
346 test_expect_success 'merge with outside renames' '
349 for type in out-to-out out-to-in in-to-out
351 test_all_match git reset --hard &&
352 test_all_match git checkout -f -b merge-$type update-deep &&
353 test_all_match git merge -m "$type" rename-$type &&
354 test_all_match git rev-parse HEAD^{tree} || return 1
358 test_expect_success 'clean' '
361 echo bogus >>.gitignore &&
362 run_on_all cp ../.gitignore . &&
363 test_all_match git add .gitignore &&
364 test_all_match git commit -m "ignore bogus files" &&
366 run_on_sparse mkdir folder1 &&
367 run_on_all touch folder1/bogus &&
369 test_all_match git status --porcelain=v2 &&
370 test_all_match git clean -f &&
371 test_all_match git status --porcelain=v2 &&
372 test_sparse_match ls &&
373 test_sparse_match ls folder1 &&
375 test_all_match git clean -xf &&
376 test_all_match git status --porcelain=v2 &&
377 test_sparse_match ls &&
378 test_sparse_match ls folder1 &&
380 test_all_match git clean -xdf &&
381 test_all_match git status --porcelain=v2 &&
382 test_sparse_match ls &&
383 test_sparse_match ls folder1 &&
385 test_sparse_match test_path_is_dir folder1
388 test_expect_success 'submodule handling' '
391 test_all_match mkdir modules &&
392 test_all_match touch modules/a &&
393 test_all_match git add modules &&
394 test_all_match git commit -m "add modules directory" &&
396 run_on_all git submodule add "$(pwd)/initial-repo" modules/sub &&
397 test_all_match git commit -m "add submodule" &&
399 # having a submodule prevents "modules" from collapse
400 test-tool -C sparse-index read-cache --table >cache &&
401 grep "100644 blob .* modules/a" cache &&
402 grep "160000 commit $(git -C initial-repo rev-parse HEAD) modules/sub" cache
405 test_expect_success 'sparse-index is expanded and converted back' '
408 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
409 git -C sparse-index -c core.fsmonitor="" reset --hard &&
410 test_region index convert_to_sparse trace2.txt &&
411 test_region index ensure_full_index trace2.txt &&
414 GIT_TRACE2_EVENT="$(pwd)/trace2.txt" GIT_TRACE2_EVENT_NESTING=10 \
415 git -C sparse-index -c core.fsmonitor="" status -uno &&
416 test_region index ensure_full_index trace2.txt