##// END OF EJS Templates
phases: simplify phase exchange and movement over pushkey...
Pierre-Yves David -
r15892:592b3d17 default
parent child Browse files
Show More
@@ -1555,10 +1555,10 b' class localrepository(repo.repository):'
1555 if remotephases and not publishing:
1555 if remotephases and not publishing:
1556 # remote is new and unpublishing
1556 # remote is new and unpublishing
1557 subset = common + added
1557 subset = common + added
1558 rheads, rroots = phases.analyzeremotephases(self, subset,
1558 pheads, _dr = phases.analyzeremotephases(self, subset,
1559 remotephases)
1559 remotephases)
1560 for phase, boundary in enumerate(rheads):
1560 phases.advanceboundary(self, phases.public, pheads)
1561 phases.advanceboundary(self, phase, boundary)
1561 phases.advanceboundary(self, phases.draft, common + added)
1562 else:
1562 else:
1563 # Remote is old or publishing all common changesets
1563 # Remote is old or publishing all common changesets
1564 # should be seen as public
1564 # should be seen as public
@@ -1627,72 +1627,32 b' class localrepository(repo.repository):'
1627 # don't push any phase data as there is nothing to push
1627 # don't push any phase data as there is nothing to push
1628 else:
1628 else:
1629 ana = phases.analyzeremotephases(self, fut, remotephases)
1629 ana = phases.analyzeremotephases(self, fut, remotephases)
1630 rheads, rroots = ana
1630 pheads, droots = ana
1631 ### Apply remote phase on local
1631 ### Apply remote phase on local
1632 if remotephases.get('publishing', False):
1632 if remotephases.get('publishing', False):
1633 phases.advanceboundary(self, phases.public, fut)
1633 phases.advanceboundary(self, phases.public, fut)
1634 else: # publish = False
1634 else: # publish = False
1635 for phase, rpheads in enumerate(rheads):
1635 phases.advanceboundary(self, phases.public, pheads)
1636 phases.advanceboundary(self, phase, rpheads)
1636 phases.advanceboundary(self, phases.draft, fut)
1637 ### Apply local phase on remote
1637 ### Apply local phase on remote
1638 #
1638 #
1639 # XXX If push failed we should use strict common and not
1639 # XXX If push failed we should use strict common and not
1640 # future to avoir pushing phase data on unknown changeset.
1640 # future to avoid pushing phase data on unknown changeset.
1641 # This is to done later.
1641 # This is to done later.
1642
1642
1643 # element we want to push
1643 # Get the list of all revs draft on remote by public here.
1644 topush = []
1644 # XXX Beware that revset break if droots is not strictly
1645
1645 # XXX root we may want to ensure it is but it is costly
1646 # store details of known remote phase of several revision
1646 outdated = self.set('heads((%ln::%ln) and public())',
1647 # /!\ set of index I holds rev where: I <= rev.phase()
1647 droots, fut)
1648 # /!\ public phase (index 0) is ignored
1648 for newremotehead in outdated:
1649 remdetails = [set() for i in xrange(len(phases.allphases))]
1650 _revs = set()
1651 for relremphase in phases.trackedphases[::-1]:
1652 # we iterate backward because the list alway grows
1653 # when filled in this direction.
1654 _revs.update(self.revs('%ln::%ln',
1655 rroots[relremphase], fut))
1656 remdetails[relremphase].update(_revs)
1657
1658 for phase in phases.allphases[:-1]:
1659 # We don't need the last phase as we will never want to
1660 # move anything to it while moving phase backward.
1661
1662 # Get the list of all revs on remote which are in a
1663 # phase higher than currently processed phase.
1664 relremrev = remdetails[phase + 1]
1665
1666 if not relremrev:
1667 # no candidate to remote push anymore
1668 # break before any expensive revset
1669 break
1670
1671 #dynamical inject appropriate phase symbol
1672 phasename = phases.phasenames[phase]
1673 odrevset = 'heads(%%ld and %s())' % phasename
1674 outdated = self.set(odrevset, relremrev)
1675 for od in outdated:
1676 candstart = len(remdetails) - 1
1677 candstop = phase + 1
1678 candidateold = xrange(candstart, candstop, -1)
1679 for oldphase in candidateold:
1680 if od.rev() in remdetails[oldphase]:
1681 break
1682 else: # last one: no need to search
1683 oldphase = phase + 1
1684 topush.append((oldphase, phase, od))
1685
1686 # push every needed data
1687 for oldphase, newphase, newremotehead in topush:
1688 r = remote.pushkey('phases',
1649 r = remote.pushkey('phases',
1689 newremotehead.hex(),
1650 newremotehead.hex(),
1690 str(oldphase), str(newphase))
1651 str(phases.draft),
1652 str(phases.public))
1691 if not r:
1653 if not r:
1692 self.ui.warn(_('updating phase of %s '
1654 self.ui.warn(_('updating %s to public failed!\n')
1693 'to %s from %s failed!\n')
1655 % newremotehead)
1694 % (newremotehead, newphase,
1695 oldphase))
1696 finally:
1656 finally:
1697 locallock.release()
1657 locallock.release()
1698 finally:
1658 finally:
@@ -203,9 +203,10 b' def retractboundary(repo, targetphase, n'
203 def listphases(repo):
203 def listphases(repo):
204 """List phases root for serialisation over pushkey"""
204 """List phases root for serialisation over pushkey"""
205 keys = {}
205 keys = {}
206 for phase in trackedphases:
206 value = '%i' % draft
207 for root in repo._phaseroots[phase]:
207 for root in repo._phaseroots[draft]:
208 keys[hex(root)] = '%i' % phase
208 keys[hex(root)] = value
209
209 if repo.ui.configbool('phases', 'publish', True):
210 if repo.ui.configbool('phases', 'publish', True):
210 # Add an extra data to let remote know we are a publishing repo.
211 # Add an extra data to let remote know we are a publishing repo.
211 # Publishing repo can't just pretend they are old repo. When pushing to
212 # Publishing repo can't just pretend they are old repo. When pushing to
@@ -264,20 +265,26 b' def analyzeremotephases(repo, subset, ro'
264 Accept unknown element input
265 Accept unknown element input
265 """
266 """
266 # build list from dictionary
267 # build list from dictionary
267 phaseroots = [[] for p in allphases]
268 draftroots = []
269 nm = repo.changelog.nodemap # to filter unknown node
268 for nhex, phase in roots.iteritems():
270 for nhex, phase in roots.iteritems():
269 if nhex == 'publishing': # ignore data related to publish option
271 if nhex == 'publishing': # ignore data related to publish option
270 continue
272 continue
271 node = bin(nhex)
273 node = bin(nhex)
272 phase = int(phase)
274 phase = int(phase)
273 if node in repo:
275 if phase == 0:
274 phaseroots[phase].append(node)
276 if node != nullid:
277 msg = _('ignoring inconsistense public root from remote: %s')
278 repo.ui.warn(msg, nhex)
279 elif phase == 1:
280 if node in nm:
281 draftroots.append(node)
282 else:
283 msg = _('ignoring unexpected root from remote: %i %s')
284 repo.ui.warn(msg, phase, nhex)
275 # compute heads
285 # compute heads
276 phaseheads = [[] for p in allphases]
286 revset = repo.set('heads((%ln + parents(%ln)) - (%ln::%ln))',
277 for phase in allphases[:-1]:
287 subset, draftroots, draftroots, subset)
278 toproof = phaseroots[phase + 1]
288 publicheads = [c.node() for c in revset]
279 revset = repo.set('heads((%ln + parents(%ln)) - (%ln::%ln))',
289 return publicheads, draftroots
280 subset, toproof, toproof, subset)
281 phaseheads[phase].extend(c.node() for c in revset)
282 return phaseheads, phaseroots
283
290
@@ -29,7 +29,7 b' expect ssl error'
29 searching for changes
29 searching for changes
30 remote: ssl required
30 remote: ssl required
31 remote: ssl required
31 remote: ssl required
32 updating phase of ba677d0156c1 to 0 from 1 failed!
32 updating ba677d0156c1 to public failed!
33 % serve errors
33 % serve errors
34
34
35 expect authorization error
35 expect authorization error
General Comments 0
You need to be logged in to leave comments. Login now