]>
Commit | Line | Data |
---|---|---|
cf9dc653 MW |
1 | #!/bin/sh |
2 | # | |
3 | # Copyright (C) 2006 Martin Waitz <tali@admingilde.org> | |
4 | # | |
5 | ||
6 | test_description='test clone --reference' | |
95cf2c01 | 7 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
8 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
9 | ||
cf9dc653 MW |
10 | . ./test-lib.sh |
11 | ||
46d76d6c | 12 | base_dir=$(pwd) |
cf9dc653 | 13 | |
4ba776c2 DB |
14 | U=$base_dir/UPLOAD_LOG |
15 | ||
bc192300 JK |
16 | # create a commit in repo $1 with name $2 |
17 | commit_in () { | |
18 | ( | |
19 | cd "$1" && | |
20 | echo "$2" >"$2" && | |
21 | git add "$2" && | |
22 | git commit -m "$2" | |
23 | ) | |
24 | } | |
25 | ||
26 | # check that there are $2 loose objects in repo $1 | |
27 | test_objcount () { | |
28 | echo "$2" >expect && | |
29 | git -C "$1" count-objects >actual.raw && | |
30 | cut -d' ' -f1 <actual.raw >actual && | |
31 | test_cmp expect actual | |
32 | } | |
33 | ||
34 | test_expect_success 'preparing first repository' ' | |
35 | test_create_repo A && | |
36 | commit_in A file1 | |
37 | ' | |
cf9dc653 | 38 | |
bc192300 JK |
39 | test_expect_success 'preparing second repository' ' |
40 | git clone A B && | |
41 | commit_in B file2 && | |
42 | git -C B repack -ad && | |
43 | git -C B prune | |
44 | ' | |
cf9dc653 | 45 | |
bc192300 JK |
46 | test_expect_success 'cloning with reference (-l -s)' ' |
47 | git clone -l -s --reference B A C | |
48 | ' | |
cf9dc653 | 49 | |
bc192300 JK |
50 | test_expect_success 'existence of info/alternates' ' |
51 | test_line_count = 2 C/.git/objects/info/alternates | |
52 | ' | |
cf9dc653 | 53 | |
bc192300 | 54 | test_expect_success 'pulling from reference' ' |
95cf2c01 | 55 | git -C C pull ../B main |
bc192300 | 56 | ' |
cf9dc653 | 57 | |
bc192300 JK |
58 | test_expect_success 'that reference gets used' ' |
59 | test_objcount C 0 | |
60 | ' | |
4ba776c2 | 61 | |
2ad23273 JK |
62 | test_expect_success 'cloning with reference (no -l -s)' ' |
63 | GIT_TRACE_PACKET=$U.D git clone --reference B "file://$(pwd)/A" D | |
64 | ' | |
4ba776c2 | 65 | |
2ad23273 JK |
66 | test_expect_success 'fetched no objects' ' |
67 | test -s "$U.D" && | |
68 | ! grep " want" "$U.D" | |
69 | ' | |
1f7d1a53 | 70 | |
bc192300 JK |
71 | test_expect_success 'existence of info/alternates' ' |
72 | test_line_count = 1 D/.git/objects/info/alternates | |
73 | ' | |
1f7d1a53 | 74 | |
bc192300 | 75 | test_expect_success 'pulling from reference' ' |
95cf2c01 | 76 | git -C D pull ../B main |
bc192300 | 77 | ' |
cf9dc653 | 78 | |
bc192300 JK |
79 | test_expect_success 'that reference gets used' ' |
80 | test_objcount D 0 | |
81 | ' | |
cf9dc653 | 82 | |
bc192300 JK |
83 | test_expect_success 'updating origin' ' |
84 | commit_in A file3 && | |
85 | git -C A repack -ad && | |
86 | git -C A prune | |
87 | ' | |
cf9dc653 | 88 | |
bc192300 JK |
89 | test_expect_success 'pulling changes from origin' ' |
90 | git -C C pull origin | |
91 | ' | |
cf9dc653 MW |
92 | |
93 | # the 2 local objects are commit and tree from the merge | |
bc192300 JK |
94 | test_expect_success 'that alternate to origin gets used' ' |
95 | test_objcount C 2 | |
96 | ' | |
1f7d1a53 | 97 | |
bc192300 JK |
98 | test_expect_success 'pulling changes from origin' ' |
99 | git -C D pull origin | |
100 | ' | |
1f7d1a53 JH |
101 | |
102 | # the 5 local objects are expected; file3 blob, commit in A to add it | |
103 | # and its tree, and 2 are our tree and the merge commit. | |
bc192300 JK |
104 | test_expect_success 'check objects expected to exist locally' ' |
105 | test_objcount D 5 | |
106 | ' | |
fabb0199 | 107 | |
bc192300 JK |
108 | test_expect_success 'preparing alternate repository #1' ' |
109 | test_create_repo F && | |
110 | commit_in F file1 | |
111 | ' | |
fabb0199 | 112 | |
bc192300 JK |
113 | test_expect_success 'cloning alternate repo #2 and adding changes to repo #1' ' |
114 | git clone F G && | |
115 | commit_in F file2 | |
116 | ' | |
fabb0199 | 117 | |
bc192300 JK |
118 | test_expect_success 'cloning alternate repo #1, using #2 as reference' ' |
119 | git clone --reference G F H | |
120 | ' | |
b50c8469 | 121 | |
bc192300 JK |
122 | test_expect_success 'cloning with reference being subset of source (-l -s)' ' |
123 | git clone -l -s --reference A B E | |
124 | ' | |
b50c8469 | 125 | |
77b9b1d1 JK |
126 | test_expect_success 'cloning with multiple references drops duplicates' ' |
127 | git clone -s --reference B --reference A --reference B A dups && | |
128 | test_line_count = 2 dups/.git/objects/info/alternates | |
129 | ' | |
130 | ||
09116a1c JH |
131 | test_expect_success 'clone with reference from a tagged repository' ' |
132 | ( | |
bc192300 | 133 | cd A && git tag -a -m tagged HEAD |
09116a1c JH |
134 | ) && |
135 | git clone --reference=A A I | |
136 | ' | |
137 | ||
acede2eb MH |
138 | test_expect_success 'prepare branched repository' ' |
139 | git clone A J && | |
140 | ( | |
141 | cd J && | |
95cf2c01 | 142 | git checkout -b other main^ && |
acede2eb MH |
143 | echo other >otherfile && |
144 | git add otherfile && | |
145 | git commit -m other && | |
95cf2c01 | 146 | git checkout main |
acede2eb MH |
147 | ) |
148 | ' | |
149 | ||
f2576591 | 150 | test_expect_success 'fetch with incomplete alternates' ' |
acede2eb MH |
151 | git init K && |
152 | echo "$base_dir/A/.git/objects" >K/.git/objects/info/alternates && | |
153 | ( | |
154 | cd K && | |
155 | git remote add J "file://$base_dir/J" && | |
2ad23273 | 156 | GIT_TRACE_PACKET=$U.K git fetch J |
acede2eb | 157 | ) && |
95cf2c01 | 158 | main_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/main) && |
2ad23273 | 159 | test -s "$U.K" && |
95cf2c01 | 160 | ! grep " want $main_object" "$U.K" && |
acede2eb | 161 | tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) && |
97a83fa8 | 162 | ! grep " want $tag_object" "$U.K" |
acede2eb MH |
163 | ' |
164 | ||
b552b56d AS |
165 | test_expect_success 'clone using repo with gitfile as a reference' ' |
166 | git clone --separate-git-dir=L A M && | |
167 | git clone --reference=M A N && | |
168 | echo "$base_dir/L/objects" >expected && | |
169 | test_cmp expected "$base_dir/N/.git/objects/info/alternates" | |
170 | ' | |
171 | ||
172 | test_expect_success 'clone using repo pointed at by gitfile as reference' ' | |
173 | git clone --reference=M/.git A O && | |
174 | echo "$base_dir/L/objects" >expected && | |
175 | test_cmp expected "$base_dir/O/.git/objects/info/alternates" | |
176 | ' | |
177 | ||
fb1d6dab JH |
178 | test_expect_success 'clone and dissociate from reference' ' |
179 | git init P && | |
180 | ( | |
64d1022e | 181 | cd P && test_commit one |
fb1d6dab JH |
182 | ) && |
183 | git clone P Q && | |
184 | ( | |
185 | cd Q && test_commit two | |
186 | ) && | |
187 | git clone --no-local --reference=P Q R && | |
188 | git clone --no-local --reference=P --dissociate Q S && | |
189 | # removing the reference P would corrupt R but not S | |
190 | rm -fr P && | |
191 | test_must_fail git -C R fsck && | |
192 | git -C S fsck | |
193 | ' | |
786b150c | 194 | test_expect_success 'clone, dissociate from partial reference and repack' ' |
11911bf7 JS |
195 | rm -fr P Q R && |
196 | git init P && | |
197 | ( | |
198 | cd P && | |
199 | test_commit one && | |
200 | git repack && | |
201 | test_commit two && | |
202 | git repack | |
203 | ) && | |
204 | git clone --bare P Q && | |
205 | ( | |
206 | cd P && | |
207 | git checkout -b second && | |
208 | test_commit three && | |
209 | git repack | |
210 | ) && | |
211 | git clone --bare --dissociate --reference=P Q R && | |
212 | ls R/objects/pack/*.pack >packs.txt && | |
213 | test_line_count = 1 packs.txt | |
214 | ' | |
fb1d6dab | 215 | |
0181681e AR |
216 | test_expect_success 'clone, dissociate from alternates' ' |
217 | rm -fr A B C && | |
218 | test_create_repo A && | |
219 | commit_in A file1 && | |
220 | git clone --reference=A A B && | |
221 | test_line_count = 1 B/.git/objects/info/alternates && | |
222 | git clone --local --dissociate B C && | |
223 | ! test -f C/.git/objects/info/alternates && | |
224 | ( cd C && git fsck ) | |
225 | ' | |
226 | ||
03156169 ÆAB |
227 | test_expect_success 'setup repo with garbage in objects/*' ' |
228 | git init S && | |
229 | ( | |
230 | cd S && | |
231 | test_commit A && | |
232 | ||
233 | cd .git/objects && | |
234 | >.some-hidden-file && | |
235 | >some-file && | |
236 | mkdir .some-hidden-dir && | |
237 | >.some-hidden-dir/some-file && | |
238 | >.some-hidden-dir/.some-dot-file && | |
239 | mkdir some-dir && | |
240 | >some-dir/some-file && | |
241 | >some-dir/.some-dot-file | |
242 | ) | |
243 | ' | |
244 | ||
245 | test_expect_success 'clone a repo with garbage in objects/*' ' | |
246 | for option in --local --no-hardlinks --shared --dissociate | |
247 | do | |
248 | git clone $option S S$option || return 1 && | |
249 | git -C S$option fsck || return 1 | |
250 | done && | |
251 | find S-* -name "*some*" | sort >actual && | |
252 | cat >expected <<-EOF && | |
68c7c59c MT |
253 | S--dissociate/.git/objects/.some-hidden-dir |
254 | S--dissociate/.git/objects/.some-hidden-dir/.some-dot-file | |
255 | S--dissociate/.git/objects/.some-hidden-dir/some-file | |
03156169 ÆAB |
256 | S--dissociate/.git/objects/.some-hidden-file |
257 | S--dissociate/.git/objects/some-dir | |
258 | S--dissociate/.git/objects/some-dir/.some-dot-file | |
259 | S--dissociate/.git/objects/some-dir/some-file | |
260 | S--dissociate/.git/objects/some-file | |
68c7c59c MT |
261 | S--local/.git/objects/.some-hidden-dir |
262 | S--local/.git/objects/.some-hidden-dir/.some-dot-file | |
263 | S--local/.git/objects/.some-hidden-dir/some-file | |
03156169 ÆAB |
264 | S--local/.git/objects/.some-hidden-file |
265 | S--local/.git/objects/some-dir | |
266 | S--local/.git/objects/some-dir/.some-dot-file | |
267 | S--local/.git/objects/some-dir/some-file | |
268 | S--local/.git/objects/some-file | |
68c7c59c MT |
269 | S--no-hardlinks/.git/objects/.some-hidden-dir |
270 | S--no-hardlinks/.git/objects/.some-hidden-dir/.some-dot-file | |
271 | S--no-hardlinks/.git/objects/.some-hidden-dir/some-file | |
03156169 ÆAB |
272 | S--no-hardlinks/.git/objects/.some-hidden-file |
273 | S--no-hardlinks/.git/objects/some-dir | |
274 | S--no-hardlinks/.git/objects/some-dir/.some-dot-file | |
275 | S--no-hardlinks/.git/objects/some-dir/some-file | |
276 | S--no-hardlinks/.git/objects/some-file | |
277 | EOF | |
278 | test_cmp expected actual | |
279 | ' | |
280 | ||
36596fd2 | 281 | test_expect_success SYMLINKS 'setup repo with manually symlinked or unknown files at objects/' ' |
03156169 ÆAB |
282 | git init T && |
283 | ( | |
284 | cd T && | |
285 | git config gc.auto 0 && | |
286 | test_commit A && | |
287 | git gc && | |
288 | test_commit B && | |
289 | ||
290 | cd .git/objects && | |
291 | mv pack packs && | |
292 | ln -s packs pack && | |
293 | find ?? -type d >loose-dirs && | |
294 | last_loose=$(tail -n 1 loose-dirs) && | |
03156169 ÆAB |
295 | mv $last_loose a-loose-dir && |
296 | ln -s a-loose-dir $last_loose && | |
36596fd2 MT |
297 | first_loose=$(head -n 1 loose-dirs) && |
298 | rm -f loose-dirs && | |
299 | ||
300 | cd $first_loose && | |
301 | obj=$(ls *) && | |
302 | mv $obj ../an-object && | |
303 | ln -s ../an-object $obj && | |
304 | ||
305 | cd ../ && | |
03156169 | 306 | find . -type f | sort >../../../T.objects-files.raw && |
36596fd2 | 307 | find . -type l | sort >../../../T.objects-symlinks.raw && |
03156169 ÆAB |
308 | echo unknown_content >unknown_file |
309 | ) && | |
310 | git -C T fsck && | |
311 | git -C T rev-list --all --objects >T.objects | |
312 | ' | |
313 | ||
314 | ||
36596fd2 | 315 | test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at objects/' ' |
03156169 ÆAB |
316 | for option in --local --no-hardlinks --shared --dissociate |
317 | do | |
318 | git clone $option T T$option || return 1 && | |
319 | git -C T$option fsck || return 1 && | |
320 | git -C T$option rev-list --all --objects >T$option.objects && | |
321 | test_cmp T.objects T$option.objects && | |
322 | ( | |
323 | cd T$option/.git/objects && | |
36596fd2 MT |
324 | find . -type f | sort >../../../T$option.objects-files.raw && |
325 | find . -type l | sort >../../../T$option.objects-symlinks.raw | |
03156169 ÆAB |
326 | ) |
327 | done && | |
328 | ||
329 | for raw in $(ls T*.raw) | |
330 | do | |
331 | sed -e "s!/../!/Y/!; s![0-9a-f]\{38,\}!Z!" -e "/commit-graph/d" \ | |
277eb5af | 332 | -e "/multi-pack-index/d" <$raw >$raw.de-sha-1 && |
333 | sort $raw.de-sha-1 >$raw.de-sha || return 1 | |
03156169 ÆAB |
334 | done && |
335 | ||
336 | cat >expected-files <<-EOF && | |
337 | ./Y/Z | |
338 | ./Y/Z | |
277eb5af | 339 | ./Y/Z |
03156169 | 340 | ./a-loose-dir/Z |
36596fd2 | 341 | ./an-object |
03156169 ÆAB |
342 | ./info/packs |
343 | ./pack/pack-Z.idx | |
344 | ./pack/pack-Z.pack | |
345 | ./packs/pack-Z.idx | |
346 | ./packs/pack-Z.pack | |
347 | ./unknown_file | |
348 | EOF | |
349 | ||
36596fd2 | 350 | for option in --local --no-hardlinks --dissociate |
03156169 | 351 | do |
36596fd2 MT |
352 | test_cmp expected-files T$option.objects-files.raw.de-sha || return 1 && |
353 | test_must_be_empty T$option.objects-symlinks.raw.de-sha || return 1 | |
03156169 ÆAB |
354 | done && |
355 | ||
356 | echo ./info/alternates >expected-files && | |
36596fd2 MT |
357 | test_cmp expected-files T--shared.objects-files.raw && |
358 | test_must_be_empty T--shared.objects-symlinks.raw | |
03156169 ÆAB |
359 | ' |
360 | ||
cf9dc653 | 361 | test_done |