##// 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 caps['obsmarkers'] = supportedformat
1323 caps['obsmarkers'] = supportedformat
1324 if allowpushback:
1324 if allowpushback:
1325 caps['pushback'] = ()
1325 caps['pushback'] = ()
1326 if not repo.ui.configbool('experimental', 'checkheads-strict', True):
1327 caps['checkheads'] = ('related',)
1326 return caps
1328 return caps
1327
1329
1328 def bundle2caps(remote):
1330 def bundle2caps(remote):
@@ -1603,6 +1605,35 b' def handlecheckheads(op, inpart):'
1603 raise error.PushRaced('repository changed while pushing - '
1605 raise error.PushRaced('repository changed while pushing - '
1604 'please try again')
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 @parthandler('output')
1637 @parthandler('output')
1607 def handleoutput(op, inpart):
1638 def handleoutput(op, inpart):
1608 """forward output captured on the server to the client"""
1639 """forward output captured on the server to the client"""
@@ -332,6 +332,7 b' def checkheads(pushop):'
332 headssum = _headssummary(pushop)
332 headssum = _headssummary(pushop)
333 else:
333 else:
334 headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
334 headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
335 pushop.pushbranchmap = headssum
335 newbranches = [branch for branch, heads in headssum.iteritems()
336 newbranches = [branch for branch, heads in headssum.iteritems()
336 if heads[0] is None]
337 if heads[0] is None]
337 # 1. Check for new branches on the remote.
338 # 1. Check for new branches on the remote.
@@ -323,8 +323,21 b' class pushoperation(object):'
323 self.bkresult = None
323 self.bkresult = None
324 # discover.outgoing object (contains common and outgoing data)
324 # discover.outgoing object (contains common and outgoing data)
325 self.outgoing = None
325 self.outgoing = None
326 # all remote heads before the push
326 # all remote topological heads before the push
327 self.remoteheads = None
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 # testable as a boolean indicating if any nodes are missing locally.
341 # testable as a boolean indicating if any nodes are missing locally.
329 self.incoming = None
342 self.incoming = None
330 # phases changes that must be pushed along side the changesets
343 # phases changes that must be pushed along side the changesets
@@ -712,8 +725,23 b' def _pushb2ctxcheckheads(pushop, bundler'
712
725
713 Exists as an independent function to aid extensions
726 Exists as an independent function to aid extensions
714 """
727 """
715 if not pushop.force:
728 # * 'force' do not check for push race,
716 bundler.newpart('check:heads', data=iter(pushop.remoteheads))
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 @b2partsgenerator('changeset')
746 @b2partsgenerator('changeset')
719 def _pushb2ctx(pushop, bundler):
747 def _pushb2ctx(pushop, bundler):
@@ -102,6 +102,21 b' A set of extension and shell functions e'
102 > graph = log -G --rev 'sort(all(), "topo")'
102 > graph = log -G --rev 'sort(all(), "topo")'
103 > EOF
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 Setup
120 Setup
106 -----
121 -----
107
122
@@ -265,6 +280,7 b' Pushing'
265
280
266 Check the result of the push
281 Check the result of the push
267
282
283 #if strict
268 $ cat ./push-log
284 $ cat ./push-log
269 pushing to ssh://user@dummy/server
285 pushing to ssh://user@dummy/server
270 searching for changes
286 searching for changes
@@ -282,6 +298,34 b' Check the result of the push'
282 |/
298 |/
283 @ 842e2fac6304 C-ROOT (default)
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 Pushing while someone creates a new head
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 (resync-all)
340 (resync-all)
297
341
342 #if strict
343
298 $ hg -R ./server pull ./client-racy
344 $ hg -R ./server pull ./client-racy
299 pulling from ./client-racy
345 pulling from ./client-racy
300 searching for changes
346 searching for changes
@@ -303,6 +349,17 b' Pushing a new changeset while someone cr'
303 adding file changes
349 adding file changes
304 added 1 changesets with 1 changes to 1 files
350 added 1 changesets with 1 changes to 1 files
305 (run 'hg update' to get a working copy)
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 $ hg -R ./client-other pull
363 $ hg -R ./client-other pull
307 pulling from ssh://user@dummy/server
364 pulling from ssh://user@dummy/server
308 searching for changes
365 searching for changes
@@ -367,6 +424,8 b' Pushing'
367
424
368 Check the result of the push
425 Check the result of the push
369
426
427 #if strict
428
370 $ cat ./push-log
429 $ cat ./push-log
371 pushing to ssh://user@dummy/server
430 pushing to ssh://user@dummy/server
372 searching for changes
431 searching for changes
@@ -389,6 +448,39 b' Check the result of the push'
389 @ 842e2fac6304 C-ROOT (default)
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 Pushing touching different named branch (same topo): new branch raced
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 (resync-all)
495 (resync-all)
404
496
497 #if strict
498
405 $ hg -R ./server pull ./client-racy
499 $ hg -R ./server pull ./client-racy
406 pulling from ./client-racy
500 pulling from ./client-racy
407 searching for changes
501 searching for changes
@@ -410,6 +504,17 b' Pushing two children on the same head, o'
410 adding file changes
504 adding file changes
411 added 1 changesets with 1 changes to 1 files
505 added 1 changesets with 1 changes to 1 files
412 (run 'hg update' to get a working copy)
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 $ hg -R ./client-other pull
518 $ hg -R ./client-other pull
414 pulling from ssh://user@dummy/server
519 pulling from ssh://user@dummy/server
415 searching for changes
520 searching for changes
@@ -480,6 +585,7 b' Pushing'
480
585
481 Check the result of the push
586 Check the result of the push
482
587
588 #if strict
483 $ cat ./push-log
589 $ cat ./push-log
484 pushing to ssh://user@dummy/server
590 pushing to ssh://user@dummy/server
485 searching for changes
591 searching for changes
@@ -505,6 +611,43 b' Check the result of the push'
505 |/
611 |/
506 @ 842e2fac6304 C-ROOT (default)
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 pushing touching different named branch (same topo): old branch raced
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 (resync-all)
663 (resync-all)
521
664
665 #if strict
666
522 $ hg -R ./server pull ./client-racy
667 $ hg -R ./server pull ./client-racy
523 pulling from ./client-racy
668 pulling from ./client-racy
524 searching for changes
669 searching for changes
@@ -527,6 +672,17 b' Pushing two children on the same head, o'
527 adding file changes
672 adding file changes
528 added 1 changesets with 1 changes to 1 files (+1 heads)
673 added 1 changesets with 1 changes to 1 files (+1 heads)
529 (run 'hg heads .' to see heads, 'hg merge' to merge)
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 $ hg -R ./client-other pull
686 $ hg -R ./client-other pull
531 pulling from ssh://user@dummy/server
687 pulling from ssh://user@dummy/server
532 searching for changes
688 searching for changes
@@ -600,6 +756,8 b' Pushing'
600
756
601 Check the result of the push
757 Check the result of the push
602
758
759 #if strict
760
603 $ cat ./push-log
761 $ cat ./push-log
604 pushing to ssh://user@dummy/server
762 pushing to ssh://user@dummy/server
605 searching for changes
763 searching for changes
@@ -630,6 +788,48 b' Check the result of the push'
630 @ 842e2fac6304 C-ROOT (default)
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 pushing racing push touch multiple heads
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 (resync-all)
845 (resync-all)
646
846
847 #if strict
848
647 $ hg -R ./server pull ./client-racy
849 $ hg -R ./server pull ./client-racy
648 pulling from ./client-racy
850 pulling from ./client-racy
649 searching for changes
851 searching for changes
@@ -652,6 +854,18 b' There are multiple heads, but the racing'
652 adding file changes
854 adding file changes
653 added 1 changesets with 1 changes to 1 files (+1 heads)
855 added 1 changesets with 1 changes to 1 files (+1 heads)
654 (run 'hg heads .' to see heads, 'hg merge' to merge)
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 $ hg -R ./client-other pull
869 $ hg -R ./client-other pull
656 pulling from ssh://user@dummy/server
870 pulling from ssh://user@dummy/server
657 searching for changes
871 searching for changes
General Comments 0
You need to be logged in to leave comments. Login now