76 # did a local lock get acquired? |
76 # did a local lock get acquired? |
77 self.locallocked = None |
77 self.locallocked = None |
78 # step already performed |
78 # step already performed |
79 # (used to check what steps have been already performed through bundle2) |
79 # (used to check what steps have been already performed through bundle2) |
80 self.stepsdone = set() |
80 self.stepsdone = set() |
81 # Integer version of the push result |
81 # Integer version of the changegroup push result |
82 # - None means nothing to push |
82 # - None means nothing to push |
83 # - 0 means HTTP error |
83 # - 0 means HTTP error |
84 # - 1 means we pushed and remote head count is unchanged *or* |
84 # - 1 means we pushed and remote head count is unchanged *or* |
85 # we have outgoing changesets but refused to push |
85 # we have outgoing changesets but refused to push |
86 # - other values as described by addchangegroup() |
86 # - other values as described by addchangegroup() |
87 self.ret = None |
87 self.cgresult = None |
88 # discover.outgoing object (contains common and outgoing data) |
88 # discover.outgoing object (contains common and outgoing data) |
89 self.outgoing = None |
89 self.outgoing = None |
90 # all remote heads before the push |
90 # all remote heads before the push |
91 self.remoteheads = None |
91 self.remoteheads = None |
92 # testable as a boolean indicating if any nodes are missing locally. |
92 # testable as a boolean indicating if any nodes are missing locally. |
138 return cheads |
138 return cheads |
139 |
139 |
140 @property |
140 @property |
141 def commonheads(self): |
141 def commonheads(self): |
142 """set of all common heads after changeset bundle push""" |
142 """set of all common heads after changeset bundle push""" |
143 if self.ret: |
143 if self.cgresult: |
144 return self.futureheads |
144 return self.futureheads |
145 else: |
145 else: |
146 return self.fallbackheads |
146 return self.fallbackheads |
147 |
147 |
148 def push(repo, remote, force=False, revs=None, newbranch=False): |
148 def push(repo, remote, force=False, revs=None, newbranch=False): |
386 |
386 |
387 @b2partsgenerator('changeset') |
387 @b2partsgenerator('changeset') |
388 def _pushb2ctx(pushop, bundler): |
388 def _pushb2ctx(pushop, bundler): |
389 """handle changegroup push through bundle2 |
389 """handle changegroup push through bundle2 |
390 |
390 |
391 addchangegroup result is stored in the ``pushop.ret`` attribute. |
391 addchangegroup result is stored in the ``pushop.cgresult`` attribute. |
392 """ |
392 """ |
393 if 'changesets' in pushop.stepsdone: |
393 if 'changesets' in pushop.stepsdone: |
394 return |
394 return |
395 pushop.stepsdone.add('changesets') |
395 pushop.stepsdone.add('changesets') |
396 # Send known heads to the server for race detection. |
396 # Send known heads to the server for race detection. |
405 cgpart = bundler.newpart('B2X:CHANGEGROUP', data=cg.getchunks()) |
405 cgpart = bundler.newpart('B2X:CHANGEGROUP', data=cg.getchunks()) |
406 def handlereply(op): |
406 def handlereply(op): |
407 """extract addchangroup returns from server reply""" |
407 """extract addchangroup returns from server reply""" |
408 cgreplies = op.records.getreplies(cgpart.id) |
408 cgreplies = op.records.getreplies(cgpart.id) |
409 assert len(cgreplies['changegroup']) == 1 |
409 assert len(cgreplies['changegroup']) == 1 |
410 pushop.ret = cgreplies['changegroup'][0]['return'] |
410 pushop.cgresult = cgreplies['changegroup'][0]['return'] |
411 return handlereply |
411 return handlereply |
412 |
412 |
413 @b2partsgenerator('phase') |
413 @b2partsgenerator('phase') |
414 def _pushb2phases(pushop, bundler): |
414 def _pushb2phases(pushop, bundler): |
415 """handle phase push through bundle2""" |
415 """handle phase push through bundle2""" |
556 remoteheads = ['force'] |
556 remoteheads = ['force'] |
557 else: |
557 else: |
558 remoteheads = pushop.remoteheads |
558 remoteheads = pushop.remoteheads |
559 # ssh: return remote's addchangegroup() |
559 # ssh: return remote's addchangegroup() |
560 # http: return remote's addchangegroup() or 0 for error |
560 # http: return remote's addchangegroup() or 0 for error |
561 pushop.ret = pushop.remote.unbundle(cg, remoteheads, |
561 pushop.cgresult = pushop.remote.unbundle(cg, remoteheads, |
562 pushop.repo.url()) |
562 pushop.repo.url()) |
563 else: |
563 else: |
564 # we return an integer indicating remote head count |
564 # we return an integer indicating remote head count |
565 # change |
565 # change |
566 pushop.ret = pushop.remote.addchangegroup(cg, 'push', pushop.repo.url()) |
566 pushop.cgresult = pushop.remote.addchangegroup(cg, 'push', |
|
567 pushop.repo.url()) |
567 |
568 |
568 def _pushsyncphase(pushop): |
569 def _pushsyncphase(pushop): |
569 """synchronise phase information locally and remotely""" |
570 """synchronise phase information locally and remotely""" |
570 cheads = pushop.commonheads |
571 cheads = pushop.commonheads |
571 # even when we don't push, exchanging phase data is useful |
572 # even when we don't push, exchanging phase data is useful |
572 remotephases = pushop.remote.listkeys('phases') |
573 remotephases = pushop.remote.listkeys('phases') |
573 if (pushop.ui.configbool('ui', '_usedassubrepo', False) |
574 if (pushop.ui.configbool('ui', '_usedassubrepo', False) |
574 and remotephases # server supports phases |
575 and remotephases # server supports phases |
575 and pushop.ret is None # nothing was pushed |
576 and pushop.cgresult is None # nothing was pushed |
576 and remotephases.get('publishing', False)): |
577 and remotephases.get('publishing', False)): |
577 # When: |
578 # When: |
578 # - this is a subrepo push |
579 # - this is a subrepo push |
579 # - and remote support phase |
580 # - and remote support phase |
580 # - and no changeset was pushed |
581 # - and no changeset was pushed |
597 else: # publish = False |
598 else: # publish = False |
598 _localphasemove(pushop, pheads) |
599 _localphasemove(pushop, pheads) |
599 _localphasemove(pushop, cheads, phases.draft) |
600 _localphasemove(pushop, cheads, phases.draft) |
600 ### Apply local phase on remote |
601 ### Apply local phase on remote |
601 |
602 |
602 if pushop.ret: |
603 if pushop.cgresult: |
603 if 'phases' in pushop.stepsdone: |
604 if 'phases' in pushop.stepsdone: |
604 # phases already pushed though bundle2 |
605 # phases already pushed though bundle2 |
605 return |
606 return |
606 outdated = pushop.outdatedphases |
607 outdated = pushop.outdatedphases |
607 else: |
608 else: |
695 msg = _('failed to push some obsolete markers!\n') |
696 msg = _('failed to push some obsolete markers!\n') |
696 repo.ui.warn(msg) |
697 repo.ui.warn(msg) |
697 |
698 |
698 def _pushbookmark(pushop): |
699 def _pushbookmark(pushop): |
699 """Update bookmark position on remote""" |
700 """Update bookmark position on remote""" |
700 if pushop.ret == 0 or 'bookmarks' in pushop.stepsdone: |
701 if pushop.cgresult == 0 or 'bookmarks' in pushop.stepsdone: |
701 return |
702 return |
702 pushop.stepsdone.add('bookmarks') |
703 pushop.stepsdone.add('bookmarks') |
703 ui = pushop.ui |
704 ui = pushop.ui |
704 remote = pushop.remote |
705 remote = pushop.remote |
705 for b, old, new in pushop.outbookmarks: |
706 for b, old, new in pushop.outbookmarks: |