# HG changeset patch # User Pierre-Yves David # Date 1326238066 -3600 # Node ID 7299e09a85a23c25e1a3d63fda2b9bf7f5a13097 # Parent cd956049fc14b023c80a440025d3b01cb0ba02f1 phases: make outgoing object and discovery aware of exclusion The outgoing object gains an "excluded" members holding all changesets which were excluded because there where secret. The core discovery code now remove secret changeset from discovery by default. This means that any command relying on discovery will exclude secret changeset. Most notable one are outgoing and bundle. (But bundle with and explicit ``--base`` still allow to bundle outgoing changeset. diff -r cd956049fc14 -r 7299e09a85a2 mercurial/discovery.py --- a/mercurial/discovery.py Mon Jan 09 03:47:16 2012 +0100 +++ b/mercurial/discovery.py Wed Jan 11 00:27:46 2012 +0100 @@ -7,7 +7,7 @@ from node import nullid, short from i18n import _ -import util, setdiscovery, treediscovery +import util, setdiscovery, treediscovery, phases def findcommonincoming(repo, remote, heads=None, force=False): """Return a tuple (common, anyincoming, heads) used to identify the common @@ -54,6 +54,7 @@ missing is a list of all nodes present in local but not in remote. common is a list of all nodes shared between the two repos. + excluded is the list of missing changeset that shouldn't be sent remotely. missingheads is the list of heads of missing. commonheads is the list of heads of common. @@ -66,6 +67,7 @@ self._revlog = revlog self._common = None self._missing = None + self.excluded = [] def _computecommonmissing(self): sets = self._revlog.findcommonmissing(self.commonheads, @@ -94,8 +96,41 @@ If commoninc is given, it must the the result of a prior call to findcommonincoming(repo, other, force) to avoid recomputing it here.''' - common, _any, _hds = commoninc or findcommonincoming(repo, other, force=force) - return outgoing(repo.changelog, common, onlyheads or repo.heads()) + # declare an empty outgoing object to be filled later + og = outgoing(repo.changelog, None, None) + + # get common set if not provided + if commoninc is None: + commoninc = findcommonincoming(repo, other, force=force) + og.commonheads, _any, _hds = commoninc + + # compute outgoing + if not repo._phaseroots[phases.secret]: + og.missingheads = onlyheads or repo.heads() + elif onlyheads is None: + # use visible heads as it should be cached + og.missingheads = phases.visibleheads(repo) + og.excluded = [ctx.node() for ctx in repo.set('secret()')] + else: + # compute common, missing and exclude secret stuff + sets = repo.changelog.findcommonmissing(og.commonheads, onlyheads) + og._common, allmissing = sets + og._missing = missing = [] + og._excluded = excluded = [] + for node in allmissing: + if repo[node].phase() >= phases.secret: + excluded.append(node) + else: + missing.append(node) + if excluded: + # update missing heads + rset = repo.set('heads(%ln)', missing) + missingheads = [ctx.node() for ctx in rset] + else: + missingheads = onlyheads + og.missingheads = missingheads + + return og def prepush(repo, remote, force, revs, newbranch): '''Analyze the local and remote repositories and determine which @@ -121,29 +156,17 @@ _common, inc, remoteheads = commoninc cl = repo.changelog - alloutg = outgoing.missing + outg = outgoing.missing common = outgoing.commonheads - outg = [] - secret = [] - for o in alloutg: - if repo[o].phase() >= 2: - secret.append(o) - else: - outg.append(o) if not outg: - if secret: + if outgoing.excluded: repo.ui.status(_("no changes to push but %i secret changesets\n") - % len(secret)) + % len(outgoing.excluded)) else: repo.ui.status(_("no changes found\n")) return None, 1, common - if secret: - # recompute target revs - revs = [ctx.node() for ctx in repo.set('heads(::(%ld))', - map(repo.changelog.rev, outg))] - if not force and remoteheads != [nullid]: if remote.capable('branchmap'): # Check for each named branch if we're creating new remote heads. @@ -241,7 +264,8 @@ if unsynced: repo.ui.warn(_("note: unsynced remote changes!\n")) - if revs is None: + if revs is None and not outgoing.excluded: + # push everything, # use the fast path, no race possible on push cg = repo._changegroup(outg, 'push') else: diff -r cd956049fc14 -r 7299e09a85a2 tests/test-check-code-hg.t --- a/tests/test-check-code-hg.t Mon Jan 09 03:47:16 2012 +0100 +++ b/tests/test-check-code-hg.t Wed Jan 11 00:27:46 2012 +0100 @@ -351,9 +351,6 @@ > If onlyheads is given, only nodes ancestral to nodes in onlyheads (inclusive) warning: line over 80 characters mercurial/discovery.py:0: - > common, _any, _hds = commoninc or findcommonincoming(repo, other, force=force) - warning: line over 80 characters - mercurial/discovery.py:0: > def findcommonoutgoing(repo, other, onlyheads=None, force=False, commoninc=None): warning: line over 80 characters mercurial/dispatch.py:0: diff -r cd956049fc14 -r 7299e09a85a2 tests/test-phases.t --- a/tests/test-phases.t Mon Jan 09 03:47:16 2012 +0100 +++ b/tests/test-phases.t Wed Jan 11 00:27:46 2012 +0100 @@ -95,6 +95,23 @@ > [phases] > publish=False > EOF + $ hg outgoing ../push-dest --template='{rev} {phase} {desc|firstline}\n' + comparing with ../push-dest + searching for changes + 0 public A + 1 public B + 2 draft C + 3 draft D + 6 draft B' + $ hg outgoing -r default ../push-dest --template='{rev} {phase} {desc|firstline}\n' + comparing with ../push-dest + searching for changes + 0 public A + 1 public B + 2 draft C + 3 draft D + 6 draft B' + $ hg push ../push-dest -f # force because we push multiple heads pushing to ../push-dest searching for changes @@ -140,6 +157,13 @@ 0 0 A $ cd .. +But secret can still be bundled explicitly + + $ cd initialrepo + $ hg bundle --base '4^' -r 'children(4)' ../secret-bundle.hg + 4 changesets found + $ cd .. + Test revset $ cd initialrepo