comparison mercurial/localrepo.py @ 15892:592b3d1742a1

phases: simplify phase exchange and movement over pushkey The code now only exchange draft root and only care about movement related to public//draft boundary. There is multiple reason to simplify this code: * Secret are never discovered anymore * We decided to not support more the three existing phase Removing phase index from pushkey (if ever decided) will be made in another commit.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Fri, 13 Jan 2012 02:04:16 +0100
parents 249d3420ec9c
children 23921c17299a
comparison
equal deleted inserted replaced
15891:249d3420ec9c 15892:592b3d1742a1
1553 remotephases = remote.listkeys('phases') 1553 remotephases = remote.listkeys('phases')
1554 publishing = bool(remotephases.get('publishing', False)) 1554 publishing = bool(remotephases.get('publishing', False))
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
1565 phases.advanceboundary(self, phases.public, common + added) 1565 phases.advanceboundary(self, phases.public, common + added)
1566 finally: 1566 finally:
1625 if not remotephases: # old server or public only repo 1625 if not remotephases: # old server or public only repo
1626 phases.advanceboundary(self, phases.public, fut) 1626 phases.advanceboundary(self, phases.public, fut)
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:
1699 if lock is not None: 1659 if lock is not None:
1700 lock.release() 1660 lock.release()