The second batch
[git] / t / t2080-parallel-checkout-basics.sh
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 the
7 working tree.
8 '
9
10 TEST_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 #
43 test_expect_success 'setup repo for checkout with various types of changes' '
44         git init sub &&
45         (
46                 cd sub &&
47                 git checkout -b B2 &&
48                 echo B2 >file &&
49                 git add file &&
50                 git commit -m file &&
51
52                 git checkout -b B1 &&
53                 echo B1 >file &&
54                 git add file &&
55                 git commit -m file
56         ) &&
57
58         git init various &&
59         (
60                 cd various &&
61
62                 git checkout -b B1 &&
63                 mkdir a c e &&
64                 echo a/a >a/a &&
65                 echo b >b &&
66                 echo c/c >c/c &&
67                 test_ln_s_add c d &&
68                 echo e/e >e/e &&
69                 git submodule add ../sub f &&
70                 git submodule add ../sub g &&
71                 test_ln_s_add c h &&
72
73                 echo "B1 i" >i &&
74                 test_ln_s_add c j &&
75                 git submodule add -b B1 ../sub k &&
76                 mkdir l &&
77                 echo l/l >l/l &&
78
79                 git add . &&
80                 git commit -m B1 &&
81
82                 git checkout -b B2 &&
83                 git rm -rf :^.gitmodules :^k &&
84                 mkdir b d f &&
85                 echo a >a &&
86                 echo b/b >b/b &&
87                 test_ln_s_add b c &&
88                 echo d/d >d/d &&
89                 git submodule add ../sub e &&
90                 echo f/f >f/f &&
91                 test_ln_s_add b g &&
92                 git submodule add ../sub h &&
93
94                 echo "B2 i" >i &&
95                 test_ln_s_add b j &&
96                 git -C k checkout B2 &&
97                 mkdir m &&
98                 echo m/m >m/m &&
99
100                 git add . &&
101                 git commit -m B2 &&
102
103                 git checkout --recurse-submodules B1
104         )
105 '
106
107 for mode in sequential parallel sequential-fallback
108 do
109         case $mode in
110         sequential)          workers=1 threshold=0 expected_workers=0 ;;
111         parallel)            workers=2 threshold=0 expected_workers=2 ;;
112         sequential-fallback) workers=2 threshold=100 expected_workers=0 ;;
113         esac
114
115         test_expect_success "$mode checkout" '
116                 repo=various_$mode &&
117                 cp -R -P various $repo &&
118
119                 # The just copied files have more recent timestamps than their
120                 # associated index entries. So refresh the cached timestamps
121                 # to avoid an "entry not up-to-date" error from `git checkout`.
122                 # We only have to do this for the submodules as `git checkout`
123                 # will already refresh the superproject index before performing
124                 # the up-to-date check.
125                 #
126                 git -C $repo submodule foreach "git update-index --refresh" &&
127
128                 set_checkout_config $workers $threshold &&
129                 test_checkout_workers $expected_workers \
130                         git -C $repo checkout --recurse-submodules B2 &&
131                 verify_checkout $repo
132         '
133 done
134
135 for mode in parallel sequential-fallback
136 do
137         case $mode in
138         parallel)            workers=2 threshold=0 expected_workers=2 ;;
139         sequential-fallback) workers=2 threshold=100 expected_workers=0 ;;
140         esac
141
142         test_expect_success "$mode checkout on clone" '
143                 repo=various_${mode}_clone &&
144                 set_checkout_config $workers $threshold &&
145                 test_checkout_workers $expected_workers \
146                         git clone --recurse-submodules --branch B2 various $repo &&
147                 verify_checkout $repo
148         '
149 done
150
151 # Just to be paranoid, actually compare the working trees' contents directly.
152 test_expect_success 'compare the working trees' '
153         rm -rf various_*/.git &&
154         rm -rf various_*/*/.git &&
155
156         # We use `git diff` instead of `diff -r` because the latter would
157         # follow symlinks, and not all `diff` implementations support the
158         # `--no-dereference` option.
159         #
160         git diff --no-index various_sequential various_parallel &&
161         git diff --no-index various_sequential various_parallel_clone &&
162         git diff --no-index various_sequential various_sequential-fallback &&
163         git diff --no-index various_sequential various_sequential-fallback_clone
164 '
165
166 # Currently, each submodule is checked out in a separated child process, but
167 # these subprocesses must also be able to use parallel checkout workers to
168 # write the submodules' entries.
169 test_expect_success 'submodules can use parallel checkout' '
170         set_checkout_config 2 0 &&
171         git init super &&
172         (
173                 cd super &&
174                 git init sub &&
175                 test_commit -C sub A &&
176                 test_commit -C sub B &&
177                 git submodule add ./sub &&
178                 git commit -m sub &&
179                 rm sub/* &&
180                 test_checkout_workers 2 git checkout --recurse-submodules .
181         )
182 '
183
184 test_expect_success 'parallel checkout respects --[no]-force' '
185         set_checkout_config 2 0 &&
186         git init dirty &&
187         (
188                 cd dirty &&
189                 mkdir D &&
190                 test_commit D/F &&
191                 test_commit F &&
192
193                 rm -rf D &&
194                 echo changed >D &&
195                 echo changed >F.t &&
196
197                 # We expect 0 workers because there is nothing to be done
198                 test_checkout_workers 0 git checkout HEAD &&
199                 test_path_is_file D &&
200                 grep changed D &&
201                 grep changed F.t &&
202
203                 test_checkout_workers 2 git checkout --force HEAD &&
204                 test_path_is_dir D &&
205                 grep D/F D/F.t &&
206                 grep F F.t
207         )
208 '
209
210 test_expect_success SYMLINKS 'parallel checkout checks for symlinks in leading dirs' '
211         set_checkout_config 2 0 &&
212         git init symlinks &&
213         (
214                 cd symlinks &&
215                 mkdir D untracked &&
216                 # Commit 2 files to have enough work for 2 parallel workers
217                 test_commit D/A &&
218                 test_commit D/B &&
219                 rm -rf D &&
220                 ln -s untracked D &&
221
222                 test_checkout_workers 2 git checkout --force HEAD &&
223                 ! test -h D &&
224                 grep D/A D/A.t &&
225                 grep D/B D/B.t
226         )
227 '
228
229 test_done