Raw
1 #!/bin/sh
2
3 test_description='behavior of diff when reading objects in a partial clone'
4
5 . ./test-lib.sh
6
7 test_expect_success 'git show batches blobs' '
8 test_when_finished "rm -rf server client trace" &&
9
10 test_create_repo server &&
11 echo a >server/a &&
12 echo b >server/b &&
13 git -C server add a b &&
14 git -C server commit -m x &&
15
16 test_config -C server uploadpack.allowfilter 1 &&
17 test_config -C server uploadpack.allowanysha1inwant 1 &&
18 git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
19
20 # Ensure that there is exactly 1 negotiation by checking that there is
21 # only 1 "done" line sent. ("done" marks the end of negotiation.)
22 GIT_TRACE_PACKET="$(pwd)/trace" git -C client show HEAD &&
23 grep "fetch> done" trace >done_lines &&
24 test_line_count = 1 done_lines
25 '
26
27 test_expect_success 'diff batches blobs' '
28 test_when_finished "rm -rf server client trace" &&
29
30 test_create_repo server &&
31 echo a >server/a &&
32 echo b >server/b &&
33 git -C server add a b &&
34 git -C server commit -m x &&
35 echo c >server/c &&
36 echo d >server/d &&
37 git -C server add c d &&
38 git -C server commit -m x &&
39
40 test_config -C server uploadpack.allowfilter 1 &&
41 test_config -C server uploadpack.allowanysha1inwant 1 &&
42 git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
43
44 # Ensure that there is exactly 1 negotiation by checking that there is
45 # only 1 "done" line sent. ("done" marks the end of negotiation.)
46 GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD &&
47 grep "fetch> done" trace >done_lines &&
48 test_line_count = 1 done_lines
49 '
50
51 test_expect_success 'diff skips same-OID blobs' '
52 test_when_finished "rm -rf server client trace" &&
53
54 test_create_repo server &&
55 echo a >server/a &&
56 echo b >server/b &&
57 git -C server add a b &&
58 git -C server commit -m x &&
59 echo another-a >server/a &&
60 git -C server add a &&
61 git -C server commit -m x &&
62
63 test_config -C server uploadpack.allowfilter 1 &&
64 test_config -C server uploadpack.allowanysha1inwant 1 &&
65 git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
66
67 echo a | git hash-object --stdin >hash-old-a &&
68 echo another-a | git hash-object --stdin >hash-new-a &&
69 echo b | git hash-object --stdin >hash-b &&
70
71 # Ensure that only a and another-a are fetched.
72 GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD &&
73 grep "want $(cat hash-old-a)" trace &&
74 grep "want $(cat hash-new-a)" trace &&
75 ! grep "want $(cat hash-b)" trace
76 '
77
78 test_expect_success 'when fetching missing objects, diff skips GITLINKs' '
79 test_when_finished "rm -rf sub server client trace" &&
80 test_config_global protocol.file.allow always &&
81
82 test_create_repo sub &&
83 test_commit -C sub first &&
84
85 test_create_repo server &&
86 echo a >server/a &&
87 git -C server add a &&
88 git -C server submodule add "file://$(pwd)/sub" &&
89 git -C server commit -m x &&
90
91 test_commit -C server/sub second &&
92 echo another-a >server/a &&
93 git -C server add a sub &&
94 git -C server commit -m x &&
95
96 test_config -C server uploadpack.allowfilter 1 &&
97 test_config -C server uploadpack.allowanysha1inwant 1 &&
98 git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
99
100 echo a | git hash-object --stdin >hash-old-a &&
101 echo another-a | git hash-object --stdin >hash-new-a &&
102
103 # Ensure that a and another-a are fetched, and check (by successful
104 # execution of the diff) that no invalid OIDs are sent.
105 GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff HEAD^ HEAD &&
106 grep "want $(cat hash-old-a)" trace &&
107 grep "want $(cat hash-new-a)" trace
108 '
109
110 test_expect_success 'diff with rename detection batches blobs' '
111 test_when_finished "rm -rf server client trace" &&
112
113 test_create_repo server &&
114 echo a >server/a &&
115 printf "b\nb\nb\nb\nb\n" >server/b &&
116 git -C server add a b &&
117 git -C server commit -m x &&
118 rm server/b &&
119 printf "b\nb\nb\nb\nbX\n" >server/c &&
120 git -C server add c &&
121 git -C server commit -a -m x &&
122
123 test_config -C server uploadpack.allowfilter 1 &&
124 test_config -C server uploadpack.allowanysha1inwant 1 &&
125 git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
126
127 # Ensure that there is exactly 1 negotiation by checking that there is
128 # only 1 "done" line sent. ("done" marks the end of negotiation.)
129 GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD >out &&
130 grep ":100644 100644.*R[0-9][0-9][0-9].*b.*c" out &&
131 grep "fetch> done" trace >done_lines &&
132 test_line_count = 1 done_lines
133 '
134
135 test_expect_success 'diff succeeds even if prefetch triggered by break-rewrites' '
136 test_when_finished "rm -rf server client trace" &&
137
138 test_create_repo server &&
139 echo xyz >server/foo &&
140 mkdir server/bar &&
141 test_seq -f "line %d" 1 100 >server/bar/baz &&
142 git -C server add -A &&
143 git -C server commit -m x &&
144
145 echo xyzz >server/foo &&
146 test_seq -f "line %d" 90 190 >server/bar/baz &&
147 git -C server add -A &&
148 git -C server commit -m x &&
149
150 test_config -C server uploadpack.allowfilter 1 &&
151 test_config -C server uploadpack.allowanysha1inwant 1 &&
152 git clone --filter=blob:limit=0 "file://$(pwd)/server" client &&
153
154 # Fetch bar/baz without fetching foo.
155 # Foo will be lazily fetched during break rewrites detection.
156 git -C client checkout HEAD~1 bar &&
157
158 # Ensure baz in the working tree is different from baz in HEAD~1.
159 # We need baz to trigger break-rewrites detection.
160 git -C client reset --hard HEAD &&
161
162 # break-rewrites detection in reset.
163 git -C client reset HEAD~1
164 '
165
166 test_expect_success 'diff succeeds even if entries are removed from queue' '
167 test_when_finished "rm -rf server client trace" &&
168
169 test_create_repo server &&
170 for l in a c e g i p
171 do
172 echo $l >server/$l &&
173 git -C server add $l || return 1
174 done &&
175 git -C server commit -m x &&
176
177 for l in a e i
178 do
179 git -C server rm $l || return 1
180 done &&
181
182 for l in b d f i
183 do
184 echo $l$l >server/$l &&
185 git -C server add $l || return 1
186 done &&
187 git -C server commit -a -m x &&
188
189 test_config -C server uploadpack.allowfilter 1 &&
190 test_config -C server uploadpack.allowanysha1inwant 1 &&
191 git clone --filter=blob:limit=0 "file://$(pwd)/server" client &&
192
193 for file in $(ls client)
194 do
195 cat client/$file >$file &&
196 mv $file client/$file || return 1
197 done &&
198 git -C client diff --name-only --relative HEAD^
199 '
200
201 test_expect_success 'diff does not fetch anything if inexact rename detection is not needed' '
202 test_when_finished "rm -rf server client trace" &&
203
204 test_create_repo server &&
205 echo a >server/a &&
206 printf "b\nb\nb\nb\nb\n" >server/b &&
207 git -C server add a b &&
208 git -C server commit -m x &&
209 mv server/b server/c &&
210 git -C server add c &&
211 git -C server commit -a -m x &&
212
213 test_config -C server uploadpack.allowfilter 1 &&
214 test_config -C server uploadpack.allowanysha1inwant 1 &&
215 git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
216
217 # Ensure no fetches.
218 GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD &&
219 test_path_is_missing trace
220 '
221
222 test_expect_success 'diff --break-rewrites fetches only if necessary, and batches blobs if it does' '
223 test_when_finished "rm -rf server client trace" &&
224
225 test_create_repo server &&
226 echo a >server/a &&
227 printf "b\nb\nb\nb\nb\n" >server/b &&
228 git -C server add a b &&
229 git -C server commit -m x &&
230 printf "c\nc\nc\nc\nc\n" >server/b &&
231 git -C server commit -a -m x &&
232
233 test_config -C server uploadpack.allowfilter 1 &&
234 test_config -C server uploadpack.allowanysha1inwant 1 &&
235 git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client &&
236
237 # Ensure no fetches.
238 GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD &&
239 test_path_is_missing trace &&
240
241 # But with --break-rewrites, ensure that there is exactly 1 negotiation
242 # by checking that there is only 1 "done" line sent. ("done" marks the
243 # end of negotiation.)
244 GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --break-rewrites --raw -M HEAD^ HEAD &&
245 grep "fetch> done" trace >done_lines &&
246 test_line_count = 1 done_lines
247 '
248
249 test_done