[PATCH 6 of 6] phases: exchange phase boundaries on push

Pierre-Yves David pierre-yves.david at ens-lyon.org
Mon Dec 12 17:52:03 CST 2011


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at logilab.fr>
# Date 1323703085 -3600
# Node ID e881e8502df1b8cd48dec0b5d9c644870a2645d1
# Parent  163ebb7a6e4bdfc3e2fb8c29ef7d1fbf325d80dd
phases: exchange phase boundaries on push

For now phase sync is tried even if push fails with some know pathological
case. The exact behavior is to be discussed and implemented later.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -1586,6 +1586,8 @@
                 cg, remote_heads, fut = discovery.prepush(self, remote, force,
                                                            revs, newbranch)
                 ret = remote_heads
+                # create a callback for addchangegroup.
+                # If will be used branch of the conditionnal too.
                 if cg is not None:
                     if unbundle:
                         # local repo finds heads on server, finds out what
@@ -1600,9 +1602,41 @@
                     else:
                         # we return an integer indicating remote head count change
                         ret = remote.addchangegroup(cg, 'push', self.url())
-                # if we don't push, the common data is already useful
-                # everything exchange is public for now
-                phases.advanceboundary(self, 0, fut)
+
+                # even when we don't push, exchanging phase data is useful
+                remotephases = remote.listkeys('phaseroots')
+                if not remotephases: # old server or public only repo
+                    phases.advanceboundary(self, 0, fut)
+                    # don't push any phase data as there is nothing to push
+                else:
+                    ana = phases.analyseremotephases(self, fut, remotephases)
+                    rheads, rroots = ana
+                    ### Apply remote phase on local
+                    if hex(nullid) in remotephases: # publish = True
+                        phases.advanceboundary(self, 0, fut)
+                    else: # publish = False
+                        for phase, rpheads in enumerate(rheads):
+                            phases.advanceboundary(self, phase, rpheads)
+                    ### Apply local phase on remote
+                    #
+                    # XXX If push failed we should use strict common and not
+                    # future to avoir pushing phase data on unknown changeset.
+                    # This is to done later.
+                    futctx = [self[n] for n in fut if n != nullid]
+                    for phase in phases.trackedphases[::-1]:
+                        prevphase = phase -1
+                        # get all candidate for head in previous phase
+                        inprev = [ctx for ctx in futctx
+                                      if ctx.phase() == prevphase]
+                        for newremotehead in  self.set('heads(%ld & (%ln::))',
+                                              inprev, rroots[phase]):
+                            r = remote.pushkey('phaseheads',
+                                               newremotehead.hex(),
+                                               str(phase), str(prevphase))
+                            if not r:
+                                self.ui.warn(_('updating phase of %s'
+                                               'to %s failed!\n')
+                                                % (newremotehead, prevphase))
             finally:
                 locallock.release()
         finally:
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -179,6 +179,7 @@
   pushing to ../a
   searching for changes
   no changes found
+  pushkey hook: HG_KEY=07f3376c1e655977439df2a814e3cc14b27abac2 HG_NAMESPACE=phaseheads HG_NEW=0 HG_OLD=1 HG_RET=1 
   exporting bookmark foo
   pushkey hook: HG_KEY=foo HG_NAMESPACE=bookmarks HG_NEW=0000000000000000000000000000000000000000 HG_RET=1 
   $ cd ../a
@@ -192,7 +193,7 @@
   pulling from ../a
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
   no changes found
-  listkeys hook: HG_NAMESPACE=phaseroots HG_VALUES={'0000000000000000000000000000000000000000': '0', 'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1'} 
+  listkeys hook: HG_NAMESPACE=phaseroots HG_VALUES={'0000000000000000000000000000000000000000': '0', '539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10': '1'} 
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
   importing bookmark bar
   $ cd ../a
@@ -206,6 +207,7 @@
   pushing to ../a
   searching for changes
   no changes found
+  listkeys hook: HG_NAMESPACE=phaseroots HG_VALUES={'0000000000000000000000000000000000000000': '0', '539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10': '1'} 
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
   listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'} 
   exporting bookmark baz
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
@@ -270,3 +270,216 @@
   1 0 a-B - 548a3d25dbf0
   0 0 a-A - 054250a37db4
   $ cd ..
+
+Push
+````
+
+initial setup
+
+  $ cd alpha
+  $ hg glog
+  o  changeset:   6:145e75495359
+  |  tag:         tip
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     n-B
+  |
+  o  changeset:   5:d6bcb4f74035
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     n-A
+  |
+  o  changeset:   4:f54f1bb90ff3
+  |  parent:      1:548a3d25dbf0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     b-A
+  |
+  | @  changeset:   3:b555f63b6063
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:00 1970 +0000
+  | |  summary:     a-D
+  | |
+  | o  changeset:   2:54acac6f23ab
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:00 1970 +0000
+  |    summary:     a-C
+  |
+  o  changeset:   1:548a3d25dbf0
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:00 1970 +0000
+  |  summary:     a-B
+  |
+  o  changeset:   0:054250a37db4
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     a-A
+  
+  $ mkcommit a-E
+  $ mkcommit a-F
+  $ mkcommit a-G
+  $ hg up d6bcb4f74035 -q
+  $ mkcommit a-H
+  created new head
+  $ hgph
+  10 1 a-H - 967b449fbc94
+  9 1 a-G - 3e27b6f1eee1
+  8 1 a-F - b740e3e5c05d
+  7 1 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
+
+Pushing to Publish=False (unknown changeset)
+
+  $ hg push ../mu -r b740e3e5c05d # a-F
+  pushing to ../mu
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  $ hgph
+  10 1 a-H - 967b449fbc94
+  9 1 a-G - 3e27b6f1eee1
+  8 1 a-F - b740e3e5c05d
+  7 1 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
+
+  $ cd ../mu
+  $ hgph # d6bcb4f74035 and 145e75495359 changed because common is too smart
+  8 1 a-F - b740e3e5c05d
+  7 1 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
+
+Pushing to Publish=True (unknown changeset)
+
+  $ hg push ../beta -r b740e3e5c05d
+  pushing to ../beta
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 2 changes to 2 files
+  $ hgph # again d6bcb4f74035 and 145e75495359 changed because common is too smart
+  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
+
+Pushing to Publish=True (common changeset)
+
+  $ cd ../beta
+  $ hg push ../alpha
+  pushing to ../alpha
+  searching for changes
+  no changes found
+  $ hgph
+  6 0 a-F - b740e3e5c05d
+  5 0 a-E - e9f537e46dea
+  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
+  $ cd ../alpha
+  $ hgph # e9f537e46dea and b740e3e5c05d should have been sync to 0
+  10 1 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
+
+Pushing to Publish=False (common changeset that change phase + unknown one)
+
+  $ hg push ../mu -r 967b449fbc94 -f
+  pushing to ../mu
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  $ hgph
+  10 1 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
+  $ cd ../mu
+  $ hgph # d6bcb4f74035 should have changed phase
+  >      # again d6bcb4f74035 and 145e75495359 changed because common was too smart
+  9 1 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
+
+
+Pushing to Publish=True (common changeset from publish=False)
+
+  $ hg push ../alpha
+  pushing to ../alpha
+  searching for changes
+  no changes found
+  $ hgph
+  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
+  $ hgph -R ../alpha # a-H should have been synced to 0
+  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
+
diff --git a/tests/test-push-http.t b/tests/test-push-http.t
--- a/tests/test-push-http.t
+++ b/tests/test-push-http.t
@@ -28,6 +28,8 @@
   pushing to http://localhost:$HGPORT/
   searching for changes
   remote: ssl required
+  remote: ssl required
+  updating phase of ba677d0156c1to 0 failed!
   % serve errors
 
 expect authorization error
diff --git a/tests/test-treediscovery.t b/tests/test-treediscovery.t
--- a/tests/test-treediscovery.t
+++ b/tests/test-treediscovery.t
@@ -42,7 +42,7 @@
   $ hg pull -R empty1 $remote
   pulling from http://localhost:$HGPORT/
   no changes found
-  $ hg push -R empty1 $remote
+  $ hg push -R empty1 $remote --traceback
   pushing to http://localhost:$HGPORT/
   no changes found
   $ tstop


More information about the Mercurial-devel mailing list