mercurial/discovery.py
changeset 15838 7299e09a85a2
parent 15837 cd956049fc14
child 15893 eb6867b98223
--- 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: