##// END OF EJS Templates
push: add a way to allow concurrent pushes on unrelated heads...
marmoute -
r32709:16ada4cb default
parent child Browse files
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:
716 bundler.newpart('check:heads', data=iter(pushop.remoteheads))
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:
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 $ hg -R ./client-other pull
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 $ hg -R ./client-other pull
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 $ hg -R ./client-other pull
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 $ hg -R ./client-other pull
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