changeset 15713:cff25e4b37d2

phases: do not exchange secret changesets Any secret changesets will be excluded from pull and push. Phase data are properly synchronized on pull and push if a changeset is seen as secret locally but is non-secret remote side. This patch does not handle the case of a changeset secret on remote but known locally.
author Pierre-Yves David <pierre-yves.david@ens-lyon.org>
date Thu, 22 Dec 2011 00:42:25 +0100
parents 06b8b74720d6
children 049643a31b9a
files mercurial/discovery.py mercurial/setdiscovery.py mercurial/wireproto.py tests/test-phases-exchange.t tests/test-phases.t
diffstat 5 files changed, 131 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/discovery.py	Thu Dec 22 00:40:46 2011 +0100
+++ b/mercurial/discovery.py	Thu Dec 22 00:42:25 2011 +0100
@@ -85,12 +85,28 @@
     _common, inc, remoteheads = commoninc
 
     cl = repo.changelog
-    outg = cl.findmissing(common, revs)
+    alloutg = cl.findmissing(common, revs)
+    outg = []
+    secret = []
+    for o in alloutg:
+        if repo[o].phase() >= 2:
+            secret.append(o)
+        else:
+            outg.append(o)
 
     if not outg:
-        repo.ui.status(_("no changes found\n"))
+        if secret:
+            repo.ui.status(_("no changes to push but %i secret changesets\n")
+                           % len(secret))
+        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.
--- a/mercurial/setdiscovery.py	Thu Dec 22 00:40:46 2011 +0100
+++ b/mercurial/setdiscovery.py	Thu Dec 22 00:42:25 2011 +0100
@@ -9,6 +9,7 @@
 from node import nullid
 from i18n import _
 import random, collections, util, dagutil
+import phases
 
 def _updatesample(dag, nodes, sample, always, quicksamplesize=0):
     # if nodes is empty we scan the entire graph
@@ -99,7 +100,7 @@
     sample = ownheads
     if remote.local():
         # stopgap until we have a proper localpeer that supports batch()
-        srvheadhashes = remote.heads()
+        srvheadhashes = phases.visibleheads(remote)
         yesno = remote.known(dag.externalizeall(sample))
     elif remote.capable('batch'):
         batch = remote.batch()
--- a/mercurial/wireproto.py	Thu Dec 22 00:40:46 2011 +0100
+++ b/mercurial/wireproto.py	Thu Dec 22 00:42:25 2011 +0100
@@ -10,6 +10,7 @@
 from node import bin, hex
 import changegroup as changegroupmod
 import repo, error, encoding, util, store
+import phases
 
 # abstract batching support
 
@@ -449,7 +450,7 @@
     return streamres(proto.groupchunks(cg))
 
 def heads(repo, proto):
-    h = repo.heads()
+    h = phases.visibleheads(repo)
     return encodelist(h) + "\n"
 
 def hello(repo, proto):
--- a/tests/test-phases-exchange.t	Thu Dec 22 00:40:46 2011 +0100
+++ b/tests/test-phases-exchange.t	Thu Dec 22 00:42:25 2011 +0100
@@ -7,7 +7,9 @@
   $ mkcommit() {
   >    echo "$1" > "$1"
   >    hg add "$1"
-  >    hg ci -m "$1"
+  >    message="$1"
+  >    shift
+  >    hg ci -m "$message" $*
   > }
 
   $ hg init alpha
@@ -478,6 +480,7 @@
 
 Pushing to Publish=True (common changeset from publish=False)
 
+(in mu)
   $ hg push ../alpha
   pushing to ../alpha
   searching for changes
@@ -506,3 +509,62 @@
   1 0 a-B - 548a3d25dbf0
   0 0 a-A - 054250a37db4
 
+
+Discovery locally secret changeset on a remote repository:
+
+- should make it non-secret
+
+  $ cd ../alpha
+  $ mkcommit A-secret --config phases.new-commit=2
+  $ hgph
+  11 2 A-secret - 435b5d83910c
+  10 0 a-H - 967b449fbc94
+  9 1 a-G - 3e27b6f1eee1
+  8 0 a-F - b740e3e5c05d
+  7 0 a-E - e9f537e46dea
+  6 0 n-B - 145e75495359
+  5 0 n-A - d6bcb4f74035
+  4 0 b-A - f54f1bb90ff3
+  3 0 a-D - b555f63b6063
+  2 0 a-C - 54acac6f23ab
+  1 0 a-B - 548a3d25dbf0
+  0 0 a-A - 054250a37db4
+  $ hg bundle --base 'parents(.)' -r . ../secret-bundle.hg
+  1 changesets found
+  $ hg -R ../mu unbundle ../secret-bundle.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  (run 'hg update' to get a working copy)
+  $ hgph -R ../mu
+  10 1 A-secret - 435b5d83910c
+  9 0 a-H - 967b449fbc94
+  8 0 a-F - b740e3e5c05d
+  7 0 a-E - e9f537e46dea
+  6 0 n-B - 145e75495359
+  5 0 n-A - d6bcb4f74035
+  4 0 a-D - b555f63b6063
+  3 0 a-C - 54acac6f23ab
+  2 0 b-A - f54f1bb90ff3
+  1 0 a-B - 548a3d25dbf0
+  0 0 a-A - 054250a37db4
+  $ hg pull ../mu
+  pulling from ../mu
+  searching for changes
+  no changes found
+  $ hgph
+  11 1 A-secret - 435b5d83910c
+  10 0 a-H - 967b449fbc94
+  9 1 a-G - 3e27b6f1eee1
+  8 0 a-F - b740e3e5c05d
+  7 0 a-E - e9f537e46dea
+  6 0 n-B - 145e75495359
+  5 0 n-A - d6bcb4f74035
+  4 0 b-A - f54f1bb90ff3
+  3 0 a-D - b555f63b6063
+  2 0 a-C - 54acac6f23ab
+  1 0 a-B - 548a3d25dbf0
+  0 0 a-A - 054250a37db4
+
+
--- a/tests/test-phases.t	Thu Dec 22 00:40:46 2011 +0100
+++ b/tests/test-phases.t	Thu Dec 22 00:42:25 2011 +0100
@@ -88,3 +88,49 @@
   1 0 B
   0 0 A
 
+Test secret changeset are not pushed
+
+  $ hg init ../push-dest
+  $ hg push ../push-dest -f # force because we push multiple heads
+  pushing to ../push-dest
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 5 changesets with 5 changes to 5 files (+1 heads)
+  $ hglog
+  7 2 merge B' and E
+  6 0 B'
+  5 2 H
+  4 2 E
+  3 0 D
+  2 0 C
+  1 0 B
+  0 0 A
+  $ cd ../push-dest
+  $ hglog
+  4 0 B'
+  3 0 D
+  2 0 C
+  1 0 B
+  0 0 A
+  $ cd ..
+
+Test secret changeset are not pull
+
+  $ hg init pull-dest
+  $ cd pull-dest
+  $ hg pull ../initialrepo
+  pulling from ../initialrepo
+  requesting all changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 5 changesets with 5 changes to 5 files (+1 heads)
+  (run 'hg heads' to see heads, 'hg merge' to merge)
+  $ hglog
+  4 0 B'
+  3 0 D
+  2 0 C
+  1 0 B
+  0 0 A