Show More
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
1 | NO CONTENT: new file 100644, binary diff hidden |
|
NO CONTENT: new file 100644, binary diff hidden |
This diff has been collapsed as it changes many lines, (627 lines changed) Show them Hide them | |||||
@@ -0,0 +1,627 b'' | |||||
|
1 | =============================================================== | |||
|
2 | Test non-regression on the corruption associated with issue6528 | |||
|
3 | =============================================================== | |||
|
4 | ||||
|
5 | Setup | |||
|
6 | ===== | |||
|
7 | ||||
|
8 | $ hg init base-repo | |||
|
9 | $ cd base-repo | |||
|
10 | ||||
|
11 | $ cat <<EOF > a.txt | |||
|
12 | > 1 | |||
|
13 | > 2 | |||
|
14 | > 3 | |||
|
15 | > 4 | |||
|
16 | > 5 | |||
|
17 | > 6 | |||
|
18 | > EOF | |||
|
19 | ||||
|
20 | $ hg add a.txt | |||
|
21 | $ hg commit -m 'c_base_c - create a.txt' | |||
|
22 | ||||
|
23 | Modify a.txt | |||
|
24 | ||||
|
25 | $ sed -e 's/1/foo/' a.txt > a.tmp; mv a.tmp a.txt | |||
|
26 | $ hg commit -m 'c_modify_c - modify a.txt' | |||
|
27 | ||||
|
28 | Modify and rename a.txt to b.txt | |||
|
29 | ||||
|
30 | $ hg up -r "desc('c_base_c')" | |||
|
31 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
32 | $ sed -e 's/6/bar/' a.txt > a.tmp; mv a.tmp a.txt | |||
|
33 | $ hg mv a.txt b.txt | |||
|
34 | $ hg commit -m 'c_rename_c - rename and modify a.txt to b.txt' | |||
|
35 | created new head | |||
|
36 | ||||
|
37 | Merge each branch | |||
|
38 | ||||
|
39 | $ hg merge -r "desc('c_modify_c')" | |||
|
40 | merging b.txt and a.txt to b.txt | |||
|
41 | 0 files updated, 1 files merged, 0 files removed, 0 files unresolved | |||
|
42 | (branch merge, don't forget to commit) | |||
|
43 | $ hg commit -m 'c_merge_c: commit merge' | |||
|
44 | ||||
|
45 | $ hg debugrevlogindex b.txt | |||
|
46 | rev linkrev nodeid p1 p2 | |||
|
47 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
48 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
49 | ||||
|
50 | Check commit Graph | |||
|
51 | ||||
|
52 | $ hg log -G | |||
|
53 | @ changeset: 3:a1cc2bdca0aa | |||
|
54 | |\ tag: tip | |||
|
55 | | | parent: 2:615c6ccefd15 | |||
|
56 | | | parent: 1:373d507f4667 | |||
|
57 | | | user: test | |||
|
58 | | | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
59 | | | summary: c_merge_c: commit merge | |||
|
60 | | | | |||
|
61 | | o changeset: 2:615c6ccefd15 | |||
|
62 | | | parent: 0:f5a5a568022f | |||
|
63 | | | user: test | |||
|
64 | | | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
65 | | | summary: c_rename_c - rename and modify a.txt to b.txt | |||
|
66 | | | | |||
|
67 | o | changeset: 1:373d507f4667 | |||
|
68 | |/ user: test | |||
|
69 | | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
70 | | summary: c_modify_c - modify a.txt | |||
|
71 | | | |||
|
72 | o changeset: 0:f5a5a568022f | |||
|
73 | user: test | |||
|
74 | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
75 | summary: c_base_c - create a.txt | |||
|
76 | ||||
|
77 | ||||
|
78 | $ hg cat -r . b.txt | |||
|
79 | foo | |||
|
80 | 2 | |||
|
81 | 3 | |||
|
82 | 4 | |||
|
83 | 5 | |||
|
84 | bar | |||
|
85 | $ cat b.txt | |||
|
86 | foo | |||
|
87 | 2 | |||
|
88 | 3 | |||
|
89 | 4 | |||
|
90 | 5 | |||
|
91 | bar | |||
|
92 | $ cd .. | |||
|
93 | ||||
|
94 | ||||
|
95 | Check the lack of corruption | |||
|
96 | ============================ | |||
|
97 | ||||
|
98 | $ hg clone --pull base-repo cloned | |||
|
99 | requesting all changes | |||
|
100 | adding changesets | |||
|
101 | adding manifests | |||
|
102 | adding file changes | |||
|
103 | added 4 changesets with 4 changes to 2 files | |||
|
104 | new changesets f5a5a568022f:a1cc2bdca0aa | |||
|
105 | updating to branch default | |||
|
106 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
107 | $ cd cloned | |||
|
108 | $ hg up -r "desc('c_merge_c')" | |||
|
109 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
110 | ||||
|
111 | ||||
|
112 | Status is buggy, even with debugrebuilddirstate | |||
|
113 | ||||
|
114 | $ hg cat -r . b.txt | |||
|
115 | foo | |||
|
116 | 2 | |||
|
117 | 3 | |||
|
118 | 4 | |||
|
119 | 5 | |||
|
120 | bar | |||
|
121 | $ cat b.txt | |||
|
122 | foo | |||
|
123 | 2 | |||
|
124 | 3 | |||
|
125 | 4 | |||
|
126 | 5 | |||
|
127 | bar | |||
|
128 | $ hg status | |||
|
129 | $ hg debugrebuilddirstate | |||
|
130 | $ hg status | |||
|
131 | ||||
|
132 | the history was altered | |||
|
133 | ||||
|
134 | in theory p1/p2 order does not matter but in practice p1 == nullid is used as a | |||
|
135 | marker that some metadata are present and should be fetched. | |||
|
136 | ||||
|
137 | $ hg debugrevlogindex b.txt | |||
|
138 | rev linkrev nodeid p1 p2 | |||
|
139 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
140 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
141 | ||||
|
142 | Check commit Graph | |||
|
143 | ||||
|
144 | $ hg log -G | |||
|
145 | @ changeset: 3:a1cc2bdca0aa | |||
|
146 | |\ tag: tip | |||
|
147 | | | parent: 2:615c6ccefd15 | |||
|
148 | | | parent: 1:373d507f4667 | |||
|
149 | | | user: test | |||
|
150 | | | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
151 | | | summary: c_merge_c: commit merge | |||
|
152 | | | | |||
|
153 | | o changeset: 2:615c6ccefd15 | |||
|
154 | | | parent: 0:f5a5a568022f | |||
|
155 | | | user: test | |||
|
156 | | | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
157 | | | summary: c_rename_c - rename and modify a.txt to b.txt | |||
|
158 | | | | |||
|
159 | o | changeset: 1:373d507f4667 | |||
|
160 | |/ user: test | |||
|
161 | | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
162 | | summary: c_modify_c - modify a.txt | |||
|
163 | | | |||
|
164 | o changeset: 0:f5a5a568022f | |||
|
165 | user: test | |||
|
166 | date: Thu Jan 01 00:00:00 1970 +0000 | |||
|
167 | summary: c_base_c - create a.txt | |||
|
168 | ||||
|
169 | ||||
|
170 | Test the command that fixes the issue | |||
|
171 | ===================================== | |||
|
172 | ||||
|
173 | Restore a broken repository with multiple broken revisions and a filename that | |||
|
174 | would get encoded to test the `report` options. | |||
|
175 | It's a tarball because unbundle might magically fix the issue later. | |||
|
176 | ||||
|
177 | $ cd .. | |||
|
178 | $ mkdir repo-to-fix | |||
|
179 | $ cd repo-to-fix | |||
|
180 | #if windows | |||
|
181 | tar interprets `:` in paths (like `C:`) as being remote, force local on Windows | |||
|
182 | only since some versions of tar don't have this flag. | |||
|
183 | ||||
|
184 | $ tar --force-local -xf $TESTDIR/bundles/issue6528.tar | |||
|
185 | #else | |||
|
186 | $ tar xf $TESTDIR/bundles/issue6528.tar | |||
|
187 | #endif | |||
|
188 | ||||
|
189 | Check that the issue is present | |||
|
190 | $ hg st | |||
|
191 | M D.txt | |||
|
192 | M b.txt | |||
|
193 | $ hg debugrevlogindex b.txt | |||
|
194 | rev linkrev nodeid p1 p2 | |||
|
195 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
196 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |||
|
197 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
198 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |||
|
199 | $ hg debugrevlogindex D.txt | |||
|
200 | rev linkrev nodeid p1 p2 | |||
|
201 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
202 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |||
|
203 | ||||
|
204 | Dry-run the fix | |||
|
205 | $ hg debug-repair-issue6528 --dry-run | |||
|
206 | found affected revision 1 for filelog 'data/D.txt.i' | |||
|
207 | found affected revision 1 for filelog 'data/b.txt.i' | |||
|
208 | found affected revision 3 for filelog 'data/b.txt.i' | |||
|
209 | $ hg st | |||
|
210 | M D.txt | |||
|
211 | M b.txt | |||
|
212 | $ hg debugrevlogindex b.txt | |||
|
213 | rev linkrev nodeid p1 p2 | |||
|
214 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
215 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |||
|
216 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
217 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |||
|
218 | $ hg debugrevlogindex D.txt | |||
|
219 | rev linkrev nodeid p1 p2 | |||
|
220 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
221 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |||
|
222 | ||||
|
223 | Test the --paranoid option | |||
|
224 | $ hg debug-repair-issue6528 --dry-run --paranoid | |||
|
225 | found affected revision 1 for filelog 'data/D.txt.i' | |||
|
226 | found affected revision 1 for filelog 'data/b.txt.i' | |||
|
227 | found affected revision 3 for filelog 'data/b.txt.i' | |||
|
228 | $ hg st | |||
|
229 | M D.txt | |||
|
230 | M b.txt | |||
|
231 | $ hg debugrevlogindex b.txt | |||
|
232 | rev linkrev nodeid p1 p2 | |||
|
233 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
234 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |||
|
235 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
236 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |||
|
237 | $ hg debugrevlogindex D.txt | |||
|
238 | rev linkrev nodeid p1 p2 | |||
|
239 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
240 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |||
|
241 | ||||
|
242 | Run the fix | |||
|
243 | $ hg debug-repair-issue6528 | |||
|
244 | found affected revision 1 for filelog 'data/D.txt.i' | |||
|
245 | repaired revision 1 of 'filelog data/D.txt.i' | |||
|
246 | found affected revision 1 for filelog 'data/b.txt.i' | |||
|
247 | found affected revision 3 for filelog 'data/b.txt.i' | |||
|
248 | repaired revision 1 of 'filelog data/b.txt.i' | |||
|
249 | repaired revision 3 of 'filelog data/b.txt.i' | |||
|
250 | ||||
|
251 | Check that the fix worked and that running it twice does nothing | |||
|
252 | $ hg st | |||
|
253 | $ hg debugrevlogindex b.txt | |||
|
254 | rev linkrev nodeid p1 p2 | |||
|
255 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
256 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
257 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
258 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |||
|
259 | $ hg debugrevlogindex D.txt | |||
|
260 | rev linkrev nodeid p1 p2 | |||
|
261 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
262 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |||
|
263 | $ hg debug-repair-issue6528 | |||
|
264 | no affected revisions were found | |||
|
265 | $ hg st | |||
|
266 | $ hg debugrevlogindex b.txt | |||
|
267 | rev linkrev nodeid p1 p2 | |||
|
268 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
269 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
270 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
271 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |||
|
272 | $ hg debugrevlogindex D.txt | |||
|
273 | rev linkrev nodeid p1 p2 | |||
|
274 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
275 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |||
|
276 | ||||
|
277 | Try the using the report options | |||
|
278 | -------------------------------- | |||
|
279 | ||||
|
280 | $ cd .. | |||
|
281 | $ mkdir repo-to-fix-report | |||
|
282 | $ cd repo-to-fix | |||
|
283 | #if windows | |||
|
284 | tar interprets `:` in paths (like `C:`) as being remote, force local on Windows | |||
|
285 | only since some versions of tar don't have this flag. | |||
|
286 | ||||
|
287 | $ tar --force-local -xf $TESTDIR/bundles/issue6528.tar | |||
|
288 | #else | |||
|
289 | $ tar xf $TESTDIR/bundles/issue6528.tar | |||
|
290 | #endif | |||
|
291 | ||||
|
292 | $ hg debug-repair-issue6528 --to-report $TESTTMP/report.txt | |||
|
293 | found affected revision 1 for filelog 'data/D.txt.i' | |||
|
294 | found affected revision 1 for filelog 'data/b.txt.i' | |||
|
295 | found affected revision 3 for filelog 'data/b.txt.i' | |||
|
296 | $ cat $TESTTMP/report.txt | |||
|
297 | 2a80419dfc31d7dfb308ac40f3f138282de7d73b D.txt | |||
|
298 | a58b36ad6b6545195952793099613c2116f3563b,ea4f2f2463cca5b29ddf3461012b8ce5c6dac175 b.txt | |||
|
299 | ||||
|
300 | $ hg debug-repair-issue6528 --from-report $TESTTMP/report.txt --dry-run | |||
|
301 | loading report file '$TESTTMP/report.txt' | |||
|
302 | found affected revision 1 for filelog 'D.txt' | |||
|
303 | found affected revision 1 for filelog 'b.txt' | |||
|
304 | found affected revision 3 for filelog 'b.txt' | |||
|
305 | $ hg st | |||
|
306 | M D.txt | |||
|
307 | M b.txt | |||
|
308 | $ hg debugrevlogindex b.txt | |||
|
309 | rev linkrev nodeid p1 p2 | |||
|
310 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
311 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |||
|
312 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
313 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |||
|
314 | $ hg debugrevlogindex D.txt | |||
|
315 | rev linkrev nodeid p1 p2 | |||
|
316 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
317 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |||
|
318 | ||||
|
319 | $ hg debug-repair-issue6528 --from-report $TESTTMP/report.txt | |||
|
320 | loading report file '$TESTTMP/report.txt' | |||
|
321 | found affected revision 1 for filelog 'D.txt' | |||
|
322 | repaired revision 1 of 'filelog data/D.txt.i' | |||
|
323 | found affected revision 1 for filelog 'b.txt' | |||
|
324 | found affected revision 3 for filelog 'b.txt' | |||
|
325 | repaired revision 1 of 'filelog data/b.txt.i' | |||
|
326 | repaired revision 3 of 'filelog data/b.txt.i' | |||
|
327 | $ hg st | |||
|
328 | $ hg debugrevlogindex b.txt | |||
|
329 | rev linkrev nodeid p1 p2 | |||
|
330 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
331 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
332 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
333 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |||
|
334 | $ hg debugrevlogindex D.txt | |||
|
335 | rev linkrev nodeid p1 p2 | |||
|
336 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
337 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |||
|
338 | ||||
|
339 | Check that the revision is not "fixed" again | |||
|
340 | ||||
|
341 | $ hg debug-repair-issue6528 --from-report $TESTTMP/report.txt | |||
|
342 | loading report file '$TESTTMP/report.txt' | |||
|
343 | revision 2a80419dfc31d7dfb308ac40f3f138282de7d73b of file 'D.txt' is not affected | |||
|
344 | no affected revisions were found for 'D.txt' | |||
|
345 | revision a58b36ad6b6545195952793099613c2116f3563b of file 'b.txt' is not affected | |||
|
346 | revision ea4f2f2463cca5b29ddf3461012b8ce5c6dac175 of file 'b.txt' is not affected | |||
|
347 | no affected revisions were found for 'b.txt' | |||
|
348 | $ hg st | |||
|
349 | $ hg debugrevlogindex b.txt | |||
|
350 | rev linkrev nodeid p1 p2 | |||
|
351 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
352 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
353 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
354 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |||
|
355 | $ hg debugrevlogindex D.txt | |||
|
356 | rev linkrev nodeid p1 p2 | |||
|
357 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
358 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |||
|
359 | ||||
|
360 | Try it with a non-inline revlog | |||
|
361 | ------------------------------- | |||
|
362 | ||||
|
363 | $ cd .. | |||
|
364 | $ mkdir $TESTTMP/ext | |||
|
365 | $ cat << EOF > $TESTTMP/ext/small_inline.py | |||
|
366 | > from mercurial import revlog | |||
|
367 | > revlog._maxinline = 8 | |||
|
368 | > EOF | |||
|
369 | ||||
|
370 | $ cat << EOF >> $HGRCPATH | |||
|
371 | > [extensions] | |||
|
372 | > small_inline=$TESTTMP/ext/small_inline.py | |||
|
373 | > EOF | |||
|
374 | ||||
|
375 | $ mkdir repo-to-fix-not-inline | |||
|
376 | $ cd repo-to-fix-not-inline | |||
|
377 | #if windows | |||
|
378 | tar interprets `:` in paths (like `C:`) as being remote, force local on Windows | |||
|
379 | only since some versions of tar don't have this flag. | |||
|
380 | ||||
|
381 | $ tar --force-local -xf $TESTDIR/bundles/issue6528.tar | |||
|
382 | #else | |||
|
383 | $ tar xf $TESTDIR/bundles/issue6528.tar | |||
|
384 | #endif | |||
|
385 | $ echo b >> b.txt | |||
|
386 | $ hg commit -qm "inline -> separate" | |||
|
387 | $ find .hg -name *b.txt.d | |||
|
388 | .hg/store/data/b.txt.d | |||
|
389 | ||||
|
390 | Status is correct, but the problem is still there, in the earlier revision | |||
|
391 | $ hg st | |||
|
392 | $ hg up 3 | |||
|
393 | 1 files updated, 0 files merged, 1 files removed, 0 files unresolved | |||
|
394 | $ hg st | |||
|
395 | M b.txt | |||
|
396 | $ hg debugrevlogindex b.txt | |||
|
397 | rev linkrev nodeid p1 p2 | |||
|
398 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
399 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |||
|
400 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
401 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |||
|
402 | 4 8 db234885e2fe ea4f2f2463cc 000000000000 | |||
|
403 | $ hg debugrevlogindex D.txt | |||
|
404 | rev linkrev nodeid p1 p2 | |||
|
405 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
406 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |||
|
407 | 2 8 65aecc89bb5d 2a80419dfc31 000000000000 | |||
|
408 | ||||
|
409 | Run the fix on the non-inline revlog | |||
|
410 | $ hg debug-repair-issue6528 | |||
|
411 | found affected revision 1 for filelog 'data/D.txt.i' | |||
|
412 | repaired revision 1 of 'filelog data/D.txt.i' | |||
|
413 | found affected revision 1 for filelog 'data/b.txt.i' | |||
|
414 | found affected revision 3 for filelog 'data/b.txt.i' | |||
|
415 | repaired revision 1 of 'filelog data/b.txt.i' | |||
|
416 | repaired revision 3 of 'filelog data/b.txt.i' | |||
|
417 | ||||
|
418 | Check that it worked | |||
|
419 | $ hg debugrevlogindex b.txt | |||
|
420 | rev linkrev nodeid p1 p2 | |||
|
421 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
422 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
423 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
424 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |||
|
425 | 4 8 db234885e2fe ea4f2f2463cc 000000000000 | |||
|
426 | $ hg debugrevlogindex D.txt | |||
|
427 | rev linkrev nodeid p1 p2 | |||
|
428 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
429 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |||
|
430 | 2 8 65aecc89bb5d 2a80419dfc31 000000000000 | |||
|
431 | $ hg debug-repair-issue6528 | |||
|
432 | no affected revisions were found | |||
|
433 | $ hg st | |||
|
434 | ||||
|
435 | $ cd .. | |||
|
436 | ||||
|
437 | Applying a bad bundle should fix it on the fly | |||
|
438 | ---------------------------------------------- | |||
|
439 | ||||
|
440 | from a v1 bundle | |||
|
441 | ~~~~~~~~~~~~~~~~ | |||
|
442 | ||||
|
443 | $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v1 | |||
|
444 | bzip2-v1 | |||
|
445 | ||||
|
446 | $ hg init unbundle-v1 | |||
|
447 | $ cd unbundle-v1 | |||
|
448 | ||||
|
449 | $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v1 | |||
|
450 | adding changesets | |||
|
451 | adding manifests | |||
|
452 | adding file changes | |||
|
453 | added 8 changesets with 12 changes to 4 files | |||
|
454 | new changesets f5a5a568022f:3beabb508514 (8 drafts) | |||
|
455 | (run 'hg update' to get a working copy) | |||
|
456 | ||||
|
457 | Check that revision were fixed on the fly | |||
|
458 | ||||
|
459 | $ hg debugrevlogindex b.txt | |||
|
460 | rev linkrev nodeid p1 p2 | |||
|
461 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
462 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
463 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
464 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |||
|
465 | ||||
|
466 | $ hg debugrevlogindex D.txt | |||
|
467 | rev linkrev nodeid p1 p2 | |||
|
468 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
469 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |||
|
470 | ||||
|
471 | That we don't see the symptoms of the bug | |||
|
472 | ||||
|
473 | $ hg up -- -1 | |||
|
474 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
475 | $ hg status | |||
|
476 | ||||
|
477 | And that the repair command does not find anything to fix | |||
|
478 | ||||
|
479 | $ hg debug-repair-issue6528 | |||
|
480 | no affected revisions were found | |||
|
481 | ||||
|
482 | $ cd .. | |||
|
483 | ||||
|
484 | from a v2 bundle | |||
|
485 | ~~~~~~~~~~~~~~~~ | |||
|
486 | ||||
|
487 | $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v2 | |||
|
488 | bzip2-v2 | |||
|
489 | ||||
|
490 | $ hg init unbundle-v2 | |||
|
491 | $ cd unbundle-v2 | |||
|
492 | ||||
|
493 | $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v2 | |||
|
494 | adding changesets | |||
|
495 | adding manifests | |||
|
496 | adding file changes | |||
|
497 | added 8 changesets with 12 changes to 4 files | |||
|
498 | new changesets f5a5a568022f:3beabb508514 (8 drafts) | |||
|
499 | (run 'hg update' to get a working copy) | |||
|
500 | ||||
|
501 | Check that revision were fixed on the fly | |||
|
502 | ||||
|
503 | $ hg debugrevlogindex b.txt | |||
|
504 | rev linkrev nodeid p1 p2 | |||
|
505 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
506 | 1 3 a58b36ad6b65 000000000000 05b806ebe5ea | |||
|
507 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
508 | 3 7 ea4f2f2463cc 000000000000 216a5fe8b8ed | |||
|
509 | ||||
|
510 | $ hg debugrevlogindex D.txt | |||
|
511 | rev linkrev nodeid p1 p2 | |||
|
512 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
513 | 1 7 2a80419dfc31 000000000000 2a8d3833f2fb | |||
|
514 | ||||
|
515 | That we don't see the symptoms of the bug | |||
|
516 | ||||
|
517 | $ hg up -- -1 | |||
|
518 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
519 | $ hg status | |||
|
520 | ||||
|
521 | And that the repair command does not find anything to fix | |||
|
522 | ||||
|
523 | $ hg debug-repair-issue6528 | |||
|
524 | no affected revisions were found | |||
|
525 | ||||
|
526 | $ cd .. | |||
|
527 | ||||
|
528 | A config option can disable the fixing of the bad bundle on the fly | |||
|
529 | ------------------------------------------------------------------- | |||
|
530 | ||||
|
531 | ||||
|
532 | ||||
|
533 | from a v1 bundle | |||
|
534 | ~~~~~~~~~~~~~~~~ | |||
|
535 | ||||
|
536 | $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v1 | |||
|
537 | bzip2-v1 | |||
|
538 | ||||
|
539 | $ hg init unbundle-v1-no-fix | |||
|
540 | $ cd unbundle-v1-no-fix | |||
|
541 | ||||
|
542 | $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v1 --config storage.revlog.issue6528.fix-incoming=no | |||
|
543 | adding changesets | |||
|
544 | adding manifests | |||
|
545 | adding file changes | |||
|
546 | added 8 changesets with 12 changes to 4 files | |||
|
547 | new changesets f5a5a568022f:3beabb508514 (8 drafts) | |||
|
548 | (run 'hg update' to get a working copy) | |||
|
549 | ||||
|
550 | Check that revision were not fixed on the fly | |||
|
551 | ||||
|
552 | $ hg debugrevlogindex b.txt | |||
|
553 | rev linkrev nodeid p1 p2 | |||
|
554 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
555 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |||
|
556 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
557 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |||
|
558 | ||||
|
559 | $ hg debugrevlogindex D.txt | |||
|
560 | rev linkrev nodeid p1 p2 | |||
|
561 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
562 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |||
|
563 | ||||
|
564 | That we do see the symptoms of the bug | |||
|
565 | ||||
|
566 | $ hg up -- -1 | |||
|
567 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
568 | $ hg status | |||
|
569 | M D.txt (?) | |||
|
570 | M b.txt (?) | |||
|
571 | ||||
|
572 | And that the repair command find issue to fix. | |||
|
573 | ||||
|
574 | $ hg debug-repair-issue6528 --dry-run | |||
|
575 | found affected revision 1 for filelog 'data/D.txt.i' | |||
|
576 | found affected revision 1 for filelog 'data/b.txt.i' | |||
|
577 | found affected revision 3 for filelog 'data/b.txt.i' | |||
|
578 | ||||
|
579 | $ cd .. | |||
|
580 | ||||
|
581 | from a v2 bundle | |||
|
582 | ~~~~~~~~~~~~~~~~ | |||
|
583 | ||||
|
584 | $ hg debugbundle --spec "$TESTDIR"/bundles/issue6528.hg-v2 | |||
|
585 | bzip2-v2 | |||
|
586 | ||||
|
587 | $ hg init unbundle-v2-no-fix | |||
|
588 | $ cd unbundle-v2-no-fix | |||
|
589 | ||||
|
590 | $ hg unbundle "$TESTDIR"/bundles/issue6528.hg-v2 --config storage.revlog.issue6528.fix-incoming=no | |||
|
591 | adding changesets | |||
|
592 | adding manifests | |||
|
593 | adding file changes | |||
|
594 | added 8 changesets with 12 changes to 4 files | |||
|
595 | new changesets f5a5a568022f:3beabb508514 (8 drafts) | |||
|
596 | (run 'hg update' to get a working copy) | |||
|
597 | ||||
|
598 | Check that revision were not fixed on the fly | |||
|
599 | ||||
|
600 | $ hg debugrevlogindex b.txt | |||
|
601 | rev linkrev nodeid p1 p2 | |||
|
602 | 0 2 05b806ebe5ea 000000000000 000000000000 | |||
|
603 | 1 3 a58b36ad6b65 05b806ebe5ea 000000000000 | |||
|
604 | 2 6 216a5fe8b8ed 000000000000 000000000000 | |||
|
605 | 3 7 ea4f2f2463cc 216a5fe8b8ed 000000000000 | |||
|
606 | ||||
|
607 | $ hg debugrevlogindex D.txt | |||
|
608 | rev linkrev nodeid p1 p2 | |||
|
609 | 0 6 2a8d3833f2fb 000000000000 000000000000 | |||
|
610 | 1 7 2a80419dfc31 2a8d3833f2fb 000000000000 | |||
|
611 | ||||
|
612 | That we do see the symptoms of the bug | |||
|
613 | ||||
|
614 | $ hg up -- -1 | |||
|
615 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
616 | $ hg status | |||
|
617 | M D.txt (?) | |||
|
618 | M b.txt (?) | |||
|
619 | ||||
|
620 | And that the repair command find issue to fix. | |||
|
621 | ||||
|
622 | $ hg debug-repair-issue6528 --dry-run | |||
|
623 | found affected revision 1 for filelog 'data/D.txt.i' | |||
|
624 | found affected revision 1 for filelog 'data/b.txt.i' | |||
|
625 | found affected revision 3 for filelog 'data/b.txt.i' | |||
|
626 | ||||
|
627 | $ cd .. |
@@ -211,3 +211,7 b' d5d9177c0045d206db575bae6daa98e2cb2fe5bc' | |||||
211 | f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmB+71MQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91Vj+EADBa/tHfgyymKmXXl9DSlzwEhX1DkCE0aRcsbfXujnpOQrDi09pfHvtYEbgJfl6m8JEUOjuRRcxofnIWOC9UJCGC3ZfW5tTcHomCFlqjHhUxGKsvQ1Wcec1IH3mmzhqLnd0X57EgnNC6APwgxNVRmC0q7M7rSlNiE8BkHEUuyCau5FvpgdF31Aqa9IQP95pmmeDwL4ByPR1Nssu2/8N5vbcQm55gdjcggNjBvNEbaFHDS9NlGS8quvCMwRZkr3meDfTeCs9d2MveXXvV8GVOFq+WHMoURVijTjON+HuXB7HLegyhVOcigfbU5zxGY/IAJ/tAYEzBLWSYW6wjsN5uuZP267XhKpd2FT8Cfe9t3OnN1K21ndltlaMSdGyAynuepzVE0IELOCiKlgBZkdnft2XkUt2DDg/TqhOeXmUBzIFVze5KULSgrFvjkx71iV22LUGkIxzIuW5ieBMeZotKHzI+ZXO7xNSDIdoSfERKUqfYJKbksnBQLRxYUO77KetjocsMMYyB4Dpzu05+eWpYtZs2u5PsqP/Jv84Mz3QR0szAI1h3KlhmbkvKxnWnFYasAdFPMluX4G4X+9+MulODCwgw/RvQhh13M2QP0vGb1Xzu/JOuxRr3zuliTUfszd7YHVJoROzuT9PlcZ4criwZwv+fvbCN+F9LRbeI/BQBVZi6w== |
|
211 | f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmB+71MQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91Vj+EADBa/tHfgyymKmXXl9DSlzwEhX1DkCE0aRcsbfXujnpOQrDi09pfHvtYEbgJfl6m8JEUOjuRRcxofnIWOC9UJCGC3ZfW5tTcHomCFlqjHhUxGKsvQ1Wcec1IH3mmzhqLnd0X57EgnNC6APwgxNVRmC0q7M7rSlNiE8BkHEUuyCau5FvpgdF31Aqa9IQP95pmmeDwL4ByPR1Nssu2/8N5vbcQm55gdjcggNjBvNEbaFHDS9NlGS8quvCMwRZkr3meDfTeCs9d2MveXXvV8GVOFq+WHMoURVijTjON+HuXB7HLegyhVOcigfbU5zxGY/IAJ/tAYEzBLWSYW6wjsN5uuZP267XhKpd2FT8Cfe9t3OnN1K21ndltlaMSdGyAynuepzVE0IELOCiKlgBZkdnft2XkUt2DDg/TqhOeXmUBzIFVze5KULSgrFvjkx71iV22LUGkIxzIuW5ieBMeZotKHzI+ZXO7xNSDIdoSfERKUqfYJKbksnBQLRxYUO77KetjocsMMYyB4Dpzu05+eWpYtZs2u5PsqP/Jv84Mz3QR0szAI1h3KlhmbkvKxnWnFYasAdFPMluX4G4X+9+MulODCwgw/RvQhh13M2QP0vGb1Xzu/JOuxRr3zuliTUfszd7YHVJoROzuT9PlcZ4criwZwv+fvbCN+F9LRbeI/BQBVZi6w== | |
212 | 8d2b62d716b095507effaa8d56f87cd27ba659ab 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmCAO3gQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YvWD/4kn4nLsu6W6hpSmB6qZB7y9adX8mqwzpSfnt0hwesk5FiBmGnDWHT5IvGHRTq0B3+peG9NH5R0h1WgtCdyh6YxGg0CZwNoarv64U8llS+PTXp8YZo/bVex7QGKQJr45Xik4ZH6htJ0muJUhzpHa6wkthTxK2OuaTTJvJ53lY8dR4lmefxSYPAwWs/jOzkmPwIeK8EnG0ZcBtmheJESOzKnmmOF6N4GnUGFFz/W5q8Gfeqj9xKKDt+zdPHXCEZUYivBcMPL7UNti2kvrp3R7VXBzbw/bPAJTrq68M4Z9mFb0qRZ88ubGXu+LEufsG2Dls/ZF0GnBPeReuFFrg9jimQqo6Rf/+4vV+GtFBY71aofFDDex9/s0q7skNEBxLP6r/KfsachYzvdciRS46zLelrL/NhpDvM6mHOLWmuycCeYShYctGbc2zDK7vD136Da6xlWU5Qci/+6zTtAjaKqdIpJuIzBfKdhaakri8vlpplpNLIDMfTTLyYKVAuHUtZcwHcHWmx54b2ulAmNXtc5yB/JqRIUined+Z6KlYc7c7MKEo2FB2/0okIbx7bIiXbV2of4j3ufv+NPIQel1qsnX58vbYL1spdfynNMTHQ+TYc9lUvuq31znu2LLJ9ZhTOiLEt1QZB28lTukzNuH2MEpGWtrOBIC9AcXjyyZ8HlIwEWMA== |
|
212 | 8d2b62d716b095507effaa8d56f87cd27ba659ab 0 iQJEBAABCAAuFiEEK8zhT1xnJaouqK63ucncgkqlvdUFAmCAO3gQHHJhZkBkdXJpbjQyLmNvbQAKCRC5ydyCSqW91YvWD/4kn4nLsu6W6hpSmB6qZB7y9adX8mqwzpSfnt0hwesk5FiBmGnDWHT5IvGHRTq0B3+peG9NH5R0h1WgtCdyh6YxGg0CZwNoarv64U8llS+PTXp8YZo/bVex7QGKQJr45Xik4ZH6htJ0muJUhzpHa6wkthTxK2OuaTTJvJ53lY8dR4lmefxSYPAwWs/jOzkmPwIeK8EnG0ZcBtmheJESOzKnmmOF6N4GnUGFFz/W5q8Gfeqj9xKKDt+zdPHXCEZUYivBcMPL7UNti2kvrp3R7VXBzbw/bPAJTrq68M4Z9mFb0qRZ88ubGXu+LEufsG2Dls/ZF0GnBPeReuFFrg9jimQqo6Rf/+4vV+GtFBY71aofFDDex9/s0q7skNEBxLP6r/KfsachYzvdciRS46zLelrL/NhpDvM6mHOLWmuycCeYShYctGbc2zDK7vD136Da6xlWU5Qci/+6zTtAjaKqdIpJuIzBfKdhaakri8vlpplpNLIDMfTTLyYKVAuHUtZcwHcHWmx54b2ulAmNXtc5yB/JqRIUined+Z6KlYc7c7MKEo2FB2/0okIbx7bIiXbV2of4j3ufv+NPIQel1qsnX58vbYL1spdfynNMTHQ+TYc9lUvuq31znu2LLJ9ZhTOiLEt1QZB28lTukzNuH2MEpGWtrOBIC9AcXjyyZ8HlIwEWMA== | |
213 | 067f2c53fb24506c9e9fb4639871b13b19a85f8a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmCQMXEVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfpJgP/isIDkbMuhot376RY2SwilSCkjJRoKRCDyLjJReBUF29t+DPWs8h971t2v5DIasfuQZthMv9A6DYcyEs1Q3NTKvT4TMKTTrqQfIe8UMmUa9PI1SIuTShiWbwonrN8rrVMVVcjPO/gookMV8/uoYW3wn/SThkBEYYauONBBVKbQ/Bt31/OPbEeAEdb/IEJ9X9PL1sfQkf+/DA/cwawS+xn01GAxWybx8eJkcJFdGdUcl/PYWgX76RSUhGvD6aHRJTZ1+sXy7+ligfpdPkNrQ248mVEEQkmZaCQ39dQPMX5zLa2hEX6eW9b1BEhNjHzbDfyqwc+F5czLw+R56vjPUyRCkxAZ6Q5Q3vkgLPBlZ2Ay0Lta/5+qGWcX+nDzfKfr2FhBLAnRZG/M+M2ckzR+8twyKg7/vdD8e/B3+Oxmu5QTS8xuj1628Brf9IehedQHoEPDe2M5ynhlEcybkbLz1R7zWKrh2h76OGQtspcjF997W1uZFx+DH6kHSznIm/8zEXy13R2nZk/0YtGX2UjZDv9bZ5X3B7T1673uscx3VpiT8YLJVKX7FyFLMgUbVY9ZGFlQ/pzUP3gTGa5rAB8b72U45jlXdKKvCn9B3hbS4j9OzJKpjsspWDmFHl2/a01ZOL/SZtMlm7FeYymUXKc10dndXlXTlGxHFUJQsii6t3dDyf |
|
213 | 067f2c53fb24506c9e9fb4639871b13b19a85f8a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmCQMXEVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfpJgP/isIDkbMuhot376RY2SwilSCkjJRoKRCDyLjJReBUF29t+DPWs8h971t2v5DIasfuQZthMv9A6DYcyEs1Q3NTKvT4TMKTTrqQfIe8UMmUa9PI1SIuTShiWbwonrN8rrVMVVcjPO/gookMV8/uoYW3wn/SThkBEYYauONBBVKbQ/Bt31/OPbEeAEdb/IEJ9X9PL1sfQkf+/DA/cwawS+xn01GAxWybx8eJkcJFdGdUcl/PYWgX76RSUhGvD6aHRJTZ1+sXy7+ligfpdPkNrQ248mVEEQkmZaCQ39dQPMX5zLa2hEX6eW9b1BEhNjHzbDfyqwc+F5czLw+R56vjPUyRCkxAZ6Q5Q3vkgLPBlZ2Ay0Lta/5+qGWcX+nDzfKfr2FhBLAnRZG/M+M2ckzR+8twyKg7/vdD8e/B3+Oxmu5QTS8xuj1628Brf9IehedQHoEPDe2M5ynhlEcybkbLz1R7zWKrh2h76OGQtspcjF997W1uZFx+DH6kHSznIm/8zEXy13R2nZk/0YtGX2UjZDv9bZ5X3B7T1673uscx3VpiT8YLJVKX7FyFLMgUbVY9ZGFlQ/pzUP3gTGa5rAB8b72U45jlXdKKvCn9B3hbS4j9OzJKpjsspWDmFHl2/a01ZOL/SZtMlm7FeYymUXKc10dndXlXTlGxHFUJQsii6t3dDyf | |
|
214 | 411dc27fd9fd076d6a031a08fcaace659afe2fe3 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmDnSgwVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOftvQP/j1mvheFHsv5TSJ2IEKgEK4G/cIxt+taoWpecEUVN5JAk7q4Y1xnzcoyqQdAyvZcTu7m4ESx865XW6Jvc0I2pG+uKcmO7ZfwrAOugoXXxrlXtopVfDDFZOLlk72x+Z5tQpL9QcBUgetkuOZLFhT+1ETjnFd2H4P4pwPjdTpn+YBmDmh1tWTMzllTDDzvZeE6iAjIpM9IQKL4jKxcEjPAX2XDa1xWhd/o9NZC9kYSTIBQvbFWAz3A0PSAudz0lu5YDXKJNtIHlzZtMFmcUlqJGM4MlD6v9tm8EQbCWTgOm0+wB5miDqv05aC6axD3LnSgrlPsmRDZCIRAws1JHEjKYFob7VRMxpivW7GDSd6QrmUbTHYN5eY0v1YB62dCa8W9qk2E7R5VdLRi4haFTv42u7jOZT0tSzRv/R0QppoVQ7/Fpqpps+aoZBM6EGj/pAxRgBTHeyI9WTFUAYDbhRuN9EoJAqRUCpXn39oR+TsaD9COENAJroX2WLIY8XFD3UzrpA9NPt7JE9mufWoNipNqLdLY7k3p3UxX0/SDboVlax6ORpQN+YzYhCesJaAOhlTAXMRMyXsfw/ScYttXxmIJ7BINYEMSXM55uiUPYFjE/GuZjbjgqk3dmJr7ceAyGa5v+m5Hr6efPSRHKUAxkEcDsXpcTHyEOVt3l7Qwfd+oUumK | |||
|
215 | d7515d29761d5ada7d9c765f517db67db75dea9a 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmD4lQMVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfVsMP/19G6aZBokNRdErXcT86ahVy82IquR/CmLJcdj/4nehmBXToLCmdeqKe17ZKgZ7bnPnevhO07zPub7RUhDixnb7OxpbXiyP7x67FAqAfKvi8rZggmeWZT5kpiltoBIvHDlOlQhsgtfea0REULyn4zNB6dLED5zh2Ddr5LcWIjfOvIWo1F0eFMcRszL8f2u2ei2dERDuG8MSzMsiFHMAPRMHJjm+YukJBuz78CH4qT/Inkq52ao+3GCh4fFBhPG5+IABeCn1J4cAAK06mPcJqa7fbv7NfUCN9MeDNQUsUGGfIhKzGHJTb7PwXkKJ3qpLPs4FYGV1ZTucrIU1i65hXuf66QcYGlAQmKavS7xDOfZhzrZrAKe65dLpWdEH5mpTMcjaMBS+mhfMJT7DQg9T/9jISiKeqiFNkNOy1cobpJWes8iFwihEBtEhCtiVgnf7i7IzZY/spmSmP4ot/MEBi3jMjvAEaH1HyDGOPuBuqRSIRU+Mf5o1yB2kZmGL9vHWUzm/ySjQFYte061OyE9bZrbF9daOTdRip/CXPApOneVBIMwXc7fWDu45cKyVg7kYo8a0gcFfg39Ceja3Z8iJSFtJTuj1Sd9q8YU6pxqDrfPm1byJJlb7SvAoZfIGQPFk+DF6UVEcWRC0MYRm2bHXlaZwNVpgmFv6ZOVja3jxCJkw8 | |||
|
216 | 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmESg/wVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOf6kAP/1w3elvhAYQcK9hkEVCg4sQgnvcatOafCNaK0dVW9OOFbt+8DNUcHbtUHZtR6ETmSAMlWilIr/1vRMjy0Zic6afJ30oq8i+4f6DgLyTsLQL/QdwJQIwi2fZmHebv1PSrhT9tJAwtH6oG3cNhSq8KMme4l7sVR7ekB34Cmzk3fa5udMOuQG9xWbGTmeEsx0kYb+1oag+NnnZJqVTi68gGGxRW8TYZ1APXJcrZVfkldtaIWx6U1UdkWSTqWHV4fnnctp/1M+IgXCLT0iupY5LnxqGKQcMte7WKRPPdfhGF1ta+LN+QPHbwXhDRDIWPBVbDeHxjKcjz3h+DOeF0b7c5vKDADgo9LtHui9QhBJiCDHwsM+8gA+kNEDbtvIYYQ6CLxX9m1TttxI4ASIzFGIQF6nBr3mjQCzmOoWtgVh7R4dsQ9YZgm4twjsIg3g0MDhmgs71jn6Gp4BficF25nY8J6Ct8YopkPs2sfiBYJmyh9NJLDjwqNnjq3MBervPX3B+7p1dfIsK4JoSuop5A4lc4OOEhrwm5BKIxm30R4NtB15RZ7nI0DcRFcwNQiTYPG+nOaPsFzeZD6lj8+YnuLyo2aCnf4K26/1YTlE1wOFkCb1reL99++i8FP94poHBKZ7+6HT6gk4Mmnfb52II4yWlh/CYLeKEzFFfAiOTvfhzpIvqg | |||
|
217 | 53221078e0de65d1a821ce5311dec45a7a978301 0 iQJJBAABCgAzFiEEgY2HzRrBgMOUyG5jOjPeRg2ew58FAmEeqLUVHDc4OTVwdWxraXRAZ21haWwuY29tAAoJEDoz3kYNnsOfMb4P/R4oPBjSKrlGbuxYClNdP0lV4C1NUU1SPa+Il4QwGQteKD+RDfvp8z8+c45rVIEGiUNzaSJP/ZEyhBVW657rYzIhBnZgqnpwBzOViqe4Q3lHiq6wPKjEDIRJafcqMb6MaViPS6iRn6hhMlAcPcoabwhXrUgv8QyxVSTFlJm0RGbUVekQLIWKEAnwcWLHKt0d2DrB0/706xXtKxdJ8N/2WCVOOkr7UvpdLXo3quOz1S930/o1iF/csggsi9q4oZYj2XBdBGHayoqkhKAQMyBfXH19RqW3SWZafY8whrZDCz+9AAmJJk8hjQl6xrT/ZVweRfqvRoMJBgjQdFTi58wjC8995ZXKEC7jsJCEblyRJkc23opuAArPEkJXLDR+oK1vOfikaRjmQoMPAMDjbxTUyVOuHcX+PxMtq9NAO0MKcnSr+D2Xc28TGY9PkBhRkEnN3nlZH5z7DvF8GfOnUt5SGhFiQHhXnL6jDBCQVDKAoCJn0WKDG9+29I6st2eGEwKaIjZQ9NCtaLASiauopMOyWWbHeM58bCl80TBXuj+3W+mo+zDSLoGwWJc5oFdFpmnGGTQtkxPDiV4ksIgJAMb/KHkGY+RxnEsWgX1VcR2c1sYD4nzOjrt4RuvX1i+cfzRjLOchPiru7BbrBQRTXGhrvNzsS9laTCxCH2oDazIudia4 |
@@ -224,3 +224,7 b' d5d9177c0045d206db575bae6daa98e2cb2fe5bc' | |||||
224 | f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0 |
|
224 | f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0 | |
225 | 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1 |
|
225 | 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1 | |
226 | 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8 |
|
226 | 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8 | |
|
227 | 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1 | |||
|
228 | d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0 | |||
|
229 | 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1 | |||
|
230 | 53221078e0de65d1a821ce5311dec45a7a978301 5.9 |
@@ -270,9 +270,27 b' osx:' | |||||
270 | pyoxidizer: |
|
270 | pyoxidizer: | |
271 | $(PYOXIDIZER) build --path ./rust/hgcli --release |
|
271 | $(PYOXIDIZER) build --path ./rust/hgcli --release | |
272 |
|
272 | |||
|
273 | ||||
|
274 | PYOX_DIR=build/pyoxidizer/x86_64-pc-windows-msvc/release/app | |||
|
275 | ||||
|
276 | # a temporary target to setup all we need for run-tests.py --pyoxidizer | |||
|
277 | # (should go away as the run-tests implementation improves | |||
|
278 | pyoxidizer-windows-tests: pyoxidizer | |||
|
279 | rm -rf $(PYOX_DIR)/templates | |||
|
280 | cp -ar $(PYOX_DIR)/lib/mercurial/templates $(PYOX_DIR)/templates | |||
|
281 | rm -rf $(PYOX_DIR)/helptext | |||
|
282 | cp -ar $(PYOX_DIR)/lib/mercurial/helptext $(PYOX_DIR)/helptext | |||
|
283 | rm -rf $(PYOX_DIR)/defaultrc | |||
|
284 | cp -ar $(PYOX_DIR)/lib/mercurial/defaultrc $(PYOX_DIR)/defaultrc | |||
|
285 | rm -rf $(PYOX_DIR)/contrib | |||
|
286 | cp -ar contrib $(PYOX_DIR)/contrib | |||
|
287 | rm -rf $(PYOX_DIR)/doc | |||
|
288 | cp -ar doc $(PYOX_DIR)/doc | |||
|
289 | ||||
|
290 | ||||
273 | .PHONY: help all local build doc cleanbutpackages clean install install-bin \ |
|
291 | .PHONY: help all local build doc cleanbutpackages clean install install-bin \ | |
274 | install-doc install-home install-home-bin install-home-doc \ |
|
292 | install-doc install-home install-home-bin install-home-doc \ | |
275 | dist dist-notests check tests rust-tests check-code format-c \ |
|
293 | dist dist-notests check tests rust-tests check-code format-c \ | |
276 | update-pot pyoxidizer \ |
|
294 | update-pot pyoxidizer pyoxidizer-windows-tests \ | |
277 | $(packaging_targets) \ |
|
295 | $(packaging_targets) \ | |
278 | osx |
|
296 | osx |
@@ -340,11 +340,6 b' commonpypats = [' | |||||
340 | (r'[^\n]\Z', "no trailing newline"), |
|
340 | (r'[^\n]\Z', "no trailing newline"), | |
341 | (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), |
|
341 | (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), | |
342 | ( |
|
342 | ( | |
343 | r'^\s+(self\.)?[A-Za-z][a-z0-9]+[A-Z]\w* = ', |
|
|||
344 | "don't use camelcase in identifiers", |
|
|||
345 | r'#.*camelcase-required', |
|
|||
346 | ), |
|
|||
347 | ( |
|
|||
348 | r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+', |
|
343 | r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+', | |
349 | "linebreak after :", |
|
344 | "linebreak after :", | |
350 | ), |
|
345 | ), |
@@ -10,7 +10,11 b' variables:' | |||||
10 | HG_CI_IMAGE_TAG: "latest" |
|
10 | HG_CI_IMAGE_TAG: "latest" | |
11 | TEST_HGTESTS_ALLOW_NETIO: "0" |
|
11 | TEST_HGTESTS_ALLOW_NETIO: "0" | |
12 |
|
12 | |||
|
13 | .all_template: &all | |||
|
14 | when: always | |||
|
15 | ||||
13 | .runtests_template: &runtests |
|
16 | .runtests_template: &runtests | |
|
17 | <<: *all | |||
14 | stage: tests |
|
18 | stage: tests | |
15 | # The runner made a clone as root. |
|
19 | # The runner made a clone as root. | |
16 | # We make a new clone owned by user used to run the step. |
|
20 | # We make a new clone owned by user used to run the step. | |
@@ -38,6 +42,7 b' checks-py3:' | |||||
38 | PYTHON: python3 |
|
42 | PYTHON: python3 | |
39 |
|
43 | |||
40 | rust-cargo-test-py2: &rust_cargo_test |
|
44 | rust-cargo-test-py2: &rust_cargo_test | |
|
45 | <<: *all | |||
41 | stage: tests |
|
46 | stage: tests | |
42 | script: |
|
47 | script: | |
43 | - echo "python used, $PYTHON" |
|
48 | - echo "python used, $PYTHON" | |
@@ -50,6 +55,7 b' rust-cargo-test-py3:' | |||||
50 | PYTHON: python3 |
|
55 | PYTHON: python3 | |
51 |
|
56 | |||
52 | phabricator-refresh: |
|
57 | phabricator-refresh: | |
|
58 | <<: *all | |||
53 | stage: phabricator |
|
59 | stage: phabricator | |
54 | variables: |
|
60 | variables: | |
55 | DEFAULT_COMMENT: ":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)" |
|
61 | DEFAULT_COMMENT: ":white_check_mark: refresh by Heptapod after a successful CI run (:octopus: :green_heart:)" | |
@@ -128,7 +134,6 b' test-py3-chg:' | |||||
128 |
|
134 | |||
129 | check-pytype-py3: |
|
135 | check-pytype-py3: | |
130 | extends: .runtests_template |
|
136 | extends: .runtests_template | |
131 | when: manual |
|
|||
132 | before_script: |
|
137 | before_script: | |
133 | - hg clone . /tmp/mercurial-ci/ --noupdate --config phases.publish=no |
|
138 | - hg clone . /tmp/mercurial-ci/ --noupdate --config phases.publish=no | |
134 | - hg -R /tmp/mercurial-ci/ update `hg log --rev '.' --template '{node}'` |
|
139 | - hg -R /tmp/mercurial-ci/ update `hg log --rev '.' --template '{node}'` | |
@@ -137,6 +142,7 b' check-pytype-py3:' | |||||
137 | - $PYTHON -m pip install --user -U pytype==2021.04.15 |
|
142 | - $PYTHON -m pip install --user -U pytype==2021.04.15 | |
138 | variables: |
|
143 | variables: | |
139 | RUNTEST_ARGS: " --allow-slow-tests tests/test-check-pytype.t" |
|
144 | RUNTEST_ARGS: " --allow-slow-tests tests/test-check-pytype.t" | |
|
145 | HGTEST_TIMEOUT: "3600" | |||
140 | PYTHON: python3 |
|
146 | PYTHON: python3 | |
141 | TEST_HGMODULEPOLICY: "c" |
|
147 | TEST_HGMODULEPOLICY: "c" | |
142 |
|
148 | |||
@@ -146,11 +152,10 b' check-pytype-py3:' | |||||
146 | # run-tests.py- it is needed to make run-tests.py generate a `python3` script |
|
152 | # run-tests.py- it is needed to make run-tests.py generate a `python3` script | |
147 | # that satisfies the various shebang lines and delegates to `py -3`. |
|
153 | # that satisfies the various shebang lines and delegates to `py -3`. | |
148 | .window_runtests_template: &windows_runtests |
|
154 | .window_runtests_template: &windows_runtests | |
|
155 | <<: *all | |||
149 | stage: tests |
|
156 | stage: tests | |
150 | before_script: |
|
157 | before_script: | |
151 | # Temporary until this is adjusted in the environment |
|
158 | - C:/MinGW/msys/1.0/bin/sh.exe --login -c 'cd "$OLDPWD" && ls -1 tests/test-check-*.* > C:/Temp/check-tests.txt' | |
152 | - $Env:TEMP="C:/Temp" |
|
|||
153 | - $Env:TMP="C:/Temp" |
|
|||
154 | # TODO: find/install cvs, bzr, perforce, gpg, sqlite3 |
|
159 | # TODO: find/install cvs, bzr, perforce, gpg, sqlite3 | |
155 |
|
160 | |||
156 | script: |
|
161 | script: | |
@@ -159,16 +164,25 b' check-pytype-py3:' | |||||
159 | - Invoke-Expression "$Env:PYTHON -V" |
|
164 | - Invoke-Expression "$Env:PYTHON -V" | |
160 | - Invoke-Expression "$Env:PYTHON -m black --version" |
|
165 | - Invoke-Expression "$Env:PYTHON -m black --version" | |
161 | - echo "$Env:RUNTEST_ARGS" |
|
166 | - echo "$Env:RUNTEST_ARGS" | |
|
167 | - echo "$Env:TMP" | |||
|
168 | - echo "$Env:TEMP" | |||
162 |
|
169 | |||
163 | - C:/MinGW/msys/1.0/bin/sh.exe --login -c 'cd "$OLDPWD" && HGTESTS_ALLOW_NETIO="$TEST_HGTESTS_ALLOW_NETIO" HGMODULEPOLICY="$TEST_HGMODULEPOLICY" $PYTHON tests/run-tests.py --color=always $RUNTEST_ARGS' |
|
170 | - C:/MinGW/msys/1.0/bin/sh.exe --login -c 'cd "$OLDPWD" && HGTESTS_ALLOW_NETIO="$TEST_HGTESTS_ALLOW_NETIO" HGMODULEPOLICY="$TEST_HGMODULEPOLICY" $PYTHON tests/run-tests.py --color=always $RUNTEST_ARGS' | |
164 |
|
171 | |||
165 | windows-py3: |
|
172 | windows-py3: | |
166 | <<: *windows_runtests |
|
173 | <<: *windows_runtests | |
167 | when: manual |
|
|||
168 | tags: |
|
174 | tags: | |
169 | - windows |
|
175 | - windows | |
170 | timeout: 2h |
|
|||
171 | variables: |
|
176 | variables: | |
172 | TEST_HGMODULEPOLICY: "c" |
|
177 | TEST_HGMODULEPOLICY: "c" | |
173 |
RUNTEST_ARGS: "--blacklist |
|
178 | RUNTEST_ARGS: "--blacklist C:/Temp/check-tests.txt" | |
174 | PYTHON: py -3 |
|
179 | PYTHON: py -3 | |
|
180 | ||||
|
181 | windows-py3-pyox: | |||
|
182 | <<: *windows_runtests | |||
|
183 | tags: | |||
|
184 | - windows | |||
|
185 | variables: | |||
|
186 | TEST_HGMODULEPOLICY: "c" | |||
|
187 | RUNTEST_ARGS: "--blacklist C:/Temp/check-tests.txt --pyoxidized" | |||
|
188 | PYTHON: py -3 |
@@ -278,6 +278,8 b' def list_stdlib_modules():' | |||||
278 | ): |
|
278 | ): | |
279 | continue |
|
279 | continue | |
280 | for top, dirs, files in os.walk(libpath): |
|
280 | for top, dirs, files in os.walk(libpath): | |
|
281 | if 'dist-packages' in top.split(os.path.sep): | |||
|
282 | continue | |||
281 | for i, d in reversed(list(enumerate(dirs))): |
|
283 | for i, d in reversed(list(enumerate(dirs))): | |
282 | if ( |
|
284 | if ( | |
283 | not os.path.exists(os.path.join(top, d, '__init__.py')) |
|
285 | not os.path.exists(os.path.join(top, d, '__init__.py')) |
@@ -19,14 +19,6 b'' | |||||
19 | $VS_BUILD_TOOLS_URL = "https://download.visualstudio.microsoft.com/download/pr/a1603c02-8a66-4b83-b821-811e3610a7c4/aa2db8bb39e0cbd23e9940d8951e0bc3/vs_buildtools.exe" |
|
19 | $VS_BUILD_TOOLS_URL = "https://download.visualstudio.microsoft.com/download/pr/a1603c02-8a66-4b83-b821-811e3610a7c4/aa2db8bb39e0cbd23e9940d8951e0bc3/vs_buildtools.exe" | |
20 | $VS_BUILD_TOOLS_SHA256 = "911E292B8E6E5F46CBC17003BDCD2D27A70E616E8D5E6E69D5D489A605CAA139" |
|
20 | $VS_BUILD_TOOLS_SHA256 = "911E292B8E6E5F46CBC17003BDCD2D27A70E616E8D5E6E69D5D489A605CAA139" | |
21 |
|
21 | |||
22 | $VC9_PYTHON_URL = "https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi" |
|
|||
23 | $VC9_PYTHON_SHA256 = "070474db76a2e625513a5835df4595df9324d820f9cc97eab2a596dcbc2f5cbf" |
|
|||
24 |
|
||||
25 | $PYTHON27_x64_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi" |
|
|||
26 | $PYTHON27_x64_SHA256 = "b74a3afa1e0bf2a6fc566a7b70d15c9bfabba3756fb077797d16fffa27800c05" |
|
|||
27 | $PYTHON27_X86_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.msi" |
|
|||
28 | $PYTHON27_X86_SHA256 = "d901802e90026e9bad76b8a81f8dd7e43c7d7e8269d9281c9e9df7a9c40480a9" |
|
|||
29 |
|
||||
30 | $PYTHON37_x86_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9.exe" |
|
22 | $PYTHON37_x86_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9.exe" | |
31 | $PYTHON37_x86_SHA256 = "769bb7c74ad1df6d7d74071cc16a984ff6182e4016e11b8949b93db487977220" |
|
23 | $PYTHON37_x86_SHA256 = "769bb7c74ad1df6d7d74071cc16a984ff6182e4016e11b8949b93db487977220" | |
32 | $PYTHON37_X64_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64.exe" |
|
24 | $PYTHON37_X64_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64.exe" | |
@@ -46,18 +38,15 b'' | |||||
46 | $PIP_URL = "https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py" |
|
38 | $PIP_URL = "https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py" | |
47 | $PIP_SHA256 = "57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe" |
|
39 | $PIP_SHA256 = "57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe" | |
48 |
|
40 | |||
49 | $VIRTUALENV_URL = "https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/virtualenv-16.7.5.tar.gz" |
|
|||
50 | $VIRTUALENV_SHA256 = "f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2" |
|
|||
51 |
|
||||
52 | $INNO_SETUP_URL = "http://files.jrsoftware.org/is/5/innosetup-5.6.1-unicode.exe" |
|
41 | $INNO_SETUP_URL = "http://files.jrsoftware.org/is/5/innosetup-5.6.1-unicode.exe" | |
53 | $INNO_SETUP_SHA256 = "27D49E9BC769E9D1B214C153011978DB90DC01C2ACD1DDCD9ED7B3FE3B96B538" |
|
42 | $INNO_SETUP_SHA256 = "27D49E9BC769E9D1B214C153011978DB90DC01C2ACD1DDCD9ED7B3FE3B96B538" | |
54 |
|
43 | |||
55 | $MINGW_BIN_URL = "https://osdn.net/frs/redir.php?m=constant&f=mingw%2F68260%2Fmingw-get-0.6.3-mingw32-pre-20170905-1-bin.zip" |
|
44 | $MINGW_BIN_URL = "https://osdn.net/frs/redir.php?m=constant&f=mingw%2F68260%2Fmingw-get-0.6.3-mingw32-pre-20170905-1-bin.zip" | |
56 | $MINGW_BIN_SHA256 = "2AB8EFD7C7D1FC8EAF8B2FA4DA4EEF8F3E47768284C021599BC7435839A046DF" |
|
45 | $MINGW_BIN_SHA256 = "2AB8EFD7C7D1FC8EAF8B2FA4DA4EEF8F3E47768284C021599BC7435839A046DF" | |
57 |
|
46 | |||
58 |
$MERCURIAL_WHEEL_FILENAME = "mercurial-5. |
|
47 | $MERCURIAL_WHEEL_FILENAME = "mercurial-5.8.1-cp39-cp39-win_amd64.whl" | |
59 |
$MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/ |
|
48 | $MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/5c/b5/a5fa664761eef29b6c90eb24cb09ab8fe2c9b4b86af41d42c17476aff29b/$MERCURIAL_WHEEL_FILENAME" | |
60 | $MERCURIAL_WHEEL_SHA256 = "1d18c7f6ca1456f0f62ee65c9a50c14cbba48ce6e924930cdb10537f5c9eaf5f" |
|
49 | $MERCURIAL_WHEEL_SHA256 = "cbf3efa68fd7ebf94691bd00d2c86bbd47ca73620c8faa4f18b6c394bf5f82b0" | |
61 |
|
50 | |||
62 | $RUSTUP_INIT_URL = "https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-pc-windows-gnu/rustup-init.exe" |
|
51 | $RUSTUP_INIT_URL = "https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-pc-windows-gnu/rustup-init.exe" | |
63 | $RUSTUP_INIT_SHA256 = "d17df34ba974b9b19cf5c75883a95475aa22ddc364591d75d174090d55711c72" |
|
52 | $RUSTUP_INIT_SHA256 = "d17df34ba974b9b19cf5c75883a95475aa22ddc364591d75d174090d55711c72" | |
@@ -91,6 +80,8 b' function Secure-Download($url, $path, $s' | |||||
91 | } |
|
80 | } | |
92 |
|
81 | |||
93 | function Invoke-Process($path, $arguments) { |
|
82 | function Invoke-Process($path, $arguments) { | |
|
83 | echo "$path $arguments" | |||
|
84 | ||||
94 | $p = Start-Process -FilePath $path -ArgumentList $arguments -Wait -PassThru -WindowStyle Hidden |
|
85 | $p = Start-Process -FilePath $path -ArgumentList $arguments -Wait -PassThru -WindowStyle Hidden | |
95 |
|
86 | |||
96 | if ($p.ExitCode -ne 0) { |
|
87 | if ($p.ExitCode -ne 0) { | |
@@ -135,9 +126,6 b' function Install-Dependencies($prefix) {' | |||||
135 |
|
126 | |||
136 | $pip = "${prefix}\assets\get-pip.py" |
|
127 | $pip = "${prefix}\assets\get-pip.py" | |
137 |
|
128 | |||
138 | Secure-Download $VC9_PYTHON_URL ${prefix}\assets\VCForPython27.msi $VC9_PYTHON_SHA256 |
|
|||
139 | Secure-Download $PYTHON27_x86_URL ${prefix}\assets\python27-x86.msi $PYTHON27_x86_SHA256 |
|
|||
140 | Secure-Download $PYTHON27_x64_URL ${prefix}\assets\python27-x64.msi $PYTHON27_x64_SHA256 |
|
|||
141 | Secure-Download $PYTHON37_x86_URL ${prefix}\assets\python37-x86.exe $PYTHON37_x86_SHA256 |
|
129 | Secure-Download $PYTHON37_x86_URL ${prefix}\assets\python37-x86.exe $PYTHON37_x86_SHA256 | |
142 | Secure-Download $PYTHON37_x64_URL ${prefix}\assets\python37-x64.exe $PYTHON37_x64_SHA256 |
|
130 | Secure-Download $PYTHON37_x64_URL ${prefix}\assets\python37-x64.exe $PYTHON37_x64_SHA256 | |
143 | Secure-Download $PYTHON38_x86_URL ${prefix}\assets\python38-x86.exe $PYTHON38_x86_SHA256 |
|
131 | Secure-Download $PYTHON38_x86_URL ${prefix}\assets\python38-x86.exe $PYTHON38_x86_SHA256 | |
@@ -145,7 +133,6 b' function Install-Dependencies($prefix) {' | |||||
145 | Secure-Download $PYTHON39_x86_URL ${prefix}\assets\python39-x86.exe $PYTHON39_x86_SHA256 |
|
133 | Secure-Download $PYTHON39_x86_URL ${prefix}\assets\python39-x86.exe $PYTHON39_x86_SHA256 | |
146 | Secure-Download $PYTHON39_x64_URL ${prefix}\assets\python39-x64.exe $PYTHON39_x64_SHA256 |
|
134 | Secure-Download $PYTHON39_x64_URL ${prefix}\assets\python39-x64.exe $PYTHON39_x64_SHA256 | |
147 | Secure-Download $PIP_URL ${pip} $PIP_SHA256 |
|
135 | Secure-Download $PIP_URL ${pip} $PIP_SHA256 | |
148 | Secure-Download $VIRTUALENV_URL ${prefix}\assets\virtualenv.tar.gz $VIRTUALENV_SHA256 |
|
|||
149 | Secure-Download $VS_BUILD_TOOLS_URL ${prefix}\assets\vs_buildtools.exe $VS_BUILD_TOOLS_SHA256 |
|
136 | Secure-Download $VS_BUILD_TOOLS_URL ${prefix}\assets\vs_buildtools.exe $VS_BUILD_TOOLS_SHA256 | |
150 | Secure-Download $INNO_SETUP_URL ${prefix}\assets\InnoSetup.exe $INNO_SETUP_SHA256 |
|
137 | Secure-Download $INNO_SETUP_URL ${prefix}\assets\InnoSetup.exe $INNO_SETUP_SHA256 | |
151 | Secure-Download $MINGW_BIN_URL ${prefix}\assets\mingw-get-bin.zip $MINGW_BIN_SHA256 |
|
138 | Secure-Download $MINGW_BIN_URL ${prefix}\assets\mingw-get-bin.zip $MINGW_BIN_SHA256 | |
@@ -153,20 +140,10 b' function Install-Dependencies($prefix) {' | |||||
153 | Secure-Download $RUSTUP_INIT_URL ${prefix}\assets\rustup-init.exe $RUSTUP_INIT_SHA256 |
|
140 | Secure-Download $RUSTUP_INIT_URL ${prefix}\assets\rustup-init.exe $RUSTUP_INIT_SHA256 | |
154 | Secure-Download $PYOXIDIZER_URL ${prefix}\assets\PyOxidizer.msi $PYOXIDIZER_SHA256 |
|
141 | Secure-Download $PYOXIDIZER_URL ${prefix}\assets\PyOxidizer.msi $PYOXIDIZER_SHA256 | |
155 |
|
142 | |||
156 | Write-Output "installing Python 2.7 32-bit" |
|
|||
157 | Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x86.msi /l* ${prefix}\assets\python27-x86.log /q TARGETDIR=${prefix}\python27-x86 ALLUSERS=" |
|
|||
158 | Invoke-Process ${prefix}\python27-x86\python.exe ${prefix}\assets\get-pip.py |
|
|||
159 | Invoke-Process ${prefix}\python27-x86\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz" |
|
|||
160 |
|
||||
161 | Write-Output "installing Python 2.7 64-bit" |
|
|||
162 | Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x64.msi /l* ${prefix}\assets\python27-x64.log /q TARGETDIR=${prefix}\python27-x64 ALLUSERS=" |
|
|||
163 | Invoke-Process ${prefix}\python27-x64\python.exe ${prefix}\assets\get-pip.py |
|
|||
164 | Invoke-Process ${prefix}\python27-x64\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz" |
|
|||
165 |
|
||||
166 | Install-Python3 "Python 3.7 32-bit" ${prefix}\assets\python37-x86.exe ${prefix}\python37-x86 ${pip} |
|
143 | Install-Python3 "Python 3.7 32-bit" ${prefix}\assets\python37-x86.exe ${prefix}\python37-x86 ${pip} | |
167 | Install-Python3 "Python 3.7 64-bit" ${prefix}\assets\python37-x64.exe ${prefix}\python37-x64 ${pip} |
|
144 | Install-Python3 "Python 3.7 64-bit" ${prefix}\assets\python37-x64.exe ${prefix}\python37-x64 ${pip} | |
168 | Install-Python3 "Python 3.8 32-bit" ${prefix}\assets\python38-x86.exe ${prefix}\python38-x86 ${pip} |
|
145 | Install-Python3 "Python 3.8 32-bit" ${prefix}\assets\python38-x86.exe ${prefix}\python38-x86 ${pip} | |
169 |
|
|
146 | # Install-Python3 "Python 3.8 64-bit" ${prefix}\assets\python38-x64.exe ${prefix}\python38-x64 ${pip} | |
170 | Install-Python3 "Python 3.9 32-bit" ${prefix}\assets\python39-x86.exe ${prefix}\python39-x86 ${pip} |
|
147 | Install-Python3 "Python 3.9 32-bit" ${prefix}\assets\python39-x86.exe ${prefix}\python39-x86 ${pip} | |
171 | Install-Python3 "Python 3.9 64-bit" ${prefix}\assets\python39-x64.exe ${prefix}\python39-x64 ${pip} |
|
148 | Install-Python3 "Python 3.9 64-bit" ${prefix}\assets\python39-x64.exe ${prefix}\python39-x64 ${pip} | |
172 |
|
149 | |||
@@ -178,9 +155,6 b' function Install-Dependencies($prefix) {' | |||||
178 |
|
155 | |||
179 | Install-Rust ${prefix} |
|
156 | Install-Rust ${prefix} | |
180 |
|
157 | |||
181 | Write-Output "installing Visual C++ 9.0 for Python 2.7" |
|
|||
182 | Invoke-Process msiexec.exe "/i ${prefix}\assets\VCForPython27.msi /l* ${prefix}\assets\VCForPython27.log /q" |
|
|||
183 |
|
||||
184 | Write-Output "installing Inno Setup" |
|
158 | Write-Output "installing Inno Setup" | |
185 | Invoke-Process ${prefix}\assets\InnoSetup.exe "/SP- /VERYSILENT /SUPPRESSMSGBOXES" |
|
159 | Invoke-Process ${prefix}\assets\InnoSetup.exe "/SP- /VERYSILENT /SUPPRESSMSGBOXES" | |
186 |
|
160 | |||
@@ -196,7 +170,7 b' function Install-Dependencies($prefix) {' | |||||
196 | # Construct a virtualenv useful for bootstrapping. It conveniently contains a |
|
170 | # Construct a virtualenv useful for bootstrapping. It conveniently contains a | |
197 | # Mercurial install. |
|
171 | # Mercurial install. | |
198 | Write-Output "creating bootstrap virtualenv with Mercurial" |
|
172 | Write-Output "creating bootstrap virtualenv with Mercurial" | |
199 |
Invoke-Process "$prefix\python |
|
173 | Invoke-Process "$prefix\python39-x64\python.exe" "-m venv ${prefix}\venv-bootstrap" | |
200 | Invoke-Process "${prefix}\venv-bootstrap\Scripts\pip.exe" "install ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME}" |
|
174 | Invoke-Process "${prefix}\venv-bootstrap\Scripts\pip.exe" "install ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME}" | |
201 | } |
|
175 | } | |
202 |
|
176 | |||
@@ -204,7 +178,7 b' function Clone-Mercurial-Repo($prefix, $' | |||||
204 | Write-Output "cloning $repo_url to $dest" |
|
178 | Write-Output "cloning $repo_url to $dest" | |
205 | # TODO Figure out why CA verification isn't working in EC2 and remove |
|
179 | # TODO Figure out why CA verification isn't working in EC2 and remove | |
206 | # --insecure. |
|
180 | # --insecure. | |
207 |
Invoke-Process "${prefix}\venv-bootstrap\Scripts\ |
|
181 | Invoke-Process "${prefix}\venv-bootstrap\Scripts\python.exe" "${prefix}\venv-bootstrap\Scripts\hg clone --insecure $repo_url $dest" | |
208 |
|
182 | |||
209 | # Mark repo as non-publishing by default for convenience. |
|
183 | # Mark repo as non-publishing by default for convenience. | |
210 | Add-Content -Path "$dest\.hg\hgrc" -Value "`n[phases]`npublish = false" |
|
184 | Add-Content -Path "$dest\.hg\hgrc" -Value "`n[phases]`npublish = false" |
@@ -4,6 +4,14 b'' | |||||
4 | # |
|
4 | # | |
5 | # pip-compile --generate-hashes --output-file=contrib/packaging/requirements-windows-py3.txt contrib/packaging/requirements-windows.txt.in |
|
5 | # pip-compile --generate-hashes --output-file=contrib/packaging/requirements-windows-py3.txt contrib/packaging/requirements-windows.txt.in | |
6 | # |
|
6 | # | |
|
7 | atomicwrites==1.4.0 \ | |||
|
8 | --hash=sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197 \ | |||
|
9 | --hash=sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a \ | |||
|
10 | # via pytest | |||
|
11 | attrs==21.2.0 \ | |||
|
12 | --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \ | |||
|
13 | --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb \ | |||
|
14 | # via pytest | |||
7 | cached-property==1.5.2 \ |
|
15 | cached-property==1.5.2 \ | |
8 | --hash=sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130 \ |
|
16 | --hash=sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130 \ | |
9 | --hash=sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0 \ |
|
17 | --hash=sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0 \ | |
@@ -48,6 +56,10 b' cffi==1.14.4 \\' | |||||
48 | --hash=sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b \ |
|
56 | --hash=sha256:f60567825f791c6f8a592f3c6e3bd93dd2934e3f9dac189308426bd76b00ef3b \ | |
49 | --hash=sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f \ |
|
57 | --hash=sha256:f803eaa94c2fcda012c047e62bc7a51b0bdabda1cad7a92a522694ea2d76e49f \ | |
50 | # via pygit2 |
|
58 | # via pygit2 | |
|
59 | colorama==0.4.4 \ | |||
|
60 | --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b \ | |||
|
61 | --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2 \ | |||
|
62 | # via pytest | |||
51 | docutils==0.16 \ |
|
63 | docutils==0.16 \ | |
52 | --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \ |
|
64 | --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \ | |
53 | --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \ |
|
65 | --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \ | |
@@ -67,14 +79,76 b' dulwich==0.20.6 ; python_version >= "3" ' | |||||
67 | --hash=sha256:e5871b86a079e9e290f52ab14559cea1b694a0b8ed2b9ebb898f6ced7f14a406 \ |
|
79 | --hash=sha256:e5871b86a079e9e290f52ab14559cea1b694a0b8ed2b9ebb898f6ced7f14a406 \ | |
68 | --hash=sha256:e593f514b8ac740b4ceeb047745b4719bfc9f334904245c6edcb3a9d002f577b \ |
|
80 | --hash=sha256:e593f514b8ac740b4ceeb047745b4719bfc9f334904245c6edcb3a9d002f577b \ | |
69 | # via -r contrib/packaging/requirements-windows.txt.in |
|
81 | # via -r contrib/packaging/requirements-windows.txt.in | |
|
82 | fuzzywuzzy==0.18.0 \ | |||
|
83 | --hash=sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8 \ | |||
|
84 | # via -r contrib/packaging/requirements-windows.txt.in | |||
|
85 | idna==3.2 \ | |||
|
86 | --hash=sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a \ | |||
|
87 | --hash=sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3 \ | |||
|
88 | # via yarl | |||
70 | importlib-metadata==3.1.0 \ |
|
89 | importlib-metadata==3.1.0 \ | |
71 | --hash=sha256:590690d61efdd716ff82c39ca9a9d4209252adfe288a4b5721181050acbd4175 \ |
|
90 | --hash=sha256:590690d61efdd716ff82c39ca9a9d4209252adfe288a4b5721181050acbd4175 \ | |
72 | --hash=sha256:d9b8a46a0885337627a6430db287176970fff18ad421becec1d64cfc763c2099 \ |
|
91 | --hash=sha256:d9b8a46a0885337627a6430db287176970fff18ad421becec1d64cfc763c2099 \ | |
73 | # via keyring |
|
92 | # via keyring, pluggy, pytest | |
|
93 | iniconfig==1.1.1 \ | |||
|
94 | --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ | |||
|
95 | --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 \ | |||
|
96 | # via pytest | |||
74 | keyring==21.4.0 \ |
|
97 | keyring==21.4.0 \ | |
75 | --hash=sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d \ |
|
98 | --hash=sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d \ | |
76 | --hash=sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466 \ |
|
99 | --hash=sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466 \ | |
77 | # via -r contrib/packaging/requirements-windows.txt.in |
|
100 | # via -r contrib/packaging/requirements-windows.txt.in | |
|
101 | multidict==5.1.0 \ | |||
|
102 | --hash=sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a \ | |||
|
103 | --hash=sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93 \ | |||
|
104 | --hash=sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632 \ | |||
|
105 | --hash=sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656 \ | |||
|
106 | --hash=sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79 \ | |||
|
107 | --hash=sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7 \ | |||
|
108 | --hash=sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d \ | |||
|
109 | --hash=sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5 \ | |||
|
110 | --hash=sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224 \ | |||
|
111 | --hash=sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26 \ | |||
|
112 | --hash=sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea \ | |||
|
113 | --hash=sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348 \ | |||
|
114 | --hash=sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6 \ | |||
|
115 | --hash=sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76 \ | |||
|
116 | --hash=sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1 \ | |||
|
117 | --hash=sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f \ | |||
|
118 | --hash=sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952 \ | |||
|
119 | --hash=sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a \ | |||
|
120 | --hash=sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37 \ | |||
|
121 | --hash=sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9 \ | |||
|
122 | --hash=sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359 \ | |||
|
123 | --hash=sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8 \ | |||
|
124 | --hash=sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da \ | |||
|
125 | --hash=sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3 \ | |||
|
126 | --hash=sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d \ | |||
|
127 | --hash=sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf \ | |||
|
128 | --hash=sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841 \ | |||
|
129 | --hash=sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d \ | |||
|
130 | --hash=sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93 \ | |||
|
131 | --hash=sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f \ | |||
|
132 | --hash=sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647 \ | |||
|
133 | --hash=sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635 \ | |||
|
134 | --hash=sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456 \ | |||
|
135 | --hash=sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda \ | |||
|
136 | --hash=sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5 \ | |||
|
137 | --hash=sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281 \ | |||
|
138 | --hash=sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80 \ | |||
|
139 | # via yarl | |||
|
140 | packaging==21.0 \ | |||
|
141 | --hash=sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7 \ | |||
|
142 | --hash=sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14 \ | |||
|
143 | # via pytest | |||
|
144 | pluggy==0.13.1 \ | |||
|
145 | --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 \ | |||
|
146 | --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d \ | |||
|
147 | # via pytest | |||
|
148 | py==1.10.0 \ | |||
|
149 | --hash=sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3 \ | |||
|
150 | --hash=sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a \ | |||
|
151 | # via pytest | |||
78 | pycparser==2.20 \ |
|
152 | pycparser==2.20 \ | |
79 | --hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \ |
|
153 | --hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \ | |
80 | --hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705 \ |
|
154 | --hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705 \ | |
@@ -102,14 +176,73 b' pygments==2.7.1 \\' | |||||
102 | --hash=sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998 \ |
|
176 | --hash=sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998 \ | |
103 | --hash=sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7 \ |
|
177 | --hash=sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7 \ | |
104 | # via -r contrib/packaging/requirements-windows.txt.in |
|
178 | # via -r contrib/packaging/requirements-windows.txt.in | |
|
179 | pyparsing==2.4.7 \ | |||
|
180 | --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 \ | |||
|
181 | --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \ | |||
|
182 | # via packaging | |||
|
183 | pytest-vcr==1.0.2 \ | |||
|
184 | --hash=sha256:23ee51b75abbcc43d926272773aae4f39f93aceb75ed56852d0bf618f92e1896 \ | |||
|
185 | # via -r contrib/packaging/requirements-windows.txt.in | |||
|
186 | pytest==6.2.4 \ | |||
|
187 | --hash=sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b \ | |||
|
188 | --hash=sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890 \ | |||
|
189 | # via pytest-vcr | |||
105 | pywin32-ctypes==0.2.0 \ |
|
190 | pywin32-ctypes==0.2.0 \ | |
106 | --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ |
|
191 | --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ | |
107 | --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 \ |
|
192 | --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 \ | |
108 | # via -r contrib/packaging/requirements-windows.txt.in, keyring |
|
193 | # via -r contrib/packaging/requirements-windows.txt.in, keyring | |
|
194 | pyyaml==5.4.1 \ | |||
|
195 | --hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \ | |||
|
196 | --hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \ | |||
|
197 | --hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \ | |||
|
198 | --hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \ | |||
|
199 | --hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \ | |||
|
200 | --hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \ | |||
|
201 | --hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \ | |||
|
202 | --hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \ | |||
|
203 | --hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \ | |||
|
204 | --hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \ | |||
|
205 | --hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e \ | |||
|
206 | --hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \ | |||
|
207 | --hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \ | |||
|
208 | --hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \ | |||
|
209 | --hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \ | |||
|
210 | --hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \ | |||
|
211 | --hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \ | |||
|
212 | --hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \ | |||
|
213 | --hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \ | |||
|
214 | --hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \ | |||
|
215 | --hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \ | |||
|
216 | --hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \ | |||
|
217 | --hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \ | |||
|
218 | --hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \ | |||
|
219 | --hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \ | |||
|
220 | --hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \ | |||
|
221 | --hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \ | |||
|
222 | --hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \ | |||
|
223 | --hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0 \ | |||
|
224 | # via vcrpy | |||
|
225 | six==1.16.0 \ | |||
|
226 | --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ | |||
|
227 | --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 \ | |||
|
228 | # via vcrpy | |||
|
229 | toml==0.10.2 \ | |||
|
230 | --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ | |||
|
231 | --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f \ | |||
|
232 | # via pytest | |||
|
233 | typing-extensions==3.10.0.0 \ | |||
|
234 | --hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \ | |||
|
235 | --hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342 \ | |||
|
236 | --hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84 \ | |||
|
237 | # via yarl | |||
109 | urllib3==1.25.11 \ |
|
238 | urllib3==1.25.11 \ | |
110 | --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \ |
|
239 | --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \ | |
111 | --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e \ |
|
240 | --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e \ | |
112 | # via dulwich |
|
241 | # via dulwich | |
|
242 | vcrpy==4.1.1 \ | |||
|
243 | --hash=sha256:12c3fcdae7b88ecf11fc0d3e6d77586549d4575a2ceee18e82eee75c1f626162 \ | |||
|
244 | --hash=sha256:57095bf22fc0a2d99ee9674cdafebed0f3ba763018582450706f7d3a74fff599 \ | |||
|
245 | # via pytest-vcr | |||
113 | windows-curses==2.2.0 \ |
|
246 | windows-curses==2.2.0 \ | |
114 | --hash=sha256:1452d771ec6f9b3fef037da2b169196a9a12be4e86a6c27dd579adac70c42028 \ |
|
247 | --hash=sha256:1452d771ec6f9b3fef037da2b169196a9a12be4e86a6c27dd579adac70c42028 \ | |
115 | --hash=sha256:267544e4f60c09af6505e50a69d7f01d7f8a281cf4bd4fc7efc3b32b9a4ef64e \ |
|
248 | --hash=sha256:267544e4f60c09af6505e50a69d7f01d7f8a281cf4bd4fc7efc3b32b9a4ef64e \ | |
@@ -120,6 +253,48 b' windows-curses==2.2.0 \\' | |||||
120 | --hash=sha256:c5cd032bc7d0f03224ab55c925059d98e81795098d59bbd10f7d05c7ea9677ce \ |
|
253 | --hash=sha256:c5cd032bc7d0f03224ab55c925059d98e81795098d59bbd10f7d05c7ea9677ce \ | |
121 | --hash=sha256:fc0be372fe6da3c39d7093154ce029115a927bf287f34b4c615e2b3f8c23dfaa \ |
|
254 | --hash=sha256:fc0be372fe6da3c39d7093154ce029115a927bf287f34b4c615e2b3f8c23dfaa \ | |
122 | # via -r contrib/packaging/requirements-windows.txt.in |
|
255 | # via -r contrib/packaging/requirements-windows.txt.in | |
|
256 | wrapt==1.12.1 \ | |||
|
257 | --hash=sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7 \ | |||
|
258 | # via vcrpy | |||
|
259 | yarl==1.6.3 \ | |||
|
260 | --hash=sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e \ | |||
|
261 | --hash=sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434 \ | |||
|
262 | --hash=sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366 \ | |||
|
263 | --hash=sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3 \ | |||
|
264 | --hash=sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec \ | |||
|
265 | --hash=sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959 \ | |||
|
266 | --hash=sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e \ | |||
|
267 | --hash=sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c \ | |||
|
268 | --hash=sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6 \ | |||
|
269 | --hash=sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a \ | |||
|
270 | --hash=sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6 \ | |||
|
271 | --hash=sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424 \ | |||
|
272 | --hash=sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e \ | |||
|
273 | --hash=sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f \ | |||
|
274 | --hash=sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50 \ | |||
|
275 | --hash=sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2 \ | |||
|
276 | --hash=sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc \ | |||
|
277 | --hash=sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4 \ | |||
|
278 | --hash=sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970 \ | |||
|
279 | --hash=sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10 \ | |||
|
280 | --hash=sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0 \ | |||
|
281 | --hash=sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406 \ | |||
|
282 | --hash=sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896 \ | |||
|
283 | --hash=sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643 \ | |||
|
284 | --hash=sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721 \ | |||
|
285 | --hash=sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478 \ | |||
|
286 | --hash=sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724 \ | |||
|
287 | --hash=sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e \ | |||
|
288 | --hash=sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8 \ | |||
|
289 | --hash=sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96 \ | |||
|
290 | --hash=sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25 \ | |||
|
291 | --hash=sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76 \ | |||
|
292 | --hash=sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2 \ | |||
|
293 | --hash=sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2 \ | |||
|
294 | --hash=sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c \ | |||
|
295 | --hash=sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a \ | |||
|
296 | --hash=sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71 \ | |||
|
297 | # via vcrpy | |||
123 | zipp==3.4.0 \ |
|
298 | zipp==3.4.0 \ | |
124 | --hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \ |
|
299 | --hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \ | |
125 | --hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb \ |
|
300 | --hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb \ |
@@ -2,9 +2,17 b' docutils' | |||||
2 | # Pinned to an old version because 0.20 drops Python 3 compatibility. |
|
2 | # Pinned to an old version because 0.20 drops Python 3 compatibility. | |
3 | dulwich < 0.20 ; python_version <= '2.7' |
|
3 | dulwich < 0.20 ; python_version <= '2.7' | |
4 | dulwich ; python_version >= '3' |
|
4 | dulwich ; python_version >= '3' | |
|
5 | ||||
|
6 | # Needed by the release note tooling | |||
|
7 | fuzzywuzzy | |||
|
8 | ||||
5 | keyring |
|
9 | keyring | |
6 | pygit2 ; python_version >= '3' |
|
10 | pygit2 ; python_version >= '3' | |
7 | pygments |
|
11 | pygments | |
|
12 | ||||
|
13 | # Needed by the phabricator tests | |||
|
14 | pytest-vcr | |||
|
15 | ||||
8 | # Need to list explicitly so dependency gets pulled in when |
|
16 | # Need to list explicitly so dependency gets pulled in when | |
9 | # not running on Windows. |
|
17 | # not running on Windows. | |
10 | pywin32-ctypes |
|
18 | pywin32-ctypes |
@@ -132,6 +132,7 b' import subprocess' | |||||
132 |
|
132 | |||
133 | from mercurial.i18n import _ |
|
133 | from mercurial.i18n import _ | |
134 | from mercurial.node import ( |
|
134 | from mercurial.node import ( | |
|
135 | nullid, | |||
135 | nullrev, |
|
136 | nullrev, | |
136 | wdirrev, |
|
137 | wdirrev, | |
137 | ) |
|
138 | ) | |
@@ -751,16 +752,17 b' def writeworkingdir(repo, ctx, filedata,' | |||||
751 |
|
752 | |||
752 | Directly updates the dirstate for the affected files. |
|
753 | Directly updates the dirstate for the affected files. | |
753 | """ |
|
754 | """ | |
|
755 | assert repo.dirstate.p2() == nullid | |||
|
756 | ||||
754 | for path, data in pycompat.iteritems(filedata): |
|
757 | for path, data in pycompat.iteritems(filedata): | |
755 | fctx = ctx[path] |
|
758 | fctx = ctx[path] | |
756 | fctx.write(data, fctx.flags()) |
|
759 | fctx.write(data, fctx.flags()) | |
757 | if repo.dirstate[path] == b'n': |
|
|||
758 | repo.dirstate.set_possibly_dirty(path) |
|
|||
759 |
|
760 | |||
760 |
oldp |
|
761 | oldp1 = repo.dirstate.p1() | |
761 |
newp |
|
762 | newp1 = replacements.get(oldp1, oldp1) | |
762 |
if newp |
|
763 | if newp1 != oldp1: | |
763 | repo.setparents(*newparentnodes) |
|
764 | with repo.dirstate.parentchange(): | |
|
765 | scmutil.movedirstate(repo, repo[newp1]) | |||
764 |
|
766 | |||
765 |
|
767 | |||
766 | def replacerev(ui, repo, ctx, filedata, replacements): |
|
768 | def replacerev(ui, repo, ctx, filedata, replacements): |
@@ -74,6 +74,8 b' class gitdirstate(object):' | |||||
74 | self._root = os.path.dirname(root) |
|
74 | self._root = os.path.dirname(root) | |
75 | self.git = gitrepo |
|
75 | self.git = gitrepo | |
76 | self._plchangecallbacks = {} |
|
76 | self._plchangecallbacks = {} | |
|
77 | # TODO: context.poststatusfixup is bad and uses this attribute | |||
|
78 | self._dirty = False | |||
77 |
|
79 | |||
78 | def p1(self): |
|
80 | def p1(self): | |
79 | try: |
|
81 | try: | |
@@ -255,12 +257,12 b' class gitdirstate(object):' | |||||
255 | if match(p): |
|
257 | if match(p): | |
256 | yield p |
|
258 | yield p | |
257 |
|
259 | |||
258 |
def |
|
260 | def set_clean(self, f, parentfiledata=None): | |
259 | """Mark a file normal and clean.""" |
|
261 | """Mark a file normal and clean.""" | |
260 | # TODO: for now we just let libgit2 re-stat the file. We can |
|
262 | # TODO: for now we just let libgit2 re-stat the file. We can | |
261 | # clearly do better. |
|
263 | # clearly do better. | |
262 |
|
264 | |||
263 |
def |
|
265 | def set_possibly_dirty(self, f): | |
264 | """Mark a file normal, but possibly dirty.""" |
|
266 | """Mark a file normal, but possibly dirty.""" | |
265 | # TODO: for now we just let libgit2 re-stat the file. We can |
|
267 | # TODO: for now we just let libgit2 re-stat the file. We can | |
266 | # clearly do better. |
|
268 | # clearly do better. | |
@@ -296,6 +298,16 b' class gitdirstate(object):' | |||||
296 | # TODO: figure out a strategy for saving index backups. |
|
298 | # TODO: figure out a strategy for saving index backups. | |
297 | pass |
|
299 | pass | |
298 |
|
300 | |||
|
301 | def set_tracked(self, f): | |||
|
302 | uf = pycompat.fsdecode(f) | |||
|
303 | if uf in self.git.index: | |||
|
304 | return False | |||
|
305 | index = self.git.index | |||
|
306 | index.read() | |||
|
307 | index.add(uf) | |||
|
308 | index.write() | |||
|
309 | return True | |||
|
310 | ||||
299 | def add(self, f): |
|
311 | def add(self, f): | |
300 | index = self.git.index |
|
312 | index = self.git.index | |
301 | index.read() |
|
313 | index.read() | |
@@ -310,6 +322,16 b' class gitdirstate(object):' | |||||
310 | index.remove(fs) |
|
322 | index.remove(fs) | |
311 | index.write() |
|
323 | index.write() | |
312 |
|
324 | |||
|
325 | def set_untracked(self, f): | |||
|
326 | index = self.git.index | |||
|
327 | index.read() | |||
|
328 | fs = pycompat.fsdecode(f) | |||
|
329 | if fs in index: | |||
|
330 | index.remove(fs) | |||
|
331 | index.write() | |||
|
332 | return True | |||
|
333 | return False | |||
|
334 | ||||
313 | def remove(self, f): |
|
335 | def remove(self, f): | |
314 | index = self.git.index |
|
336 | index = self.git.index | |
315 | index.read() |
|
337 | index.read() | |
@@ -324,6 +346,10 b' class gitdirstate(object):' | |||||
324 | # TODO |
|
346 | # TODO | |
325 | pass |
|
347 | pass | |
326 |
|
348 | |||
|
349 | def update_file(self, *args, **kwargs): | |||
|
350 | # TODO | |||
|
351 | pass | |||
|
352 | ||||
327 | @contextlib.contextmanager |
|
353 | @contextlib.contextmanager | |
328 | def parentchange(self): |
|
354 | def parentchange(self): | |
329 | # TODO: track this maybe? |
|
355 | # TODO: track this maybe? |
@@ -39,9 +39,22 b' cmdtable = {}' | |||||
39 | command = registrar.command(cmdtable) |
|
39 | command = registrar.command(cmdtable) | |
40 |
|
40 | |||
41 | try: |
|
41 | try: | |
42 | import fuzzywuzzy.fuzz as fuzz |
|
42 | # Silence a warning about python-Levenshtein. | |
|
43 | # | |||
|
44 | # We don't need the the performance that much and it get anoying in tests. | |||
|
45 | import warnings | |||
43 |
|
46 | |||
44 | fuzz.token_set_ratio |
|
47 | with warnings.catch_warnings(): | |
|
48 | warnings.filterwarnings( | |||
|
49 | action="ignore", | |||
|
50 | message=".*python-Levenshtein.*", | |||
|
51 | category=UserWarning, | |||
|
52 | module="fuzzywuzzy.fuzz", | |||
|
53 | ) | |||
|
54 | ||||
|
55 | import fuzzywuzzy.fuzz as fuzz | |||
|
56 | ||||
|
57 | fuzz.token_set_ratio | |||
45 | except ImportError: |
|
58 | except ImportError: | |
46 | fuzz = None |
|
59 | fuzz = None | |
47 |
|
60 |
@@ -186,7 +186,7 b' def onetimesetup(ui):' | |||||
186 | yield (t, u, e, s) |
|
186 | yield (t, u, e, s) | |
187 |
|
187 | |||
188 | for x in repo.store.topfiles(): |
|
188 | for x in repo.store.topfiles(): | |
189 |
if state.noflatmf and x[ |
|
189 | if state.noflatmf and x[1][:11] == b'00manifest.': | |
190 | continue |
|
190 | continue | |
191 | yield x |
|
191 | yield x | |
192 |
|
192 |
@@ -75,12 +75,6 b' from .utils import (' | |||||
75 | urlutil, |
|
75 | urlutil, | |
76 | ) |
|
76 | ) | |
77 |
|
77 | |||
78 | if pycompat.TYPE_CHECKING: |
|
|||
79 | from typing import ( |
|
|||
80 | List, |
|
|||
81 | ) |
|
|||
82 |
|
||||
83 |
|
||||
84 | table = {} |
|
78 | table = {} | |
85 | table.update(debugcommandsmod.command._table) |
|
79 | table.update(debugcommandsmod.command._table) | |
86 |
|
80 | |||
@@ -3341,7 +3335,8 b' def _dograft(ui, repo, *revs, **opts):' | |||||
3341 | ) |
|
3335 | ) | |
3342 | # checking that newnodes exist because old state files won't have it |
|
3336 | # checking that newnodes exist because old state files won't have it | |
3343 | elif statedata.get(b'newnodes') is not None: |
|
3337 | elif statedata.get(b'newnodes') is not None: | |
3344 |
nn = statedata[b'newnodes'] |
|
3338 | nn = statedata[b'newnodes'] | |
|
3339 | assert isinstance(nn, list) # list of bytes | |||
3345 | nn.append(node) |
|
3340 | nn.append(node) | |
3346 |
|
3341 | |||
3347 | # remove state when we complete successfully |
|
3342 | # remove state when we complete successfully |
@@ -1897,6 +1897,11 b' coreconfigitem(' | |||||
1897 | default=True, |
|
1897 | default=True, | |
1898 | alias=[(b'format', b'aggressivemergedeltas')], |
|
1898 | alias=[(b'format', b'aggressivemergedeltas')], | |
1899 | ) |
|
1899 | ) | |
|
1900 | coreconfigitem( | |||
|
1901 | b'storage', | |||
|
1902 | b'revlog.issue6528.fix-incoming', | |||
|
1903 | default=True, | |||
|
1904 | ) | |||
1900 | # experimental as long as rust is experimental (or a C version is implemented) |
|
1905 | # experimental as long as rust is experimental (or a C version is implemented) | |
1901 | coreconfigitem( |
|
1906 | coreconfigitem( | |
1902 | b'storage', |
|
1907 | b'storage', |
@@ -71,6 +71,7 b' from . import (' | |||||
71 | registrar, |
|
71 | registrar, | |
72 | repair, |
|
72 | repair, | |
73 | repoview, |
|
73 | repoview, | |
|
74 | requirements, | |||
74 | revlog, |
|
75 | revlog, | |
75 | revset, |
|
76 | revset, | |
76 | revsetlang, |
|
77 | revsetlang, | |
@@ -105,6 +106,7 b' from .utils import (' | |||||
105 | from .revlogutils import ( |
|
106 | from .revlogutils import ( | |
106 | deltas as deltautil, |
|
107 | deltas as deltautil, | |
107 | nodemap, |
|
108 | nodemap, | |
|
109 | rewrite, | |||
108 | sidedata, |
|
110 | sidedata, | |
109 | ) |
|
111 | ) | |
110 |
|
112 | |||
@@ -1451,6 +1453,80 b' def debugfileset(ui, repo, expr, **opts)' | |||||
1451 | ui.write(b"%s\n" % f) |
|
1453 | ui.write(b"%s\n" % f) | |
1452 |
|
1454 | |||
1453 |
|
1455 | |||
|
1456 | @command( | |||
|
1457 | b"debug-repair-issue6528", | |||
|
1458 | [ | |||
|
1459 | ( | |||
|
1460 | b'', | |||
|
1461 | b'to-report', | |||
|
1462 | b'', | |||
|
1463 | _(b'build a report of affected revisions to this file'), | |||
|
1464 | _(b'FILE'), | |||
|
1465 | ), | |||
|
1466 | ( | |||
|
1467 | b'', | |||
|
1468 | b'from-report', | |||
|
1469 | b'', | |||
|
1470 | _(b'repair revisions listed in this report file'), | |||
|
1471 | _(b'FILE'), | |||
|
1472 | ), | |||
|
1473 | ( | |||
|
1474 | b'', | |||
|
1475 | b'paranoid', | |||
|
1476 | False, | |||
|
1477 | _(b'check that both detection methods do the same thing'), | |||
|
1478 | ), | |||
|
1479 | ] | |||
|
1480 | + cmdutil.dryrunopts, | |||
|
1481 | ) | |||
|
1482 | def debug_repair_issue6528(ui, repo, **opts): | |||
|
1483 | """find affected revisions and repair them. See issue6528 for more details. | |||
|
1484 | ||||
|
1485 | The `--to-report` and `--from-report` flags allow you to cache and reuse the | |||
|
1486 | computation of affected revisions for a given repository across clones. | |||
|
1487 | The report format is line-based (with empty lines ignored): | |||
|
1488 | ||||
|
1489 | ``` | |||
|
1490 | <ascii-hex of the affected revision>,... <unencoded filelog index filename> | |||
|
1491 | ``` | |||
|
1492 | ||||
|
1493 | There can be multiple broken revisions per filelog, they are separated by | |||
|
1494 | a comma with no spaces. The only space is between the revision(s) and the | |||
|
1495 | filename. | |||
|
1496 | ||||
|
1497 | Note that this does *not* mean that this repairs future affected revisions, | |||
|
1498 | that needs a separate fix at the exchange level that hasn't been written yet | |||
|
1499 | (as of 5.9rc0). | |||
|
1500 | ||||
|
1501 | There is a `--paranoid` flag to test that the fast implementation is correct | |||
|
1502 | by checking it against the slow implementation. Since this matter is quite | |||
|
1503 | urgent and testing every edge-case is probably quite costly, we use this | |||
|
1504 | method to test on large repositories as a fuzzing method of sorts. | |||
|
1505 | """ | |||
|
1506 | cmdutil.check_incompatible_arguments( | |||
|
1507 | opts, 'to_report', ['from_report', 'dry_run'] | |||
|
1508 | ) | |||
|
1509 | dry_run = opts.get('dry_run') | |||
|
1510 | to_report = opts.get('to_report') | |||
|
1511 | from_report = opts.get('from_report') | |||
|
1512 | paranoid = opts.get('paranoid') | |||
|
1513 | # TODO maybe add filelog pattern and revision pattern parameters to help | |||
|
1514 | # narrow down the search for users that know what they're looking for? | |||
|
1515 | ||||
|
1516 | if requirements.REVLOGV1_REQUIREMENT not in repo.requirements: | |||
|
1517 | msg = b"can only repair revlogv1 repositories, v2 is not affected" | |||
|
1518 | raise error.Abort(_(msg)) | |||
|
1519 | ||||
|
1520 | rewrite.repair_issue6528( | |||
|
1521 | ui, | |||
|
1522 | repo, | |||
|
1523 | dry_run=dry_run, | |||
|
1524 | to_report=to_report, | |||
|
1525 | from_report=from_report, | |||
|
1526 | paranoid=paranoid, | |||
|
1527 | ) | |||
|
1528 | ||||
|
1529 | ||||
1454 | @command(b'debugformat', [] + cmdutil.formatteropts) |
|
1530 | @command(b'debugformat', [] + cmdutil.formatteropts) | |
1455 | def debugformat(ui, repo, **opts): |
|
1531 | def debugformat(ui, repo, **opts): | |
1456 | """display format information about the current repository |
|
1532 | """display format information about the current repository |
@@ -599,7 +599,7 b' class dirstate(object):' | |||||
599 |
|
599 | |||
600 | This function must be called within a `dirstate.parentchange` context. |
|
600 | This function must be called within a `dirstate.parentchange` context. | |
601 |
|
601 | |||
602 | note: the API is at an early stage and we might need to ajust it |
|
602 | note: the API is at an early stage and we might need to adjust it | |
603 | depending of what information ends up being relevant and useful to |
|
603 | depending of what information ends up being relevant and useful to | |
604 | other processing. |
|
604 | other processing. | |
605 | """ |
|
605 | """ | |
@@ -828,7 +828,7 b' class dirstate(object):' | |||||
828 | ) |
|
828 | ) | |
829 | else: |
|
829 | else: | |
830 | util.nouideprecwarn( |
|
830 | util.nouideprecwarn( | |
831 |
b"do not use ` |
|
831 | b"do not use `add` outside of update/merge context." | |
832 | b" Use `set_tracked`", |
|
832 | b" Use `set_tracked`", | |
833 | b'6.0', |
|
833 | b'6.0', | |
834 | stacklevel=2, |
|
834 | stacklevel=2, |
@@ -20,6 +20,7 b' from .interfaces import (' | |||||
20 | from .utils import storageutil |
|
20 | from .utils import storageutil | |
21 | from .revlogutils import ( |
|
21 | from .revlogutils import ( | |
22 | constants as revlog_constants, |
|
22 | constants as revlog_constants, | |
|
23 | rewrite, | |||
23 | ) |
|
24 | ) | |
24 |
|
25 | |||
25 |
|
26 | |||
@@ -37,6 +38,8 b' class filelog(object):' | |||||
37 | # Used by LFS. |
|
38 | # Used by LFS. | |
38 | self._revlog.filename = path |
|
39 | self._revlog.filename = path | |
39 | self.nullid = self._revlog.nullid |
|
40 | self.nullid = self._revlog.nullid | |
|
41 | opts = opener.options | |||
|
42 | self._fix_issue6528 = opts.get(b'issue6528.fix-incoming', True) | |||
40 |
|
43 | |||
41 | def __len__(self): |
|
44 | def __len__(self): | |
42 | return len(self._revlog) |
|
45 | return len(self._revlog) | |
@@ -157,13 +160,18 b' class filelog(object):' | |||||
157 | ) |
|
160 | ) | |
158 | ) |
|
161 | ) | |
159 |
|
162 | |||
160 | return self._revlog.addgroup( |
|
163 | with self._revlog._writing(transaction): | |
161 | deltas, |
|
164 | ||
162 | linkmapper, |
|
165 | if self._fix_issue6528: | |
163 | transaction, |
|
166 | deltas = rewrite.filter_delta_issue6528(self._revlog, deltas) | |
164 | addrevisioncb=addrevisioncb, |
|
167 | ||
165 | duplicaterevisioncb=duplicaterevisioncb, |
|
168 | return self._revlog.addgroup( | |
166 | ) |
|
169 | deltas, | |
|
170 | linkmapper, | |||
|
171 | transaction, | |||
|
172 | addrevisioncb=addrevisioncb, | |||
|
173 | duplicaterevisioncb=duplicaterevisioncb, | |||
|
174 | ) | |||
167 |
|
175 | |||
168 | def getstrippoint(self, minlink): |
|
176 | def getstrippoint(self, minlink): | |
169 | return self._revlog.getstrippoint(minlink) |
|
177 | return self._revlog.getstrippoint(minlink) |
@@ -906,13 +906,21 b' https://www.mercurial-scm.org/wiki/Missi' | |||||
906 | with the Rust part might actually suffer some slowdown. For this reason, |
|
906 | with the Rust part might actually suffer some slowdown. For this reason, | |
907 | Such version will by default refuse to access such repositories. That |
|
907 | Such version will by default refuse to access such repositories. That | |
908 | behavior can be controlled by configuration. Check |
|
908 | behavior can be controlled by configuration. Check | |
909 | :hg:`help config.storage.revlog.persistent-nodemap.slowpath` for details. |
|
909 | :hg:`help config.storage.revlog.persistent-nodemap.slow-path` for details. | |
910 |
|
910 | |||
911 | Repository with this on-disk format require Mercurial version 5.4 or above. |
|
911 | Repository with this on-disk format require Mercurial version 5.4 or above. | |
912 |
|
912 | |||
913 | By default this format variant is disabled if fast implementation is not |
|
913 | By default this format variant is disabled if fast implementation is not | |
914 | available and enabled by default if the fast implementation is available. |
|
914 | available and enabled by default if the fast implementation is available. | |
915 |
|
915 | |||
|
916 | To accomodate install of Mercurial without the fast implementation you can | |||
|
917 | downgrade your repository. To do so run the following command: | |||
|
918 | ||||
|
919 | $ hg debugupgraderepo \ | |||
|
920 | --run \ | |||
|
921 | --config format.use-persistent-nodemap=False \ | |||
|
922 | --config storage.revlog.persistent-nodemap.slow-path=allow | |||
|
923 | ||||
916 | ``use-share-safe`` |
|
924 | ``use-share-safe`` | |
917 | Enforce "safe" behaviors for all "shares" that access this repository. |
|
925 | Enforce "safe" behaviors for all "shares" that access this repository. | |
918 |
|
926 | |||
@@ -1838,7 +1846,7 b' statistical text report generated from t' | |||||
1838 | ``json`` |
|
1846 | ``json`` | |
1839 | Render profiling data as JSON. |
|
1847 | Render profiling data as JSON. | |
1840 |
|
1848 | |||
1841 |
``freq |
|
1849 | ``freq`` | |
1842 | Sampling frequency. Specific to the ``stat`` sampling profiler. |
|
1850 | Sampling frequency. Specific to the ``stat`` sampling profiler. | |
1843 | (default: 1000) |
|
1851 | (default: 1000) | |
1844 |
|
1852 | |||
@@ -2035,6 +2043,21 b' Alias definitions for revsets. See :hg:`' | |||||
2035 | Control the strategy Mercurial uses internally to store history. Options in this |
|
2043 | Control the strategy Mercurial uses internally to store history. Options in this | |
2036 | category impact performance and repository size. |
|
2044 | category impact performance and repository size. | |
2037 |
|
2045 | |||
|
2046 | ``revlog.issue6528.fix-incoming`` | |||
|
2047 | Version 5.8 of Mercurial had a bug leading to altering the parent of file | |||
|
2048 | revision with copy information (or any other metadata) on exchange. This | |||
|
2049 | leads to the copy metadata to be overlooked by various internal logic. The | |||
|
2050 | issue was fixed in Mercurial 5.8.1. | |||
|
2051 | (See https://bz.mercurial-scm.org/show_bug.cgi?id=6528 for details) | |||
|
2052 | ||||
|
2053 | As a result Mercurial is now checking and fixing incoming file revisions to | |||
|
2054 | make sure there parents are in the right order. This behavior can be | |||
|
2055 | disabled by setting this option to `no`. This apply to revisions added | |||
|
2056 | through push, pull, clone and unbundle. | |||
|
2057 | ||||
|
2058 | To fix affected revisions that already exist within the repository, one can | |||
|
2059 | use :hg:`debug-repair-issue-6528`. | |||
|
2060 | ||||
2038 | ``revlog.optimize-delta-parent-choice`` |
|
2061 | ``revlog.optimize-delta-parent-choice`` | |
2039 | When storing a merge revision, both parents will be equally considered as |
|
2062 | When storing a merge revision, both parents will be equally considered as | |
2040 | a possible delta base. This results in better delta selection and improved |
|
2063 | a possible delta base. This results in better delta selection and improved |
@@ -1043,6 +1043,9 b' def resolverevlogstorevfsoptions(ui, req' | |||||
1043 | ) |
|
1043 | ) | |
1044 | options[b'deltabothparents'] = deltabothparents |
|
1044 | options[b'deltabothparents'] = deltabothparents | |
1045 |
|
1045 | |||
|
1046 | issue6528 = ui.configbool(b'storage', b'revlog.issue6528.fix-incoming') | |||
|
1047 | options[b'issue6528.fix-incoming'] = issue6528 | |||
|
1048 | ||||
1046 | lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta') |
|
1049 | lazydelta = ui.configbool(b'storage', b'revlog.reuse-external-delta') | |
1047 | lazydeltabase = False |
|
1050 | lazydeltabase = False | |
1048 | if lazydelta: |
|
1051 | if lazydelta: |
@@ -40,6 +40,8 b' if not ispy3:' | |||||
40 | def future_set_exception_info(f, exc_info): |
|
40 | def future_set_exception_info(f, exc_info): | |
41 | f.set_exception_info(*exc_info) |
|
41 | f.set_exception_info(*exc_info) | |
42 |
|
42 | |||
|
43 | # this is close enough for our usage | |||
|
44 | FileNotFoundError = OSError | |||
43 |
|
45 | |||
44 | else: |
|
46 | else: | |
45 | import concurrent.futures as futures |
|
47 | import concurrent.futures as futures | |
@@ -53,6 +55,8 b' else:' | |||||
53 | def future_set_exception_info(f, exc_info): |
|
55 | def future_set_exception_info(f, exc_info): | |
54 | f.set_exception(exc_info[0]) |
|
56 | f.set_exception(exc_info[0]) | |
55 |
|
57 | |||
|
58 | FileNotFoundError = __builtins__['FileNotFoundError'] | |||
|
59 | ||||
56 |
|
60 | |||
57 | def identity(a): |
|
61 | def identity(a): | |
58 | return a |
|
62 | return a |
@@ -897,10 +897,8 b' class revlog(object):' | |||||
897 | if rev == wdirrev: |
|
897 | if rev == wdirrev: | |
898 | raise error.WdirUnsupported |
|
898 | raise error.WdirUnsupported | |
899 | raise |
|
899 | raise | |
900 | if entry[5] == nullrev: |
|
900 | ||
901 |
|
|
901 | return entry[5], entry[6] | |
902 | else: |
|
|||
903 | return entry[5], entry[6] |
|
|||
904 |
|
902 | |||
905 | # fast parentrevs(rev) where rev isn't filtered |
|
903 | # fast parentrevs(rev) where rev isn't filtered | |
906 | _uncheckedparentrevs = parentrevs |
|
904 | _uncheckedparentrevs = parentrevs | |
@@ -921,11 +919,7 b' class revlog(object):' | |||||
921 | def parents(self, node): |
|
919 | def parents(self, node): | |
922 | i = self.index |
|
920 | i = self.index | |
923 | d = i[self.rev(node)] |
|
921 | d = i[self.rev(node)] | |
924 | # inline node() to avoid function call overhead |
|
922 | return i[d[5]][7], i[d[6]][7] # map revisions to nodes inline | |
925 | if d[5] == self.nullid: |
|
|||
926 | return i[d[6]][7], i[d[5]][7] |
|
|||
927 | else: |
|
|||
928 | return i[d[5]][7], i[d[6]][7] |
|
|||
929 |
|
923 | |||
930 | def chainlen(self, rev): |
|
924 | def chainlen(self, rev): | |
931 | return self._chaininfo(rev)[0] |
|
925 | return self._chaininfo(rev)[0] | |
@@ -2122,6 +2116,8 b' class revlog(object):' | |||||
2122 | dfh = self._datafp(b"w+") |
|
2116 | dfh = self._datafp(b"w+") | |
2123 | transaction.add(self._datafile, dsize) |
|
2117 | transaction.add(self._datafile, dsize) | |
2124 | if self._sidedatafile is not None: |
|
2118 | if self._sidedatafile is not None: | |
|
2119 | # revlog-v2 does not inline, help Pytype | |||
|
2120 | assert dfh is not None | |||
2125 | try: |
|
2121 | try: | |
2126 | sdfh = self.opener(self._sidedatafile, mode=b"r+") |
|
2122 | sdfh = self.opener(self._sidedatafile, mode=b"r+") | |
2127 | dfh.seek(self._docket.sidedata_end, os.SEEK_SET) |
|
2123 | dfh.seek(self._docket.sidedata_end, os.SEEK_SET) | |
@@ -2584,6 +2580,8 b' class revlog(object):' | |||||
2584 | assert not sidedata |
|
2580 | assert not sidedata | |
2585 | self._enforceinlinesize(transaction) |
|
2581 | self._enforceinlinesize(transaction) | |
2586 | if self._docket is not None: |
|
2582 | if self._docket is not None: | |
|
2583 | # revlog-v2 always has 3 writing handles, help Pytype | |||
|
2584 | assert self._writinghandles[2] is not None | |||
2587 | self._docket.index_end = self._writinghandles[0].tell() |
|
2585 | self._docket.index_end = self._writinghandles[0].tell() | |
2588 | self._docket.data_end = self._writinghandles[1].tell() |
|
2586 | self._docket.data_end = self._writinghandles[1].tell() | |
2589 | self._docket.sidedata_end = self._writinghandles[2].tell() |
|
2587 | self._docket.sidedata_end = self._writinghandles[2].tell() |
@@ -7,8 +7,10 b'' | |||||
7 | # This software may be used and distributed according to the terms of the |
|
7 | # This software may be used and distributed according to the terms of the | |
8 | # GNU General Public License version 2 or any later version. |
|
8 | # GNU General Public License version 2 or any later version. | |
9 |
|
9 | |||
|
10 | import binascii | |||
10 | import contextlib |
|
11 | import contextlib | |
11 | import os |
|
12 | import os | |
|
13 | import struct | |||
12 |
|
14 | |||
13 | from ..node import ( |
|
15 | from ..node import ( | |
14 | nullrev, |
|
16 | nullrev, | |
@@ -27,6 +29,7 b' from .constants import (' | |||||
27 | ENTRY_SIDEDATA_COMPRESSED_LENGTH, |
|
29 | ENTRY_SIDEDATA_COMPRESSED_LENGTH, | |
28 | ENTRY_SIDEDATA_COMPRESSION_MODE, |
|
30 | ENTRY_SIDEDATA_COMPRESSION_MODE, | |
29 | ENTRY_SIDEDATA_OFFSET, |
|
31 | ENTRY_SIDEDATA_OFFSET, | |
|
32 | REVIDX_ISCENSORED, | |||
30 | REVLOGV0, |
|
33 | REVLOGV0, | |
31 | REVLOGV1, |
|
34 | REVLOGV1, | |
32 | ) |
|
35 | ) | |
@@ -34,6 +37,7 b' from ..i18n import _' | |||||
34 |
|
37 | |||
35 | from .. import ( |
|
38 | from .. import ( | |
36 | error, |
|
39 | error, | |
|
40 | mdiff, | |||
37 | pycompat, |
|
41 | pycompat, | |
38 | revlogutils, |
|
42 | revlogutils, | |
39 | util, |
|
43 | util, | |
@@ -472,3 +476,411 b' def _rewrite_censor(' | |||||
472 | new_index_file.write(entry_bin) |
|
476 | new_index_file.write(entry_bin) | |
473 | revlog._docket.index_end = new_index_file.tell() |
|
477 | revlog._docket.index_end = new_index_file.tell() | |
474 | revlog._docket.data_end = new_data_file.tell() |
|
478 | revlog._docket.data_end = new_data_file.tell() | |
|
479 | ||||
|
480 | ||||
|
481 | def _get_filename_from_filelog_index(path): | |||
|
482 | # Drop the extension and the `data/` prefix | |||
|
483 | path_part = path.rsplit(b'.', 1)[0].split(b'/', 1) | |||
|
484 | if len(path_part) < 2: | |||
|
485 | msg = _(b"cannot recognize filelog from filename: '%s'") | |||
|
486 | msg %= path | |||
|
487 | raise error.Abort(msg) | |||
|
488 | ||||
|
489 | return path_part[1] | |||
|
490 | ||||
|
491 | ||||
|
492 | def _filelog_from_filename(repo, path): | |||
|
493 | """Returns the filelog for the given `path`. Stolen from `engine.py`""" | |||
|
494 | ||||
|
495 | from .. import filelog # avoid cycle | |||
|
496 | ||||
|
497 | fl = filelog.filelog(repo.svfs, path) | |||
|
498 | return fl | |||
|
499 | ||||
|
500 | ||||
|
501 | def _write_swapped_parents(repo, rl, rev, offset, fp): | |||
|
502 | """Swaps p1 and p2 and overwrites the revlog entry for `rev` in `fp`""" | |||
|
503 | from ..pure import parsers # avoid cycle | |||
|
504 | ||||
|
505 | if repo._currentlock(repo._lockref) is None: | |||
|
506 | # Let's be paranoid about it | |||
|
507 | msg = "repo needs to be locked to rewrite parents" | |||
|
508 | raise error.ProgrammingError(msg) | |||
|
509 | ||||
|
510 | index_format = parsers.IndexObject.index_format | |||
|
511 | entry = rl.index[rev] | |||
|
512 | new_entry = list(entry) | |||
|
513 | new_entry[5], new_entry[6] = entry[6], entry[5] | |||
|
514 | packed = index_format.pack(*new_entry[:8]) | |||
|
515 | fp.seek(offset) | |||
|
516 | fp.write(packed) | |||
|
517 | ||||
|
518 | ||||
|
519 | def _reorder_filelog_parents(repo, fl, to_fix): | |||
|
520 | """ | |||
|
521 | Swaps p1 and p2 for all `to_fix` revisions of filelog `fl` and writes the | |||
|
522 | new version to disk, overwriting the old one with a rename. | |||
|
523 | """ | |||
|
524 | from ..pure import parsers # avoid cycle | |||
|
525 | ||||
|
526 | ui = repo.ui | |||
|
527 | assert len(to_fix) > 0 | |||
|
528 | rl = fl._revlog | |||
|
529 | if rl._format_version != constants.REVLOGV1: | |||
|
530 | msg = "expected version 1 revlog, got version '%d'" % rl._format_version | |||
|
531 | raise error.ProgrammingError(msg) | |||
|
532 | ||||
|
533 | index_file = rl._indexfile | |||
|
534 | new_file_path = index_file + b'.tmp-parents-fix' | |||
|
535 | repaired_msg = _(b"repaired revision %d of 'filelog %s'\n") | |||
|
536 | ||||
|
537 | with ui.uninterruptible(): | |||
|
538 | try: | |||
|
539 | util.copyfile( | |||
|
540 | rl.opener.join(index_file), | |||
|
541 | rl.opener.join(new_file_path), | |||
|
542 | checkambig=rl._checkambig, | |||
|
543 | ) | |||
|
544 | ||||
|
545 | with rl.opener(new_file_path, mode=b"r+") as fp: | |||
|
546 | if rl._inline: | |||
|
547 | index = parsers.InlinedIndexObject(fp.read()) | |||
|
548 | for rev in fl.revs(): | |||
|
549 | if rev in to_fix: | |||
|
550 | offset = index._calculate_index(rev) | |||
|
551 | _write_swapped_parents(repo, rl, rev, offset, fp) | |||
|
552 | ui.write(repaired_msg % (rev, index_file)) | |||
|
553 | else: | |||
|
554 | index_format = parsers.IndexObject.index_format | |||
|
555 | for rev in to_fix: | |||
|
556 | offset = rev * index_format.size | |||
|
557 | _write_swapped_parents(repo, rl, rev, offset, fp) | |||
|
558 | ui.write(repaired_msg % (rev, index_file)) | |||
|
559 | ||||
|
560 | rl.opener.rename(new_file_path, index_file) | |||
|
561 | rl.clearcaches() | |||
|
562 | rl._loadindex() | |||
|
563 | finally: | |||
|
564 | util.tryunlink(new_file_path) | |||
|
565 | ||||
|
566 | ||||
|
567 | def _is_revision_affected(fl, filerev, metadata_cache=None): | |||
|
568 | full_text = lambda: fl._revlog.rawdata(filerev) | |||
|
569 | parent_revs = lambda: fl._revlog.parentrevs(filerev) | |||
|
570 | return _is_revision_affected_inner( | |||
|
571 | full_text, parent_revs, filerev, metadata_cache | |||
|
572 | ) | |||
|
573 | ||||
|
574 | ||||
|
575 | def _is_revision_affected_inner( | |||
|
576 | full_text, | |||
|
577 | parents_revs, | |||
|
578 | filerev, | |||
|
579 | metadata_cache=None, | |||
|
580 | ): | |||
|
581 | """Mercurial currently (5.9rc0) uses `p1 == nullrev and p2 != nullrev` as a | |||
|
582 | special meaning compared to the reverse in the context of filelog-based | |||
|
583 | copytracing. issue6528 exists because new code assumed that parent ordering | |||
|
584 | didn't matter, so this detects if the revision contains metadata (since | |||
|
585 | it's only used for filelog-based copytracing) and its parents are in the | |||
|
586 | "wrong" order.""" | |||
|
587 | try: | |||
|
588 | raw_text = full_text() | |||
|
589 | except error.CensoredNodeError: | |||
|
590 | # We don't care about censored nodes as they never carry metadata | |||
|
591 | return False | |||
|
592 | has_meta = raw_text.startswith(b'\x01\n') | |||
|
593 | if metadata_cache is not None: | |||
|
594 | metadata_cache[filerev] = has_meta | |||
|
595 | if has_meta: | |||
|
596 | (p1, p2) = parents_revs() | |||
|
597 | if p1 != nullrev and p2 == nullrev: | |||
|
598 | return True | |||
|
599 | return False | |||
|
600 | ||||
|
601 | ||||
|
602 | def _is_revision_affected_fast(repo, fl, filerev, metadata_cache): | |||
|
603 | rl = fl._revlog | |||
|
604 | is_censored = lambda: rl.iscensored(filerev) | |||
|
605 | delta_base = lambda: rl.deltaparent(filerev) | |||
|
606 | delta = lambda: rl._chunk(filerev) | |||
|
607 | full_text = lambda: rl.rawdata(filerev) | |||
|
608 | parent_revs = lambda: rl.parentrevs(filerev) | |||
|
609 | return _is_revision_affected_fast_inner( | |||
|
610 | is_censored, | |||
|
611 | delta_base, | |||
|
612 | delta, | |||
|
613 | full_text, | |||
|
614 | parent_revs, | |||
|
615 | filerev, | |||
|
616 | metadata_cache, | |||
|
617 | ) | |||
|
618 | ||||
|
619 | ||||
|
620 | def _is_revision_affected_fast_inner( | |||
|
621 | is_censored, | |||
|
622 | delta_base, | |||
|
623 | delta, | |||
|
624 | full_text, | |||
|
625 | parent_revs, | |||
|
626 | filerev, | |||
|
627 | metadata_cache, | |||
|
628 | ): | |||
|
629 | """Optimization fast-path for `_is_revision_affected`. | |||
|
630 | ||||
|
631 | `metadata_cache` is a dict of `{rev: has_metadata}` which allows any | |||
|
632 | revision to check if its base has metadata, saving computation of the full | |||
|
633 | text, instead looking at the current delta. | |||
|
634 | ||||
|
635 | This optimization only works if the revisions are looked at in order.""" | |||
|
636 | ||||
|
637 | if is_censored(): | |||
|
638 | # Censored revisions don't contain metadata, so they cannot be affected | |||
|
639 | metadata_cache[filerev] = False | |||
|
640 | return False | |||
|
641 | ||||
|
642 | p1, p2 = parent_revs() | |||
|
643 | if p1 == nullrev or p2 != nullrev: | |||
|
644 | return False | |||
|
645 | ||||
|
646 | delta_parent = delta_base() | |||
|
647 | parent_has_metadata = metadata_cache.get(delta_parent) | |||
|
648 | if parent_has_metadata is None: | |||
|
649 | return _is_revision_affected_inner( | |||
|
650 | full_text, | |||
|
651 | parent_revs, | |||
|
652 | filerev, | |||
|
653 | metadata_cache, | |||
|
654 | ) | |||
|
655 | ||||
|
656 | chunk = delta() | |||
|
657 | if not len(chunk): | |||
|
658 | # No diff for this revision | |||
|
659 | return parent_has_metadata | |||
|
660 | ||||
|
661 | header_length = 12 | |||
|
662 | if len(chunk) < header_length: | |||
|
663 | raise error.Abort(_(b"patch cannot be decoded")) | |||
|
664 | ||||
|
665 | start, _end, _length = struct.unpack(b">lll", chunk[:header_length]) | |||
|
666 | ||||
|
667 | if start < 2: # len(b'\x01\n') == 2 | |||
|
668 | # This delta does *something* to the metadata marker (if any). | |||
|
669 | # Check it the slow way | |||
|
670 | is_affected = _is_revision_affected_inner( | |||
|
671 | full_text, | |||
|
672 | parent_revs, | |||
|
673 | filerev, | |||
|
674 | metadata_cache, | |||
|
675 | ) | |||
|
676 | return is_affected | |||
|
677 | ||||
|
678 | # The diff did not remove or add the metadata header, it's then in the same | |||
|
679 | # situation as its parent | |||
|
680 | metadata_cache[filerev] = parent_has_metadata | |||
|
681 | return parent_has_metadata | |||
|
682 | ||||
|
683 | ||||
|
684 | def _from_report(ui, repo, context, from_report, dry_run): | |||
|
685 | """ | |||
|
686 | Fix the revisions given in the `from_report` file, but still checks if the | |||
|
687 | revisions are indeed affected to prevent an unfortunate cyclic situation | |||
|
688 | where we'd swap well-ordered parents again. | |||
|
689 | ||||
|
690 | See the doc for `debug_fix_issue6528` for the format documentation. | |||
|
691 | """ | |||
|
692 | ui.write(_(b"loading report file '%s'\n") % from_report) | |||
|
693 | ||||
|
694 | with context(), open(from_report, mode='rb') as f: | |||
|
695 | for line in f.read().split(b'\n'): | |||
|
696 | if not line: | |||
|
697 | continue | |||
|
698 | filenodes, filename = line.split(b' ', 1) | |||
|
699 | fl = _filelog_from_filename(repo, filename) | |||
|
700 | to_fix = set( | |||
|
701 | fl.rev(binascii.unhexlify(n)) for n in filenodes.split(b',') | |||
|
702 | ) | |||
|
703 | excluded = set() | |||
|
704 | ||||
|
705 | for filerev in to_fix: | |||
|
706 | if _is_revision_affected(fl, filerev): | |||
|
707 | msg = b"found affected revision %d for filelog '%s'\n" | |||
|
708 | ui.warn(msg % (filerev, filename)) | |||
|
709 | else: | |||
|
710 | msg = _(b"revision %s of file '%s' is not affected\n") | |||
|
711 | msg %= (binascii.hexlify(fl.node(filerev)), filename) | |||
|
712 | ui.warn(msg) | |||
|
713 | excluded.add(filerev) | |||
|
714 | ||||
|
715 | to_fix = to_fix - excluded | |||
|
716 | if not to_fix: | |||
|
717 | msg = _(b"no affected revisions were found for '%s'\n") | |||
|
718 | ui.write(msg % filename) | |||
|
719 | continue | |||
|
720 | if not dry_run: | |||
|
721 | _reorder_filelog_parents(repo, fl, sorted(to_fix)) | |||
|
722 | ||||
|
723 | ||||
|
724 | def filter_delta_issue6528(revlog, deltas_iter): | |||
|
725 | """filter incomind deltas to repaire issue 6528 on the fly""" | |||
|
726 | metadata_cache = {} | |||
|
727 | ||||
|
728 | deltacomputer = deltas.deltacomputer(revlog) | |||
|
729 | ||||
|
730 | for rev, d in enumerate(deltas_iter, len(revlog)): | |||
|
731 | ( | |||
|
732 | node, | |||
|
733 | p1_node, | |||
|
734 | p2_node, | |||
|
735 | linknode, | |||
|
736 | deltabase, | |||
|
737 | delta, | |||
|
738 | flags, | |||
|
739 | sidedata, | |||
|
740 | ) = d | |||
|
741 | ||||
|
742 | if not revlog.index.has_node(deltabase): | |||
|
743 | raise error.LookupError( | |||
|
744 | deltabase, revlog.radix, _(b'unknown parent') | |||
|
745 | ) | |||
|
746 | base_rev = revlog.rev(deltabase) | |||
|
747 | if not revlog.index.has_node(p1_node): | |||
|
748 | raise error.LookupError(p1_node, revlog.radix, _(b'unknown parent')) | |||
|
749 | p1_rev = revlog.rev(p1_node) | |||
|
750 | if not revlog.index.has_node(p2_node): | |||
|
751 | raise error.LookupError(p2_node, revlog.radix, _(b'unknown parent')) | |||
|
752 | p2_rev = revlog.rev(p2_node) | |||
|
753 | ||||
|
754 | is_censored = lambda: bool(flags & REVIDX_ISCENSORED) | |||
|
755 | delta_base = lambda: revlog.rev(delta_base) | |||
|
756 | delta_base = lambda: base_rev | |||
|
757 | parent_revs = lambda: (p1_rev, p2_rev) | |||
|
758 | ||||
|
759 | def full_text(): | |||
|
760 | # note: being able to reuse the full text computation in the | |||
|
761 | # underlying addrevision would be useful however this is a bit too | |||
|
762 | # intrusive the for the "quick" issue6528 we are writing before the | |||
|
763 | # 5.8 release | |||
|
764 | textlen = mdiff.patchedsize(revlog.size(base_rev), delta) | |||
|
765 | ||||
|
766 | revinfo = revlogutils.revisioninfo( | |||
|
767 | node, | |||
|
768 | p1_node, | |||
|
769 | p2_node, | |||
|
770 | [None], | |||
|
771 | textlen, | |||
|
772 | (base_rev, delta), | |||
|
773 | flags, | |||
|
774 | ) | |||
|
775 | # cached by the global "writing" context | |||
|
776 | assert revlog._writinghandles is not None | |||
|
777 | if revlog._inline: | |||
|
778 | fh = revlog._writinghandles[0] | |||
|
779 | else: | |||
|
780 | fh = revlog._writinghandles[1] | |||
|
781 | return deltacomputer.buildtext(revinfo, fh) | |||
|
782 | ||||
|
783 | is_affected = _is_revision_affected_fast_inner( | |||
|
784 | is_censored, | |||
|
785 | delta_base, | |||
|
786 | lambda: delta, | |||
|
787 | full_text, | |||
|
788 | parent_revs, | |||
|
789 | rev, | |||
|
790 | metadata_cache, | |||
|
791 | ) | |||
|
792 | if is_affected: | |||
|
793 | d = ( | |||
|
794 | node, | |||
|
795 | p2_node, | |||
|
796 | p1_node, | |||
|
797 | linknode, | |||
|
798 | deltabase, | |||
|
799 | delta, | |||
|
800 | flags, | |||
|
801 | sidedata, | |||
|
802 | ) | |||
|
803 | yield d | |||
|
804 | ||||
|
805 | ||||
|
806 | def repair_issue6528( | |||
|
807 | ui, repo, dry_run=False, to_report=None, from_report=None, paranoid=False | |||
|
808 | ): | |||
|
809 | from .. import store # avoid cycle | |||
|
810 | ||||
|
811 | @contextlib.contextmanager | |||
|
812 | def context(): | |||
|
813 | if dry_run or to_report: # No need for locking | |||
|
814 | yield | |||
|
815 | else: | |||
|
816 | with repo.wlock(), repo.lock(): | |||
|
817 | yield | |||
|
818 | ||||
|
819 | if from_report: | |||
|
820 | return _from_report(ui, repo, context, from_report, dry_run) | |||
|
821 | ||||
|
822 | report_entries = [] | |||
|
823 | ||||
|
824 | with context(): | |||
|
825 | files = list( | |||
|
826 | (file_type, path) | |||
|
827 | for (file_type, path, _e, _s) in repo.store.datafiles() | |||
|
828 | if path.endswith(b'.i') and file_type & store.FILEFLAGS_FILELOG | |||
|
829 | ) | |||
|
830 | ||||
|
831 | progress = ui.makeprogress( | |||
|
832 | _(b"looking for affected revisions"), | |||
|
833 | unit=_(b"filelogs"), | |||
|
834 | total=len(files), | |||
|
835 | ) | |||
|
836 | found_nothing = True | |||
|
837 | ||||
|
838 | for file_type, path in files: | |||
|
839 | if ( | |||
|
840 | not path.endswith(b'.i') | |||
|
841 | or not file_type & store.FILEFLAGS_FILELOG | |||
|
842 | ): | |||
|
843 | continue | |||
|
844 | progress.increment() | |||
|
845 | filename = _get_filename_from_filelog_index(path) | |||
|
846 | fl = _filelog_from_filename(repo, filename) | |||
|
847 | ||||
|
848 | # Set of filerevs (or hex filenodes if `to_report`) that need fixing | |||
|
849 | to_fix = set() | |||
|
850 | metadata_cache = {} | |||
|
851 | for filerev in fl.revs(): | |||
|
852 | affected = _is_revision_affected_fast( | |||
|
853 | repo, fl, filerev, metadata_cache | |||
|
854 | ) | |||
|
855 | if paranoid: | |||
|
856 | slow = _is_revision_affected(fl, filerev) | |||
|
857 | if slow != affected: | |||
|
858 | msg = _(b"paranoid check failed for '%s' at node %s") | |||
|
859 | node = binascii.hexlify(fl.node(filerev)) | |||
|
860 | raise error.Abort(msg % (filename, node)) | |||
|
861 | if affected: | |||
|
862 | msg = b"found affected revision %d for filelog '%s'\n" | |||
|
863 | ui.warn(msg % (filerev, path)) | |||
|
864 | found_nothing = False | |||
|
865 | if not dry_run: | |||
|
866 | if to_report: | |||
|
867 | to_fix.add(binascii.hexlify(fl.node(filerev))) | |||
|
868 | else: | |||
|
869 | to_fix.add(filerev) | |||
|
870 | ||||
|
871 | if to_fix: | |||
|
872 | to_fix = sorted(to_fix) | |||
|
873 | if to_report: | |||
|
874 | report_entries.append((filename, to_fix)) | |||
|
875 | else: | |||
|
876 | _reorder_filelog_parents(repo, fl, to_fix) | |||
|
877 | ||||
|
878 | if found_nothing: | |||
|
879 | ui.write(_(b"no affected revisions were found\n")) | |||
|
880 | ||||
|
881 | if to_report and report_entries: | |||
|
882 | with open(to_report, mode="wb") as f: | |||
|
883 | for path, to_fix in report_entries: | |||
|
884 | f.write(b"%s %s\n" % (b",".join(to_fix), path)) | |||
|
885 | ||||
|
886 | progress.complete() |
@@ -207,7 +207,12 b' def update_hash_refs(repo, commitmsg, pe' | |||||
207 | hashes = re.findall(NODE_RE, commitmsg) |
|
207 | hashes = re.findall(NODE_RE, commitmsg) | |
208 | unfi = repo.unfiltered() |
|
208 | unfi = repo.unfiltered() | |
209 | for h in hashes: |
|
209 | for h in hashes: | |
210 | fullnode = scmutil.resolvehexnodeidprefix(unfi, h) |
|
210 | try: | |
|
211 | fullnode = scmutil.resolvehexnodeidprefix(unfi, h) | |||
|
212 | except error.WdirUnsupported: | |||
|
213 | # Someone has an fffff... in a commit message we're | |||
|
214 | # rewriting. Don't try rewriting that. | |||
|
215 | continue | |||
211 | if fullnode is None: |
|
216 | if fullnode is None: | |
212 | continue |
|
217 | continue | |
213 | ctx = unfi[fullnode] |
|
218 | ctx = unfi[fullnode] |
@@ -569,6 +569,11 b' class encodedstore(basicstore):' | |||||
569 | self.vfs = vfsmod.filtervfs(vfs, encodefilename) |
|
569 | self.vfs = vfsmod.filtervfs(vfs, encodefilename) | |
570 | self.opener = self.vfs |
|
570 | self.opener = self.vfs | |
571 |
|
571 | |||
|
572 | # note: topfiles would also need a decode phase. It is just that in | |||
|
573 | # practice we do not have any file outside of `data/` that needs encoding. | |||
|
574 | # However that might change so we should probably add a test and encoding | |||
|
575 | # decoding for it too. see issue6548 | |||
|
576 | ||||
572 | def datafiles(self, matcher=None): |
|
577 | def datafiles(self, matcher=None): | |
573 | for t, a, b, size in super(encodedstore, self).datafiles(): |
|
578 | for t, a, b, size in super(encodedstore, self).datafiles(): | |
574 | try: |
|
579 | try: |
@@ -565,6 +565,16 b' def _makemap(repo):' | |||||
565 | def _emit2(repo, entries, totalfilesize): |
|
565 | def _emit2(repo, entries, totalfilesize): | |
566 | """actually emit the stream bundle""" |
|
566 | """actually emit the stream bundle""" | |
567 | vfsmap = _makemap(repo) |
|
567 | vfsmap = _makemap(repo) | |
|
568 | # we keep repo.vfs out of the on purpose, ther are too many danger there | |||
|
569 | # (eg: .hg/hgrc), | |||
|
570 | # | |||
|
571 | # this assert is duplicated (from _makemap) as author might think this is | |||
|
572 | # fine, while this is really not fine. | |||
|
573 | if repo.vfs in vfsmap.values(): | |||
|
574 | raise error.ProgrammingError( | |||
|
575 | b'repo.vfs must not be added to vfsmap for security reasons' | |||
|
576 | ) | |||
|
577 | ||||
568 | progress = repo.ui.makeprogress( |
|
578 | progress = repo.ui.makeprogress( | |
569 | _(b'bundle'), total=totalfilesize, unit=_(b'bytes') |
|
579 | _(b'bundle'), total=totalfilesize, unit=_(b'bytes') | |
570 | ) |
|
580 | ) | |
@@ -573,7 +583,7 b' def _emit2(repo, entries, totalfilesize)' | |||||
573 | # copy is delayed until we are in the try |
|
583 | # copy is delayed until we are in the try | |
574 | entries = [_filterfull(e, copy, vfsmap) for e in entries] |
|
584 | entries = [_filterfull(e, copy, vfsmap) for e in entries] | |
575 | yield None # this release the lock on the repository |
|
585 | yield None # this release the lock on the repository | |
576 |
|
|
586 | totalbytecount = 0 | |
577 |
|
587 | |||
578 | for src, name, ftype, data in entries: |
|
588 | for src, name, ftype, data in entries: | |
579 | vfs = vfsmap[src] |
|
589 | vfs = vfsmap[src] | |
@@ -585,6 +595,7 b' def _emit2(repo, entries, totalfilesize)' | |||||
585 | elif ftype == _filefull: |
|
595 | elif ftype == _filefull: | |
586 | fp = open(data, b'rb') |
|
596 | fp = open(data, b'rb') | |
587 | size = util.fstat(fp).st_size |
|
597 | size = util.fstat(fp).st_size | |
|
598 | bytecount = 0 | |||
588 | try: |
|
599 | try: | |
589 | yield util.uvarintencode(size) |
|
600 | yield util.uvarintencode(size) | |
590 | yield name |
|
601 | yield name | |
@@ -593,9 +604,20 b' def _emit2(repo, entries, totalfilesize)' | |||||
593 | else: |
|
604 | else: | |
594 | chunks = util.filechunkiter(fp, limit=size) |
|
605 | chunks = util.filechunkiter(fp, limit=size) | |
595 | for chunk in chunks: |
|
606 | for chunk in chunks: | |
596 |
|
|
607 | bytecount += len(chunk) | |
597 |
|
|
608 | totalbytecount += len(chunk) | |
|
609 | progress.update(totalbytecount) | |||
598 | yield chunk |
|
610 | yield chunk | |
|
611 | if bytecount != size: | |||
|
612 | # Would most likely be caused by a race due to `hg strip` or | |||
|
613 | # a revlog split | |||
|
614 | raise error.Abort( | |||
|
615 | _( | |||
|
616 | b'clone could only read %d bytes from %s, but ' | |||
|
617 | b'expected %d bytes' | |||
|
618 | ) | |||
|
619 | % (bytecount, name, size) | |||
|
620 | ) | |||
599 | finally: |
|
621 | finally: | |
600 | fp.close() |
|
622 | fp.close() | |
601 |
|
623 | |||
@@ -713,6 +735,15 b' def consumev2(repo, fp, filecount, files' | |||||
713 | progress.update(0) |
|
735 | progress.update(0) | |
714 |
|
736 | |||
715 | vfsmap = _makemap(repo) |
|
737 | vfsmap = _makemap(repo) | |
|
738 | # we keep repo.vfs out of the on purpose, ther are too many danger | |||
|
739 | # there (eg: .hg/hgrc), | |||
|
740 | # | |||
|
741 | # this assert is duplicated (from _makemap) as author might think this | |||
|
742 | # is fine, while this is really not fine. | |||
|
743 | if repo.vfs in vfsmap.values(): | |||
|
744 | raise error.ProgrammingError( | |||
|
745 | b'repo.vfs must not be added to vfsmap for security reasons' | |||
|
746 | ) | |||
716 |
|
747 | |||
717 | with repo.transaction(b'clone'): |
|
748 | with repo.transaction(b'clone'): | |
718 | ctxs = (vfs.backgroundclosing(repo.ui) for vfs in vfsmap.values()) |
|
749 | ctxs = (vfs.backgroundclosing(repo.ui) for vfs in vfsmap.values()) |
@@ -458,12 +458,14 b' class hgsubrepo(abstractsubrepo):' | |||||
458 | create = allowcreate and not r.wvfs.exists(b'%s/.hg' % path) |
|
458 | create = allowcreate and not r.wvfs.exists(b'%s/.hg' % path) | |
459 | # repository constructor does expand variables in path, which is |
|
459 | # repository constructor does expand variables in path, which is | |
460 | # unsafe since subrepo path might come from untrusted source. |
|
460 | # unsafe since subrepo path might come from untrusted source. | |
461 | if os.path.realpath(util.expandpath(root)) != root: |
|
461 | norm_root = os.path.normcase(root) | |
|
462 | real_root = os.path.normcase(os.path.realpath(util.expandpath(root))) | |||
|
463 | if real_root != norm_root: | |||
462 | raise error.Abort( |
|
464 | raise error.Abort( | |
463 | _(b'subrepo path contains illegal component: %s') % path |
|
465 | _(b'subrepo path contains illegal component: %s') % path | |
464 | ) |
|
466 | ) | |
465 | self._repo = hg.repository(r.baseui, root, create=create) |
|
467 | self._repo = hg.repository(r.baseui, root, create=create) | |
466 | if self._repo.root != root: |
|
468 | if os.path.normcase(self._repo.root) != os.path.normcase(root): | |
467 | raise error.ProgrammingError( |
|
469 | raise error.ProgrammingError( | |
468 | b'failed to reject unsafe subrepo ' |
|
470 | b'failed to reject unsafe subrepo ' | |
469 | b'path: %s (expanded to %s)' % (root, self._repo.root) |
|
471 | b'path: %s (expanded to %s)' % (root, self._repo.root) |
@@ -71,7 +71,10 b' import abc' | |||||
71 | import os |
|
71 | import os | |
72 |
|
72 | |||
73 | from .i18n import _ |
|
73 | from .i18n import _ | |
74 |
from .pycompat import |
|
74 | from .pycompat import ( | |
|
75 | FileNotFoundError, | |||
|
76 | getattr, | |||
|
77 | ) | |||
75 | from . import ( |
|
78 | from . import ( | |
76 | config, |
|
79 | config, | |
77 | encoding, |
|
80 | encoding, | |
@@ -833,6 +836,13 b' def _open_mapfile(mapfile):' | |||||
833 |
|
836 | |||
834 | def _readmapfile(fp, mapfile): |
|
837 | def _readmapfile(fp, mapfile): | |
835 | """Load template elements from the given map file""" |
|
838 | """Load template elements from the given map file""" | |
|
839 | if pycompat.iswindows: | |||
|
840 | # quick hack to make sure we can process '/' in the code dealing with | |||
|
841 | # ressource. Ideally we would make sure we use `/` instead of `ossep` | |||
|
842 | # in the templater code, but that seems a bigger and less certain | |||
|
843 | # change that we better left for the default branch. | |||
|
844 | name_paths = mapfile.split(pycompat.ossep) | |||
|
845 | mapfile = b'/'.join(name_paths) | |||
836 | base = os.path.dirname(mapfile) |
|
846 | base = os.path.dirname(mapfile) | |
837 | conf = config.config() |
|
847 | conf = config.config() | |
838 |
|
848 | |||
@@ -845,9 +855,12 b' def _readmapfile(fp, mapfile):' | |||||
845 | if not subresource: |
|
855 | if not subresource: | |
846 | if pycompat.ossep not in rel: |
|
856 | if pycompat.ossep not in rel: | |
847 | abs = rel |
|
857 | abs = rel | |
848 | subresource = resourceutil.open_resource( |
|
858 | try: | |
849 | b'mercurial.templates', rel |
|
859 | subresource = resourceutil.open_resource( | |
850 | ) |
|
860 | b'mercurial.templates', rel | |
|
861 | ) | |||
|
862 | except FileNotFoundError: | |||
|
863 | subresource = None | |||
851 | else: |
|
864 | else: | |
852 | dir = templatedir() |
|
865 | dir = templatedir() | |
853 | if dir: |
|
866 | if dir: | |
@@ -1117,6 +1130,13 b' def open_template(name, templatepath=Non' | |||||
1117 | return f, open(f, mode='rb') |
|
1130 | return f, open(f, mode='rb') | |
1118 |
|
1131 | |||
1119 | # Otherwise try to read it using the resources API |
|
1132 | # Otherwise try to read it using the resources API | |
|
1133 | if pycompat.iswindows: | |||
|
1134 | # quick hack to make sure we can process '/' in the code dealing with | |||
|
1135 | # ressource. Ideally we would make sure we use `/` instead of `ossep` | |||
|
1136 | # in the templater code, but that seems a bigger and less certain | |||
|
1137 | # change that we better left for the default branch. | |||
|
1138 | name_paths = name.split(pycompat.ossep) | |||
|
1139 | name = b'/'.join(name_paths) | |||
1120 | name_parts = name.split(b'/') |
|
1140 | name_parts = name.split(b'/') | |
1121 | package_name = b'.'.join([b'mercurial', b'templates'] + name_parts[:-1]) |
|
1141 | package_name = b'.'.join([b'mercurial', b'templates'] + name_parts[:-1]) | |
1122 | return ( |
|
1142 | return ( |
@@ -33,5 +33,11 b' def wait_file(path, timeout=10):' | |||||
33 |
|
33 | |||
34 |
|
34 | |||
35 | def write_file(path, content=b''): |
|
35 | def write_file(path, content=b''): | |
36 | with open(path, 'wb') as f: |
|
36 | if content: | |
|
37 | write_path = b'%s.tmp' % path | |||
|
38 | else: | |||
|
39 | write_path = path | |||
|
40 | with open(write_path, 'wb') as f: | |||
37 | f.write(content) |
|
41 | f.write(content) | |
|
42 | if path != write_path: | |||
|
43 | os.rename(write_path, path) |
@@ -66,7 +66,7 b' def _revlogfrompath(repo, rl_type, path)' | |||||
66 | # drop the extension and the `data/` prefix |
|
66 | # drop the extension and the `data/` prefix | |
67 | path_part = path.rsplit(b'.', 1)[0].split(b'/', 1) |
|
67 | path_part = path.rsplit(b'.', 1)[0].split(b'/', 1) | |
68 | if len(path_part) < 2: |
|
68 | if len(path_part) < 2: | |
69 | msg = _('cannot recognize revlog from filename: %s') |
|
69 | msg = _(b'cannot recognize revlog from filename: %s') | |
70 | msg %= path |
|
70 | msg %= path | |
71 | raise error.Abort(msg) |
|
71 | raise error.Abort(msg) | |
72 | path = path_part[1] |
|
72 | path = path_part[1] |
@@ -50,6 +50,14 b' def _avoidambig(path, oldstat):' | |||||
50 | class abstractvfs(object): |
|
50 | class abstractvfs(object): | |
51 | """Abstract base class; cannot be instantiated""" |
|
51 | """Abstract base class; cannot be instantiated""" | |
52 |
|
52 | |||
|
53 | # default directory separator for vfs | |||
|
54 | # | |||
|
55 | # Other vfs code always use `/` and this works fine because python file API | |||
|
56 | # abstract the use of `/` and make it work transparently. For consistency | |||
|
57 | # vfs will always use `/` when joining. This avoid some confusion in | |||
|
58 | # encoded vfs (see issue6546) | |||
|
59 | _dir_sep = b'/' | |||
|
60 | ||||
53 | def __init__(self, *args, **kwargs): |
|
61 | def __init__(self, *args, **kwargs): | |
54 | '''Prevent instantiation; don't call this from subclasses.''' |
|
62 | '''Prevent instantiation; don't call this from subclasses.''' | |
55 | raise NotImplementedError('attempted instantiating ' + str(type(self))) |
|
63 | raise NotImplementedError('attempted instantiating ' + str(type(self))) | |
@@ -152,12 +160,22 b' class abstractvfs(object):' | |||||
152 | mode = st.st_mode |
|
160 | mode = st.st_mode | |
153 | return stat.S_ISREG(mode) or stat.S_ISLNK(mode) |
|
161 | return stat.S_ISREG(mode) or stat.S_ISLNK(mode) | |
154 |
|
162 | |||
|
163 | def _join(self, *paths): | |||
|
164 | root_idx = 0 | |||
|
165 | for idx, p in enumerate(paths): | |||
|
166 | if os.path.isabs(p) or p.startswith(self._dir_sep): | |||
|
167 | root_idx = idx | |||
|
168 | if root_idx != 0: | |||
|
169 | paths = paths[root_idx:] | |||
|
170 | paths = [p for p in paths if p] | |||
|
171 | return self._dir_sep.join(paths) | |||
|
172 | ||||
155 | def reljoin(self, *paths): |
|
173 | def reljoin(self, *paths): | |
156 | """join various elements of a path together (as os.path.join would do) |
|
174 | """join various elements of a path together (as os.path.join would do) | |
157 |
|
175 | |||
158 | The vfs base is not injected so that path stay relative. This exists |
|
176 | The vfs base is not injected so that path stay relative. This exists | |
159 | to allow handling of strange encoding if needed.""" |
|
177 | to allow handling of strange encoding if needed.""" | |
160 |
return |
|
178 | return self._join(*paths) | |
161 |
|
179 | |||
162 | def split(self, path): |
|
180 | def split(self, path): | |
163 | """split top-most element of a path (as os.path.split would do) |
|
181 | """split top-most element of a path (as os.path.split would do) | |
@@ -528,7 +546,9 b' class vfs(abstractvfs):' | |||||
528 |
|
546 | |||
529 | def join(self, path, *insidef): |
|
547 | def join(self, path, *insidef): | |
530 | if path: |
|
548 | if path: | |
531 |
|
|
549 | parts = [self.base, path] | |
|
550 | parts.extend(insidef) | |||
|
551 | return self._join(*parts) | |||
532 | else: |
|
552 | else: | |
533 | return self.base |
|
553 | return self.base | |
534 |
|
554 |
@@ -200,20 +200,20 b' def get_password():' | |||||
200 | This shouldn't be called directly- use ``ui.getpass()`` instead, which |
|
200 | This shouldn't be called directly- use ``ui.getpass()`` instead, which | |
201 | checks if the session is interactive first. |
|
201 | checks if the session is interactive first. | |
202 | """ |
|
202 | """ | |
203 | pw = "" |
|
203 | pw = u"" | |
204 | while True: |
|
204 | while True: | |
205 | c = msvcrt.getwch() # pytype: disable=module-attr |
|
205 | c = msvcrt.getwch() # pytype: disable=module-attr | |
206 | if c == '\r' or c == '\n': |
|
206 | if c == u'\r' or c == u'\n': | |
207 | break |
|
207 | break | |
208 | if c == '\003': |
|
208 | if c == u'\003': | |
209 | raise KeyboardInterrupt |
|
209 | raise KeyboardInterrupt | |
210 | if c == '\b': |
|
210 | if c == u'\b': | |
211 | pw = pw[:-1] |
|
211 | pw = pw[:-1] | |
212 | else: |
|
212 | else: | |
213 | pw = pw + c |
|
213 | pw = pw + c | |
214 | msvcrt.putwch('\r') # pytype: disable=module-attr |
|
214 | msvcrt.putwch(u'\r') # pytype: disable=module-attr | |
215 | msvcrt.putwch('\n') # pytype: disable=module-attr |
|
215 | msvcrt.putwch(u'\n') # pytype: disable=module-attr | |
216 |
return encoding. |
|
216 | return encoding.unitolocal(pw) | |
217 |
|
217 | |||
218 |
|
218 | |||
219 | class winstdout(object): |
|
219 | class winstdout(object): |
@@ -47,6 +47,8 b' pub enum HgError {' | |||||
47 | /// Details about where an I/O error happened |
|
47 | /// Details about where an I/O error happened | |
48 | #[derive(Debug)] |
|
48 | #[derive(Debug)] | |
49 | pub enum IoErrorContext { |
|
49 | pub enum IoErrorContext { | |
|
50 | /// `std::fs::metadata` | |||
|
51 | ReadingMetadata(std::path::PathBuf), | |||
50 | ReadingFile(std::path::PathBuf), |
|
52 | ReadingFile(std::path::PathBuf), | |
51 | WritingFile(std::path::PathBuf), |
|
53 | WritingFile(std::path::PathBuf), | |
52 | RemovingFile(std::path::PathBuf), |
|
54 | RemovingFile(std::path::PathBuf), | |
@@ -108,6 +110,9 b' impl fmt::Display for HgError {' | |||||
108 | impl fmt::Display for IoErrorContext { |
|
110 | impl fmt::Display for IoErrorContext { | |
109 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
|
111 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | |
110 | match self { |
|
112 | match self { | |
|
113 | IoErrorContext::ReadingMetadata(path) => { | |||
|
114 | write!(f, "when reading metadata of {}", path.display()) | |||
|
115 | } | |||
111 | IoErrorContext::ReadingFile(path) => { |
|
116 | IoErrorContext::ReadingFile(path) => { | |
112 | write!(f, "when reading {}", path.display()) |
|
117 | write!(f, "when reading {}", path.display()) | |
113 | } |
|
118 | } |
@@ -6,6 +6,7 b' use crate::utils::files::get_path_from_b' | |||||
6 | use crate::utils::SliceExt; |
|
6 | use crate::utils::SliceExt; | |
7 | use memmap::{Mmap, MmapOptions}; |
|
7 | use memmap::{Mmap, MmapOptions}; | |
8 | use std::collections::HashSet; |
|
8 | use std::collections::HashSet; | |
|
9 | use std::io::ErrorKind; | |||
9 | use std::path::{Path, PathBuf}; |
|
10 | use std::path::{Path, PathBuf}; | |
10 |
|
11 | |||
11 | /// A repository on disk |
|
12 | /// A repository on disk | |
@@ -51,7 +52,7 b' impl Repo {' | |||||
51 | // ancestors() is inclusive: it first yields `current_directory` |
|
52 | // ancestors() is inclusive: it first yields `current_directory` | |
52 | // as-is. |
|
53 | // as-is. | |
53 | for ancestor in current_directory.ancestors() { |
|
54 | for ancestor in current_directory.ancestors() { | |
54 |
if ancestor.join(".hg") |
|
55 | if is_dir(ancestor.join(".hg"))? { | |
55 | return Ok(ancestor.to_path_buf()); |
|
56 | return Ok(ancestor.to_path_buf()); | |
56 | } |
|
57 | } | |
57 | } |
|
58 | } | |
@@ -73,9 +74,9 b' impl Repo {' | |||||
73 | explicit_path: Option<PathBuf>, |
|
74 | explicit_path: Option<PathBuf>, | |
74 | ) -> Result<Self, RepoError> { |
|
75 | ) -> Result<Self, RepoError> { | |
75 | if let Some(root) = explicit_path { |
|
76 | if let Some(root) = explicit_path { | |
76 |
if root.join(".hg") |
|
77 | if is_dir(root.join(".hg"))? { | |
77 | Self::new_at_path(root.to_owned(), config) |
|
78 | Self::new_at_path(root.to_owned(), config) | |
78 |
} else if |
|
79 | } else if is_file(&root)? { | |
79 | Err(HgError::unsupported("bundle repository").into()) |
|
80 | Err(HgError::unsupported("bundle repository").into()) | |
80 | } else { |
|
81 | } else { | |
81 | Err(RepoError::NotFound { |
|
82 | Err(RepoError::NotFound { | |
@@ -130,7 +131,7 b' impl Repo {' | |||||
130 | if relative { |
|
131 | if relative { | |
131 | shared_path = dot_hg.join(shared_path) |
|
132 | shared_path = dot_hg.join(shared_path) | |
132 | } |
|
133 | } | |
133 |
if ! |
|
134 | if !is_dir(&shared_path)? { | |
134 | return Err(HgError::corrupted(format!( |
|
135 | return Err(HgError::corrupted(format!( | |
135 | ".hg/sharedpath points to nonexistent directory {}", |
|
136 | ".hg/sharedpath points to nonexistent directory {}", | |
136 | shared_path.display() |
|
137 | shared_path.display() | |
@@ -286,3 +287,29 b" impl Vfs<'_> {" | |||||
286 | .with_context(|| IoErrorContext::RenamingFile { from, to }) |
|
287 | .with_context(|| IoErrorContext::RenamingFile { from, to }) | |
287 | } |
|
288 | } | |
288 | } |
|
289 | } | |
|
290 | ||||
|
291 | fn fs_metadata( | |||
|
292 | path: impl AsRef<Path>, | |||
|
293 | ) -> Result<Option<std::fs::Metadata>, HgError> { | |||
|
294 | let path = path.as_ref(); | |||
|
295 | match std::fs::metadata(path) { | |||
|
296 | Ok(meta) => Ok(Some(meta)), | |||
|
297 | Err(error) => match error.kind() { | |||
|
298 | // TODO: when we require a Rust version where `NotADirectory` is | |||
|
299 | // stable, invert this logic and return None for it and `NotFound` | |||
|
300 | // and propagate any other error. | |||
|
301 | ErrorKind::PermissionDenied => Err(error).with_context(|| { | |||
|
302 | IoErrorContext::ReadingMetadata(path.to_owned()) | |||
|
303 | }), | |||
|
304 | _ => Ok(None), | |||
|
305 | }, | |||
|
306 | } | |||
|
307 | } | |||
|
308 | ||||
|
309 | fn is_dir(path: impl AsRef<Path>) -> Result<bool, HgError> { | |||
|
310 | Ok(fs_metadata(path)?.map_or(false, |meta| meta.is_dir())) | |||
|
311 | } | |||
|
312 | ||||
|
313 | fn is_file(path: impl AsRef<Path>) -> Result<bool, HgError> { | |||
|
314 | Ok(fs_metadata(path)?.map_or(false, |meta| meta.is_file())) | |||
|
315 | } |
@@ -59,12 +59,22 b' py_class!(pub class MixedIndex |py| {' | |||||
59 |
|
59 | |||
60 | /// Return Revision if found, raises a bare `error.RevlogError` |
|
60 | /// Return Revision if found, raises a bare `error.RevlogError` | |
61 | /// in case of ambiguity, same as C version does |
|
61 | /// in case of ambiguity, same as C version does | |
62 | def get_rev(&self, node: PyBytes) -> PyResult<Option<Revision>> { |
|
62 | def get_rev(&self, pynode: PyBytes) -> PyResult<Option<Revision>> { | |
63 | let opt = self.get_nodetree(py)?.borrow(); |
|
63 | let opt = self.get_nodetree(py)?.borrow(); | |
64 | let nt = opt.as_ref().unwrap(); |
|
64 | let nt = opt.as_ref().unwrap(); | |
65 | let idx = &*self.cindex(py).borrow(); |
|
65 | let idx = &*self.cindex(py).borrow(); | |
66 | let node = node_from_py_bytes(py, &node)?; |
|
66 | let node = node_from_py_bytes(py, &pynode)?; | |
67 |
nt.find_bin(idx, node.into()) |
|
67 | match nt.find_bin(idx, node.into()) | |
|
68 | { | |||
|
69 | Ok(None) => | |||
|
70 | // fallback to C implementation, remove once | |||
|
71 | // https://bz.mercurial-scm.org/show_bug.cgi?id=6554 | |||
|
72 | // is fixed (a simple backout should do) | |||
|
73 | self.call_cindex(py, "get_rev", &PyTuple::new(py, &[pynode.into_object()]), None)? | |||
|
74 | .extract(py), | |||
|
75 | Ok(Some(rev)) => Ok(Some(rev)), | |||
|
76 | Err(e) => Err(nodemap_error(py, e)), | |||
|
77 | } | |||
68 | } |
|
78 | } | |
69 |
|
79 | |||
70 | /// same as `get_rev()` but raises a bare `error.RevlogError` if node |
|
80 | /// same as `get_rev()` but raises a bare `error.RevlogError` if node | |
@@ -94,27 +104,34 b' py_class!(pub class MixedIndex |py| {' | |||||
94 | } |
|
104 | } | |
95 | } |
|
105 | } | |
96 |
|
106 | |||
97 | def partialmatch(&self, node: PyObject) -> PyResult<Option<PyBytes>> { |
|
107 | def partialmatch(&self, pynode: PyObject) -> PyResult<Option<PyBytes>> { | |
98 | let opt = self.get_nodetree(py)?.borrow(); |
|
108 | let opt = self.get_nodetree(py)?.borrow(); | |
99 | let nt = opt.as_ref().unwrap(); |
|
109 | let nt = opt.as_ref().unwrap(); | |
100 | let idx = &*self.cindex(py).borrow(); |
|
110 | let idx = &*self.cindex(py).borrow(); | |
101 |
|
111 | |||
102 | let node_as_string = if cfg!(feature = "python3-sys") { |
|
112 | let node_as_string = if cfg!(feature = "python3-sys") { | |
103 | node.cast_as::<PyString>(py)?.to_string(py)?.to_string() |
|
113 | pynode.cast_as::<PyString>(py)?.to_string(py)?.to_string() | |
104 | } |
|
114 | } | |
105 | else { |
|
115 | else { | |
106 | let node = node.extract::<PyBytes>(py)?; |
|
116 | let node = pynode.extract::<PyBytes>(py)?; | |
107 | String::from_utf8_lossy(node.data(py)).to_string() |
|
117 | String::from_utf8_lossy(node.data(py)).to_string() | |
108 | }; |
|
118 | }; | |
109 |
|
119 | |||
110 | let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?; |
|
120 | let prefix = NodePrefix::from_hex(&node_as_string).map_err(|_| PyErr::new::<ValueError, _>(py, "Invalid node or prefix"))?; | |
111 |
|
121 | |||
112 | nt.find_bin(idx, prefix) |
|
122 | match nt.find_bin(idx, prefix) { | |
113 | // TODO make an inner API returning the node directly |
|
123 | Ok(None) => | |
114 | .map(|opt| opt.map( |
|
124 | // fallback to C implementation, remove once | |
115 | |rev| PyBytes::new(py, idx.node(rev).unwrap().as_bytes()))) |
|
125 | // https://bz.mercurial-scm.org/show_bug.cgi?id=6554 | |
116 | .map_err(|e| nodemap_error(py, e)) |
|
126 | // is fixed (a simple backout should do) | |
117 |
|
127 | self.call_cindex( | ||
|
128 | py, "partialmatch", | |||
|
129 | &PyTuple::new(py, &[pynode]), None | |||
|
130 | )?.extract(py), | |||
|
131 | Ok(Some(rev)) => | |||
|
132 | Ok(Some(PyBytes::new(py, idx.node(rev).unwrap().as_bytes()))), | |||
|
133 | Err(e) => Err(nodemap_error(py, e)), | |||
|
134 | } | |||
118 | } |
|
135 | } | |
119 |
|
136 | |||
120 | /// append an index entry |
|
137 | /// append an index entry |
@@ -35,7 +35,20 b' TIME_STAMP_SERVER_URL = VARS.get("TIME_S' | |||||
35 | IS_WINDOWS = "windows" in BUILD_TARGET_TRIPLE |
|
35 | IS_WINDOWS = "windows" in BUILD_TARGET_TRIPLE | |
36 |
|
36 | |||
37 | # Code to run in Python interpreter. |
|
37 | # Code to run in Python interpreter. | |
38 | RUN_CODE = "import hgdemandimport; hgdemandimport.enable(); from mercurial import dispatch; dispatch.run()" |
|
38 | RUN_CODE = """ | |
|
39 | import os | |||
|
40 | import sys | |||
|
41 | extra_path = os.environ.get('PYTHONPATH') | |||
|
42 | if extra_path is not None: | |||
|
43 | # extensions and hooks expect a working python environment | |||
|
44 | # We do not prepend the values because the Mercurial library wants to be in | |||
|
45 | # the front of the sys.path to avoid picking up other installations. | |||
|
46 | sys.path.extend(extra_path.split(os.pathsep)) | |||
|
47 | import hgdemandimport; | |||
|
48 | hgdemandimport.enable(); | |||
|
49 | from mercurial import dispatch; | |||
|
50 | dispatch.run(); | |||
|
51 | """ | |||
39 |
|
52 | |||
40 | set_build_path(ROOT + "/build/pyoxidizer") |
|
53 | set_build_path(ROOT + "/build/pyoxidizer") | |
41 |
|
54 |
@@ -1,4 +1,77 b'' | |||||
1 | # rhg |
|
1 | # `rhg` | |
|
2 | ||||
|
3 | The `rhg` executable implements a subset of the functionnality of `hg` | |||
|
4 | using only Rust, to avoid the startup cost of a Python interpreter. | |||
|
5 | This subset is initially small but grows over time as `rhg` is improved. | |||
|
6 | When fallback to the Python implementation is configured (see below), | |||
|
7 | `rhg` aims to be a drop-in replacement for `hg` that should behave the same, | |||
|
8 | except that some commands run faster. | |||
|
9 | ||||
|
10 | ||||
|
11 | ## Building | |||
|
12 | ||||
|
13 | To compile `rhg`, either run `cargo build --release` from this `rust/rhg/` | |||
|
14 | directory, or run `make build-rhg` from the repository root. | |||
|
15 | The executable can then be found at `rust/target/release/rhg`. | |||
|
16 | ||||
|
17 | ||||
|
18 | ## Mercurial configuration | |||
|
19 | ||||
|
20 | `rhg` reads Mercurial configuration from the usual sources: | |||
|
21 | the user’s `~/.hgrc`, a repository’s `.hg/hgrc`, command line `--config`, etc. | |||
|
22 | It has some specific configuration in the `[rhg]` section: | |||
|
23 | ||||
|
24 | * `on-unsupported` governs the behavior of `rhg` when it encounters something | |||
|
25 | that it does not support but “full” `hg` possibly does. | |||
|
26 | This can be in configuration, on the command line, or in a repository. | |||
|
27 | ||||
|
28 | - `abort`, the default value, makes `rhg` print a message to stderr | |||
|
29 | to explain what is not supported, then terminate with a 252 exit code. | |||
|
30 | - `abort-silent` makes it terminate with the same exit code, | |||
|
31 | but without printing anything. | |||
|
32 | - `fallback` makes it silently call a (presumably Python-based) `hg` | |||
|
33 | subprocess with the same command-line parameters. | |||
|
34 | The `rhg.fallback-executable` configuration must be set. | |||
|
35 | ||||
|
36 | * `fallback-executable`: path to the executable to run in a sub-process | |||
|
37 | when falling back to a Python implementation of Mercurial. | |||
2 |
|
38 | |||
3 | This project provides a fastpath Rust implementation of the Mercurial (`hg`) |
|
39 | * `allowed-extensions`: a list of extension names that `rhg` can ignore. | |
4 | version control tool. |
|
40 | ||
|
41 | Mercurial extensions can modify the behavior of existing `hg` sub-commands, | |||
|
42 | including those that `rhg` otherwise supports. | |||
|
43 | Because it cannot load Python extensions, finding them | |||
|
44 | enabled in configuration is considered “unsupported” (see above). | |||
|
45 | A few exceptions are made for extensions that `rhg` does know about, | |||
|
46 | with the Rust implementation duplicating their behavior. | |||
|
47 | ||||
|
48 | This configuration makes additional exceptions: `rhg` will proceed even if | |||
|
49 | those extensions are enabled. | |||
|
50 | ||||
|
51 | ||||
|
52 | ## Installation and configuration example | |||
|
53 | ||||
|
54 | For example, to install `rhg` as `hg` for the current user with fallback to | |||
|
55 | the system-wide install of Mercurial, and allow it to run even though the | |||
|
56 | `rebase` and `absorb` extensions are enabled, on a Unix-like platform: | |||
|
57 | ||||
|
58 | * Build `rhg` (see above) | |||
|
59 | * Make sure the `~/.local/bin` exists and is in `$PATH` | |||
|
60 | * From the repository root, make a symbolic link with | |||
|
61 | `ln -s rust/target/release/rhg ~/.local/bin/hg` | |||
|
62 | * Configure `~/.hgrc` with: | |||
|
63 | ||||
|
64 | ``` | |||
|
65 | [rhg] | |||
|
66 | on-unsupported = fallback | |||
|
67 | fallback-executable = /usr/bin/hg | |||
|
68 | allowed-extensions = rebase, absorb | |||
|
69 | ``` | |||
|
70 | ||||
|
71 | * Check that the output of running | |||
|
72 | `hg notarealsubcommand` | |||
|
73 | starts with `hg: unknown command`, which indicates fallback. | |||
|
74 | ||||
|
75 | * Check that the output of running | |||
|
76 | `hg notarealsubcommand --config rhg.on-unsupported=abort` | |||
|
77 | starts with `unsupported feature:`. |
@@ -31,5 +31,5 b" if os.name == 'nt':" | |||||
31 | hgcmd = shlex.join(cmds) |
|
31 | hgcmd = shlex.join(cmds) | |
32 | # shlex generate windows incompatible string... |
|
32 | # shlex generate windows incompatible string... | |
33 | hgcmd = hgcmd.replace("'", '"') |
|
33 | hgcmd = hgcmd.replace("'", '"') | |
34 | r = subprocess.call(hgcmd, shell=True) |
|
34 | r = subprocess.call(hgcmd, shell=True, close_fds=True) | |
35 | sys.exit(bool(r)) |
|
35 | sys.exit(bool(r)) |
@@ -199,6 +199,11 b' def has_rhg():' | |||||
199 | return 'RHG_INSTALLED_AS_HG' in os.environ |
|
199 | return 'RHG_INSTALLED_AS_HG' in os.environ | |
200 |
|
200 | |||
201 |
|
201 | |||
|
202 | @check("pyoxidizer", "running with pyoxidizer build as 'hg'") | |||
|
203 | def has_rhg(): | |||
|
204 | return 'PYOXIDIZED_INSTALLED_AS_HG' in os.environ | |||
|
205 | ||||
|
206 | ||||
202 | @check("cvs", "cvs client/server") |
|
207 | @check("cvs", "cvs client/server") | |
203 | def has_cvs(): |
|
208 | def has_cvs(): | |
204 | re = br'Concurrent Versions System.*?server' |
|
209 | re = br'Concurrent Versions System.*?server' |
@@ -594,6 +594,11 b' def getparser():' | |||||
594 | action="store_true", |
|
594 | action="store_true", | |
595 | help="install and use rhg Rust implementation in place of hg", |
|
595 | help="install and use rhg Rust implementation in place of hg", | |
596 | ) |
|
596 | ) | |
|
597 | hgconf.add_argument( | |||
|
598 | "--pyoxidized", | |||
|
599 | action="store_true", | |||
|
600 | help="build the hg binary using pyoxidizer", | |||
|
601 | ) | |||
597 | hgconf.add_argument("--compiler", help="compiler to build with") |
|
602 | hgconf.add_argument("--compiler", help="compiler to build with") | |
598 | hgconf.add_argument( |
|
603 | hgconf.add_argument( | |
599 | '--extra-config-opt', |
|
604 | '--extra-config-opt', | |
@@ -731,6 +736,8 b' def parseargs(args, parser):' | |||||
731 | parser.error( |
|
736 | parser.error( | |
732 | '--local cannot be used with --with-hg or --with-rhg or --with-chg' |
|
737 | '--local cannot be used with --with-hg or --with-rhg or --with-chg' | |
733 | ) |
|
738 | ) | |
|
739 | if options.pyoxidized: | |||
|
740 | parser.error('--pyoxidized does not work with --local (yet)') | |||
734 | testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0]))) |
|
741 | testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0]))) | |
735 | reporootdir = os.path.dirname(testdir) |
|
742 | reporootdir = os.path.dirname(testdir) | |
736 | pathandattrs = [(b'hg', 'with_hg')] |
|
743 | pathandattrs = [(b'hg', 'with_hg')] | |
@@ -764,6 +771,8 b' def parseargs(args, parser):' | |||||
764 | parser.error('chg does not work on %s' % os.name) |
|
771 | parser.error('chg does not work on %s' % os.name) | |
765 | if (options.rhg or options.with_rhg) and WINDOWS: |
|
772 | if (options.rhg or options.with_rhg) and WINDOWS: | |
766 | parser.error('rhg does not work on %s' % os.name) |
|
773 | parser.error('rhg does not work on %s' % os.name) | |
|
774 | if options.pyoxidized and not WINDOWS: | |||
|
775 | parser.error('--pyoxidized is currently Windows only') | |||
767 | if options.with_chg: |
|
776 | if options.with_chg: | |
768 | options.chg = False # no installation to temporary location |
|
777 | options.chg = False # no installation to temporary location | |
769 | options.with_chg = canonpath(_sys2bytes(options.with_chg)) |
|
778 | options.with_chg = canonpath(_sys2bytes(options.with_chg)) | |
@@ -1546,6 +1555,8 b' class Test(unittest.TestCase):' | |||||
1546 | hgrc.write(b'mergemarkers = detailed\n') |
|
1555 | hgrc.write(b'mergemarkers = detailed\n') | |
1547 | hgrc.write(b'promptecho = True\n') |
|
1556 | hgrc.write(b'promptecho = True\n') | |
1548 | hgrc.write(b'timeout.warn=15\n') |
|
1557 | hgrc.write(b'timeout.warn=15\n') | |
|
1558 | hgrc.write(b'[chgserver]\n') | |||
|
1559 | hgrc.write(b'idletimeout=60\n') | |||
1549 | hgrc.write(b'[defaults]\n') |
|
1560 | hgrc.write(b'[defaults]\n') | |
1550 | hgrc.write(b'[devel]\n') |
|
1561 | hgrc.write(b'[devel]\n') | |
1551 | hgrc.write(b'all-warnings = true\n') |
|
1562 | hgrc.write(b'all-warnings = true\n') | |
@@ -1587,6 +1598,7 b' class Test(unittest.TestCase):' | |||||
1587 | proc = subprocess.Popen( |
|
1598 | proc = subprocess.Popen( | |
1588 | _bytes2sys(cmd), |
|
1599 | _bytes2sys(cmd), | |
1589 | shell=True, |
|
1600 | shell=True, | |
|
1601 | close_fds=closefds, | |||
1590 | cwd=_bytes2sys(self._testtmp), |
|
1602 | cwd=_bytes2sys(self._testtmp), | |
1591 | env=env, |
|
1603 | env=env, | |
1592 | ) |
|
1604 | ) | |
@@ -3220,6 +3232,20 b' class TestRunner(object):' | |||||
3220 | rhgbindir = os.path.dirname(os.path.realpath(self.options.with_rhg)) |
|
3232 | rhgbindir = os.path.dirname(os.path.realpath(self.options.with_rhg)) | |
3221 | self._hgcommand = os.path.basename(self.options.with_rhg) |
|
3233 | self._hgcommand = os.path.basename(self.options.with_rhg) | |
3222 |
|
3234 | |||
|
3235 | if self.options.pyoxidized: | |||
|
3236 | testdir = os.path.dirname(_sys2bytes(canonpath(sys.argv[0]))) | |||
|
3237 | reporootdir = os.path.dirname(testdir) | |||
|
3238 | # XXX we should ideally install stuff instead of using the local build | |||
|
3239 | bin_path = ( | |||
|
3240 | b'build/pyoxidizer/x86_64-pc-windows-msvc/release/app/hg.exe' | |||
|
3241 | ) | |||
|
3242 | full_path = os.path.join(reporootdir, bin_path) | |||
|
3243 | self._hgcommand = full_path | |||
|
3244 | # Affects hghave.py | |||
|
3245 | osenvironb[b'PYOXIDIZED_INSTALLED_AS_HG'] = b'1' | |||
|
3246 | else: | |||
|
3247 | osenvironb.pop(b'PYOXIDIZED_INSTALLED_AS_HG', None) | |||
|
3248 | ||||
3223 | osenvironb[b"BINDIR"] = self._bindir |
|
3249 | osenvironb[b"BINDIR"] = self._bindir | |
3224 | osenvironb[b"PYTHON"] = PYTHON |
|
3250 | osenvironb[b"PYTHON"] = PYTHON | |
3225 |
|
3251 | |||
@@ -3460,6 +3486,8 b' class TestRunner(object):' | |||||
3460 | if self.options.rhg: |
|
3486 | if self.options.rhg: | |
3461 | assert self._installdir |
|
3487 | assert self._installdir | |
3462 | self._installrhg() |
|
3488 | self._installrhg() | |
|
3489 | elif self.options.pyoxidized: | |||
|
3490 | self._build_pyoxidized() | |||
3463 | self._use_correct_mercurial() |
|
3491 | self._use_correct_mercurial() | |
3464 |
|
3492 | |||
3465 | log( |
|
3493 | log( | |
@@ -3872,6 +3900,37 b' class TestRunner(object):' | |||||
3872 | sys.stdout.write(out) |
|
3900 | sys.stdout.write(out) | |
3873 | sys.exit(1) |
|
3901 | sys.exit(1) | |
3874 |
|
3902 | |||
|
3903 | def _build_pyoxidized(self): | |||
|
3904 | """build a pyoxidized version of mercurial into the test environment | |||
|
3905 | ||||
|
3906 | Ideally this function would be `install_pyoxidier` and would both build | |||
|
3907 | and install pyoxidier. However we are starting small to get pyoxidizer | |||
|
3908 | build binary to testing quickly. | |||
|
3909 | """ | |||
|
3910 | vlog('# build a pyoxidized version of Mercurial') | |||
|
3911 | assert os.path.dirname(self._bindir) == self._installdir | |||
|
3912 | assert self._hgroot, 'must be called after _installhg()' | |||
|
3913 | cmd = b'"%(make)s" pyoxidizer-windows-tests' % { | |||
|
3914 | b'make': b'make', | |||
|
3915 | } | |||
|
3916 | cwd = self._hgroot | |||
|
3917 | vlog("# Running", cmd) | |||
|
3918 | proc = subprocess.Popen( | |||
|
3919 | _bytes2sys(cmd), | |||
|
3920 | shell=True, | |||
|
3921 | cwd=_bytes2sys(cwd), | |||
|
3922 | stdin=subprocess.PIPE, | |||
|
3923 | stdout=subprocess.PIPE, | |||
|
3924 | stderr=subprocess.STDOUT, | |||
|
3925 | ) | |||
|
3926 | out, _err = proc.communicate() | |||
|
3927 | if proc.returncode != 0: | |||
|
3928 | if PYTHON3: | |||
|
3929 | sys.stdout.buffer.write(out) | |||
|
3930 | else: | |||
|
3931 | sys.stdout.write(out) | |||
|
3932 | sys.exit(1) | |||
|
3933 | ||||
3875 | def _outputcoverage(self): |
|
3934 | def _outputcoverage(self): | |
3876 | """Produce code coverage output.""" |
|
3935 | """Produce code coverage output.""" | |
3877 | import coverage |
|
3936 | import coverage |
@@ -631,7 +631,7 b' annotate missing file' | |||||
631 | $ rm baz |
|
631 | $ rm baz | |
632 |
|
632 | |||
633 | $ hg annotate -ncr "wdir()" baz |
|
633 | $ hg annotate -ncr "wdir()" baz | |
634 |
abort: $TESTTMP\repo |
|
634 | abort: $TESTTMP\repo/baz: $ENOENT$ (windows !) | |
635 | abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !) |
|
635 | abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !) | |
636 | [255] |
|
636 | [255] | |
637 |
|
637 | |||
@@ -640,7 +640,7 b' annotate removed file' | |||||
640 | $ hg rm baz |
|
640 | $ hg rm baz | |
641 |
|
641 | |||
642 | $ hg annotate -ncr "wdir()" baz |
|
642 | $ hg annotate -ncr "wdir()" baz | |
643 |
abort: $TESTTMP\repo |
|
643 | abort: $TESTTMP\repo/baz: $ENOENT$ (windows !) | |
644 | abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !) |
|
644 | abort: $ENOENT$: '$TESTTMP/repo/baz' (no-windows !) | |
645 | [255] |
|
645 | [255] | |
646 |
|
646 |
@@ -20,7 +20,8 b' ensure that failing ui.atexit handlers r' | |||||
20 | show help for a given topic or a help overview |
|
20 | show help for a given topic or a help overview | |
21 | error in exit handlers: |
|
21 | error in exit handlers: | |
22 | Traceback (most recent call last): |
|
22 | Traceback (most recent call last): | |
23 | File "*/mercurial/dispatch.py", line *, in _runexithandlers (glob) |
|
23 | File "*/mercurial/dispatch.py", line *, in _runexithandlers (glob) (no-pyoxidizer !) | |
|
24 | File "mercurial.dispatch", line *, in _runexithandlers (glob) (pyoxidizer !) | |||
24 | func(*args, **kwargs) |
|
25 | func(*args, **kwargs) | |
25 | File "$TESTTMP/bailatexit.py", line *, in bail (glob) |
|
26 | File "$TESTTMP/bailatexit.py", line *, in bail (glob) | |
26 | raise RuntimeError('ui.atexit handler exception') |
|
27 | raise RuntimeError('ui.atexit handler exception') |
@@ -2,6 +2,7 b' Create a repository:' | |||||
2 |
|
2 | |||
3 | #if no-extraextensions |
|
3 | #if no-extraextensions | |
4 | $ hg config |
|
4 | $ hg config | |
|
5 | chgserver.idletimeout=60 | |||
5 | devel.all-warnings=true |
|
6 | devel.all-warnings=true | |
6 | devel.default-date=0 0 |
|
7 | devel.default-date=0 0 | |
7 | extensions.fsmonitor= (fsmonitor !) |
|
8 | extensions.fsmonitor= (fsmonitor !) |
@@ -89,6 +89,13 b' add files with "tricky" name:' | |||||
89 | $ echo foo > store/undo.foo.d |
|
89 | $ echo foo > store/undo.foo.d | |
90 | $ echo foo > store/undo.foo.n |
|
90 | $ echo foo > store/undo.foo.n | |
91 | $ echo foo > store/undo.babar |
|
91 | $ echo foo > store/undo.babar | |
|
92 | ||||
|
93 | Name with special characters | |||
|
94 | ||||
|
95 | $ echo foo > store/CélesteVille_is_a_Capital_City | |||
|
96 | ||||
|
97 | All all that | |||
|
98 | ||||
92 | $ hg add . |
|
99 | $ hg add . | |
93 | adding 00changelog-ab349180a0405010.nd |
|
100 | adding 00changelog-ab349180a0405010.nd | |
94 | adding 00changelog.d |
|
101 | adding 00changelog.d | |
@@ -132,6 +139,7 b' add files with "tricky" name:' | |||||
132 | adding savanah/undo.i |
|
139 | adding savanah/undo.i | |
133 | adding savanah/undo.n |
|
140 | adding savanah/undo.n | |
134 | adding savanah/undo.py |
|
141 | adding savanah/undo.py | |
|
142 | adding store/C\xc3\xa9lesteVille_is_a_Capital_City (esc) | |||
135 | adding store/foo.d |
|
143 | adding store/foo.d | |
136 | adding store/foo.i |
|
144 | adding store/foo.i | |
137 | adding store/foo.n |
|
145 | adding store/foo.n | |
@@ -156,6 +164,19 b' add files with "tricky" name:' | |||||
156 | $ cat hg.pid > $DAEMON_PIDS |
|
164 | $ cat hg.pid > $DAEMON_PIDS | |
157 | $ cd .. |
|
165 | $ cd .. | |
158 |
|
166 | |||
|
167 | Check local clone | |||
|
168 | ================== | |||
|
169 | ||||
|
170 | The logic is close enough of uncompressed. | |||
|
171 | This is present here to reuse the testing around file with "special" names. | |||
|
172 | ||||
|
173 | $ hg clone server local-clone | |||
|
174 | updating to branch default | |||
|
175 | 1087 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
176 | ||||
|
177 | Check uncompressed | |||
|
178 | ================== | |||
|
179 | ||||
159 | Cannot stream clone when server.uncompressed is set |
|
180 | Cannot stream clone when server.uncompressed is set | |
160 |
|
181 | |||
161 | $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out' |
|
182 | $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=stream_out' | |
@@ -211,8 +232,8 b' Cannot stream clone when server.uncompre' | |||||
211 | adding changesets |
|
232 | adding changesets | |
212 | adding manifests |
|
233 | adding manifests | |
213 | adding file changes |
|
234 | adding file changes | |
214 |
added 3 changesets with 108 |
|
235 | added 3 changesets with 1087 changes to 1087 files | |
215 |
new changesets 96ee1d7354c4: |
|
236 | new changesets 96ee1d7354c4:42e820400e84 | |
216 |
|
237 | |||
217 | $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1" |
|
238 | $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1" | |
218 | 200 Script output follows |
|
239 | 200 Script output follows | |
@@ -278,8 +299,8 b' Cannot stream clone when server.uncompre' | |||||
278 | adding changesets |
|
299 | adding changesets | |
279 | adding manifests |
|
300 | adding manifests | |
280 | adding file changes |
|
301 | adding file changes | |
281 |
added 3 changesets with 108 |
|
302 | added 3 changesets with 1087 changes to 1087 files | |
282 |
new changesets 96ee1d7354c4: |
|
303 | new changesets 96ee1d7354c4:42e820400e84 | |
283 |
|
304 | |||
284 | $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1" |
|
305 | $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle' content-type --bodyfile body --hgproto 0.2 --requestheader "x-hgarg-1=bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps&cg=0&common=0000000000000000000000000000000000000000&heads=c17445101a72edac06facd130d14808dfbd5c7c2&stream=1" | |
285 | 200 Script output follows |
|
306 | 200 Script output follows | |
@@ -309,10 +330,10 b' Basic clone' | |||||
309 | #if stream-legacy |
|
330 | #if stream-legacy | |
310 | $ hg clone --stream -U http://localhost:$HGPORT clone1 |
|
331 | $ hg clone --stream -U http://localhost:$HGPORT clone1 | |
311 | streaming all changes |
|
332 | streaming all changes | |
312 |
108 |
|
333 | 1089 files to transfer, 101 KB of data (no-zstd !) | |
313 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) |
|
334 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) | |
314 |
108 |
|
335 | 1089 files to transfer, 98.5 KB of data (zstd !) | |
315 |
transferred 98. |
|
336 | transferred 98.5 KB in * seconds (*/sec) (glob) (zstd !) | |
316 | searching for changes |
|
337 | searching for changes | |
317 | no changes found |
|
338 | no changes found | |
318 | $ cat server/errors.txt |
|
339 | $ cat server/errors.txt | |
@@ -320,10 +341,10 b' Basic clone' | |||||
320 | #if stream-bundle2 |
|
341 | #if stream-bundle2 | |
321 | $ hg clone --stream -U http://localhost:$HGPORT clone1 |
|
342 | $ hg clone --stream -U http://localhost:$HGPORT clone1 | |
322 | streaming all changes |
|
343 | streaming all changes | |
323 |
109 |
|
344 | 1092 files to transfer, 101 KB of data (no-zstd !) | |
324 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) |
|
345 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) | |
325 |
109 |
|
346 | 1092 files to transfer, 98.6 KB of data (zstd !) | |
326 |
transferred 98. |
|
347 | transferred 98.6 KB in * seconds (* */sec) (glob) (zstd !) | |
327 |
|
348 | |||
328 | $ ls -1 clone1/.hg/cache |
|
349 | $ ls -1 clone1/.hg/cache | |
329 | branch2-base |
|
350 | branch2-base | |
@@ -348,12 +369,12 b' getbundle requests with stream=1 are unc' | |||||
348 |
|
369 | |||
349 | #if no-zstd no-rust |
|
370 | #if no-zstd no-rust | |
350 | $ f --size --hex --bytes 256 body |
|
371 | $ f --size --hex --bytes 256 body | |
351 |
body: size=118 |
|
372 | body: size=118737 | |
352 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| |
|
373 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| | |
353 | 0010: 80 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| |
|
374 | 0010: 80 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| | |
354 | 0020: 06 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 31 30 |....Dbytecount10| |
|
375 | 0020: 06 09 04 0c 44 62 79 74 65 63 6f 75 6e 74 31 30 |....Dbytecount10| | |
355 |
0030: 33 3 |
|
376 | 0030: 33 38 33 34 66 69 6c 65 63 6f 75 6e 74 31 30 39 |3834filecount109| | |
356 |
0040: 3 |
|
377 | 0040: 32 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |2requirementsdot| | |
357 | 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache| |
|
378 | 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache| | |
358 | 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%| |
|
379 | 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%| | |
359 | 0070: 32 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 |2Crevlogv1%2Cspa| |
|
380 | 0070: 32 43 72 65 76 6c 6f 67 76 31 25 32 43 73 70 61 |2Crevlogv1%2Cspa| | |
@@ -368,12 +389,12 b' getbundle requests with stream=1 are unc' | |||||
368 | #endif |
|
389 | #endif | |
369 | #if zstd no-rust |
|
390 | #if zstd no-rust | |
370 | $ f --size --hex --bytes 256 body |
|
391 | $ f --size --hex --bytes 256 body | |
371 |
body: size=115 |
|
392 | body: size=115921 | |
372 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| |
|
393 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| | |
373 | 0010: 9a 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| |
|
394 | 0010: 9a 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| | |
374 | 0020: 06 09 04 0c 5e 62 79 74 65 63 6f 75 6e 74 31 30 |....^bytecount10| |
|
395 | 0020: 06 09 04 0c 5e 62 79 74 65 63 6f 75 6e 74 31 30 |....^bytecount10| | |
375 |
0030: 30 3 |
|
396 | 0030: 30 39 39 32 66 69 6c 65 63 6f 75 6e 74 31 30 39 |0992filecount109| | |
376 |
0040: 3 |
|
397 | 0040: 32 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |2requirementsdot| | |
377 | 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache| |
|
398 | 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache| | |
378 | 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%| |
|
399 | 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%| | |
379 | 0070: 32 43 72 65 76 6c 6f 67 2d 63 6f 6d 70 72 65 73 |2Crevlog-compres| |
|
400 | 0070: 32 43 72 65 76 6c 6f 67 2d 63 6f 6d 70 72 65 73 |2Crevlog-compres| | |
@@ -388,12 +409,12 b' getbundle requests with stream=1 are unc' | |||||
388 | #endif |
|
409 | #endif | |
389 | #if zstd rust no-dirstate-v2 |
|
410 | #if zstd rust no-dirstate-v2 | |
390 | $ f --size --hex --bytes 256 body |
|
411 | $ f --size --hex --bytes 256 body | |
391 |
body: size=115 |
|
412 | body: size=115942 | |
392 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| |
|
413 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| | |
393 | 0010: af 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| |
|
414 | 0010: af 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| | |
394 | 0020: 06 09 04 0c 73 62 79 74 65 63 6f 75 6e 74 31 30 |....sbytecount10| |
|
415 | 0020: 06 09 04 0c 73 62 79 74 65 63 6f 75 6e 74 31 30 |....sbytecount10| | |
395 |
0030: 30 3 |
|
416 | 0030: 30 39 39 32 66 69 6c 65 63 6f 75 6e 74 31 30 39 |0992filecount109| | |
396 |
0040: 3 |
|
417 | 0040: 32 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |2requirementsdot| | |
397 | 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache| |
|
418 | 0050: 65 6e 63 6f 64 65 25 32 43 66 6e 63 61 63 68 65 |encode%2Cfncache| | |
398 | 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%| |
|
419 | 0060: 25 32 43 67 65 6e 65 72 61 6c 64 65 6c 74 61 25 |%2Cgeneraldelta%| | |
399 | 0070: 32 43 70 65 72 73 69 73 74 65 6e 74 2d 6e 6f 64 |2Cpersistent-nod| |
|
420 | 0070: 32 43 70 65 72 73 69 73 74 65 6e 74 2d 6e 6f 64 |2Cpersistent-nod| | |
@@ -408,7 +429,7 b' getbundle requests with stream=1 are unc' | |||||
408 | #endif |
|
429 | #endif | |
409 | #if zstd dirstate-v2 |
|
430 | #if zstd dirstate-v2 | |
410 | $ f --size --hex --bytes 256 body |
|
431 | $ f --size --hex --bytes 256 body | |
411 |
body: size=109 |
|
432 | body: size=109549 | |
412 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| |
|
433 | 0000: 04 6e 6f 6e 65 48 47 32 30 00 00 00 00 00 00 00 |.noneHG20.......| | |
413 | 0010: c0 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| |
|
434 | 0010: c0 07 53 54 52 45 41 4d 32 00 00 00 00 03 00 09 |..STREAM2.......| | |
414 | 0020: 05 09 04 0c 85 62 79 74 65 63 6f 75 6e 74 39 35 |.....bytecount95| |
|
435 | 0020: 05 09 04 0c 85 62 79 74 65 63 6f 75 6e 74 39 35 |.....bytecount95| | |
@@ -432,20 +453,20 b' getbundle requests with stream=1 are unc' | |||||
432 | #if stream-legacy |
|
453 | #if stream-legacy | |
433 | $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed |
|
454 | $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed | |
434 | streaming all changes |
|
455 | streaming all changes | |
435 |
108 |
|
456 | 1089 files to transfer, 101 KB of data (no-zstd !) | |
436 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) |
|
457 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) | |
437 |
108 |
|
458 | 1089 files to transfer, 98.5 KB of data (zstd !) | |
438 |
transferred 98. |
|
459 | transferred 98.5 KB in * seconds (*/sec) (glob) (zstd !) | |
439 | searching for changes |
|
460 | searching for changes | |
440 | no changes found |
|
461 | no changes found | |
441 | #endif |
|
462 | #endif | |
442 | #if stream-bundle2 |
|
463 | #if stream-bundle2 | |
443 | $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed |
|
464 | $ hg clone --uncompressed -U http://localhost:$HGPORT clone1-uncompressed | |
444 | streaming all changes |
|
465 | streaming all changes | |
445 |
109 |
|
466 | 1092 files to transfer, 101 KB of data (no-zstd !) | |
446 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) |
|
467 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) | |
447 |
109 |
|
468 | 1092 files to transfer, 98.6 KB of data (zstd !) | |
448 |
transferred 98. |
|
469 | transferred 98.6 KB in * seconds (* */sec) (glob) (zstd !) | |
449 | #endif |
|
470 | #endif | |
450 |
|
471 | |||
451 | Clone with background file closing enabled |
|
472 | Clone with background file closing enabled | |
@@ -457,12 +478,12 b' Clone with background file closing enabl' | |||||
457 | sending branchmap command |
|
478 | sending branchmap command | |
458 | streaming all changes |
|
479 | streaming all changes | |
459 | sending stream_out command |
|
480 | sending stream_out command | |
460 |
108 |
|
481 | 1089 files to transfer, 101 KB of data (no-zstd !) | |
461 |
108 |
|
482 | 1089 files to transfer, 98.5 KB of data (zstd !) | |
462 | starting 4 threads for background file closing |
|
483 | starting 4 threads for background file closing | |
463 | updating the branch cache |
|
484 | updating the branch cache | |
464 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) |
|
485 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) | |
465 |
transferred 98. |
|
486 | transferred 98.5 KB in * seconds (*/sec) (glob) (zstd !) | |
466 | query 1; heads |
|
487 | query 1; heads | |
467 | sending batch command |
|
488 | sending batch command | |
468 | searching for changes |
|
489 | searching for changes | |
@@ -489,15 +510,15 b' Clone with background file closing enabl' | |||||
489 | bundle2-input-bundle: with-transaction |
|
510 | bundle2-input-bundle: with-transaction | |
490 | bundle2-input-part: "stream2" (params: 3 mandatory) supported |
|
511 | bundle2-input-part: "stream2" (params: 3 mandatory) supported | |
491 | applying stream bundle |
|
512 | applying stream bundle | |
492 |
109 |
|
513 | 1092 files to transfer, 101 KB of data (no-zstd !) | |
493 |
109 |
|
514 | 1092 files to transfer, 98.6 KB of data (zstd !) | |
494 | starting 4 threads for background file closing |
|
515 | starting 4 threads for background file closing | |
495 | starting 4 threads for background file closing |
|
516 | starting 4 threads for background file closing | |
496 | updating the branch cache |
|
517 | updating the branch cache | |
497 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) |
|
518 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) | |
498 |
bundle2-input-part: total payload size 118 |
|
519 | bundle2-input-part: total payload size 118568 (no-zstd !) | |
499 |
transferred 98. |
|
520 | transferred 98.6 KB in * seconds (* */sec) (glob) (zstd !) | |
500 |
bundle2-input-part: total payload size 115 |
|
521 | bundle2-input-part: total payload size 115726 (zstd !) | |
501 | bundle2-input-part: "listkeys" (params: 1 mandatory) supported |
|
522 | bundle2-input-part: "listkeys" (params: 1 mandatory) supported | |
502 | bundle2-input-bundle: 2 parts total |
|
523 | bundle2-input-bundle: 2 parts total | |
503 | checking for updated bookmarks |
|
524 | checking for updated bookmarks | |
@@ -529,20 +550,20 b' Streaming of secrets can be overridden b' | |||||
529 | #if stream-legacy |
|
550 | #if stream-legacy | |
530 | $ hg clone --stream -U http://localhost:$HGPORT secret-allowed |
|
551 | $ hg clone --stream -U http://localhost:$HGPORT secret-allowed | |
531 | streaming all changes |
|
552 | streaming all changes | |
532 |
108 |
|
553 | 1089 files to transfer, 101 KB of data (no-zstd !) | |
533 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) |
|
554 | transferred 101 KB in * seconds (*/sec) (glob) (no-zstd !) | |
534 |
108 |
|
555 | 1089 files to transfer, 98.5 KB of data (zstd !) | |
535 |
transferred 98. |
|
556 | transferred 98.5 KB in * seconds (*/sec) (glob) (zstd !) | |
536 | searching for changes |
|
557 | searching for changes | |
537 | no changes found |
|
558 | no changes found | |
538 | #endif |
|
559 | #endif | |
539 | #if stream-bundle2 |
|
560 | #if stream-bundle2 | |
540 | $ hg clone --stream -U http://localhost:$HGPORT secret-allowed |
|
561 | $ hg clone --stream -U http://localhost:$HGPORT secret-allowed | |
541 | streaming all changes |
|
562 | streaming all changes | |
542 |
109 |
|
563 | 1092 files to transfer, 101 KB of data (no-zstd !) | |
543 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) |
|
564 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) | |
544 |
109 |
|
565 | 1092 files to transfer, 98.6 KB of data (zstd !) | |
545 |
transferred 98. |
|
566 | transferred 98.6 KB in * seconds (* */sec) (glob) (zstd !) | |
546 | #endif |
|
567 | #endif | |
547 |
|
568 | |||
548 | $ killdaemons.py |
|
569 | $ killdaemons.py | |
@@ -681,33 +702,33 b' clone it' | |||||
681 | #if stream-legacy |
|
702 | #if stream-legacy | |
682 | $ hg clone --stream http://localhost:$HGPORT with-bookmarks |
|
703 | $ hg clone --stream http://localhost:$HGPORT with-bookmarks | |
683 | streaming all changes |
|
704 | streaming all changes | |
684 |
108 |
|
705 | 1089 files to transfer, 101 KB of data (no-zstd !) | |
685 | transferred 101 KB in * seconds (*) (glob) (no-zstd !) |
|
706 | transferred 101 KB in * seconds (*) (glob) (no-zstd !) | |
686 |
108 |
|
707 | 1089 files to transfer, 98.5 KB of data (zstd !) | |
687 |
transferred 98. |
|
708 | transferred 98.5 KB in * seconds (*/sec) (glob) (zstd !) | |
688 | searching for changes |
|
709 | searching for changes | |
689 | no changes found |
|
710 | no changes found | |
690 | updating to branch default |
|
711 | updating to branch default | |
691 |
108 |
|
712 | 1087 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
692 | #endif |
|
713 | #endif | |
693 | #if stream-bundle2 |
|
714 | #if stream-bundle2 | |
694 | $ hg clone --stream http://localhost:$HGPORT with-bookmarks |
|
715 | $ hg clone --stream http://localhost:$HGPORT with-bookmarks | |
695 | streaming all changes |
|
716 | streaming all changes | |
696 |
109 |
|
717 | 1095 files to transfer, 102 KB of data (no-zstd !) | |
697 |
transferred 10 |
|
718 | transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !) | |
698 |
109 |
|
719 | 1095 files to transfer, 98.8 KB of data (zstd !) | |
699 |
transferred 98. |
|
720 | transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !) | |
700 | updating to branch default |
|
721 | updating to branch default | |
701 |
108 |
|
722 | 1087 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
702 | #endif |
|
723 | #endif | |
703 | $ hg verify -R with-bookmarks |
|
724 | $ hg verify -R with-bookmarks | |
704 | checking changesets |
|
725 | checking changesets | |
705 | checking manifests |
|
726 | checking manifests | |
706 | crosschecking files in changesets and manifests |
|
727 | crosschecking files in changesets and manifests | |
707 | checking files |
|
728 | checking files | |
708 |
checked 3 changesets with 108 |
|
729 | checked 3 changesets with 1087 changes to 1087 files | |
709 | $ hg -R with-bookmarks bookmarks |
|
730 | $ hg -R with-bookmarks bookmarks | |
710 |
some-bookmark 2: |
|
731 | some-bookmark 2:42e820400e84 | |
711 |
|
732 | |||
712 | Stream repository with phases |
|
733 | Stream repository with phases | |
713 | ----------------------------- |
|
734 | ----------------------------- | |
@@ -722,31 +743,31 b' Clone as publishing' | |||||
722 | #if stream-legacy |
|
743 | #if stream-legacy | |
723 | $ hg clone --stream http://localhost:$HGPORT phase-publish |
|
744 | $ hg clone --stream http://localhost:$HGPORT phase-publish | |
724 | streaming all changes |
|
745 | streaming all changes | |
725 |
108 |
|
746 | 1089 files to transfer, 101 KB of data (no-zstd !) | |
726 | transferred 101 KB in * seconds (*) (glob) (no-zstd !) |
|
747 | transferred 101 KB in * seconds (*) (glob) (no-zstd !) | |
727 |
108 |
|
748 | 1089 files to transfer, 98.5 KB of data (zstd !) | |
728 |
transferred 98. |
|
749 | transferred 98.5 KB in * seconds (*/sec) (glob) (zstd !) | |
729 | searching for changes |
|
750 | searching for changes | |
730 | no changes found |
|
751 | no changes found | |
731 | updating to branch default |
|
752 | updating to branch default | |
732 |
108 |
|
753 | 1087 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
733 | #endif |
|
754 | #endif | |
734 | #if stream-bundle2 |
|
755 | #if stream-bundle2 | |
735 | $ hg clone --stream http://localhost:$HGPORT phase-publish |
|
756 | $ hg clone --stream http://localhost:$HGPORT phase-publish | |
736 | streaming all changes |
|
757 | streaming all changes | |
737 |
109 |
|
758 | 1095 files to transfer, 102 KB of data (no-zstd !) | |
738 |
transferred 10 |
|
759 | transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !) | |
739 |
109 |
|
760 | 1095 files to transfer, 98.8 KB of data (zstd !) | |
740 |
transferred 98. |
|
761 | transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !) | |
741 | updating to branch default |
|
762 | updating to branch default | |
742 |
108 |
|
763 | 1087 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
743 | #endif |
|
764 | #endif | |
744 | $ hg verify -R phase-publish |
|
765 | $ hg verify -R phase-publish | |
745 | checking changesets |
|
766 | checking changesets | |
746 | checking manifests |
|
767 | checking manifests | |
747 | crosschecking files in changesets and manifests |
|
768 | crosschecking files in changesets and manifests | |
748 | checking files |
|
769 | checking files | |
749 |
checked 3 changesets with 108 |
|
770 | checked 3 changesets with 1087 changes to 1087 files | |
750 | $ hg -R phase-publish phase -r 'all()' |
|
771 | $ hg -R phase-publish phase -r 'all()' | |
751 | 0: public |
|
772 | 0: public | |
752 | 1: public |
|
773 | 1: public | |
@@ -769,14 +790,14 b' stream v1 unsuitable for non-publishing ' | |||||
769 |
|
790 | |||
770 | $ hg clone --stream http://localhost:$HGPORT phase-no-publish |
|
791 | $ hg clone --stream http://localhost:$HGPORT phase-no-publish | |
771 | streaming all changes |
|
792 | streaming all changes | |
772 |
108 |
|
793 | 1089 files to transfer, 101 KB of data (no-zstd !) | |
773 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) |
|
794 | transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !) | |
774 |
108 |
|
795 | 1089 files to transfer, 98.5 KB of data (zstd !) | |
775 |
transferred 98. |
|
796 | transferred 98.5 KB in * seconds (*/sec) (glob) (zstd !) | |
776 | searching for changes |
|
797 | searching for changes | |
777 | no changes found |
|
798 | no changes found | |
778 | updating to branch default |
|
799 | updating to branch default | |
779 |
108 |
|
800 | 1087 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
780 | $ hg -R phase-no-publish phase -r 'all()' |
|
801 | $ hg -R phase-no-publish phase -r 'all()' | |
781 | 0: public |
|
802 | 0: public | |
782 | 1: public |
|
803 | 1: public | |
@@ -785,12 +806,12 b' stream v1 unsuitable for non-publishing ' | |||||
785 | #if stream-bundle2 |
|
806 | #if stream-bundle2 | |
786 | $ hg clone --stream http://localhost:$HGPORT phase-no-publish |
|
807 | $ hg clone --stream http://localhost:$HGPORT phase-no-publish | |
787 | streaming all changes |
|
808 | streaming all changes | |
788 |
109 |
|
809 | 1096 files to transfer, 102 KB of data (no-zstd !) | |
789 |
transferred 10 |
|
810 | transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !) | |
790 |
109 |
|
811 | 1096 files to transfer, 98.8 KB of data (zstd !) | |
791 |
transferred 98. |
|
812 | transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !) | |
792 | updating to branch default |
|
813 | updating to branch default | |
793 |
108 |
|
814 | 1087 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
794 | $ hg -R phase-no-publish phase -r 'all()' |
|
815 | $ hg -R phase-no-publish phase -r 'all()' | |
795 | 0: draft |
|
816 | 0: draft | |
796 | 1: draft |
|
817 | 1: draft | |
@@ -801,7 +822,7 b' stream v1 unsuitable for non-publishing ' | |||||
801 | checking manifests |
|
822 | checking manifests | |
802 | crosschecking files in changesets and manifests |
|
823 | crosschecking files in changesets and manifests | |
803 | checking files |
|
824 | checking files | |
804 |
checked 3 changesets with 108 |
|
825 | checked 3 changesets with 1087 changes to 1087 files | |
805 |
|
826 | |||
806 | $ killdaemons.py |
|
827 | $ killdaemons.py | |
807 |
|
828 | |||
@@ -840,22 +861,22 b' Clone non-publishing with obsolescence' | |||||
840 |
|
861 | |||
841 | $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence |
|
862 | $ hg clone -U --stream http://localhost:$HGPORT with-obsolescence | |
842 | streaming all changes |
|
863 | streaming all changes | |
843 |
109 |
|
864 | 1097 files to transfer, 102 KB of data (no-zstd !) | |
844 | transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !) |
|
865 | transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !) | |
845 |
109 |
|
866 | 1097 files to transfer, 99.2 KB of data (zstd !) | |
846 |
transferred 99. |
|
867 | transferred 99.2 KB in * seconds (* */sec) (glob) (zstd !) | |
847 | $ hg -R with-obsolescence log -T '{rev}: {phase}\n' |
|
868 | $ hg -R with-obsolescence log -T '{rev}: {phase}\n' | |
848 | 2: draft |
|
869 | 2: draft | |
849 | 1: draft |
|
870 | 1: draft | |
850 | 0: draft |
|
871 | 0: draft | |
851 | $ hg debugobsolete -R with-obsolescence |
|
872 | $ hg debugobsolete -R with-obsolescence | |
852 | aa82d3f59e13f41649d8ba3324e1ac8849ba78e7 0 {7406a3463c3de22c4288b4306d199705369a285a} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} |
|
873 | e53e122156df12330d3a0b72351e3a84bfd14195 0 {42e820400e843bc479ad36068ff772a69c8affe9} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} | |
853 | $ hg verify -R with-obsolescence |
|
874 | $ hg verify -R with-obsolescence | |
854 | checking changesets |
|
875 | checking changesets | |
855 | checking manifests |
|
876 | checking manifests | |
856 | crosschecking files in changesets and manifests |
|
877 | crosschecking files in changesets and manifests | |
857 | checking files |
|
878 | checking files | |
858 |
checked 4 changesets with 108 |
|
879 | checked 4 changesets with 1088 changes to 1087 files | |
859 |
|
880 | |||
860 | $ hg clone -U --stream --config experimental.evolution=0 http://localhost:$HGPORT with-obsolescence-no-evolution |
|
881 | $ hg clone -U --stream --config experimental.evolution=0 http://localhost:$HGPORT with-obsolescence-no-evolution | |
861 | streaming all changes |
|
882 | streaming all changes |
@@ -214,6 +214,7 b' check that local configs for the cached ' | |||||
214 | ... runcommand(server, [b'-R', b'foo', b'showconfig', b'ui', b'defaults']) |
|
214 | ... runcommand(server, [b'-R', b'foo', b'showconfig', b'ui', b'defaults']) | |
215 | *** runcommand showconfig |
|
215 | *** runcommand showconfig | |
216 | bundle.mainreporoot=$TESTTMP/repo |
|
216 | bundle.mainreporoot=$TESTTMP/repo | |
|
217 | chgserver.idletimeout=60 | |||
217 | devel.all-warnings=true |
|
218 | devel.all-warnings=true | |
218 | devel.default-date=0 0 |
|
219 | devel.default-date=0 0 | |
219 | extensions.fsmonitor= (fsmonitor !) |
|
220 | extensions.fsmonitor= (fsmonitor !) |
@@ -74,6 +74,7 b' Do not show debug commands if there are ' | |||||
74 |
|
74 | |||
75 | Show debug commands if there are no other candidates |
|
75 | Show debug commands if there are no other candidates | |
76 | $ hg debugcomplete debug |
|
76 | $ hg debugcomplete debug | |
|
77 | debug-repair-issue6528 | |||
77 | debugancestor |
|
78 | debugancestor | |
78 | debugantivirusrunning |
|
79 | debugantivirusrunning | |
79 | debugapplystreamclonebundle |
|
80 | debugapplystreamclonebundle | |
@@ -266,6 +267,7 b' Show all commands + options' | |||||
266 | config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template |
|
267 | config: untrusted, exp-all-known, edit, local, source, shared, non-shared, global, template | |
267 | continue: dry-run |
|
268 | continue: dry-run | |
268 | copy: forget, after, at-rev, force, include, exclude, dry-run |
|
269 | copy: forget, after, at-rev, force, include, exclude, dry-run | |
|
270 | debug-repair-issue6528: to-report, from-report, paranoid, dry-run | |||
269 | debugancestor: |
|
271 | debugancestor: | |
270 | debugantivirusrunning: |
|
272 | debugantivirusrunning: | |
271 | debugapplystreamclonebundle: |
|
273 | debugapplystreamclonebundle: |
@@ -98,7 +98,7 b'' | |||||
98 | > EOF |
|
98 | > EOF | |
99 | $ hg buggylocking |
|
99 | $ hg buggylocking | |
100 | devel-warn: "wlock" acquired after "lock" at: $TESTTMP/buggylocking.py:* (buggylocking) (glob) |
|
100 | devel-warn: "wlock" acquired after "lock" at: $TESTTMP/buggylocking.py:* (buggylocking) (glob) | |
101 | #if no-chg |
|
101 | #if no-chg no-pyoxidizer | |
102 | $ hg buggylocking --traceback |
|
102 | $ hg buggylocking --traceback | |
103 | devel-warn: "wlock" acquired after "lock" at: |
|
103 | devel-warn: "wlock" acquired after "lock" at: | |
104 | */hg:* in <module> (glob) (?) |
|
104 | */hg:* in <module> (glob) (?) | |
@@ -115,7 +115,8 b'' | |||||
115 | */mercurial/dispatch.py:* in <lambda> (glob) |
|
115 | */mercurial/dispatch.py:* in <lambda> (glob) | |
116 | */mercurial/util.py:* in check (glob) |
|
116 | */mercurial/util.py:* in check (glob) | |
117 | $TESTTMP/buggylocking.py:* in buggylocking (glob) |
|
117 | $TESTTMP/buggylocking.py:* in buggylocking (glob) | |
118 | #else |
|
118 | #endif | |
|
119 | #if chg no-pyoxidizer | |||
119 | $ hg buggylocking --traceback |
|
120 | $ hg buggylocking --traceback | |
120 | devel-warn: "wlock" acquired after "lock" at: |
|
121 | devel-warn: "wlock" acquired after "lock" at: | |
121 | */hg:* in <module> (glob) (?) |
|
122 | */hg:* in <module> (glob) (?) | |
@@ -156,6 +157,24 b'' | |||||
156 | */mercurial/util.py:* in check (glob) |
|
157 | */mercurial/util.py:* in check (glob) | |
157 | $TESTTMP/buggylocking.py:* in buggylocking (glob) |
|
158 | $TESTTMP/buggylocking.py:* in buggylocking (glob) | |
158 | #endif |
|
159 | #endif | |
|
160 | #if pyoxidizer | |||
|
161 | $ hg buggylocking --traceback | |||
|
162 | devel-warn: "wlock" acquired after "lock" at: | |||
|
163 | <string>:* (glob) | |||
|
164 | mercurial.dispatch:* in run (glob) | |||
|
165 | mercurial.dispatch:* in dispatch (glob) | |||
|
166 | mercurial.dispatch:* in _rundispatch (glob) | |||
|
167 | mercurial.dispatch:* in _runcatch (glob) | |||
|
168 | mercurial.dispatch:* in _callcatch (glob) | |||
|
169 | mercurial.scmutil:* in callcatch (glob) | |||
|
170 | mercurial.dispatch:* in _runcatchfunc (glob) | |||
|
171 | mercurial.dispatch:* in _dispatch (glob) | |||
|
172 | mercurial.dispatch:* in runcommand (glob) | |||
|
173 | mercurial.dispatch:* in _runcommand (glob) | |||
|
174 | mercurial.dispatch:* in <lambda> (glob) | |||
|
175 | mercurial.util:* in check (glob) | |||
|
176 | $TESTTMP/buggylocking.py:* in buggylocking (glob) | |||
|
177 | #endif | |||
159 | $ hg properlocking |
|
178 | $ hg properlocking | |
160 | $ hg nowaitlocking |
|
179 | $ hg nowaitlocking | |
161 |
|
180 | |||
@@ -180,7 +199,7 b' Stripping from a transaction' | |||||
180 | devel-warn: foorbar is deprecated, go shopping |
|
199 | devel-warn: foorbar is deprecated, go shopping | |
181 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: $TESTTMP/buggylocking.py:* (oldanddeprecated) (glob) |
|
200 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: $TESTTMP/buggylocking.py:* (oldanddeprecated) (glob) | |
182 |
|
201 | |||
183 | #if no-chg |
|
202 | #if no-chg no-pyoxidizer | |
184 | $ hg oldanddeprecated --traceback |
|
203 | $ hg oldanddeprecated --traceback | |
185 | devel-warn: foorbar is deprecated, go shopping |
|
204 | devel-warn: foorbar is deprecated, go shopping | |
186 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: |
|
205 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: | |
@@ -198,7 +217,8 b' Stripping from a transaction' | |||||
198 | */mercurial/dispatch.py:* in <lambda> (glob) |
|
217 | */mercurial/dispatch.py:* in <lambda> (glob) | |
199 | */mercurial/util.py:* in check (glob) |
|
218 | */mercurial/util.py:* in check (glob) | |
200 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) |
|
219 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) | |
201 | #else |
|
220 | #endif | |
|
221 | #if chg no-pyoxidizer | |||
202 | $ hg oldanddeprecated --traceback |
|
222 | $ hg oldanddeprecated --traceback | |
203 | devel-warn: foorbar is deprecated, go shopping |
|
223 | devel-warn: foorbar is deprecated, go shopping | |
204 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: |
|
224 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: | |
@@ -240,8 +260,27 b' Stripping from a transaction' | |||||
240 | */mercurial/util.py:* in check (glob) |
|
260 | */mercurial/util.py:* in check (glob) | |
241 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) |
|
261 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) | |
242 | #endif |
|
262 | #endif | |
|
263 | #if pyoxidizer | |||
|
264 | $ hg oldanddeprecated --traceback | |||
|
265 | devel-warn: foorbar is deprecated, go shopping | |||
|
266 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: | |||
|
267 | <string>:* (glob) | |||
|
268 | mercurial.dispatch:* in run (glob) | |||
|
269 | mercurial.dispatch:* in dispatch (glob) | |||
|
270 | mercurial.dispatch:* in _rundispatch (glob) | |||
|
271 | mercurial.dispatch:* in _runcatch (glob) | |||
|
272 | mercurial.dispatch:* in _callcatch (glob) | |||
|
273 | mercurial.scmutil:* in callcatch (glob) | |||
|
274 | mercurial.dispatch:* in _runcatchfunc (glob) | |||
|
275 | mercurial.dispatch:* in _dispatch (glob) | |||
|
276 | mercurial.dispatch:* in runcommand (glob) | |||
|
277 | mercurial.dispatch:* in _runcommand (glob) | |||
|
278 | mercurial.dispatch:* in <lambda> (glob) | |||
|
279 | mercurial.util:* in check (glob) | |||
|
280 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) | |||
|
281 | #endif | |||
243 |
|
282 | |||
244 | #if no-chg |
|
283 | #if no-chg no-pyoxidizer | |
245 | $ hg blackbox -l 7 |
|
284 | $ hg blackbox -l 7 | |
246 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated |
|
285 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated | |
247 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> devel-warn: foorbar is deprecated, go shopping |
|
286 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> devel-warn: foorbar is deprecated, go shopping | |
@@ -266,7 +305,8 b' Stripping from a transaction' | |||||
266 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) |
|
305 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) | |
267 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated --traceback exited 0 after * seconds (glob) |
|
306 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated --traceback exited 0 after * seconds (glob) | |
268 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> blackbox -l 7 |
|
307 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> blackbox -l 7 | |
269 | #else |
|
308 | #endif | |
|
309 | #if chg no-pyoxidizer | |||
270 | $ hg blackbox -l 7 |
|
310 | $ hg blackbox -l 7 | |
271 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated |
|
311 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated | |
272 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> devel-warn: foorbar is deprecated, go shopping |
|
312 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> devel-warn: foorbar is deprecated, go shopping | |
@@ -315,6 +355,32 b' Stripping from a transaction' | |||||
315 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated --traceback exited 0 after * seconds (glob) |
|
355 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated --traceback exited 0 after * seconds (glob) | |
316 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> blackbox -l 7 |
|
356 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> blackbox -l 7 | |
317 | #endif |
|
357 | #endif | |
|
358 | #if pyoxidizer | |||
|
359 | $ hg blackbox -l 7 | |||
|
360 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated | |||
|
361 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> devel-warn: foorbar is deprecated, go shopping | |||
|
362 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: $TESTTMP/buggylocking.py:* (oldanddeprecated) (glob) | |||
|
363 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated exited 0 after * seconds (glob) | |||
|
364 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated --traceback | |||
|
365 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> devel-warn: foorbar is deprecated, go shopping | |||
|
366 | (compatibility will be dropped after Mercurial-42.1337, update your code.) at: | |||
|
367 | <string>:* in <module> (glob) | |||
|
368 | mercurial.dispatch:* in run (glob) | |||
|
369 | mercurial.dispatch:* in dispatch (glob) | |||
|
370 | mercurial.dispatch:* in _rundispatch (glob) | |||
|
371 | mercurial.dispatch:* in _runcatch (glob) | |||
|
372 | mercurial.dispatch:* in _callcatch (glob) | |||
|
373 | mercurial.scmutil* in callcatch (glob) | |||
|
374 | mercurial.dispatch:* in _runcatchfunc (glob) | |||
|
375 | mercurial.dispatch:* in _dispatch (glob) | |||
|
376 | mercurial.dispatch:* in runcommand (glob) | |||
|
377 | mercurial.dispatch:* in _runcommand (glob) | |||
|
378 | mercurial.dispatch:* in <lambda> (glob) | |||
|
379 | mercurial.util:* in check (glob) | |||
|
380 | $TESTTMP/buggylocking.py:* in oldanddeprecated (glob) | |||
|
381 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> oldanddeprecated --traceback exited 0 after * seconds (glob) | |||
|
382 | 1970/01/01 00:00:00 bob @cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b (5000)> blackbox -l 7 | |||
|
383 | #endif | |||
318 |
|
384 | |||
319 | Test programming error failure: |
|
385 | Test programming error failure: | |
320 |
|
386 | |||
@@ -389,8 +455,10 b' Test warning on config option access and' | |||||
389 | > EOF |
|
455 | > EOF | |
390 |
|
456 | |||
391 | $ hg --config "extensions.buggyconfig=${TESTTMP}/buggyconfig.py" buggyconfig |
|
457 | $ hg --config "extensions.buggyconfig=${TESTTMP}/buggyconfig.py" buggyconfig | |
392 | devel-warn: extension 'buggyconfig' overwrite config item 'ui.interactive' at: */mercurial/extensions.py:* (_loadextra) (glob) |
|
458 | devel-warn: extension 'buggyconfig' overwrite config item 'ui.interactive' at: */mercurial/extensions.py:* (_loadextra) (glob) (no-pyoxidizer !) | |
393 | devel-warn: extension 'buggyconfig' overwrite config item 'ui.quiet' at: */mercurial/extensions.py:* (_loadextra) (glob) |
|
459 | devel-warn: extension 'buggyconfig' overwrite config item 'ui.quiet' at: */mercurial/extensions.py:* (_loadextra) (glob) (no-pyoxidizer !) | |
|
460 | devel-warn: extension 'buggyconfig' overwrite config item 'ui.interactive' at: mercurial.extensions:* (_loadextra) (glob) (pyoxidizer !) | |||
|
461 | devel-warn: extension 'buggyconfig' overwrite config item 'ui.quiet' at: mercurial.extensions:* (_loadextra) (glob) (pyoxidizer !) | |||
394 | devel-warn: specifying a mismatched default value for a registered config item: 'ui.quiet' 'True' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob) |
|
462 | devel-warn: specifying a mismatched default value for a registered config item: 'ui.quiet' 'True' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob) | |
395 | devel-warn: specifying a mismatched default value for a registered config item: 'ui.interactive' 'False' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob) |
|
463 | devel-warn: specifying a mismatched default value for a registered config item: 'ui.interactive' 'False' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob) | |
396 | devel-warn: specifying a mismatched default value for a registered config item: 'test.some' 'bar' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob) |
|
464 | devel-warn: specifying a mismatched default value for a registered config item: 'test.some' 'bar' at: $TESTTMP/buggyconfig.py:* (cmdbuggyconfig) (glob) |
@@ -668,7 +668,8 b" Make sure a broken uisetup doesn't globa" | |||||
668 | Even though the extension fails during uisetup, hg is still basically usable: |
|
668 | Even though the extension fails during uisetup, hg is still basically usable: | |
669 | $ hg --config extensions.baduisetup=$TESTTMP/baduisetup.py version |
|
669 | $ hg --config extensions.baduisetup=$TESTTMP/baduisetup.py version | |
670 | Traceback (most recent call last): |
|
670 | Traceback (most recent call last): | |
671 | File "*/mercurial/extensions.py", line *, in _runuisetup (glob) |
|
671 | File "*/mercurial/extensions.py", line *, in _runuisetup (glob) (no-pyoxidizer !) | |
|
672 | File "mercurial.extensions", line *, in _runuisetup (glob) (pyoxidizer !) | |||
672 | uisetup(ui) |
|
673 | uisetup(ui) | |
673 | File "$TESTTMP/baduisetup.py", line 2, in uisetup |
|
674 | File "$TESTTMP/baduisetup.py", line 2, in uisetup | |
674 | 1 / 0 |
|
675 | 1 / 0 | |
@@ -1377,6 +1378,18 b' Disabled extensions:' | |||||
1377 | (use 'hg help extensions' for information on enabling extensions) |
|
1378 | (use 'hg help extensions' for information on enabling extensions) | |
1378 |
|
1379 | |||
1379 |
|
1380 | |||
|
1381 | Help can find unimported extensions | |||
|
1382 | ----------------------------------- | |||
|
1383 | ||||
|
1384 | XXX-PYOXIDIZER since the frozen binary does not have source directory tree, | |||
|
1385 | this make the checking for actual file under `hgext` a bit complicated. In | |||
|
1386 | addition these tests do some strange dance to ensure some other module are the | |||
|
1387 | first in `sys.path` (since the current install path is always in front | |||
|
1388 | otherwise) that are fragile and that does not match reality in the field. So | |||
|
1389 | for now we disable this test untill a deeper rework of that logic is done. | |||
|
1390 | ||||
|
1391 | #if no-pyoxidizer | |||
|
1392 | ||||
1380 | Broken disabled extension and command: |
|
1393 | Broken disabled extension and command: | |
1381 |
|
1394 | |||
1382 | $ mkdir hgext |
|
1395 | $ mkdir hgext | |
@@ -1412,6 +1425,10 b' Broken disabled extension and command:' | |||||
1412 | (try 'hg help --keyword foo') |
|
1425 | (try 'hg help --keyword foo') | |
1413 | [255] |
|
1426 | [255] | |
1414 |
|
1427 | |||
|
1428 | #endif | |||
|
1429 | ||||
|
1430 | --- | |||
|
1431 | ||||
1415 | $ cat > throw.py <<EOF |
|
1432 | $ cat > throw.py <<EOF | |
1416 | > from mercurial import commands, registrar, util |
|
1433 | > from mercurial import commands, registrar, util | |
1417 | > cmdtable = {} |
|
1434 | > cmdtable = {} |
@@ -3,6 +3,7 b' approximates the behavior of code format' | |||||
3 |
|
3 | |||
4 | $ UPPERCASEPY="$TESTTMP/uppercase.py" |
|
4 | $ UPPERCASEPY="$TESTTMP/uppercase.py" | |
5 | $ cat > $UPPERCASEPY <<EOF |
|
5 | $ cat > $UPPERCASEPY <<EOF | |
|
6 | > import re | |||
6 | > import sys |
|
7 | > import sys | |
7 | > from mercurial.utils.procutil import setbinary |
|
8 | > from mercurial.utils.procutil import setbinary | |
8 | > setbinary(sys.stdin) |
|
9 | > setbinary(sys.stdin) | |
@@ -10,16 +11,18 b' approximates the behavior of code format' | |||||
10 | > stdin = getattr(sys.stdin, 'buffer', sys.stdin) |
|
11 | > stdin = getattr(sys.stdin, 'buffer', sys.stdin) | |
11 | > stdout = getattr(sys.stdout, 'buffer', sys.stdout) |
|
12 | > stdout = getattr(sys.stdout, 'buffer', sys.stdout) | |
12 | > lines = set() |
|
13 | > lines = set() | |
|
14 | > def format(text): | |||
|
15 | > return re.sub(b' +', b' ', text.upper()) | |||
13 | > for arg in sys.argv[1:]: |
|
16 | > for arg in sys.argv[1:]: | |
14 | > if arg == 'all': |
|
17 | > if arg == 'all': | |
15 |
> stdout.write(stdin.read() |
|
18 | > stdout.write(format(stdin.read())) | |
16 | > sys.exit(0) |
|
19 | > sys.exit(0) | |
17 | > else: |
|
20 | > else: | |
18 | > first, last = arg.split('-') |
|
21 | > first, last = arg.split('-') | |
19 | > lines.update(range(int(first), int(last) + 1)) |
|
22 | > lines.update(range(int(first), int(last) + 1)) | |
20 | > for i, line in enumerate(stdin.readlines()): |
|
23 | > for i, line in enumerate(stdin.readlines()): | |
21 | > if i + 1 in lines: |
|
24 | > if i + 1 in lines: | |
22 |
> stdout.write(line |
|
25 | > stdout.write(format(line)) | |
23 | > else: |
|
26 | > else: | |
24 | > stdout.write(line) |
|
27 | > stdout.write(line) | |
25 | > EOF |
|
28 | > EOF | |
@@ -354,6 +357,23 b' Fixing the working directory should stil' | |||||
354 |
|
357 | |||
355 | $ cd .. |
|
358 | $ cd .. | |
356 |
|
359 | |||
|
360 | Test that the working copy is reported clean if formatting of the parent makes | |||
|
361 | it clean. | |||
|
362 | $ hg init wc-already-formatted | |||
|
363 | $ cd wc-already-formatted | |||
|
364 | ||||
|
365 | $ printf "hello world\n" > hello.whole | |||
|
366 | $ hg commit -Am initial | |||
|
367 | adding hello.whole | |||
|
368 | $ hg fix -w * | |||
|
369 | $ hg st | |||
|
370 | M hello.whole | |||
|
371 | $ hg fix -s . * | |||
|
372 | $ hg st | |||
|
373 | $ hg diff | |||
|
374 | ||||
|
375 | $ cd .. | |||
|
376 | ||||
357 | Test the effect of fixing the working directory for each possible status, with |
|
377 | Test the effect of fixing the working directory for each possible status, with | |
358 | and without providing explicit file arguments. |
|
378 | and without providing explicit file arguments. | |
359 |
|
379 |
@@ -201,14 +201,17 b' Ensure the data got to the server OK' | |||||
201 | > EOF |
|
201 | > EOF | |
202 | $ hg debugrebuilddirstate |
|
202 | $ hg debugrebuilddirstate | |
203 | Traceback (most recent call last): |
|
203 | Traceback (most recent call last): | |
204 | File "*/mercurial/extensions.py", line *, in _runextsetup (glob) |
|
204 | File "*/mercurial/extensions.py", line *, in _runextsetup (glob) (no-pyoxidizer !) | |
|
205 | File "mercurial.extensions", line *, in _runextsetup (glob) (pyoxidizer !) | |||
205 | extsetup(ui) |
|
206 | extsetup(ui) | |
206 | File "*/tests/flagprocessorext.py", line *, in extsetup (glob) |
|
207 | File "*/tests/flagprocessorext.py", line *, in extsetup (glob) | |
207 | flagutil.addflagprocessor( (py38 !) |
|
208 | flagutil.addflagprocessor( (py38 !) | |
208 | validatehash, (no-py38 !) |
|
209 | validatehash, (no-py38 !) | |
209 | File "*/mercurial/revlogutils/flagutil.py", line *, in addflagprocessor (glob) |
|
210 | File "*/mercurial/revlogutils/flagutil.py", line *, in addflagprocessor (glob) (no-pyoxidizer !) | |
|
211 | File "mercurial.revlogutils.flagutil", line *, in addflagprocessor (glob) (pyoxidizer !) | |||
210 | insertflagprocessor(flag, processor, flagprocessors) |
|
212 | insertflagprocessor(flag, processor, flagprocessors) | |
211 | File "*/mercurial/revlogutils/flagutil.py", line *, in insertflagprocessor (glob) |
|
213 | File "*/mercurial/revlogutils/flagutil.py", line *, in insertflagprocessor (glob) (no-pyoxidizer !) | |
|
214 | File "mercurial.revlogutils.flagutil", line *, in insertflagprocessor (glob) (pyoxidizer !) | |||
212 | raise error.Abort(msg) |
|
215 | raise error.Abort(msg) | |
213 | mercurial.error.Abort: cannot register multiple processors on flag '0x8'. (py3 !) |
|
216 | mercurial.error.Abort: cannot register multiple processors on flag '0x8'. (py3 !) | |
214 | Abort: cannot register multiple processors on flag '0x8'. (no-py3 !) |
|
217 | Abort: cannot register multiple processors on flag '0x8'. (no-py3 !) |
@@ -975,6 +975,9 b' Test list of internal help commands' | |||||
975 | $ hg help debug |
|
975 | $ hg help debug | |
976 | debug commands (internal and unsupported): |
|
976 | debug commands (internal and unsupported): | |
977 |
|
977 | |||
|
978 | debug-repair-issue6528 | |||
|
979 | find affected revisions and repair them. See issue6528 for more | |||
|
980 | details. | |||
978 | debugancestor |
|
981 | debugancestor | |
979 | find the ancestor revision of two revisions in a given index |
|
982 | find the ancestor revision of two revisions in a given index | |
980 | debugantivirusrunning |
|
983 | debugantivirusrunning |
@@ -303,5 +303,16 b' Check that zeroconf respect HGRCSKIPREPO' | |||||
303 | $ hg paths --config extensions.zeroconf= |
|
303 | $ hg paths --config extensions.zeroconf= | |
304 | config error at $TESTTMP/.hg/hgrc:3: [broken |
|
304 | config error at $TESTTMP/.hg/hgrc:3: [broken | |
305 | [255] |
|
305 | [255] | |
|
306 | ||||
|
307 | XXX-PYOXIDIZER Pyoxidizer build have trouble with zeroconf for unclear reason, | |||
|
308 | we accept the bad output for now as this is the last thing in the way of | |||
|
309 | testing the pyoxidizer build. | |||
|
310 | ||||
|
311 | #if no-pyoxidizer | |||
306 | $ HGRCSKIPREPO=1 hg paths --config extensions.zeroconf= |
|
312 | $ HGRCSKIPREPO=1 hg paths --config extensions.zeroconf= | |
307 | foo = $TESTTMP/bar |
|
313 | foo = $TESTTMP/bar | |
|
314 | #else | |||
|
315 | $ HGRCSKIPREPO=1 hg paths --config extensions.zeroconf= | |||
|
316 | abort: An invalid argument was supplied (known-bad-output !) | |||
|
317 | [255] | |||
|
318 | #endif |
@@ -5,7 +5,8 b' hg debuginstall' | |||||
5 | checking Python implementation (*) (glob) |
|
5 | checking Python implementation (*) (glob) | |
6 | checking Python version (2.*) (glob) (no-py3 !) |
|
6 | checking Python version (2.*) (glob) (no-py3 !) | |
7 | checking Python version (3.*) (glob) (py3 !) |
|
7 | checking Python version (3.*) (glob) (py3 !) | |
8 | checking Python lib (.*[Ll]ib.*)... (re) |
|
8 | checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !) | |
|
9 | checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !) | |||
9 | checking Python security support (*) (glob) |
|
10 | checking Python security support (*) (glob) | |
10 | TLS 1.2 not supported by Python install; network connections lack modern security (?) |
|
11 | TLS 1.2 not supported by Python install; network connections lack modern security (?) | |
11 | SNI not supported by Python install; may have connectivity issues with some servers (?) |
|
12 | SNI not supported by Python install; may have connectivity issues with some servers (?) | |
@@ -18,8 +19,10 b' hg debuginstall' | |||||
18 | checking available compression engines (*zlib*) (glob) |
|
19 | checking available compression engines (*zlib*) (glob) | |
19 | checking available compression engines for wire protocol (*zlib*) (glob) |
|
20 | checking available compression engines for wire protocol (*zlib*) (glob) | |
20 | checking "re2" regexp engine \((available|missing)\) (re) |
|
21 | checking "re2" regexp engine \((available|missing)\) (re) | |
21 | checking templates (*mercurial?templates)... (glob) |
|
22 | checking templates (*mercurial?templates)... (glob) (no-pyoxidizer !) | |
22 | checking default template (*mercurial?templates?map-cmdline.default) (glob) |
|
23 | checking templates (*app?templates)... (glob) (pyoxidizer !) | |
|
24 | checking default template (*mercurial?templates?map-cmdline.default) (glob) (no-pyoxidizer !) | |||
|
25 | checking default template (*app?templates?map-cmdline.default) (glob) (pyoxidizer !) | |||
23 | checking commit editor... (*) (glob) |
|
26 | checking commit editor... (*) (glob) | |
24 | checking username (test) |
|
27 | checking username (test) | |
25 | no problems detected |
|
28 | no problems detected | |
@@ -31,7 +34,8 b' hg debuginstall JSON' | |||||
31 | "compengines": ["bz2", "bz2truncated", "none", "zlib"*], (glob) |
|
34 | "compengines": ["bz2", "bz2truncated", "none", "zlib"*], (glob) | |
32 | "compenginesavail": ["bz2", "bz2truncated", "none", "zlib"*], (glob) |
|
35 | "compenginesavail": ["bz2", "bz2truncated", "none", "zlib"*], (glob) | |
33 | "compenginesserver": [*"zlib"*], (glob) |
|
36 | "compenginesserver": [*"zlib"*], (glob) | |
34 | "defaulttemplate": "*mercurial?templates?map-cmdline.default", (glob) |
|
37 | "defaulttemplate": "*mercurial?templates?map-cmdline.default", (glob) (no-pyoxidizer !) | |
|
38 | "defaulttemplate": "*app?templates?map-cmdline.default", (glob) (pyoxidizer !) | |||
35 | "defaulttemplateerror": null, |
|
39 | "defaulttemplateerror": null, | |
36 | "defaulttemplatenotfound": "default", |
|
40 | "defaulttemplatenotfound": "default", | |
37 | "editor": "*", (glob) |
|
41 | "editor": "*", (glob) | |
@@ -50,7 +54,8 b' hg debuginstall JSON' | |||||
50 | "pythonsecurity": [*], (glob) |
|
54 | "pythonsecurity": [*], (glob) | |
51 | "pythonver": "*.*.*", (glob) |
|
55 | "pythonver": "*.*.*", (glob) | |
52 | "re2": (true|false), (re) |
|
56 | "re2": (true|false), (re) | |
53 | "templatedirs": "*mercurial?templates", (glob) |
|
57 | "templatedirs": "*mercurial?templates", (glob) (no-pyoxidizer !) | |
|
58 | "templatedirs": "*app?templates", (glob) (pyoxidizer !) | |||
54 | "username": "test", |
|
59 | "username": "test", | |
55 | "usernameerror": null, |
|
60 | "usernameerror": null, | |
56 | "vinotfound": false |
|
61 | "vinotfound": false | |
@@ -64,7 +69,8 b' hg debuginstall with no username' | |||||
64 | checking Python implementation (*) (glob) |
|
69 | checking Python implementation (*) (glob) | |
65 | checking Python version (2.*) (glob) (no-py3 !) |
|
70 | checking Python version (2.*) (glob) (no-py3 !) | |
66 | checking Python version (3.*) (glob) (py3 !) |
|
71 | checking Python version (3.*) (glob) (py3 !) | |
67 | checking Python lib (.*[Ll]ib.*)... (re) |
|
72 | checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !) | |
|
73 | checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !) | |||
68 | checking Python security support (*) (glob) |
|
74 | checking Python security support (*) (glob) | |
69 | TLS 1.2 not supported by Python install; network connections lack modern security (?) |
|
75 | TLS 1.2 not supported by Python install; network connections lack modern security (?) | |
70 | SNI not supported by Python install; may have connectivity issues with some servers (?) |
|
76 | SNI not supported by Python install; may have connectivity issues with some servers (?) | |
@@ -77,8 +83,10 b' hg debuginstall with no username' | |||||
77 | checking available compression engines (*zlib*) (glob) |
|
83 | checking available compression engines (*zlib*) (glob) | |
78 | checking available compression engines for wire protocol (*zlib*) (glob) |
|
84 | checking available compression engines for wire protocol (*zlib*) (glob) | |
79 | checking "re2" regexp engine \((available|missing)\) (re) |
|
85 | checking "re2" regexp engine \((available|missing)\) (re) | |
80 | checking templates (*mercurial?templates)... (glob) |
|
86 | checking templates (*mercurial?templates)... (glob) (no-pyoxidizer !) | |
81 | checking default template (*mercurial?templates?map-cmdline.default) (glob) |
|
87 | checking templates (*app?templates)... (glob) (pyoxidizer !) | |
|
88 | checking default template (*mercurial?templates?map-cmdline.default) (glob) (no-pyoxidizer !) | |||
|
89 | checking default template (*app?templates?map-cmdline.default) (glob) (pyoxidizer !) | |||
82 | checking commit editor... (*) (glob) |
|
90 | checking commit editor... (*) (glob) | |
83 | checking username... |
|
91 | checking username... | |
84 | no username supplied |
|
92 | no username supplied | |
@@ -111,7 +119,8 b' path variables are expanded (~ is the sa' | |||||
111 | checking Python implementation (*) (glob) |
|
119 | checking Python implementation (*) (glob) | |
112 | checking Python version (2.*) (glob) (no-py3 !) |
|
120 | checking Python version (2.*) (glob) (no-py3 !) | |
113 | checking Python version (3.*) (glob) (py3 !) |
|
121 | checking Python version (3.*) (glob) (py3 !) | |
114 | checking Python lib (.*[Ll]ib.*)... (re) |
|
122 | checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !) | |
|
123 | checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !) | |||
115 | checking Python security support (*) (glob) |
|
124 | checking Python security support (*) (glob) | |
116 | TLS 1.2 not supported by Python install; network connections lack modern security (?) |
|
125 | TLS 1.2 not supported by Python install; network connections lack modern security (?) | |
117 | SNI not supported by Python install; may have connectivity issues with some servers (?) |
|
126 | SNI not supported by Python install; may have connectivity issues with some servers (?) | |
@@ -124,8 +133,10 b' path variables are expanded (~ is the sa' | |||||
124 | checking available compression engines (*zlib*) (glob) |
|
133 | checking available compression engines (*zlib*) (glob) | |
125 | checking available compression engines for wire protocol (*zlib*) (glob) |
|
134 | checking available compression engines for wire protocol (*zlib*) (glob) | |
126 | checking "re2" regexp engine \((available|missing)\) (re) |
|
135 | checking "re2" regexp engine \((available|missing)\) (re) | |
127 | checking templates (*mercurial?templates)... (glob) |
|
136 | checking templates (*mercurial?templates)... (glob) (no-pyoxidizer !) | |
128 | checking default template (*mercurial?templates?map-cmdline.default) (glob) |
|
137 | checking templates (*app?templates)... (glob) (pyoxidizer !) | |
|
138 | checking default template (*mercurial?templates?map-cmdline.default) (glob) (no-pyoxidizer !) | |||
|
139 | checking default template (*app?templates?map-cmdline.default) (glob) (pyoxidizer !) | |||
129 | checking commit editor... ($TESTTMP/tools/testeditor.exe) |
|
140 | checking commit editor... ($TESTTMP/tools/testeditor.exe) | |
130 | checking username (test) |
|
141 | checking username (test) | |
131 | no problems detected |
|
142 | no problems detected | |
@@ -138,7 +149,8 b' not found (this is intentionally using b' | |||||
138 | checking Python implementation (*) (glob) |
|
149 | checking Python implementation (*) (glob) | |
139 | checking Python version (2.*) (glob) (no-py3 !) |
|
150 | checking Python version (2.*) (glob) (no-py3 !) | |
140 | checking Python version (3.*) (glob) (py3 !) |
|
151 | checking Python version (3.*) (glob) (py3 !) | |
141 | checking Python lib (.*[Ll]ib.*)... (re) |
|
152 | checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !) | |
|
153 | checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !) | |||
142 | checking Python security support (*) (glob) |
|
154 | checking Python security support (*) (glob) | |
143 | TLS 1.2 not supported by Python install; network connections lack modern security (?) |
|
155 | TLS 1.2 not supported by Python install; network connections lack modern security (?) | |
144 | SNI not supported by Python install; may have connectivity issues with some servers (?) |
|
156 | SNI not supported by Python install; may have connectivity issues with some servers (?) | |
@@ -151,8 +163,10 b' not found (this is intentionally using b' | |||||
151 | checking available compression engines (*zlib*) (glob) |
|
163 | checking available compression engines (*zlib*) (glob) | |
152 | checking available compression engines for wire protocol (*zlib*) (glob) |
|
164 | checking available compression engines for wire protocol (*zlib*) (glob) | |
153 | checking "re2" regexp engine \((available|missing)\) (re) |
|
165 | checking "re2" regexp engine \((available|missing)\) (re) | |
154 | checking templates (*mercurial?templates)... (glob) |
|
166 | checking templates (*mercurial?templates)... (glob) (no-pyoxidizer !) | |
155 | checking default template (*mercurial?templates?map-cmdline.default) (glob) |
|
167 | checking templates (*app?templates)... (glob) (pyoxidizer !) | |
|
168 | checking default template (*mercurial?templates?map-cmdline.default) (glob) (no-pyoxidizer !) | |||
|
169 | checking default template (*app?templates?map-cmdline.default) (glob) (pyoxidizer !) | |||
156 | checking commit editor... (c:\foo\bar\baz.exe) (windows !) |
|
170 | checking commit editor... (c:\foo\bar\baz.exe) (windows !) | |
157 | Can't find editor 'c:\foo\bar\baz.exe' in PATH (windows !) |
|
171 | Can't find editor 'c:\foo\bar\baz.exe' in PATH (windows !) | |
158 | checking commit editor... (c:foobarbaz.exe) (no-windows !) |
|
172 | checking commit editor... (c:foobarbaz.exe) (no-windows !) | |
@@ -184,7 +198,7 b' On Python 2, we use the 3rd party virtua' | |||||
184 | $ cd $TESTTMP |
|
198 | $ cd $TESTTMP | |
185 | $ unset PYTHONPATH |
|
199 | $ unset PYTHONPATH | |
186 |
|
200 | |||
187 | #if py3 ensurepip network-io |
|
201 | #if py3 ensurepip network-io no-pyoxidizer | |
188 | $ "$PYTHON" -m venv installenv >> pip.log |
|
202 | $ "$PYTHON" -m venv installenv >> pip.log | |
189 |
|
203 | |||
190 | Hack: Debian does something a bit different in ensurepip.bootstrap. This makes |
|
204 | Hack: Debian does something a bit different in ensurepip.bootstrap. This makes | |
@@ -224,7 +238,7 b" since it's bin on most platforms but Scr" | |||||
224 | no problems detected |
|
238 | no problems detected | |
225 | #endif |
|
239 | #endif | |
226 |
|
240 | |||
227 | #if virtualenv no-py3 network-io |
|
241 | #if virtualenv no-py3 network-io no-pyoxidizer | |
228 |
|
242 | |||
229 | Note: --no-site-packages is the default for all versions enabled by hghave |
|
243 | Note: --no-site-packages is the default for all versions enabled by hghave | |
230 |
|
244 |
@@ -179,7 +179,7 b' has been emitted, just in a different or' | |||||
179 |
|
179 | |||
180 |
|
180 | |||
181 | $ hg log -T '{if(ellipsis,"...")}{node|short} {p1node|short} {p2node|short} {desc}\n' | sort |
|
181 | $ hg log -T '{if(ellipsis,"...")}{node|short} {p1node|short} {p2node|short} {desc}\n' | sort | |
182 |
...2a20009de83e 3ac1f5779de3 |
|
182 | ...2a20009de83e 000000000000 3ac1f5779de3 outside 10 | |
183 | ...3ac1f5779de3 bb96a08b062a 465567bdfb2d merge a/b/c/d 9 |
|
183 | ...3ac1f5779de3 bb96a08b062a 465567bdfb2d merge a/b/c/d 9 | |
184 | ...8d874d57adea 7ef88b4dd4fa 000000000000 outside 12 |
|
184 | ...8d874d57adea 7ef88b4dd4fa 000000000000 outside 12 | |
185 | ...b844052e7b3b 000000000000 000000000000 outside 2c |
|
185 | ...b844052e7b3b 000000000000 000000000000 outside 2c |
@@ -5,85 +5,90 b' XXX-RHG this test hangs if `hg` is reall' | |||||
5 | buggy. This need to be resolved sooner than later. |
|
5 | buggy. This need to be resolved sooner than later. | |
6 |
|
6 | |||
7 | Dummy extension simulating unsafe long running command |
|
7 | Dummy extension simulating unsafe long running command | |
8 | $ cat > sleepext.py <<EOF |
|
8 | $ SYNC_FILE="$TESTTMP/sync-file" | |
9 | > import itertools |
|
9 | $ export SYNC_FILE | |
|
10 | $ DONE_FILE="$TESTTMP/done-file" | |||
|
11 | $ export DONE_FILE | |||
|
12 | $ | |||
|
13 | $ cat > wait_ext.py <<EOF | |||
|
14 | > import os | |||
10 | > import time |
|
15 | > import time | |
11 | > |
|
16 | > | |
12 | > from mercurial.i18n import _ |
|
17 | > from mercurial.i18n import _ | |
13 | > from mercurial import registrar |
|
18 | > from mercurial import registrar | |
|
19 | > from mercurial import testing | |||
14 | > |
|
20 | > | |
15 | > cmdtable = {} |
|
21 | > cmdtable = {} | |
16 | > command = registrar.command(cmdtable) |
|
22 | > command = registrar.command(cmdtable) | |
17 | > |
|
23 | > | |
18 |
> @command(b'sl |
|
24 | > @command(b'wait-signal', [], _(b'SYNC_FILE DONE_FILE'), norepo=True) | |
19 | > def sleep(ui, sleeptime=b"1", **opts): |
|
25 | > def sleep(ui, sync_file=b"$SYNC_FILE", done_file=b"$DONE_FILE", **opts): | |
|
26 | > start = time.time() | |||
20 | > with ui.uninterruptible(): |
|
27 | > with ui.uninterruptible(): | |
21 | > for _i in itertools.repeat(None, int(sleeptime)): |
|
28 | > testing.write_file(sync_file, b'%d' % os.getpid()) | |
22 | > time.sleep(1) |
|
29 | > testing.wait_file(done_file) | |
|
30 | > # make sure we get rescheduled and the signal get a chance to be handled | |||
|
31 | > time.sleep(0.1) | |||
23 | > ui.warn(b"end of unsafe operation\n") |
|
32 | > ui.warn(b"end of unsafe operation\n") | |
24 |
> ui.warn(b"% |
|
33 | > ui.warn(b"%d second(s) passed\n" % int(time.time() - start)) | |
25 | > EOF |
|
34 | > EOF | |
26 |
|
35 | |||
|
36 | $ cat > send-signal.sh << EOF | |||
|
37 | > #!/bin/sh | |||
|
38 | > SIG=\$1 | |||
|
39 | > if [ -z "\$SIG" ]; then | |||
|
40 | > echo "send-signal.sh requires one argument" >&2 | |||
|
41 | > exit 1 | |||
|
42 | > fi | |||
|
43 | > "$RUNTESTDIR/testlib/wait-on-file" 10 "$SYNC_FILE" || exit 2 | |||
|
44 | > kill -s \$SIG \`cat "$SYNC_FILE"\` | |||
|
45 | > sleep 1 | |||
|
46 | > touch "$DONE_FILE" | |||
|
47 | > EOF | |||
|
48 | ||||
|
49 | #if no-windows | |||
|
50 | $ chmod +x send-signal.sh | |||
|
51 | #endif | |||
|
52 | ||||
27 | Kludge to emulate timeout(1) which is not generally available. |
|
53 | Kludge to emulate timeout(1) which is not generally available. | |
28 | $ cat > timeout.py <<EOF |
|
|||
29 | > from __future__ import print_function |
|
|||
30 | > import argparse |
|
|||
31 | > import signal |
|
|||
32 | > import subprocess |
|
|||
33 | > import sys |
|
|||
34 | > import time |
|
|||
35 | > |
|
|||
36 | > ap = argparse.ArgumentParser() |
|
|||
37 | > ap.add_argument('-s', nargs=1, default='SIGTERM') |
|
|||
38 | > ap.add_argument('duration', nargs=1, type=int) |
|
|||
39 | > ap.add_argument('argv', nargs='*') |
|
|||
40 | > opts = ap.parse_args() |
|
|||
41 | > try: |
|
|||
42 | > sig = int(opts.s[0]) |
|
|||
43 | > except ValueError: |
|
|||
44 | > sname = opts.s[0] |
|
|||
45 | > if not sname.startswith('SIG'): |
|
|||
46 | > sname = 'SIG' + sname |
|
|||
47 | > sig = getattr(signal, sname) |
|
|||
48 | > proc = subprocess.Popen(opts.argv) |
|
|||
49 | > time.sleep(opts.duration[0]) |
|
|||
50 | > proc.poll() |
|
|||
51 | > if proc.returncode is None: |
|
|||
52 | > proc.send_signal(sig) |
|
|||
53 | > proc.wait() |
|
|||
54 | > sys.exit(124) |
|
|||
55 | > EOF |
|
|||
56 |
|
54 | |||
57 | Set up repository |
|
55 | Set up repository | |
58 | $ hg init repo |
|
56 | $ hg init repo | |
59 | $ cd repo |
|
57 | $ cd repo | |
60 | $ cat >> $HGRCPATH << EOF |
|
58 | $ cat >> $HGRCPATH << EOF | |
61 | > [extensions] |
|
59 | > [extensions] | |
62 | > sleepext = ../sleepext.py |
|
60 | > wait_ext = $TESTTMP/wait_ext.py | |
63 | > EOF |
|
61 | > EOF | |
64 |
|
62 | |||
|
63 | ||||
65 | Test ctrl-c |
|
64 | Test ctrl-c | |
66 | $ "$PYTHON" $TESTTMP/timeout.py -s INT 1 hg sleep 2 |
|
65 | $ rm -f $SYNC_FILE $DONE_FILE | |
|
66 | $ sh -c "../send-signal.sh INT" & | |||
|
67 | $ hg wait-signal | |||
67 | interrupted! |
|
68 | interrupted! | |
68 |
[ |
|
69 | [255] | |
69 |
|
70 | |||
70 | $ cat >> $HGRCPATH << EOF |
|
71 | $ cat >> $HGRCPATH << EOF | |
71 | > [experimental] |
|
72 | > [experimental] | |
72 | > nointerrupt = yes |
|
73 | > nointerrupt = yes | |
73 | > EOF |
|
74 | > EOF | |
74 |
|
75 | |||
75 | $ "$PYTHON" $TESTTMP/timeout.py -s INT 1 hg sleep 2 |
|
76 | $ rm -f $SYNC_FILE $DONE_FILE | |
|
77 | $ sh -c "../send-signal.sh INT" & | |||
|
78 | $ hg wait-signal | |||
76 | interrupted! |
|
79 | interrupted! | |
77 |
[ |
|
80 | [255] | |
78 |
|
81 | |||
79 | $ cat >> $HGRCPATH << EOF |
|
82 | $ cat >> $HGRCPATH << EOF | |
80 | > [experimental] |
|
83 | > [experimental] | |
81 | > nointerrupt-interactiveonly = False |
|
84 | > nointerrupt-interactiveonly = False | |
82 | > EOF |
|
85 | > EOF | |
83 |
|
86 | |||
84 | $ "$PYTHON" $TESTTMP/timeout.py -s INT 1 hg sleep 2 |
|
87 | $ rm -f $SYNC_FILE $DONE_FILE | |
|
88 | $ sh -c "../send-signal.sh INT" & | |||
|
89 | $ hg wait-signal | |||
85 | shutting down cleanly |
|
90 | shutting down cleanly | |
86 | press ^C again to terminate immediately (dangerous) |
|
91 | press ^C again to terminate immediately (dangerous) | |
87 | end of unsafe operation |
|
92 | end of unsafe operation | |
88 | interrupted! |
|
93 | interrupted! | |
89 |
[ |
|
94 | [255] |
@@ -219,27 +219,27 b' use shell=True in the subprocess call:' | |||||
219 | #endif |
|
219 | #endif | |
220 |
|
220 | |||
221 | A complicated pager command gets worse behavior. Bonus points if you can |
|
221 | A complicated pager command gets worse behavior. Bonus points if you can | |
222 | improve this. Windows apparently does this better? |
|
222 | improve this. Windows apparently does this better, but only sometimes? | |
223 | #if windows |
|
223 | #if windows | |
224 | $ hg log --limit 3 \ |
|
224 | $ hg log --limit 3 \ | |
225 | > --config pager.pager='this-command-better-never-exist --seriously' \ |
|
225 | > --config pager.pager='this-command-better-never-exist --seriously' \ | |
226 | > 2>/dev/null || true |
|
226 | > 2>/dev/null || true | |
227 | \x1b[0;33mchangeset: 10:46106edeeb38\x1b[0m (esc) |
|
227 | \x1b[0;33mchangeset: 10:46106edeeb38\x1b[0m (esc) (?) | |
228 | tag: tip |
|
228 | tag: tip (?) | |
229 | user: test |
|
229 | user: test (?) | |
230 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
230 | date: Thu Jan 01 00:00:00 1970 +0000 (?) | |
231 | summary: modify a 10 |
|
231 | summary: modify a 10 (?) | |
232 |
|
232 | (?) | ||
233 | \x1b[0;33mchangeset: 9:6dd8ea7dd621\x1b[0m (esc) |
|
233 | \x1b[0;33mchangeset: 9:6dd8ea7dd621\x1b[0m (esc) (?) | |
234 | user: test |
|
234 | user: test (?) | |
235 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
235 | date: Thu Jan 01 00:00:00 1970 +0000 (?) | |
236 | summary: modify a 9 |
|
236 | summary: modify a 9 (?) | |
237 |
|
237 | (?) | ||
238 | \x1b[0;33mchangeset: 8:cff05a6312fe\x1b[0m (esc) |
|
238 | \x1b[0;33mchangeset: 8:cff05a6312fe\x1b[0m (esc) (?) | |
239 | user: test |
|
239 | user: test (?) | |
240 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
240 | date: Thu Jan 01 00:00:00 1970 +0000 (?) | |
241 | summary: modify a 8 |
|
241 | summary: modify a 8 (?) | |
242 |
|
242 | (?) | ||
243 | #else |
|
243 | #else | |
244 | $ hg log --limit 3 \ |
|
244 | $ hg log --limit 3 \ | |
245 | > --config pager.pager='this-command-better-never-exist --seriously' \ |
|
245 | > --config pager.pager='this-command-better-never-exist --seriously' \ |
@@ -140,11 +140,22 b' output:' | |||||
140 |
|
140 | |||
141 | zeroconf wraps ui.configitems(), which shouldn't crash at least: |
|
141 | zeroconf wraps ui.configitems(), which shouldn't crash at least: | |
142 |
|
142 | |||
|
143 | XXX-PYOXIDIZER Pyoxidizer build have trouble with zeroconf for unclear reason, | |||
|
144 | we accept the bad output for now as this is the last thing in the way of | |||
|
145 | testing the pyoxidizer build. | |||
|
146 | ||||
|
147 | #if no-pyoxidizer | |||
143 | $ hg paths --config extensions.zeroconf= |
|
148 | $ hg paths --config extensions.zeroconf= | |
144 | dupe = $TESTTMP/b#tip |
|
149 | dupe = $TESTTMP/b#tip | |
145 | dupe:pushurl = https://example.com/dupe |
|
150 | dupe:pushurl = https://example.com/dupe | |
146 | expand = $TESTTMP/a/$SOMETHING/bar |
|
151 | expand = $TESTTMP/a/$SOMETHING/bar | |
147 | insecure = http://foo:***@example.com/ |
|
152 | insecure = http://foo:***@example.com/ | |
|
153 | #else | |||
|
154 | $ hg paths --config extensions.zeroconf= | |||
|
155 | abort: An invalid argument was supplied (known-bad-output !) | |||
|
156 | [255] | |||
|
157 | #endif | |||
|
158 | ||||
148 |
|
159 | |||
149 | $ cd .. |
|
160 | $ cd .. | |
150 |
|
161 |
@@ -428,6 +428,46 b" mercurial don't crash" | |||||
428 | data-length: 121088 |
|
428 | data-length: 121088 | |
429 | data-unused: 0 |
|
429 | data-unused: 0 | |
430 | data-unused: 0.000% |
|
430 | data-unused: 0.000% | |
|
431 | ||||
|
432 | Sub-case: fallback for corrupted data file | |||
|
433 | ------------------------------------------ | |||
|
434 | ||||
|
435 | Sabotaging the data file so that nodemap resolutions fail, triggering fallback to | |||
|
436 | (non-persistent) C implementation. | |||
|
437 | ||||
|
438 | ||||
|
439 | $ UUID=`hg debugnodemap --metadata| grep 'uid:' | \ | |||
|
440 | > sed 's/uid: //'` | |||
|
441 | $ FILE=.hg/store/00changelog-"${UUID}".nd | |||
|
442 | $ python -c "fobj = open('$FILE', 'r+b'); fobj.write(b'\xff' * 121088); fobj.close()" | |||
|
443 | ||||
|
444 | The nodemap data file is still considered in sync with the docket. This | |||
|
445 | would fail without the fallback to the (non-persistent) C implementation: | |||
|
446 | ||||
|
447 | $ hg log -r b355ef8adce0949b8bdf6afc72ca853740d65944 -T '{rev}\n' --traceback | |||
|
448 | 5002 | |||
|
449 | ||||
|
450 | The nodemap data file hasn't been fixed, more tests can be inserted: | |||
|
451 | ||||
|
452 | $ hg debugnodemap --dump-disk | f --bytes=256 --hexdump --size | |||
|
453 | size=121088 | |||
|
454 | 0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
455 | 0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
456 | 0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
457 | 0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
458 | 0040: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
459 | 0050: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
460 | 0060: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
461 | 0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
462 | 0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
463 | 0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
464 | 00a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
465 | 00b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
466 | 00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
467 | 00d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
468 | 00e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
469 | 00f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff |................| | |||
|
470 | ||||
431 | $ mv ../tmp-data-file $FILE |
|
471 | $ mv ../tmp-data-file $FILE | |
432 | $ mv ../tmp-docket .hg/store/00changelog.n |
|
472 | $ mv ../tmp-docket .hg/store/00changelog.n | |
433 |
|
473 |
@@ -898,11 +898,11 b' Check we deny its usage on older reposit' | |||||
898 | A X |
|
898 | A X | |
899 | $ hg --config "phases.new-commit=internal" commit -m "my test internal commit" 2>&1 | grep ProgrammingError |
|
899 | $ hg --config "phases.new-commit=internal" commit -m "my test internal commit" 2>&1 | grep ProgrammingError | |
900 | ** ProgrammingError: this repository does not support the internal phase |
|
900 | ** ProgrammingError: this repository does not support the internal phase | |
901 | raise error.ProgrammingError(msg) |
|
901 | raise error.ProgrammingError(msg) (no-pyoxidizer !) | |
902 | *ProgrammingError: this repository does not support the internal phase (glob) |
|
902 | *ProgrammingError: this repository does not support the internal phase (glob) | |
903 | $ hg --config "phases.new-commit=archived" commit -m "my test archived commit" 2>&1 | grep ProgrammingError |
|
903 | $ hg --config "phases.new-commit=archived" commit -m "my test archived commit" 2>&1 | grep ProgrammingError | |
904 | ** ProgrammingError: this repository does not support the archived phase |
|
904 | ** ProgrammingError: this repository does not support the archived phase | |
905 | raise error.ProgrammingError(msg) |
|
905 | raise error.ProgrammingError(msg) (no-pyoxidizer !) | |
906 | *ProgrammingError: this repository does not support the archived phase (glob) |
|
906 | *ProgrammingError: this repository does not support the archived phase (glob) | |
907 |
|
907 | |||
908 | $ cd .. |
|
908 | $ cd .. |
@@ -963,6 +963,46 b' definition.' | |||||
963 | o 0: d20a80d4def3 'base' |
|
963 | o 0: d20a80d4def3 'base' | |
964 |
|
964 | |||
965 |
|
965 | |||
|
966 | Test that update_hash_refs works. | |||
|
967 | $ hg co 0 | |||
|
968 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
|
969 | $ echo update_hash_refs > update_hash_refs | |||
|
970 | $ hg add update_hash_refs | |||
|
971 | $ hg ci -m 'this will change hash' | |||
|
972 | created new head | |||
|
973 | $ echo changed >> update_hash_refs | |||
|
974 | $ hg ci -m "this starts as the child of `hg log -r . -T'{node|short}'` but not 506e2454484b. Also, ffffffffffffffff" | |||
|
975 | $ hg tglog | |||
|
976 | @ 5: a8b42cbbde83 'this starts as the child of 98789aa60148 but not 506e2454484b. Also, ffffffffffffffff' | |||
|
977 | | | |||
|
978 | o 4: 98789aa60148 'this will change hash' | |||
|
979 | | | |||
|
980 | | o 3: 506e2454484b 'merge' | |||
|
981 | | |\ | |||
|
982 | +---o 2: 531f80391e4a 'c' | |||
|
983 | | | | |||
|
984 | | o 1: 6f252845ea45 'a' | |||
|
985 | |/ | |||
|
986 | o 0: d20a80d4def3 'base' | |||
|
987 | ||||
|
988 | $ hg rebase -r '.^::' -d 3 | |||
|
989 | rebasing 4:98789aa60148 "this will change hash" | |||
|
990 | rebasing 5:a8b42cbbde83 tip "this starts as the child of 98789aa60148 but not 506e2454484b. Also, ffffffffffffffff" | |||
|
991 | saved backup bundle to $TESTTMP/keep_merge/.hg/strip-backup/98789aa60148-da3f4c2c-rebase.hg | |||
|
992 | $ hg tglog | |||
|
993 | @ 5: 0fd2912e6cc1 'this starts as the child of c16c25696fe7 but not 506e2454484b. Also, ffffffffffffffff' | |||
|
994 | | | |||
|
995 | o 4: c16c25696fe7 'this will change hash' | |||
|
996 | | | |||
|
997 | o 3: 506e2454484b 'merge' | |||
|
998 | |\ | |||
|
999 | | o 2: 531f80391e4a 'c' | |||
|
1000 | | | | |||
|
1001 | o | 1: 6f252845ea45 'a' | |||
|
1002 | |/ | |||
|
1003 | o 0: d20a80d4def3 'base' | |||
|
1004 | ||||
|
1005 | ||||
966 | $ cd .. |
|
1006 | $ cd .. | |
967 |
|
1007 | |||
968 | Test (virtual) working directory without changes, created by merge conflict |
|
1008 | Test (virtual) working directory without changes, created by merge conflict |
@@ -44,13 +44,20 b' With -v and -p HGPORT2' | |||||
44 | listening at http://localhost/ (bound to *$LOCALIP*:HGPORT2) (glob) (?) |
|
44 | listening at http://localhost/ (bound to *$LOCALIP*:HGPORT2) (glob) (?) | |
45 | % errors |
|
45 | % errors | |
46 |
|
46 | |||
47 | With -v and -p daytime (should fail because low port) |
|
47 | With -v and -p daytime | |
48 |
|
48 | |||
49 | #if no-root no-windows |
|
49 | # On some system this will fails because port < 1024 are not bindable by normal | |
|
50 | # users. | |||
|
51 | # | |||
|
52 | # On some others the kernel is configured to allow any user to bind them and | |||
|
53 | # this will work fine | |||
|
54 | ||||
|
55 | #if no-windows | |||
50 |
$ |
|
56 | $ KILLQUIETLY=Y | |
51 |
$ |
|
57 | $ hgserve -p daytime | |
52 | abort: cannot start server at 'localhost:13': Permission denied |
|
58 | abort: cannot start server at 'localhost:13': Permission denied (?) | |
53 | abort: child process failed to start |
|
59 | abort: child process failed to start (?) | |
|
60 | listening at http://localhost/ (bound to $LOCALIP:13) (?) | |||
54 | % errors |
|
61 | % errors | |
55 | $ KILLQUIETLY=N |
|
62 | $ KILLQUIETLY=N | |
56 | #endif |
|
63 | #endif |
@@ -1,5 +1,20 b'' | |||||
1 | #require git |
|
1 | #require git | |
2 |
|
2 | |||
|
3 | # XXX-CHG When running with python2 + chg this test tend to get stuck and end up | |||
|
4 | # as a time-out error. My effort to reproduce this outside of the CI failed. The | |||
|
5 | # test itself seems to pass fine, but never "complete". Debugging it is slow and | |||
|
6 | # tedious. This as a bad impact on the development process as most CI run end up | |||
|
7 | # wasting abotu 1h until that one fails. | |||
|
8 | # | |||
|
9 | # Pierre-Yves David, Augie Fackler and Raphaël Gomès all agreed to disable this | |||
|
10 | # case in that specific case until we figure this out (or we drop python2 o:-) ) | |||
|
11 | ||||
|
12 | #if no-py3 chg | |||
|
13 | $ echo 'skipped: this test get stuck on the CI with python2 + chg. investigation needed' | |||
|
14 | $ exit 80 | |||
|
15 | #endif | |||
|
16 | ||||
|
17 | ||||
3 |
|
|
18 | make git commits repeatable | |
4 |
|
19 | |||
5 | $ cat >> $HGRCPATH <<EOF |
|
20 | $ cat >> $HGRCPATH <<EOF |
@@ -41,7 +41,23 b' content until it is committed.' | |||||
41 | setup |
|
41 | setup | |
42 | ----- |
|
42 | ----- | |
43 |
|
43 | |||
44 | synchronisation+output script: |
|
44 | synchronisation+output script using the following schedule: | |
|
45 | ||||
|
46 | [A1] "external" is started | |||
|
47 | [A2] "external" waits on EXT_UNLOCK | |||
|
48 | [A2] "external" + creates EXT_WAITING → unlocks [C1] | |||
|
49 | [B1] "hg commit/pull" is started | |||
|
50 | [B2] "hg commit/pull" is ready to be committed | |||
|
51 | [B3] "hg commit/pull" spawn "internal" using a pretxnclose hook (need [C4]) | |||
|
52 | [C1] "internal" waits on EXT_WAITING (need [A2]) | |||
|
53 | [C2] "internal" creates EXT_UNLOCK → unlocks [A2] | |||
|
54 | [C3] "internal" show the tipmost revision (inside of the transaction) | |||
|
55 | [C4] "internal" waits on EXT_DONE (need [A4]) | |||
|
56 | [A3] "external" show the tipmost revision (outside of the transaction) | |||
|
57 | [A4] "external" creates EXT_DONE → unlocks [C4] | |||
|
58 | [C5] "internal" end of execution -> unlock [B3] | |||
|
59 | [B4] "hg commit/pull" transaction is committed on disk | |||
|
60 | ||||
45 |
|
61 | |||
46 |
$ |
|
62 | $ mkdir sync | |
47 | $ mkdir output |
|
63 | $ mkdir output | |
@@ -60,8 +76,10 b' synchronisation+output script:' | |||||
60 | > EOF |
|
76 | > EOF | |
61 | $ cat << EOF > script/internal.sh |
|
77 | $ cat << EOF > script/internal.sh | |
62 | > #!/bin/sh |
|
78 | > #!/bin/sh | |
|
79 | > "$RUNTESTDIR/testlib/wait-on-file" 5 "$HG_TEST_FILE_EXT_WAITING" | |||
|
80 | > touch "$HG_TEST_FILE_EXT_UNLOCK" | |||
63 | > hg log --rev 'tip' -T 'internal: {rev} {desc}\n' > "$TESTTMP/output/internal.out" |
|
81 | > hg log --rev 'tip' -T 'internal: {rev} {desc}\n' > "$TESTTMP/output/internal.out" | |
64 |
> "$RUNTESTDIR/testlib/wait-on-file" 5 "$HG_TEST_FILE_EXT_DONE" |
|
82 | > "$RUNTESTDIR/testlib/wait-on-file" 5 "$HG_TEST_FILE_EXT_DONE" | |
65 | > EOF |
|
83 | > EOF | |
66 |
|
84 | |||
67 |
|
85 |
General Comments 0
You need to be logged in to leave comments.
Login now