diff --git a/mercurial/phases.py b/mercurial/phases.py --- a/mercurial/phases.py +++ b/mercurial/phases.py @@ -100,3 +100,43 @@ def retractboundary(repo, targetphase, n del repo._phaserev repo._dirtyphases = True + +def listphases(repo): + """List phases root for serialisation over pushkey""" + keys = {} + for phase in trackedphases: + for root in repo._phaseroots[phase]: + keys[hex(root)] = '%i' % phase + if repo.ui.configbool('phases', 'publish', True): + # Add an extra data to let remote know we are a publishing repo. + # Publishing repo can't just pretend they are old repo. When pushing to + # a publishing repo, the client still need to push phase boundary + # + # Push do not only push changeset. It also push phase data. New + # phase data may apply to common changeset which won't be push (as they + # are common). Here is a very simple example: + # + # 1) repo A push changeset X as draft to repo B + # 2) repo B make changeset X public + # 3) repo B push to repo A. X is not pushed but the data that X as now + # public should + # + # The server can't handle it on it's own as it has no idea of client + # phase data. + keys['publishing'] = 'True' + return keys + +def pushphase(repo, nhex, oldphasestr, newphasestr): + """List phases root for serialisation over pushkey""" + lock = repo.lock() + try: + currentphase = repo[nhex].phase() + newphase = abs(int(newphasestr)) # let's avoid negative index surprise + oldphase = abs(int(oldphasestr)) # let's avoid negative index surprise + if currentphase == oldphase and newphase < oldphase: + advanceboundary(repo, newphase, [bin(nhex)]) + return 1 + else: + return 0 + finally: + lock.release() diff --git a/mercurial/pushkey.py b/mercurial/pushkey.py --- a/mercurial/pushkey.py +++ b/mercurial/pushkey.py @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -import bookmarks +import bookmarks, phases def _nslist(repo): n = {} @@ -14,7 +14,9 @@ def _nslist(repo): return n _namespaces = {"namespaces": (lambda *x: False, _nslist), - "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks)} + "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks), + "phases": (phases.pushphase, phases.listphases), + } def register(namespace, pushkey, listkeys): _namespaces[namespace] = (pushkey, listkeys) diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t --- a/tests/test-bookmarks-pushpull.t +++ b/tests/test-bookmarks-pushpull.t @@ -34,6 +34,7 @@ import bookmark by name Y 0:4e3505fd9583 $ hg debugpushkey ../a namespaces bookmarks + phases namespaces $ hg debugpushkey ../a bookmarks Y 4e3505fd95835d721066b76e75dbb8cc554d7f77 @@ -151,6 +152,7 @@ hgweb $ hg debugpushkey http://localhost:$HGPORT/ namespaces bookmarks + phases namespaces $ hg debugpushkey http://localhost:$HGPORT/ bookmarks Y 4e3505fd95835d721066b76e75dbb8cc554d7f77 diff --git a/tests/test-ssh.t b/tests/test-ssh.t --- a/tests/test-ssh.t +++ b/tests/test-ssh.t @@ -165,6 +165,7 @@ test pushkeys and bookmarks $ cd ../local $ hg debugpushkey --config ui.ssh="python $TESTDIR/dummyssh" ssh://user@dummy/remote namespaces bookmarks + phases namespaces $ hg book foo -r 0 $ hg out -B