Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 15820:2673006f7989
phases: fix phase synchronization on push
The bugs seemed to show up when element not in future common changeset should
hold new hold phase data.
The whole phase push machinery was rewritten in the process.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Wed, 04 Jan 2012 01:12:31 +0100 |
parents | 57241845a4bb |
children | cd956049fc14 |
comparison
equal
deleted
inserted
replaced
15819:33ca11b010e2 | 15820:2673006f7989 |
---|---|
1630 ### Apply local phase on remote | 1630 ### Apply local phase on remote |
1631 # | 1631 # |
1632 # XXX If push failed we should use strict common and not | 1632 # XXX If push failed we should use strict common and not |
1633 # future to avoir pushing phase data on unknown changeset. | 1633 # future to avoir pushing phase data on unknown changeset. |
1634 # This is to done later. | 1634 # This is to done later. |
1635 futctx = [self[n] for n in fut if n != nullid] | 1635 |
1636 for phase in phases.trackedphases[::-1]: | 1636 # element we want to push |
1637 prevphase = phase -1 | 1637 topush = [] |
1638 # get all candidate for head in previous phase | 1638 |
1639 inprev = [ctx for ctx in futctx | 1639 # store details of known remote phase of several revision |
1640 if ctx.phase() == prevphase] | 1640 # /!\ set of index I holds rev where: I <= rev.phase() |
1641 for newremotehead in self.set('heads(%ld & (%ln::))', | 1641 # /!\ public phase (index 0) is ignored |
1642 inprev, rroots[phase]): | 1642 remdetails = [set() for i in xrange(len(phases.allphases))] |
1643 r = remote.pushkey('phases', | 1643 _revs = set() |
1644 newremotehead.hex(), | 1644 for relremphase in phases.trackedphases[::-1]: |
1645 str(phase), str(prevphase)) | 1645 # we iterate backward because the list alway grows |
1646 if not r: | 1646 # when filled in this direction. |
1647 self.ui.warn(_('updating phase of %s' | 1647 _revs.update(self.revs('%ln::%ln', |
1648 'to %s failed!\n') | 1648 rroots[relremphase], fut)) |
1649 % (newremotehead, prevphase)) | 1649 remdetails[relremphase].update(_revs) |
1650 | |
1651 for phase in phases.allphases[:-1]: | |
1652 # We don't need the last phase as we will never want to | |
1653 # move anything to it while moving phase backward. | |
1654 | |
1655 # Get the list of all revs on remote which are in a | |
1656 # phase higher than currently processed phase. | |
1657 relremrev = remdetails[phase + 1] | |
1658 | |
1659 if not relremrev: | |
1660 # no candidate to remote push anymore | |
1661 # break before any expensive revset | |
1662 break | |
1663 | |
1664 #dynamical inject appropriate phase symbol | |
1665 phasename = phases.phasenames[phase] | |
1666 odrevset = 'heads(%%ld and %s())' % phasename | |
1667 outdated = self.set(odrevset, relremrev) | |
1668 for od in outdated: | |
1669 candstart = len(remdetails) - 1 | |
1670 candstop = phase + 1 | |
1671 candidateold = xrange(candstart, candstop, -1) | |
1672 for oldphase in candidateold: | |
1673 if od.rev() in remdetails[oldphase]: | |
1674 break | |
1675 else: # last one: no need to search | |
1676 oldphase = phase + 1 | |
1677 topush.append((oldphase, phase, od)) | |
1678 | |
1679 # push every needed data | |
1680 for oldphase, newphase, newremotehead in topush: | |
1681 r = remote.pushkey('phases', | |
1682 newremotehead.hex(), | |
1683 str(oldphase), str(newphase)) | |
1684 if not r: | |
1685 self.ui.warn(_('updating phase of %s ' | |
1686 'to %s from %s failed!\n') | |
1687 % (newremotehead, newphase, | |
1688 oldphase)) | |
1650 finally: | 1689 finally: |
1651 locallock.release() | 1690 locallock.release() |
1652 finally: | 1691 finally: |
1653 if lock is not None: | 1692 if lock is not None: |
1654 lock.release() | 1693 lock.release() |