Show More
@@ -1323,6 +1323,8 b' def getrepocaps(repo, allowpushback=Fals' | |||
|
1323 | 1323 | caps['obsmarkers'] = supportedformat |
|
1324 | 1324 | if allowpushback: |
|
1325 | 1325 | caps['pushback'] = () |
|
1326 | if not repo.ui.configbool('experimental', 'checkheads-strict', True): | |
|
1327 | caps['checkheads'] = ('related',) | |
|
1326 | 1328 | return caps |
|
1327 | 1329 | |
|
1328 | 1330 | def bundle2caps(remote): |
@@ -1603,6 +1605,35 b' def handlecheckheads(op, inpart):' | |||
|
1603 | 1605 | raise error.PushRaced('repository changed while pushing - ' |
|
1604 | 1606 | 'please try again') |
|
1605 | 1607 | |
|
1608 | @parthandler('check:updated-heads') | |
|
1609 | def handlecheckupdatedheads(op, inpart): | |
|
1610 | """check for race on the heads touched by a push | |
|
1611 | ||
|
1612 | This is similar to 'check:heads' but focus on the heads actually updated | |
|
1613 | during the push. If other activities happen on unrelated heads, it is | |
|
1614 | ignored. | |
|
1615 | ||
|
1616 | This allow server with high traffic to avoid push contention as long as | |
|
1617 | unrelated parts of the graph are involved.""" | |
|
1618 | h = inpart.read(20) | |
|
1619 | heads = [] | |
|
1620 | while len(h) == 20: | |
|
1621 | heads.append(h) | |
|
1622 | h = inpart.read(20) | |
|
1623 | assert not h | |
|
1624 | # trigger a transaction so that we are guaranteed to have the lock now. | |
|
1625 | if op.ui.configbool('experimental', 'bundle2lazylocking'): | |
|
1626 | op.gettransaction() | |
|
1627 | ||
|
1628 | currentheads = set() | |
|
1629 | for ls in op.repo.branchmap().itervalues(): | |
|
1630 | currentheads.update(ls) | |
|
1631 | ||
|
1632 | for h in heads: | |
|
1633 | if h not in currentheads: | |
|
1634 | raise error.PushRaced('repository changed while pushing - ' | |
|
1635 | 'please try again') | |
|
1636 | ||
|
1606 | 1637 | @parthandler('output') |
|
1607 | 1638 | def handleoutput(op, inpart): |
|
1608 | 1639 | """forward output captured on the server to the client""" |
@@ -332,6 +332,7 b' def checkheads(pushop):' | |||
|
332 | 332 | headssum = _headssummary(pushop) |
|
333 | 333 | else: |
|
334 | 334 | headssum = _oldheadssummary(repo, remoteheads, outgoing, inc) |
|
335 | pushop.pushbranchmap = headssum | |
|
335 | 336 | newbranches = [branch for branch, heads in headssum.iteritems() |
|
336 | 337 | if heads[0] is None] |
|
337 | 338 | # 1. Check for new branches on the remote. |
@@ -323,8 +323,21 b' class pushoperation(object):' | |||
|
323 | 323 | self.bkresult = None |
|
324 | 324 | # discover.outgoing object (contains common and outgoing data) |
|
325 | 325 | self.outgoing = None |
|
326 | # all remote heads before the push | |
|
326 | # all remote topological heads before the push | |
|
327 | 327 | self.remoteheads = None |
|
328 | # Details of the remote branch pre and post push | |
|
329 | # | |
|
330 | # mapping: {'branch': ([remoteheads], | |
|
331 | # [newheads], | |
|
332 | # [unsyncedheads], | |
|
333 | # [discardedheads])} | |
|
334 | # - branch: the branch name | |
|
335 | # - remoteheads: the list of remote heads known locally | |
|
336 | # None if the branch is new | |
|
337 | # - newheads: the new remote heads (known locally) with outgoing pushed | |
|
338 | # - unsyncedheads: the list of remote heads unknown locally. | |
|
339 | # - discardedheads: the list of remote heads made obsolete by the push | |
|
340 | self.pushbranchmap = None | |
|
328 | 341 | # testable as a boolean indicating if any nodes are missing locally. |
|
329 | 342 | self.incoming = None |
|
330 | 343 | # phases changes that must be pushed along side the changesets |
@@ -712,8 +725,23 b' def _pushb2ctxcheckheads(pushop, bundler' | |||
|
712 | 725 | |
|
713 | 726 | Exists as an independent function to aid extensions |
|
714 | 727 | """ |
|
715 | if not pushop.force: | |
|
728 | # * 'force' do not check for push race, | |
|
729 | # * if we don't push anything, there are nothing to check. | |
|
730 | if not pushop.force and pushop.outgoing.missingheads: | |
|
731 | allowunrelated = 'related' in bundler.capabilities.get('checkheads', ()) | |
|
732 | if not allowunrelated: | |
|
716 | 733 | bundler.newpart('check:heads', data=iter(pushop.remoteheads)) |
|
734 | else: | |
|
735 | affected = set() | |
|
736 | for branch, heads in pushop.pushbranchmap.iteritems(): | |
|
737 | remoteheads, newheads, unsyncedheads, discardedheads = heads | |
|
738 | if remoteheads is not None: | |
|
739 | remote = set(remoteheads) | |
|
740 | affected |= set(discardedheads) & remote | |
|
741 | affected |= remote - set(newheads) | |
|
742 | if affected: | |
|
743 | data = iter(sorted(affected)) | |
|
744 | bundler.newpart('check:updated-heads', data=data) | |
|
717 | 745 | |
|
718 | 746 | @b2partsgenerator('changeset') |
|
719 | 747 | def _pushb2ctx(pushop, bundler): |
@@ -102,6 +102,21 b' A set of extension and shell functions e' | |||
|
102 | 102 | > graph = log -G --rev 'sort(all(), "topo")' |
|
103 | 103 | > EOF |
|
104 | 104 | |
|
105 | We tests multiple cases: | |
|
106 | * strict: no race detected, | |
|
107 | * unrelated: race on unrelated heads are allowed. | |
|
108 | ||
|
109 | #testcases strict unrelated | |
|
110 | ||
|
111 | #if unrelated | |
|
112 | ||
|
113 | $ cat >> $HGRCPATH << EOF | |
|
114 | > [experimental] | |
|
115 | > checkheads-strict = no | |
|
116 | > EOF | |
|
117 | ||
|
118 | #endif | |
|
119 | ||
|
105 | 120 | Setup |
|
106 | 121 | ----- |
|
107 | 122 | |
@@ -265,6 +280,7 b' Pushing' | |||
|
265 | 280 | |
|
266 | 281 | Check the result of the push |
|
267 | 282 | |
|
283 | #if strict | |
|
268 | 284 | $ cat ./push-log |
|
269 | 285 | pushing to ssh://user@dummy/server |
|
270 | 286 | searching for changes |
@@ -282,6 +298,34 b' Check the result of the push' | |||
|
282 | 298 | |/ |
|
283 | 299 | @ 842e2fac6304 C-ROOT (default) |
|
284 | 300 | |
|
301 | #endif | |
|
302 | #if unrelated | |
|
303 | ||
|
304 | (The two heads are unrelated, push should be allowed) | |
|
305 | ||
|
306 | $ cat ./push-log | |
|
307 | pushing to ssh://user@dummy/server | |
|
308 | searching for changes | |
|
309 | wrote ready: $TESTTMP/readyfile | |
|
310 | waiting on: $TESTTMP/watchfile | |
|
311 | remote: adding changesets | |
|
312 | remote: adding manifests | |
|
313 | remote: adding file changes | |
|
314 | remote: added 1 changesets with 1 changes to 1 files | |
|
315 | ||
|
316 | $ hg -R server graph | |
|
317 | o 59e76faf78bd C-D (default) | |
|
318 | | | |
|
319 | o a9149a1428e2 C-B (default) | |
|
320 | | | |
|
321 | | o 51c544a58128 C-C (default) | |
|
322 | | | | |
|
323 | | o 98217d5a1659 C-A (default) | |
|
324 | |/ | |
|
325 | @ 842e2fac6304 C-ROOT (default) | |
|
326 | ||
|
327 | #endif | |
|
328 | ||
|
285 | 329 | Pushing while someone creates a new head |
|
286 | 330 | ----------------------------------------- |
|
287 | 331 | |
@@ -295,6 +339,8 b' Pushing a new changeset while someone cr' | |||
|
295 | 339 | |
|
296 | 340 | (resync-all) |
|
297 | 341 | |
|
342 | #if strict | |
|
343 | ||
|
298 | 344 | $ hg -R ./server pull ./client-racy |
|
299 | 345 | pulling from ./client-racy |
|
300 | 346 | searching for changes |
@@ -303,6 +349,17 b' Pushing a new changeset while someone cr' | |||
|
303 | 349 | adding file changes |
|
304 | 350 | added 1 changesets with 1 changes to 1 files |
|
305 | 351 | (run 'hg update' to get a working copy) |
|
352 | ||
|
353 | #endif | |
|
354 | #if unrelated | |
|
355 | ||
|
356 | $ hg -R ./server pull ./client-racy | |
|
357 | pulling from ./client-racy | |
|
358 | searching for changes | |
|
359 | no changes found | |
|
360 | ||
|
361 | #endif | |
|
362 | ||
|
306 | 363 |
$ |
|
307 | 364 | pulling from ssh://user@dummy/server |
|
308 | 365 | searching for changes |
@@ -367,6 +424,8 b' Pushing' | |||
|
367 | 424 | |
|
368 | 425 | Check the result of the push |
|
369 | 426 | |
|
427 | #if strict | |
|
428 | ||
|
370 | 429 | $ cat ./push-log |
|
371 | 430 | pushing to ssh://user@dummy/server |
|
372 | 431 | searching for changes |
@@ -389,6 +448,39 b' Check the result of the push' | |||
|
389 | 448 | @ 842e2fac6304 C-ROOT (default) |
|
390 | 449 | |
|
391 | 450 | |
|
451 | #endif | |
|
452 | ||
|
453 | #if unrelated | |
|
454 | ||
|
455 | (The racing new head do not affect existing heads, push should go through) | |
|
456 | ||
|
457 | $ cat ./push-log | |
|
458 | pushing to ssh://user@dummy/server | |
|
459 | searching for changes | |
|
460 | wrote ready: $TESTTMP/readyfile | |
|
461 | waiting on: $TESTTMP/watchfile | |
|
462 | remote: adding changesets | |
|
463 | remote: adding manifests | |
|
464 | remote: adding file changes | |
|
465 | remote: added 1 changesets with 1 changes to 1 files | |
|
466 | ||
|
467 | $ hg -R server graph | |
|
468 | o d9e379a8c432 C-F (default) | |
|
469 | | | |
|
470 | o 51c544a58128 C-C (default) | |
|
471 | | | |
|
472 | | o d603e2c0cdd7 C-E (default) | |
|
473 | |/ | |
|
474 | o 98217d5a1659 C-A (default) | |
|
475 | | | |
|
476 | | o 59e76faf78bd C-D (default) | |
|
477 | | | | |
|
478 | | o a9149a1428e2 C-B (default) | |
|
479 | |/ | |
|
480 | @ 842e2fac6304 C-ROOT (default) | |
|
481 | ||
|
482 | #endif | |
|
483 | ||
|
392 | 484 | Pushing touching different named branch (same topo): new branch raced |
|
393 | 485 | --------------------------------------------------------------------- |
|
394 | 486 | |
@@ -402,6 +494,8 b' Pushing two children on the same head, o' | |||
|
402 | 494 | |
|
403 | 495 | (resync-all) |
|
404 | 496 | |
|
497 | #if strict | |
|
498 | ||
|
405 | 499 | $ hg -R ./server pull ./client-racy |
|
406 | 500 | pulling from ./client-racy |
|
407 | 501 | searching for changes |
@@ -410,6 +504,17 b' Pushing two children on the same head, o' | |||
|
410 | 504 | adding file changes |
|
411 | 505 | added 1 changesets with 1 changes to 1 files |
|
412 | 506 | (run 'hg update' to get a working copy) |
|
507 | ||
|
508 | #endif | |
|
509 | #if unrelated | |
|
510 | ||
|
511 | $ hg -R ./server pull ./client-racy | |
|
512 | pulling from ./client-racy | |
|
513 | searching for changes | |
|
514 | no changes found | |
|
515 | ||
|
516 | #endif | |
|
517 | ||
|
413 | 518 |
$ |
|
414 | 519 | pulling from ssh://user@dummy/server |
|
415 | 520 | searching for changes |
@@ -480,6 +585,7 b' Pushing' | |||
|
480 | 585 | |
|
481 | 586 | Check the result of the push |
|
482 | 587 | |
|
588 | #if strict | |
|
483 | 589 | $ cat ./push-log |
|
484 | 590 | pushing to ssh://user@dummy/server |
|
485 | 591 | searching for changes |
@@ -505,6 +611,43 b' Check the result of the push' | |||
|
505 | 611 | |/ |
|
506 | 612 | @ 842e2fac6304 C-ROOT (default) |
|
507 | 613 | |
|
614 | #endif | |
|
615 | #if unrelated | |
|
616 | ||
|
617 | (unrelated named branches are unrelated) | |
|
618 | ||
|
619 | $ cat ./push-log | |
|
620 | pushing to ssh://user@dummy/server | |
|
621 | searching for changes | |
|
622 | wrote ready: $TESTTMP/readyfile | |
|
623 | waiting on: $TESTTMP/watchfile | |
|
624 | remote: adding changesets | |
|
625 | remote: adding manifests | |
|
626 | remote: adding file changes | |
|
627 | remote: added 1 changesets with 1 changes to 1 files (+1 heads) | |
|
628 | ||
|
629 | $ hg -R server graph | |
|
630 | o 833be552cfe6 C-H (my-first-test-branch) | |
|
631 | | | |
|
632 | | o 75d69cba5402 C-G (default) | |
|
633 | |/ | |
|
634 | o d9e379a8c432 C-F (default) | |
|
635 | | | |
|
636 | o 51c544a58128 C-C (default) | |
|
637 | | | |
|
638 | | o d603e2c0cdd7 C-E (default) | |
|
639 | |/ | |
|
640 | o 98217d5a1659 C-A (default) | |
|
641 | | | |
|
642 | | o 59e76faf78bd C-D (default) | |
|
643 | | | | |
|
644 | | o a9149a1428e2 C-B (default) | |
|
645 | |/ | |
|
646 | @ 842e2fac6304 C-ROOT (default) | |
|
647 | ||
|
648 | #endif | |
|
649 | ||
|
650 | The racing new head do not affect existing heads, push should go through | |
|
508 | 651 | |
|
509 | 652 | pushing touching different named branch (same topo): old branch raced |
|
510 | 653 | --------------------------------------------------------------------- |
@@ -519,6 +662,8 b' Pushing two children on the same head, o' | |||
|
519 | 662 | |
|
520 | 663 | (resync-all) |
|
521 | 664 | |
|
665 | #if strict | |
|
666 | ||
|
522 | 667 | $ hg -R ./server pull ./client-racy |
|
523 | 668 | pulling from ./client-racy |
|
524 | 669 | searching for changes |
@@ -527,6 +672,17 b' Pushing two children on the same head, o' | |||
|
527 | 672 | adding file changes |
|
528 | 673 | added 1 changesets with 1 changes to 1 files (+1 heads) |
|
529 | 674 | (run 'hg heads .' to see heads, 'hg merge' to merge) |
|
675 | ||
|
676 | #endif | |
|
677 | #if unrelated | |
|
678 | ||
|
679 | $ hg -R ./server pull ./client-racy | |
|
680 | pulling from ./client-racy | |
|
681 | searching for changes | |
|
682 | no changes found | |
|
683 | ||
|
684 | #endif | |
|
685 | ||
|
530 | 686 |
$ |
|
531 | 687 | pulling from ssh://user@dummy/server |
|
532 | 688 | searching for changes |
@@ -600,6 +756,8 b' Pushing' | |||
|
600 | 756 | |
|
601 | 757 | Check the result of the push |
|
602 | 758 | |
|
759 | #if strict | |
|
760 | ||
|
603 | 761 | $ cat ./push-log |
|
604 | 762 | pushing to ssh://user@dummy/server |
|
605 | 763 | searching for changes |
@@ -630,6 +788,48 b' Check the result of the push' | |||
|
630 | 788 | @ 842e2fac6304 C-ROOT (default) |
|
631 | 789 | |
|
632 | 790 | |
|
791 | #endif | |
|
792 | ||
|
793 | #if unrelated | |
|
794 | ||
|
795 | (unrelated named branches are unrelated) | |
|
796 | ||
|
797 | $ cat ./push-log | |
|
798 | pushing to ssh://user@dummy/server | |
|
799 | searching for changes | |
|
800 | wrote ready: $TESTTMP/readyfile | |
|
801 | waiting on: $TESTTMP/watchfile | |
|
802 | remote: adding changesets | |
|
803 | remote: adding manifests | |
|
804 | remote: adding file changes | |
|
805 | remote: added 1 changesets with 1 changes to 1 files (+1 heads) | |
|
806 | ||
|
807 | $ hg -R server graph | |
|
808 | o 89420bf00fae C-J (default) | |
|
809 | | | |
|
810 | | o b35ed749f288 C-I (my-second-test-branch) | |
|
811 | |/ | |
|
812 | o 75d69cba5402 C-G (default) | |
|
813 | | | |
|
814 | | o 833be552cfe6 C-H (my-first-test-branch) | |
|
815 | |/ | |
|
816 | o d9e379a8c432 C-F (default) | |
|
817 | | | |
|
818 | o 51c544a58128 C-C (default) | |
|
819 | | | |
|
820 | | o d603e2c0cdd7 C-E (default) | |
|
821 | |/ | |
|
822 | o 98217d5a1659 C-A (default) | |
|
823 | | | |
|
824 | | o 59e76faf78bd C-D (default) | |
|
825 | | | | |
|
826 | | o a9149a1428e2 C-B (default) | |
|
827 | |/ | |
|
828 | @ 842e2fac6304 C-ROOT (default) | |
|
829 | ||
|
830 | ||
|
831 | #endif | |
|
832 | ||
|
633 | 833 | pushing racing push touch multiple heads |
|
634 | 834 | ---------------------------------------- |
|
635 | 835 | |
@@ -644,6 +844,8 b' There are multiple heads, but the racing' | |||
|
644 | 844 | |
|
645 | 845 | (resync-all) |
|
646 | 846 | |
|
847 | #if strict | |
|
848 | ||
|
647 | 849 | $ hg -R ./server pull ./client-racy |
|
648 | 850 | pulling from ./client-racy |
|
649 | 851 | searching for changes |
@@ -652,6 +854,18 b' There are multiple heads, but the racing' | |||
|
652 | 854 | adding file changes |
|
653 | 855 | added 1 changesets with 1 changes to 1 files (+1 heads) |
|
654 | 856 | (run 'hg heads .' to see heads, 'hg merge' to merge) |
|
857 | ||
|
858 | #endif | |
|
859 | ||
|
860 | #if unrelated | |
|
861 | ||
|
862 | $ hg -R ./server pull ./client-racy | |
|
863 | pulling from ./client-racy | |
|
864 | searching for changes | |
|
865 | no changes found | |
|
866 | ||
|
867 | #endif | |
|
868 | ||
|
655 | 869 |
$ |
|
656 | 870 | pulling from ssh://user@dummy/server |
|
657 | 871 | searching for changes |
General Comments 0
You need to be logged in to leave comments.
Login now