]> git.ipfire.org Git - thirdparty/git.git/blob - t/t1092-sparse-checkout-compatibility.sh
Merge branch 'en/ort-directory-rename'
[thirdparty/git.git] / t / t1092-sparse-checkout-compatibility.sh
1 #!/bin/sh
2
3 test_description='compare full workdir to sparse workdir'
4
5 . ./test-lib.sh
6
7 test_expect_success 'setup' '
8 git init initial-repo &&
9 (
10 cd initial-repo &&
11 echo a >a &&
12 echo "after deep" >e &&
13 echo "after folder1" >g &&
14 echo "after x" >z &&
15 mkdir folder1 folder2 deep x &&
16 mkdir deep/deeper1 deep/deeper2 &&
17 mkdir deep/deeper1/deepest &&
18 echo "after deeper1" >deep/e &&
19 echo "after deepest" >deep/deeper1/e &&
20 cp a folder1 &&
21 cp a folder2 &&
22 cp a x &&
23 cp a deep &&
24 cp a deep/deeper1 &&
25 cp a deep/deeper2 &&
26 cp a deep/deeper1/deepest &&
27 cp -r deep/deeper1/deepest deep/deeper2 &&
28 git add . &&
29 git commit -m "initial commit" &&
30 git checkout -b base &&
31 for dir in folder1 folder2 deep
32 do
33 git checkout -b update-$dir &&
34 echo "updated $dir" >$dir/a &&
35 git commit -a -m "update $dir" || return 1
36 done &&
37
38 git checkout -b rename-base base &&
39 echo >folder1/larger-content <<-\EOF &&
40 matching
41 lines
42 help
43 inexact
44 renames
45 EOF
46 cp folder1/larger-content folder2/ &&
47 cp folder1/larger-content deep/deeper1/ &&
48 git add . &&
49 git commit -m "add interesting rename content" &&
50
51 git checkout -b rename-out-to-out rename-base &&
52 mv folder1/a folder2/b &&
53 mv folder1/larger-content folder2/edited-content &&
54 echo >>folder2/edited-content &&
55 git add . &&
56 git commit -m "rename folder1/... to folder2/..." &&
57
58 git checkout -b rename-out-to-in rename-base &&
59 mv folder1/a deep/deeper1/b &&
60 mv folder1/larger-content deep/deeper1/edited-content &&
61 echo >>deep/deeper1/edited-content &&
62 git add . &&
63 git commit -m "rename folder1/... to deep/deeper1/..." &&
64
65 git checkout -b rename-in-to-out rename-base &&
66 mv deep/deeper1/a folder1/b &&
67 mv deep/deeper1/larger-content folder1/edited-content &&
68 echo >>folder1/edited-content &&
69 git add . &&
70 git commit -m "rename deep/deeper1/... to folder1/..." &&
71
72 git checkout -b deepest base &&
73 echo "updated deepest" >deep/deeper1/deepest/a &&
74 git commit -a -m "update deepest" &&
75
76 git checkout -f base &&
77 git reset --hard
78 )
79 '
80
81 init_repos () {
82 rm -rf full-checkout sparse-checkout sparse-index &&
83
84 # create repos in initial state
85 cp -r initial-repo full-checkout &&
86 git -C full-checkout reset --hard &&
87
88 cp -r initial-repo sparse-checkout &&
89 git -C sparse-checkout reset --hard &&
90 git -C sparse-checkout sparse-checkout init --cone &&
91
92 # initialize sparse-checkout definitions
93 git -C sparse-checkout sparse-checkout set deep
94 }
95
96 run_on_sparse () {
97 (
98 cd sparse-checkout &&
99 $* >../sparse-checkout-out 2>../sparse-checkout-err
100 )
101 }
102
103 run_on_all () {
104 (
105 cd full-checkout &&
106 $* >../full-checkout-out 2>../full-checkout-err
107 ) &&
108 run_on_sparse $*
109 }
110
111 test_all_match () {
112 run_on_all $* &&
113 test_cmp full-checkout-out sparse-checkout-out &&
114 test_cmp full-checkout-err sparse-checkout-err
115 }
116
117 test_expect_success 'status with options' '
118 init_repos &&
119 test_all_match git status --porcelain=v2 &&
120 test_all_match git status --porcelain=v2 -z -u &&
121 test_all_match git status --porcelain=v2 -uno &&
122 run_on_all "touch README.md" &&
123 test_all_match git status --porcelain=v2 &&
124 test_all_match git status --porcelain=v2 -z -u &&
125 test_all_match git status --porcelain=v2 -uno &&
126 test_all_match git add README.md &&
127 test_all_match git status --porcelain=v2 &&
128 test_all_match git status --porcelain=v2 -z -u &&
129 test_all_match git status --porcelain=v2 -uno
130 '
131
132 test_expect_success 'add, commit, checkout' '
133 init_repos &&
134
135 write_script edit-contents <<-\EOF &&
136 echo text >>$1
137 EOF
138 run_on_all "../edit-contents README.md" &&
139
140 test_all_match git add README.md &&
141 test_all_match git status --porcelain=v2 &&
142 test_all_match git commit -m "Add README.md" &&
143
144 test_all_match git checkout HEAD~1 &&
145 test_all_match git checkout - &&
146
147 run_on_all "../edit-contents README.md" &&
148
149 test_all_match git add -A &&
150 test_all_match git status --porcelain=v2 &&
151 test_all_match git commit -m "Extend README.md" &&
152
153 test_all_match git checkout HEAD~1 &&
154 test_all_match git checkout - &&
155
156 run_on_all "../edit-contents deep/newfile" &&
157
158 test_all_match git status --porcelain=v2 -uno &&
159 test_all_match git status --porcelain=v2 &&
160 test_all_match git add . &&
161 test_all_match git status --porcelain=v2 &&
162 test_all_match git commit -m "add deep/newfile" &&
163
164 test_all_match git checkout HEAD~1 &&
165 test_all_match git checkout -
166 '
167
168 test_expect_success 'checkout and reset --hard' '
169 init_repos &&
170
171 test_all_match git checkout update-folder1 &&
172 test_all_match git status --porcelain=v2 &&
173
174 test_all_match git checkout update-deep &&
175 test_all_match git status --porcelain=v2 &&
176
177 test_all_match git checkout -b reset-test &&
178 test_all_match git reset --hard deepest &&
179 test_all_match git reset --hard update-folder1 &&
180 test_all_match git reset --hard update-folder2
181 '
182
183 test_expect_success 'diff --staged' '
184 init_repos &&
185
186 write_script edit-contents <<-\EOF &&
187 echo text >>README.md
188 EOF
189 run_on_all "../edit-contents" &&
190
191 test_all_match git diff &&
192 test_all_match git diff --staged &&
193 test_all_match git add README.md &&
194 test_all_match git diff &&
195 test_all_match git diff --staged
196 '
197
198 test_expect_success 'diff with renames' '
199 init_repos &&
200
201 for branch in rename-out-to-out rename-out-to-in rename-in-to-out
202 do
203 test_all_match git checkout rename-base &&
204 test_all_match git checkout $branch -- .&&
205 test_all_match git diff --staged --no-renames &&
206 test_all_match git diff --staged --find-renames || return 1
207 done
208 '
209
210 test_expect_success 'log with pathspec outside sparse definition' '
211 init_repos &&
212
213 test_all_match git log -- a &&
214 test_all_match git log -- folder1/a &&
215 test_all_match git log -- folder2/a &&
216 test_all_match git log -- deep/a &&
217 test_all_match git log -- deep/deeper1/a &&
218 test_all_match git log -- deep/deeper1/deepest/a &&
219
220 test_all_match git checkout update-folder1 &&
221 test_all_match git log -- folder1/a
222 '
223
224 test_expect_success 'blame with pathspec inside sparse definition' '
225 init_repos &&
226
227 test_all_match git blame a &&
228 test_all_match git blame deep/a &&
229 test_all_match git blame deep/deeper1/a &&
230 test_all_match git blame deep/deeper1/deepest/a
231 '
232
233 # TODO: blame currently does not support blaming files outside of the
234 # sparse definition. It complains that the file doesn't exist locally.
235 test_expect_failure 'blame with pathspec outside sparse definition' '
236 init_repos &&
237
238 test_all_match git blame folder1/a &&
239 test_all_match git blame folder2/a &&
240 test_all_match git blame deep/deeper2/a &&
241 test_all_match git blame deep/deeper2/deepest/a
242 '
243
244 # TODO: reset currently does not behave as expected when in a
245 # sparse-checkout.
246 test_expect_failure 'checkout and reset (mixed)' '
247 init_repos &&
248
249 test_all_match git checkout -b reset-test update-deep &&
250 test_all_match git reset deepest &&
251 test_all_match git reset update-folder1 &&
252 test_all_match git reset update-folder2
253 '
254
255 test_expect_success 'merge' '
256 init_repos &&
257
258 test_all_match git checkout -b merge update-deep &&
259 test_all_match git merge -m "folder1" update-folder1 &&
260 test_all_match git rev-parse HEAD^{tree} &&
261 test_all_match git merge -m "folder2" update-folder2 &&
262 test_all_match git rev-parse HEAD^{tree}
263 '
264
265 test_expect_success 'merge with outside renames' '
266 init_repos &&
267
268 for type in out-to-out out-to-in in-to-out
269 do
270 test_all_match git reset --hard &&
271 test_all_match git checkout -f -b merge-$type update-deep &&
272 test_all_match git merge -m "$type" rename-$type &&
273 test_all_match git rev-parse HEAD^{tree} || return 1
274 done
275 '
276
277 test_expect_success 'clean' '
278 init_repos &&
279
280 echo bogus >>.gitignore &&
281 run_on_all cp ../.gitignore . &&
282 test_all_match git add .gitignore &&
283 test_all_match git commit -m ignore-bogus-files &&
284
285 run_on_sparse mkdir folder1 &&
286 run_on_all touch folder1/bogus &&
287
288 test_all_match git status --porcelain=v2 &&
289 test_all_match git clean -f &&
290 test_all_match git status --porcelain=v2 &&
291
292 test_all_match git clean -xf &&
293 test_all_match git status --porcelain=v2 &&
294
295 test_all_match git clean -xdf &&
296 test_all_match git status --porcelain=v2 &&
297
298 test_path_is_dir sparse-checkout/folder1
299 '
300
301 test_done