[PATCH 6 of 8] obsolete: exchange obsolete marker over pushkey
pierre-yves.david at logilab.fr
pierre-yves.david at logilab.fr
Thu Jun 7 17:24:57 UTC 2012
# HG changeset patch
# User Pierre-Yves.David at ens-lyon.org
# Date 1339089719 -7200
# Node ID e1d9043377d43a41c37f086aadfbe0552854c29a
# Parent 740baee7f4950cb25ef79fa0782c1b8dfe8ffb92
obsolete: exchange obsolete marker over pushkey
For a version of the exchange, all markers are exchange. This won't
scale and we will need a better protocol later.
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -2,16 +2,15 @@
#
# Copyright 2005-2007 Matt Mackall <mpm at selenic.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-
from node import bin, hex, nullid, nullrev, short
from i18n import _
import repo, changegroup, subrepo, discovery, pushkey, obsolete
import changelog, dirstate, filelog, manifest, context, bookmarks, phases
-import lock, transaction, store, encoding
+import lock, transaction, store, encoding, base85
import scmutil, util, extensions, hook, error, revset
import match as matchmod
import merge as mergemod
import tags as tagsmod
from lock import release
@@ -1617,10 +1616,15 @@ class localrepository(repo.repository):
phases.advanceboundary(self, phases.draft, subset)
else:
# Remote is old or publishing all common changesets
# should be seen as public
phases.advanceboundary(self, phases.public, subset)
+
+ remoteobs = remote.listkeys('obsolete')
+ if 'dump' in remoteobs:
+ data = base85.b85decode(remoteobs['dump'])
+ self.obsstore.mergemarkers(data)
finally:
lock.release()
return result
@@ -1757,10 +1761,16 @@ class localrepository(repo.repository):
str(phases.draft),
str(phases.public))
if not r:
self.ui.warn(_('updating %s to public failed!\n')
% newremotehead)
+ if 'obsolete' in self.listkeys('namespaces') and self.obsstore:
+ data = self.obsstore._writemarkers()
+ r = remote.pushkey('obsolete', 'dump', '',
+ base85.b85encode(data))
+ if not r:
+ self.ui.warn(_('failed to push obsolete markers!\n'))
finally:
if lock is not None:
lock.release()
finally:
locallock.release()
diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py
--- a/mercurial/obsolete.py
+++ b/mercurial/obsolete.py
@@ -50,11 +50,11 @@ The header is followed by the markers. E
string contains a key and a value, separated by a color ':', without
additional encoding. Keys cannot contain '\0' or ':' and values
cannot contain '\0'.
"""
import struct
-from mercurial import util
+from mercurial import util, base85
from i18n import _
_pack = struct.pack
_unpack = struct.unpack
@@ -164,10 +164,13 @@ class obsstore(object):
self.successors = {}
def __iter__(self):
return iter(self._all)
+ def __nonzero__(self):
+ return bool(self._all)
+
def create(self, prec, succs=(), flag=0, metadata=None):
"""obsolete: add a new obsolete marker
* ensuring it is hashable
* check mandatory metadata
@@ -193,10 +196,17 @@ class obsstore(object):
def loadmarkers(self, data):
"""Load all markers in data, mark them as known."""
for marker in _readmarkers(data):
self._load(marker)
+ def mergemarkers(self, data):
+ other = set(_readmarkers(data))
+ local = set(self._all)
+ new = other - local
+ for marker in new:
+ self.add(marker)
+
def flushmarkers(self, stream):
"""Write all markers to a stream
After this operation, "new" markers are considered "known"."""
self._writemarkers(stream)
@@ -207,24 +217,52 @@ class obsstore(object):
pre, sucs = marker[:2]
self.precursors.setdefault(pre, set()).add(marker)
for suc in sucs:
self.successors.setdefault(suc, set()).add(marker)
- def _writemarkers(self, stream):
+ def _writemarkers(self, stream=None):
# Kept separate from flushmarkers(), it will be reused for
# markers exchange.
- stream.write(_pack('>B', _fmversion))
+ if stream is None:
+ final = []
+ w = final.append
+ else:
+ w = stream.write
+ w(_pack('>B', _fmversion))
for marker in self._all:
pre, sucs, flags, metadata = marker
nbsuc = len(sucs)
format = _fmfixed + (_fmnode * nbsuc)
data = [nbsuc, len(metadata), flags, pre]
data.extend(sucs)
- stream.write(_pack(format, *data))
- stream.write(metadata)
+ w(_pack(format, *data))
+ w(metadata)
+ if stream is None:
+ return ''.join(final)
+def listmarkers(repo):
+ """List markers over pushkey"""
+ if not repo.obsstore:
+ return {}
+ data = repo.obsstore._writemarkers()
+ return {'dump': base85.b85encode(data)}
+def pushmarker(repo, key, old, new):
+ """Push markers over pushkey"""
+ if key != 'dump':
+ repo.ui.warn(_('unknown key: %r') % key)
+ return 0
+ if old:
+ repo.ui.warn(_('unexpected old value') % key)
+ return 0
+ data = base85.b85decode(new)
+ lock = repo.lock()
+ try:
+ repo.obsstore.mergemarkers(data)
+ return 1
+ finally:
+ lock.release()
def allmarkers(repo):
"""all obsolete markers known in a repository"""
for markerdata in repo.obsstore:
yield marker(repo, markerdata)
diff --git a/mercurial/pushkey.py b/mercurial/pushkey.py
--- a/mercurial/pushkey.py
+++ b/mercurial/pushkey.py
@@ -3,21 +3,22 @@
# Copyright 2010 Matt Mackall <mpm at selenic.com>
#
# 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, phases
+import bookmarks, phases, obsolete
def _nslist(repo):
n = {}
for k in _namespaces:
n[k] = ""
return n
_namespaces = {"namespaces": (lambda *x: False, _nslist),
"bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks),
"phases": (phases.pushphase, phases.listphases),
+ "obsolete": (obsolete.pushmarker, obsolete.listmarkers),
}
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
@@ -38,10 +38,11 @@ import bookmark by name
Z 0:4e3505fd9583
$ hg debugpushkey ../a namespaces
bookmarks
phases
namespaces
+ obsolete
$ hg debugpushkey ../a bookmarks
Y 4e3505fd95835d721066b76e75dbb8cc554d7f77
X 4e3505fd95835d721066b76e75dbb8cc554d7f77
Z 4e3505fd95835d721066b76e75dbb8cc554d7f77
$ hg pull -B X ../a
@@ -202,10 +203,11 @@ hgweb
$ hg debugpushkey http://localhost:$HGPORT/ namespaces
bookmarks
phases
namespaces
+ obsolete
$ hg debugpushkey http://localhost:$HGPORT/ bookmarks
Y 4efff6d98829d9c824c621afd6e3f01865f5439f
foobar 9b140be1080824d768c5a4691a564088eede71f9
Z 0d2164f0ce0d8f1d6f94351eba04b794909be66c
foo 0000000000000000000000000000000000000000
diff --git a/tests/test-hook.t b/tests/test-hook.t
--- a/tests/test-hook.t
+++ b/tests/test-hook.t
@@ -192,10 +192,11 @@ listkeys hook
$ hg pull -B bar ../a
pulling from ../a
listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
no changes found
listkeys hook: HG_NAMESPACE=phases HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
+ listkeys hook: HG_NAMESPACE=obsolete HG_VALUES={}
listkeys hook: HG_NAMESPACE=bookmarks HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
adding remote bookmark bar
importing bookmark bar
$ cd ../a
diff --git a/tests/test-http-proxy.t b/tests/test-http-proxy.t
--- a/tests/test-http-proxy.t
+++ b/tests/test-http-proxy.t
@@ -103,22 +103,26 @@ do not use the proxy if it is in the no
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=batch HTTP/1.1" - - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=getbundle HTTP/1.1" - - x-hgarg-1:common=0000000000000000000000000000000000000000&heads=83180e7845de420a1bb46896fd5fe05294f8d629 (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=phases (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=obsolete (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys HTTP/1.1" - - x-hgarg-1:namespace=bookmarks (glob)
diff --git a/tests/test-https.t b/tests/test-https.t
--- a/tests/test-https.t
+++ b/tests/test-https.t
@@ -117,10 +117,11 @@ clone via pull
adding changesets
adding manifests
adding file changes
added 1 changesets with 4 changes to 4 files
warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
+ warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
updating to branch default
4 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg verify -R copy-pull
checking changesets
checking manifests
@@ -146,10 +147,11 @@ pull without cacert
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
changegroup hook: HG_NODE=5fed3813f7f5e1824344fdc9cf8f63bb662c292d HG_SOURCE=pull HG_URL=https://localhost:$HGPORT/
+ warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
(run 'hg update' to get a working copy)
$ cd ..
cacert configured in local repo
@@ -174,10 +176,11 @@ variables in the filename
$ P=`pwd` hg -R copy-pull pull --insecure
warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
pulling from https://localhost:$HGPORT/
searching for changes
no changes found
+ warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
cacert mismatch
$ hg -R copy-pull pull --config web.cacerts=pub.pem https://127.0.0.1:$HGPORT/
abort: 127.0.0.1 certificate error: certificate is for localhost
@@ -186,18 +189,20 @@ cacert mismatch
$ hg -R copy-pull pull --config web.cacerts=pub.pem https://127.0.0.1:$HGPORT/ --insecure
warning: 127.0.0.1 certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
pulling from https://127.0.0.1:$HGPORT/
searching for changes
no changes found
+ warning: 127.0.0.1 certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
$ hg -R copy-pull pull --config web.cacerts=pub-other.pem
abort: error: *:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed (glob)
[255]
$ hg -R copy-pull pull --config web.cacerts=pub-other.pem --insecure
warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
pulling from https://localhost:$HGPORT/
searching for changes
no changes found
+ warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
Test server cert which isn't valid yet
$ hg -R test serve -p $HGPORT1 -d --pid-file=hg1.pid --certificate=server-not-yet.pem
$ cat hg1.pid >> $DAEMON_PIDS
@@ -251,10 +256,11 @@ Test unvalidated https through proxy
$ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull --insecure --traceback
warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
pulling from https://localhost:$HGPORT/
searching for changes
no changes found
+ warning: localhost certificate with fingerprint 91:4f:1a:ff:87:24:9c:09:b6:85:9b:88:b1:90:6d:30:75:64:91:ca not verified (check hostfingerprints or web.cacerts config setting)
Test https with cacert and fingerprint through proxy
$ http_proxy=http://localhost:$HGPORT1/ hg -R copy-pull pull --config web.cacerts=pub.pem
pulling from https://localhost:$HGPORT/
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -57,5 +57,87 @@ Register two markers with a missing node
$ hg debugobsolete
245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'}
cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
+
+ $ cd ..
+
+Exchange Test
+============================
+
+Destination repo does not have any data
+---------------------------------------
+
+Try to pull markers
+
+ $ hg init tmpc
+ $ cd tmpc
+ $ hg pull ../tmpb
+ pulling from ../tmpb
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 6 changesets with 6 changes to 6 files (+3 heads)
+ (run 'hg heads' to see heads, 'hg merge' to merge)
+ $ hg debugobsolete
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
+
+ $ cd ..
+
+Try to pull markers
+
+ $ hg init tmpd
+ $ hg -R tmpb push tmpd
+ pushing to tmpd
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 6 changesets with 6 changes to 6 files (+3 heads)
+ $ hg -R tmpd debugobsolete
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
+
+
+Destination repo have existing data
+---------------------------------------
+
+On pull
+
+ $ hg init tmpe
+ $ cd tmpe
+ $ hg debugobsolete -d '1339 0' 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339
+ $ hg pull ../tmpb
+ pulling from ../tmpb
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 6 changesets with 6 changes to 6 files (+3 heads)
+ (run 'hg heads' to see heads, 'hg merge' to merge)
+ $ hg debugobsolete
+ 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
+
+On push
+
+ $ hg push ../tmpc
+ pushing to ../tmpc
+ searching for changes
+ no changes found
+ [1]
+ $ hg -R ../tmpc debugobsolete
+ ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
+ cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
+ 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f 0 {'date': '56 12', 'user': 'test'}
+ 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
+ 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
diff --git a/tests/test-ssh.t b/tests/test-ssh.t
--- a/tests/test-ssh.t
+++ b/tests/test-ssh.t
@@ -165,10 +165,11 @@ test pushkeys and bookmarks
$ cd ../local
$ hg debugpushkey --config ui.ssh="python \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
bookmarks
phases
namespaces
+ obsolete
$ hg book foo -r 0
$ hg out -B
comparing with ssh://user@dummy/remote
searching for changed bookmarks
foo 1160648e36ce
More information about the Mercurial-devel
mailing list