# HG changeset patch # User Pierre-Yves David # Date 2011-11-10 23:21:17 # Node ID fa47291b3f1faa6e19fb6268b1f05c1944254136 # Parent a44446ff9ad8c673c7b097230b842b945bd8e3ce phases: mark content pushed as public in local repo on push diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -67,14 +67,18 @@ def prepush(repo, remote, force, revs, n on circumstances: If we are not going to push anything, return a tuple (None, - outgoing) where outgoing is 0 if there are no outgoing + outgoing, common) where outgoing is 0 if there are no outgoing changesets and 1 if there are, but we refuse to push them - (e.g. would create new remote heads). + (e.g. would create new remote heads). The third element "common" + is the list of heads of the common set between local and remote. - Otherwise, return a tuple (changegroup, remoteheads), where - changegroup is a readable file-like object whose read() returns - successive changegroup chunks ready to be sent over the wire and - remoteheads is the list of remote heads.''' + Otherwise, return a tuple (changegroup, remoteheads, futureheads), + where changegroup is a readable file-like object whose read() + returns successive changegroup chunks ready to be sent over the + wire, remoteheads is the list of remote heads and futureheads is + the list of heads of the common set between local and remote to + be after push completion. + ''' commoninc = findcommonincoming(repo, remote, force=force) common, revs = findcommonoutgoing(repo, remote, onlyheads=revs, commoninc=commoninc, force=force) @@ -85,7 +89,7 @@ def prepush(repo, remote, force, revs, n if not outg: repo.ui.status(_("no changes found\n")) - return None, 1 + return None, 1, common if not force and remoteheads != [nullid]: if remote.capable('branchmap'): @@ -189,4 +193,10 @@ def prepush(repo, remote, force, revs, n cg = repo._changegroup(outg, 'push') else: cg = repo.getbundle('push', heads=revs, common=common) - return cg, remoteheads + # no need to compute outg ancestor. All node in outg have either: + # - parents in outg + # - parents in common + # - nullid parent + rset = repo.set('heads(%ln + %ln)', common, outg) + futureheads = [ctx.node() for ctx in rset] + return cg, remoteheads, futureheads diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -1554,24 +1554,32 @@ class localrepository(repo.repository): if not unbundle: lock = remote.lock() try: - cg, remote_heads = discovery.prepush(self, remote, force, revs, - newbranch) - ret = remote_heads - if cg is not None: - if unbundle: - # local repo finds heads on server, finds out what - # revs it must push. once revs transferred, if server - # finds it has different heads (someone else won - # commit/push race), server aborts. - if force: - remote_heads = ['force'] - # ssh: return remote's addchangegroup() - # http: return remote's addchangegroup() or 0 for error - ret = remote.unbundle(cg, remote_heads, 'push') - else: - # we return an integer indicating remote head count change - ret = remote.addchangegroup(cg, 'push', self.url(), - lock=lock) + # get local lock as we might write phase data + locallock = self.lock() + try: + cg, remote_heads, fut = discovery.prepush(self, remote, force, + revs, newbranch) + ret = remote_heads + if cg is not None: + if unbundle: + # local repo finds heads on server, finds out what + # revs it must push. once revs transferred, if server + # finds it has different heads (someone else won + # commit/push race), server aborts. + if force: + remote_heads = ['force'] + # ssh: return remote's addchangegroup() + # http: return remote's addchangegroup() or 0 for error + ret = remote.unbundle(cg, remote_heads, 'push') + else: + # we return an integer indicating remote head count change + ret = remote.addchangegroup(cg, 'push', self.url(), + lock=lock) + # if we don't push, the common data is already useful + # everything exchange is public for now + phases.advanceboundary(self, 0, fut) + finally: + locallock.release() finally: if lock is not None: lock.release() diff --git a/tests/test-phases-exchange.t b/tests/test-phases-exchange.t --- a/tests/test-phases-exchange.t +++ b/tests/test-phases-exchange.t @@ -30,6 +30,12 @@ adding manifests adding file changes added 2 changesets with 2 changes to 2 files + $ hgph + 3 1 a-D + 2 1 a-C + 1 0 a-B + 0 0 a-A + $ cd ../beta $ hgph 1 0 a-B @@ -55,4 +61,22 @@ 1 0 a-B 0 0 a-A +pull did not updated ../alpha state. +push from alpha to beta should update phase even if nothing is transfered + $ cd ../alpha + $ hgph # not updated by remote pull + 3 1 a-D + 2 1 a-C + 1 0 a-B + 0 0 a-A + $ hg push ../beta + pushing to ../beta + searching for changes + no changes found + $ hgph + 3 0 a-D + 2 0 a-C + 1 0 a-B + 0 0 a-A +