Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 17192:1ac628cd7113
peer: introduce real peer classes
This change separates peer implementations from the repository implementation.
localpeer currently is a simple pass-through to localrepository, except for
legacy calls, which have already been removed from localpeer. This ensures that
the local client code only uses the most modern peer API when talking to local
repos.
Peers have a .local() method which returns either None or the underlying
localrepository (or descendant thereof). Repos have a .peer() method to return
a freshly constructed localpeer. The latter is used by hg.peer(), and also to
allow folks to pass either a peer or a repo to some generic helper methods.
We might want to get rid of .peer() eventually.
The only user of locallegacypeer is debugdiscovery, which uses it to pose as a
pre-setdiscovery client. But we decided to leave the old API defined in
locallegacypeer for clarity and maybe for other uses in the future.
It might be nice to actually define the peer API directly in peer.py as stub
methods. One problem there is, however, that localpeer implements
lock/addchangegroup, whereas the true remote peers implement unbundle.
It might be desireable to get rid of this distinction eventually.
author | Peter Arrenbrecht <peter.arrenbrecht@gmail.com> |
---|---|
date | Fri, 13 Jul 2012 21:47:06 +0200 |
parents | 4253cfee08ef |
children | 1d710fe5ee0e |
comparison
equal
deleted
inserted
replaced
17191:5884812686f7 | 17192:1ac628cd7113 |
---|---|
4 # | 4 # |
5 # This software may be used and distributed according to the terms of the | 5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. | 6 # GNU General Public License version 2 or any later version. |
7 from node import bin, hex, nullid, nullrev, short | 7 from node import bin, hex, nullid, nullrev, short |
8 from i18n import _ | 8 from i18n import _ |
9 import repo, changegroup, subrepo, discovery, pushkey, obsolete | 9 import peer, changegroup, subrepo, discovery, pushkey, obsolete |
10 import changelog, dirstate, filelog, manifest, context, bookmarks, phases | 10 import changelog, dirstate, filelog, manifest, context, bookmarks, phases |
11 import lock, transaction, store, encoding, base85 | 11 import lock, transaction, store, encoding, base85 |
12 import scmutil, util, extensions, hook, error, revset | 12 import scmutil, util, extensions, hook, error, revset |
13 import match as matchmod | 13 import match as matchmod |
14 import merge as mergemod | 14 import merge as mergemod |
21 class storecache(filecache): | 21 class storecache(filecache): |
22 """filecache for files in the store""" | 22 """filecache for files in the store""" |
23 def join(self, obj, fname): | 23 def join(self, obj, fname): |
24 return obj.sjoin(fname) | 24 return obj.sjoin(fname) |
25 | 25 |
26 class localrepository(repo.repository): | 26 MODERNCAPS = set(('lookup', 'branchmap', 'pushkey', 'known', 'getbundle')) |
27 capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey', | 27 LEGACYCAPS = MODERNCAPS.union(set(['changegroupsubset'])) |
28 'known', 'getbundle')) | 28 |
29 class localpeer(peer.peerrepository): | |
30 '''peer for a local repo; reflects only the most recent API''' | |
31 | |
32 def __init__(self, repo, caps=MODERNCAPS): | |
33 peer.peerrepository.__init__(self) | |
34 self._repo = repo | |
35 self.ui = repo.ui | |
36 self._caps = repo._restrictcapabilities(caps) | |
37 self.requirements = repo.requirements | |
38 self.supportedformats = repo.supportedformats | |
39 | |
40 def close(self): | |
41 self._repo.close() | |
42 | |
43 def _capabilities(self): | |
44 return self._caps | |
45 | |
46 def local(self): | |
47 return self._repo | |
48 | |
49 def cancopy(self): | |
50 return self._repo.cancopy() # so bundlerepo can override | |
51 | |
52 def url(self): | |
53 return self._repo.url() | |
54 | |
55 def lookup(self, key): | |
56 return self._repo.lookup(key) | |
57 | |
58 def branchmap(self): | |
59 return self._repo.branchmap() | |
60 | |
61 def heads(self): | |
62 return self._repo.heads() | |
63 | |
64 def known(self, nodes): | |
65 return self._repo.known(nodes) | |
66 | |
67 def getbundle(self, source, heads=None, common=None): | |
68 return self._repo.getbundle(source, heads=heads, common=common) | |
69 | |
70 # TODO We might want to move the next two calls into legacypeer and add | |
71 # unbundle instead. | |
72 | |
73 def lock(self): | |
74 return self._repo.lock() | |
75 | |
76 def addchangegroup(self, cg, source, url): | |
77 return self._repo.addchangegroup(cg, source, url) | |
78 | |
79 def pushkey(self, namespace, key, old, new): | |
80 return self._repo.pushkey(namespace, key, old, new) | |
81 | |
82 def listkeys(self, namespace): | |
83 return self._repo.listkeys(namespace) | |
84 | |
85 def debugwireargs(self, one, two, three=None, four=None, five=None): | |
86 '''used to test argument passing over the wire''' | |
87 return "%s %s %s %s %s" % (one, two, three, four, five) | |
88 | |
89 class locallegacypeer(localpeer): | |
90 '''peer extension which implements legacy methods too; used for tests with | |
91 restricted capabilities''' | |
92 | |
93 def __init__(self, repo): | |
94 localpeer.__init__(self, repo, caps=LEGACYCAPS) | |
95 | |
96 def branches(self, nodes): | |
97 return self._repo.branches(nodes) | |
98 | |
99 def between(self, pairs): | |
100 return self._repo.between(pairs) | |
101 | |
102 def changegroup(self, basenodes, source): | |
103 return self._repo.changegroup(basenodes, source) | |
104 | |
105 def changegroupsubset(self, bases, heads, source): | |
106 return self._repo.changegroupsubset(bases, heads, source) | |
107 | |
108 class localrepository(object): | |
109 | |
29 supportedformats = set(('revlogv1', 'generaldelta')) | 110 supportedformats = set(('revlogv1', 'generaldelta')) |
30 supported = supportedformats | set(('store', 'fncache', 'shared', | 111 supported = supportedformats | set(('store', 'fncache', 'shared', |
31 'dotencode')) | 112 'dotencode')) |
32 openerreqs = set(('revlogv1', 'generaldelta')) | 113 openerreqs = set(('revlogv1', 'generaldelta')) |
33 requirements = ['revlogv1'] | 114 requirements = ['revlogv1'] |
34 | 115 |
35 def _baserequirements(self, create): | 116 def _baserequirements(self, create): |
36 return self.requirements[:] | 117 return self.requirements[:] |
37 | 118 |
38 def __init__(self, baseui, path=None, create=False): | 119 def __init__(self, baseui, path=None, create=False): |
39 repo.repository.__init__(self) | |
40 self.wopener = scmutil.opener(path, expand=True) | 120 self.wopener = scmutil.opener(path, expand=True) |
41 self.wvfs = self.wopener | 121 self.wvfs = self.wopener |
42 self.root = self.wvfs.base | 122 self.root = self.wvfs.base |
43 self.path = self.wvfs.join(".hg") | 123 self.path = self.wvfs.join(".hg") |
44 self.origroot = path | 124 self.origroot = path |
124 # (used by the filecache decorator) | 204 # (used by the filecache decorator) |
125 # | 205 # |
126 # Maps a property name to its util.filecacheentry | 206 # Maps a property name to its util.filecacheentry |
127 self._filecache = {} | 207 self._filecache = {} |
128 | 208 |
209 def close(self): | |
210 pass | |
211 | |
212 def _restrictcapabilities(self, caps): | |
213 return caps | |
214 | |
129 def _applyrequirements(self, requirements): | 215 def _applyrequirements(self, requirements): |
130 self.requirements = requirements | 216 self.requirements = requirements |
131 self.sopener.options = dict((r, 1) for r in requirements | 217 self.sopener.options = dict((r, 1) for r in requirements |
132 if r in self.openerreqs) | 218 if r in self.openerreqs) |
133 | 219 |
173 return sub.checknested(subpath[len(prefix) + 1:]) | 259 return sub.checknested(subpath[len(prefix) + 1:]) |
174 else: | 260 else: |
175 parts.pop() | 261 parts.pop() |
176 return False | 262 return False |
177 | 263 |
264 def peer(self): | |
265 return localpeer(self) # not cached to avoid reference cycle | |
266 | |
178 @filecache('bookmarks') | 267 @filecache('bookmarks') |
179 def _bookmarks(self): | 268 def _bookmarks(self): |
180 return bookmarks.read(self) | 269 return bookmarks.read(self) |
181 | 270 |
182 @filecache('bookmarks.current') | 271 @filecache('bookmarks.current') |
665 result.append(resp) | 754 result.append(resp) |
666 return result | 755 return result |
667 | 756 |
668 def local(self): | 757 def local(self): |
669 return self | 758 return self |
759 | |
760 def cancopy(self): | |
761 return self.local() # so statichttprepo's override of local() works | |
670 | 762 |
671 def join(self, f): | 763 def join(self, f): |
672 return os.path.join(self.path, f) | 764 return os.path.join(self.path, f) |
673 | 765 |
674 def wjoin(self, f): | 766 def wjoin(self, f): |