##// END OF EJS Templates
merge with stable
Matt Harbison -
r48667:155a2ec8 merge default
parent child Browse files
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 /tmp/check-tests.txt"
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.1.2-cp27-cp27m-win_amd64.whl"
47 $MERCURIAL_WHEEL_FILENAME = "mercurial-5.8.1-cp39-cp39-win_amd64.whl"
59 $MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/6d/47/e031e47f7fe9b16e4e3383da47e2b0a7eae6e603996bc67a03ec4fa1b3f4/$MERCURIAL_WHEEL_FILENAME"
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 Install-Python3 "Python 3.8 64-bit" ${prefix}\assets\python38-x64.exe ${prefix}\python38-x64 ${pip}
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\python27-x64\Scripts\virtualenv.exe" "${prefix}\venv-bootstrap"
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\hg.exe" "clone --insecure $repo_url $dest"
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 oldparentnodes = repo.dirstate.parents()
761 oldp1 = repo.dirstate.p1()
761 newparentnodes = [replacements.get(n, n) for n in oldparentnodes]
762 newp1 = replacements.get(oldp1, oldp1)
762 if newparentnodes != oldparentnodes:
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 normal(self, f, parentfiledata=None):
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 normallookup(self, f):
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[0][:11] == b'00manifest.':
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'] # type: List[bytes]
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 `remove` outside of update/merge context."
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 ``frequency``
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 return entry[6], entry[5]
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 seen = 0
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 seen += len(chunk)
607 bytecount += len(chunk)
597 progress.update(seen)
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 getattr
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 os.path.join(*paths)
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 return os.path.join(self.base, path, *insidef)
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.strtolocal(pw)
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").is_dir() {
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").is_dir() {
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 root.is_file() {
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 !shared_path.is_dir() {
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()).map_err(|e| nodemap_error(py, e))
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\baz: $ENOENT$ (windows !)
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\baz: $ENOENT$ (windows !)
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 1086 changes to 1086 files
235 added 3 changesets with 1087 changes to 1087 files
215 new changesets 96ee1d7354c4:7406a3463c3d
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 1086 changes to 1086 files
302 added 3 changesets with 1087 changes to 1087 files
282 new changesets 96ee1d7354c4:7406a3463c3d
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 1088 files to transfer, 101 KB of data (no-zstd !)
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 1088 files to transfer, 98.4 KB of data (zstd !)
335 1089 files to transfer, 98.5 KB of data (zstd !)
315 transferred 98.4 KB in * seconds (*/sec) (glob) (zstd !)
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 1091 files to transfer, 101 KB of data (no-zstd !)
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 1091 files to transfer, 98.5 KB of data (zstd !)
346 1092 files to transfer, 98.6 KB of data (zstd !)
326 transferred 98.5 KB in * seconds (* */sec) (glob) (zstd !)
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=118551
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 36 39 35 66 69 6c 65 63 6f 75 6e 74 31 30 39 |3695filecount109|
376 0030: 33 38 33 34 66 69 6c 65 63 6f 75 6e 74 31 30 39 |3834filecount109|
356 0040: 31 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |1requirementsdot|
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=115738
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 38 35 36 66 69 6c 65 63 6f 75 6e 74 31 30 39 |0856filecount109|
396 0030: 30 39 39 32 66 69 6c 65 63 6f 75 6e 74 31 30 39 |0992filecount109|
376 0040: 31 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |1requirementsdot|
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=115759
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 38 35 36 66 69 6c 65 63 6f 75 6e 74 31 30 39 |0856filecount109|
416 0030: 30 39 39 32 66 69 6c 65 63 6f 75 6e 74 31 30 39 |0992filecount109|
396 0040: 31 72 65 71 75 69 72 65 6d 65 6e 74 73 64 6f 74 |1requirementsdot|
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=109449
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 1088 files to transfer, 101 KB of data (no-zstd !)
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 1088 files to transfer, 98.4 KB of data (zstd !)
458 1089 files to transfer, 98.5 KB of data (zstd !)
438 transferred 98.4 KB in * seconds (*/sec) (glob) (zstd !)
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 1091 files to transfer, 101 KB of data (no-zstd !)
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 1091 files to transfer, 98.5 KB of data (zstd !)
468 1092 files to transfer, 98.6 KB of data (zstd !)
448 transferred 98.5 KB in * seconds (* */sec) (glob) (zstd !)
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 1088 files to transfer, 101 KB of data (no-zstd !)
481 1089 files to transfer, 101 KB of data (no-zstd !)
461 1088 files to transfer, 98.4 KB of data (zstd !)
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.4 KB in * seconds (*/sec) (glob) (zstd !)
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 1091 files to transfer, 101 KB of data (no-zstd !)
513 1092 files to transfer, 101 KB of data (no-zstd !)
493 1091 files to transfer, 98.5 KB of data (zstd !)
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 118382 (no-zstd !)
519 bundle2-input-part: total payload size 118568 (no-zstd !)
499 transferred 98.5 KB in * seconds (* */sec) (glob) (zstd !)
520 transferred 98.6 KB in * seconds (* */sec) (glob) (zstd !)
500 bundle2-input-part: total payload size 115543 (zstd !)
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 1088 files to transfer, 101 KB of data (no-zstd !)
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 1088 files to transfer, 98.4 KB of data (zstd !)
555 1089 files to transfer, 98.5 KB of data (zstd !)
535 transferred 98.4 KB in * seconds (*/sec) (glob) (zstd !)
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 1091 files to transfer, 101 KB of data (no-zstd !)
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 1091 files to transfer, 98.5 KB of data (zstd !)
565 1092 files to transfer, 98.6 KB of data (zstd !)
545 transferred 98.5 KB in * seconds (* */sec) (glob) (zstd !)
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 1088 files to transfer, 101 KB of data (no-zstd !)
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 1088 files to transfer, 98.4 KB of data (zstd !)
707 1089 files to transfer, 98.5 KB of data (zstd !)
687 transferred 98.4 KB in * seconds (*/sec) (glob) (zstd !)
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 1086 files updated, 0 files merged, 0 files removed, 0 files unresolved
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 1094 files to transfer, 101 KB of data (no-zstd !)
717 1095 files to transfer, 102 KB of data (no-zstd !)
697 transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !)
718 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
698 1094 files to transfer, 98.7 KB of data (zstd !)
719 1095 files to transfer, 98.8 KB of data (zstd !)
699 transferred 98.7 KB in * seconds (* */sec) (glob) (zstd !)
720 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
700 updating to branch default
721 updating to branch default
701 1086 files updated, 0 files merged, 0 files removed, 0 files unresolved
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 1086 changes to 1086 files
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:7406a3463c3d
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 1088 files to transfer, 101 KB of data (no-zstd !)
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 1088 files to transfer, 98.4 KB of data (zstd !)
748 1089 files to transfer, 98.5 KB of data (zstd !)
728 transferred 98.4 KB in * seconds (*/sec) (glob) (zstd !)
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 1086 files updated, 0 files merged, 0 files removed, 0 files unresolved
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 1094 files to transfer, 101 KB of data (no-zstd !)
758 1095 files to transfer, 102 KB of data (no-zstd !)
738 transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !)
759 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
739 1094 files to transfer, 98.7 KB of data (zstd !)
760 1095 files to transfer, 98.8 KB of data (zstd !)
740 transferred 98.7 KB in * seconds (* */sec) (glob) (zstd !)
761 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
741 updating to branch default
762 updating to branch default
742 1086 files updated, 0 files merged, 0 files removed, 0 files unresolved
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 1086 changes to 1086 files
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 1088 files to transfer, 101 KB of data (no-zstd !)
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 1088 files to transfer, 98.4 KB of data (zstd !)
795 1089 files to transfer, 98.5 KB of data (zstd !)
775 transferred 98.4 KB in * seconds (*/sec) (glob) (zstd !)
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 1086 files updated, 0 files merged, 0 files removed, 0 files unresolved
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 1095 files to transfer, 101 KB of data (no-zstd !)
809 1096 files to transfer, 102 KB of data (no-zstd !)
789 transferred 101 KB in * seconds (* */sec) (glob) (no-zstd !)
810 transferred 102 KB in * seconds (* */sec) (glob) (no-zstd !)
790 1095 files to transfer, 98.7 KB of data (zstd !)
811 1096 files to transfer, 98.8 KB of data (zstd !)
791 transferred 98.7 KB in * seconds (* */sec) (glob) (zstd !)
812 transferred 98.8 KB in * seconds (* */sec) (glob) (zstd !)
792 updating to branch default
813 updating to branch default
793 1086 files updated, 0 files merged, 0 files removed, 0 files unresolved
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 1086 changes to 1086 files
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 1096 files to transfer, 102 KB of data (no-zstd !)
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 1096 files to transfer, 99.1 KB of data (zstd !)
866 1097 files to transfer, 99.2 KB of data (zstd !)
846 transferred 99.1 KB in * seconds (* */sec) (glob) (zstd !)
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 1087 changes to 1086 files
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().upper())
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.upper())
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 000000000000 outside 10
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'sleep', [], _(b'TIME'), norepo=True)
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"%s second(s) passed\n" % sleeptime)
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 [124]
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 [124]
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 [124]
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 $ KILLQUIETLY=Y
56 $ KILLQUIETLY=Y
51 $ hgserve -p daytime
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 make git commits repeatable
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 $ mkdir sync
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" "$HG_TEST_FILE_EXT_UNLOCK"
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