bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 2018.5.157
by Andrew Bennetts Remove unnecessary trivial divergences from bzr.dev. | 1 | # Copyright (C) 2006, 2007 Canonical Ltd
 | 
| 2018.5.4
by Andrew Bennetts Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler. | 2 | #
 | 
| 3 | # This program is free software; you can redistribute it and/or modify
 | |
| 4 | # it under the terms of the GNU General Public License as published by
 | |
| 5 | # the Free Software Foundation; either version 2 of the License, or
 | |
| 6 | # (at your option) any later version.
 | |
| 7 | #
 | |
| 8 | # This program is distributed in the hope that it will be useful,
 | |
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| 11 | # GNU General Public License for more details.
 | |
| 12 | #
 | |
| 13 | # You should have received a copy of the GNU General Public License
 | |
| 14 | # along with this program; if not, write to the Free Software
 | |
| 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
| 16 | ||
| 2018.5.19
by Andrew Bennetts Add docstrings to all the new modules, and a few other places. | 17 | """Basic server-side logic for dealing with requests."""
 | 
| 18 | ||
| 19 | ||
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 20 | import tempfile | 
| 21 | ||
| 2402.1.2
by Andrew Bennetts Deal with review comments. | 22 | from bzrlib import ( | 
| 23 | bzrdir, | |
| 24 | errors, | |
| 25 | registry, | |
| 26 | revision, | |
| 27 |     )
 | |
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 28 | from bzrlib.bundle.serializer import write_bundle | 
| 29 | ||
| 2018.5.4
by Andrew Bennetts Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler. | 30 | |
| 31 | class SmartServerRequest(object): | |
| 2402.1.2
by Andrew Bennetts Deal with review comments. | 32 | """Base class for request handlers.""" | 
| 2018.5.4
by Andrew Bennetts Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler. | 33 | |
| 34 | def __init__(self, backing_transport): | |
| 2402.1.2
by Andrew Bennetts Deal with review comments. | 35 | """Constructor. | 
| 36 | ||
| 37 |         :param backing_transport: the base transport to be used when performing
 | |
| 38 |             this request.
 | |
| 39 |         """
 | |
| 2018.5.4
by Andrew Bennetts Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler. | 40 | self._backing_transport = backing_transport | 
| 2018.5.5
by Andrew Bennetts Pass body_bytes directly to SmartServerRequest.do_body | 41 | |
| 2018.5.24
by Andrew Bennetts Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts) | 42 | def _check_enabled(self): | 
| 43 | """Raises DisabledMethod if this method is disabled.""" | |
| 44 |         pass
 | |
| 45 | ||
| 2018.5.19
by Andrew Bennetts Add docstrings to all the new modules, and a few other places. | 46 | def do(self, *args): | 
| 2018.5.24
by Andrew Bennetts Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts) | 47 | """Mandatory extension point for SmartServerRequest subclasses. | 
| 48 |         
 | |
| 49 |         Subclasses must implement this.
 | |
| 2018.5.19
by Andrew Bennetts Add docstrings to all the new modules, and a few other places. | 50 |         
 | 
| 51 |         This should return a SmartServerResponse if this command expects to
 | |
| 52 |         receive no body.
 | |
| 53 |         """
 | |
| 2018.5.5
by Andrew Bennetts Pass body_bytes directly to SmartServerRequest.do_body | 54 | raise NotImplementedError(self.do) | 
| 55 | ||
| 2018.5.24
by Andrew Bennetts Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts) | 56 | def execute(self, *args): | 
| 57 | """Public entry point to execute this request. | |
| 58 | ||
| 59 |         It will return a SmartServerResponse if the command does not expect a
 | |
| 60 |         body.
 | |
| 61 | ||
| 62 |         :param *args: the arguments of the request.
 | |
| 63 |         """
 | |
| 64 | self._check_enabled() | |
| 65 | return self.do(*args) | |
| 66 | ||
| 2018.5.5
by Andrew Bennetts Pass body_bytes directly to SmartServerRequest.do_body | 67 | def do_body(self, body_bytes): | 
| 2018.5.19
by Andrew Bennetts Add docstrings to all the new modules, and a few other places. | 68 | """Called if the client sends a body with the request. | 
| 69 |         
 | |
| 70 |         Must return a SmartServerResponse.
 | |
| 71 |         """
 | |
| 72 |         # TODO: if a client erroneously sends a request that shouldn't have a
 | |
| 73 |         # body, what to do?  Probably SmartServerRequestHandler should catch
 | |
| 74 |         # this NotImplementedError and translate it into a 'bad request' error
 | |
| 75 |         # to send to the client.
 | |
| 2018.5.4
by Andrew Bennetts Split smart server VFS logic out into a new file, and start using the command pattern in the SmartServerRequestHandler. | 76 | raise NotImplementedError(self.do_body) | 
| 77 | ||
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 78 | |
| 2018.5.16
by Andrew Bennetts Move SmartServerResponse to smart/request.py, untangling more import dependencies. | 79 | class SmartServerResponse(object): | 
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 80 | """A response to a client request. | 
| 81 |     
 | |
| 82 |     This base class should not be used. Instead use
 | |
| 83 |     SuccessfulSmartServerResponse and FailedSmartServerResponse as appropriate.
 | |
| 84 |     """
 | |
| 2018.5.16
by Andrew Bennetts Move SmartServerResponse to smart/request.py, untangling more import dependencies. | 85 | |
| 86 | def __init__(self, args, body=None): | |
| 87 | self.args = args | |
| 88 | self.body = body | |
| 89 | ||
| 2402.1.1
by Andrew Bennetts Use the Command pattern for handling smart server commands. | 90 | def __eq__(self, other): | 
| 91 | if other is None: | |
| 92 | return False | |
| 93 | return other.args == self.args and other.body == self.body | |
| 94 | ||
| 95 | def __repr__(self): | |
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 96 | return "<SmartServerResponse args=%r body=%r>" % (self.is_successful(), | 
| 97 | self.args, self.body) | |
| 2402.1.1
by Andrew Bennetts Use the Command pattern for handling smart server commands. | 98 | |
| 2018.5.16
by Andrew Bennetts Move SmartServerResponse to smart/request.py, untangling more import dependencies. | 99 | |
| 2432.4.2
by Robert Collins Add FailedSmartServerResponse. | 100 | class FailedSmartServerResponse(SmartServerResponse): | 
| 101 | """A SmartServerResponse for a request which failed.""" | |
| 102 | ||
| 103 | def is_successful(self): | |
| 104 | """FailedSmartServerResponse are not successful.""" | |
| 105 | return False | |
| 106 | ||
| 107 | ||
| 2432.4.1
by Robert Collins Add SuccessfulSmartServerResponse. | 108 | class SuccessfulSmartServerResponse(SmartServerResponse): | 
| 109 | """A SmartServerResponse for a successfully completed request.""" | |
| 110 | ||
| 111 | def is_successful(self): | |
| 112 | """SuccessfulSmartServerResponse are successful.""" | |
| 113 | return True | |
| 114 | ||
| 2018.5.16
by Andrew Bennetts Move SmartServerResponse to smart/request.py, untangling more import dependencies. | 115 | |
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 116 | class SmartServerRequestHandler(object): | 
| 117 | """Protocol logic for smart server. | |
| 118 |     
 | |
| 119 |     This doesn't handle serialization at all, it just processes requests and
 | |
| 120 |     creates responses.
 | |
| 121 |     """
 | |
| 122 | ||
| 123 |     # IMPORTANT FOR IMPLEMENTORS: It is important that SmartServerRequestHandler
 | |
| 124 |     # not contain encoding or decoding logic to allow the wire protocol to vary
 | |
| 125 |     # from the object protocol: we will want to tweak the wire protocol separate
 | |
| 126 |     # from the object model, and ideally we will be able to do that without
 | |
| 127 |     # having a SmartServerRequestHandler subclass for each wire protocol, rather
 | |
| 128 |     # just a Protocol subclass.
 | |
| 129 | ||
| 130 |     # TODO: Better way of representing the body for commands that take it,
 | |
| 131 |     # and allow it to be streamed into the server.
 | |
| 132 | ||
| 2018.5.17
by Andrew Bennetts Paramaterise the commands handled by SmartServerRequestHandler. | 133 | def __init__(self, backing_transport, commands): | 
| 134 | """Constructor. | |
| 135 | ||
| 136 |         :param backing_transport: a Transport to handle requests for.
 | |
| 2018.5.23
by Andrew Bennetts Use a Registry for smart server command handlers. | 137 |         :param commands: a registry mapping command names to SmartServerRequest
 | 
| 2018.5.17
by Andrew Bennetts Paramaterise the commands handled by SmartServerRequestHandler. | 138 |             subclasses. e.g. bzrlib.transport.smart.vfs.vfs_commands.
 | 
| 139 |         """
 | |
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 140 | self._backing_transport = backing_transport | 
| 2018.5.17
by Andrew Bennetts Paramaterise the commands handled by SmartServerRequestHandler. | 141 | self._commands = commands | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 142 | self._body_bytes = '' | 
| 143 | self.response = None | |
| 144 | self.finished_reading = False | |
| 145 | self._command = None | |
| 146 | ||
| 147 | def accept_body(self, bytes): | |
| 148 | """Accept body data.""" | |
| 149 | ||
| 150 |         # TODO: This should be overriden for each command that desired body data
 | |
| 151 |         # to handle the right format of that data, i.e. plain bytes, a bundle,
 | |
| 152 |         # etc.  The deserialisation into that format should be done in the
 | |
| 153 |         # Protocol object.
 | |
| 154 | ||
| 155 |         # default fallback is to accumulate bytes.
 | |
| 156 | self._body_bytes += bytes | |
| 157 | ||
| 158 | def end_of_body(self): | |
| 159 | """No more body data will be received.""" | |
| 160 | self._run_handler_code(self._command.do_body, (self._body_bytes,), {}) | |
| 161 |         # cannot read after this.
 | |
| 162 | self.finished_reading = True | |
| 163 | ||
| 164 | def dispatch_command(self, cmd, args): | |
| 165 | """Deprecated compatibility method.""" # XXX XXX | |
| 2018.5.23
by Andrew Bennetts Use a Registry for smart server command handlers. | 166 | try: | 
| 167 | command = self._commands.get(cmd) | |
| 168 | except LookupError: | |
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 169 | raise errors.SmartProtocolError("bad request %r" % (cmd,)) | 
| 170 | self._command = command(self._backing_transport) | |
| 2018.5.24
by Andrew Bennetts Setting NO_SMART_VFS in environment will disable VFS methods in the smart server. (Robert Collins, John Arbash Meinel, Andrew Bennetts) | 171 | self._run_handler_code(self._command.execute, args, {}) | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 172 | |
| 173 | def _run_handler_code(self, callable, args, kwargs): | |
| 174 | """Run some handler specific code 'callable'. | |
| 175 | ||
| 176 |         If a result is returned, it is considered to be the commands response,
 | |
| 177 |         and finished_reading is set true, and its assigned to self.response.
 | |
| 178 | ||
| 179 |         Any exceptions caught are translated and a response object created
 | |
| 180 |         from them.
 | |
| 181 |         """
 | |
| 182 | result = self._call_converting_errors(callable, args, kwargs) | |
| 2018.5.19
by Andrew Bennetts Add docstrings to all the new modules, and a few other places. | 183 | |
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 184 | if result is not None: | 
| 185 | self.response = result | |
| 186 | self.finished_reading = True | |
| 187 | ||
| 188 | def _call_converting_errors(self, callable, args, kwargs): | |
| 189 | """Call callable converting errors to Response objects.""" | |
| 190 |         # XXX: most of this error conversion is VFS-related, and thus ought to
 | |
| 191 |         # be in SmartServerVFSRequestHandler somewhere.
 | |
| 192 | try: | |
| 193 | return callable(*args, **kwargs) | |
| 194 | except errors.NoSuchFile, e: | |
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 195 | return FailedSmartServerResponse(('NoSuchFile', e.path)) | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 196 | except errors.FileExists, e: | 
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 197 | return FailedSmartServerResponse(('FileExists', e.path)) | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 198 | except errors.DirectoryNotEmpty, e: | 
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 199 | return FailedSmartServerResponse(('DirectoryNotEmpty', e.path)) | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 200 | except errors.ShortReadvError, e: | 
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 201 | return FailedSmartServerResponse(('ShortReadvError', | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 202 | e.path, str(e.offset), str(e.length), str(e.actual))) | 
| 203 | except UnicodeError, e: | |
| 204 |             # If it is a DecodeError, than most likely we are starting
 | |
| 205 |             # with a plain string
 | |
| 206 | str_or_unicode = e.object | |
| 207 | if isinstance(str_or_unicode, unicode): | |
| 208 |                 # XXX: UTF-8 might have \x01 (our seperator byte) in it.  We
 | |
| 209 |                 # should escape it somehow.
 | |
| 210 | val = 'u:' + str_or_unicode.encode('utf-8') | |
| 211 | else: | |
| 212 | val = 's:' + str_or_unicode.encode('base64') | |
| 213 |             # This handles UnicodeEncodeError or UnicodeDecodeError
 | |
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 214 | return FailedSmartServerResponse((e.__class__.__name__, | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 215 | e.encoding, val, str(e.start), str(e.end), e.reason)) | 
| 216 | except errors.TransportNotPossible, e: | |
| 217 | if e.msg == "readonly transport": | |
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 218 | return FailedSmartServerResponse(('ReadOnlyError', )) | 
| 2018.5.14
by Andrew Bennetts Move SmartTCPServer to smart/server.py, and SmartServerRequestHandler to smart/request.py. | 219 | else: | 
| 220 |                 raise
 | |
| 221 | ||
| 222 | ||
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 223 | class HelloRequest(SmartServerRequest): | 
| 2432.2.6
by Andrew Bennetts Improve HelloRequest's docstring. | 224 | """Answer a version request with the highest protocol version this server | 
| 225 |     supports.
 | |
| 226 |     """
 | |
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 227 | |
| 228 | def do(self): | |
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 229 | return SuccessfulSmartServerResponse(('ok', '2')) | 
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 230 | |
| 231 | ||
| 232 | class GetBundleRequest(SmartServerRequest): | |
| 2402.1.2
by Andrew Bennetts Deal with review comments. | 233 | """Get a bundle of from the null revision to the specified revision.""" | 
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 234 | |
| 235 | def do(self, path, revision_id): | |
| 236 |         # open transport relative to our base
 | |
| 237 | t = self._backing_transport.clone(path) | |
| 238 | control, extra_path = bzrdir.BzrDir.open_containing_from_transport(t) | |
| 239 | repo = control.open_repository() | |
| 240 | tmpf = tempfile.TemporaryFile() | |
| 241 | base_revision = revision.NULL_REVISION | |
| 242 | write_bundle(repo, revision_id, base_revision, tmpf) | |
| 243 | tmpf.seek(0) | |
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 244 | return SuccessfulSmartServerResponse((), tmpf.read()) | 
| 2018.5.6
by Andrew Bennetts Tidy ups, and turn do_hello and do_get_bundle into command objects. | 245 | |
| 246 | ||
| 2018.5.95
by Andrew Bennetts Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes. | 247 | class SmartServerIsReadonly(SmartServerRequest): | 
| 248 |     # XXX: this request method belongs somewhere else.
 | |
| 249 | ||
| 250 | def do(self): | |
| 251 | if self._backing_transport.is_readonly(): | |
| 252 | answer = 'yes' | |
| 253 | else: | |
| 254 | answer = 'no' | |
| 2432.4.5
by Robert Collins Make using SuccessfulSmartServerResponse and FailedSmartServerResponse mandatory rather than optional in smart server logic. | 255 | return SuccessfulSmartServerResponse((answer,)) | 
| 2018.5.95
by Andrew Bennetts Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes. | 256 | |
| 257 | ||
| 2018.5.23
by Andrew Bennetts Use a Registry for smart server command handlers. | 258 | request_handlers = registry.Registry() | 
| 259 | request_handlers.register_lazy( | |
| 260 | 'append', 'bzrlib.smart.vfs', 'AppendRequest') | |
| 261 | request_handlers.register_lazy( | |
| 2018.5.59
by Robert Collins Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil). | 262 | 'Branch.get_config_file', 'bzrlib.smart.branch', 'SmartServerBranchGetConfigFile') | 
| 263 | request_handlers.register_lazy( | |
| 2018.5.51
by Wouter van Heyst Test and implement RemoteBranch.last_revision_info() | 264 | 'Branch.last_revision_info', 'bzrlib.smart.branch', 'SmartServerBranchRequestLastRevisionInfo') | 
| 265 | request_handlers.register_lazy( | |
| 2018.5.79
by Andrew Bennetts Implement RemoteBranch.lock_write/unlock as smart operations. | 266 | 'Branch.lock_write', 'bzrlib.smart.branch', 'SmartServerBranchRequestLockWrite') | 
| 267 | request_handlers.register_lazy( | |
| 2018.5.38
by Robert Collins Implement RemoteBranch.revision_history(). | 268 | 'Branch.revision_history', 'bzrlib.smart.branch', 'SmartServerRequestRevisionHistory') | 
| 269 | request_handlers.register_lazy( | |
| 2018.5.77
by Wouter van Heyst Fix typo in request_handlers registration of Branch.set_last_revision, and test that registration | 270 | 'Branch.set_last_revision', 'bzrlib.smart.branch', 'SmartServerBranchRequestSetLastRevision') | 
| 2018.12.3
by Andrew Bennetts Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it. | 271 | request_handlers.register_lazy( | 
| 2018.5.79
by Andrew Bennetts Implement RemoteBranch.lock_write/unlock as smart operations. | 272 | 'Branch.unlock', 'bzrlib.smart.branch', 'SmartServerBranchRequestUnlock') | 
| 273 | request_handlers.register_lazy( | |
| 2018.5.34
by Robert Collins Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository. | 274 | 'BzrDir.find_repository', 'bzrlib.smart.bzrdir', 'SmartServerRequestFindRepository') | 
| 275 | request_handlers.register_lazy( | |
| 2018.5.42
by Robert Collins Various hopefully improvements, but wsgi is broken, handing over to spiv :). | 276 | 'BzrDirFormat.initialize', 'bzrlib.smart.bzrdir', 'SmartServerRequestInitializeBzrDir') | 
| 277 | request_handlers.register_lazy( | |
| 2018.6.1
by Robert Collins Implement a BzrDir.open_branch smart server method for opening a branch without VFS. | 278 | 'BzrDir.open_branch', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBranch') | 
| 279 | request_handlers.register_lazy( | |
| 2018.5.23
by Andrew Bennetts Use a Registry for smart server command handlers. | 280 | 'delete', 'bzrlib.smart.vfs', 'DeleteRequest') | 
| 281 | request_handlers.register_lazy( | |
| 282 | 'get', 'bzrlib.smart.vfs', 'GetRequest') | |
| 283 | request_handlers.register_lazy( | |
| 284 | 'get_bundle', 'bzrlib.smart.request', 'GetBundleRequest') | |
| 285 | request_handlers.register_lazy( | |
| 286 | 'has', 'bzrlib.smart.vfs', 'HasRequest') | |
| 287 | request_handlers.register_lazy( | |
| 288 | 'hello', 'bzrlib.smart.request', 'HelloRequest') | |
| 289 | request_handlers.register_lazy( | |
| 2018.5.37
by Andrew Bennetts Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names. | 290 | 'iter_files_recursive', 'bzrlib.smart.vfs', 'IterFilesRecursiveRequest') | 
| 2018.5.23
by Andrew Bennetts Use a Registry for smart server command handlers. | 291 | request_handlers.register_lazy( | 
| 292 | 'list_dir', 'bzrlib.smart.vfs', 'ListDirRequest') | |
| 293 | request_handlers.register_lazy( | |
| 2018.5.37
by Andrew Bennetts Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names. | 294 | 'mkdir', 'bzrlib.smart.vfs', 'MkdirRequest') | 
| 295 | request_handlers.register_lazy( | |
| 296 | 'move', 'bzrlib.smart.vfs', 'MoveRequest') | |
| 297 | request_handlers.register_lazy( | |
| 298 | 'put', 'bzrlib.smart.vfs', 'PutRequest') | |
| 299 | request_handlers.register_lazy( | |
| 300 | 'put_non_atomic', 'bzrlib.smart.vfs', 'PutNonAtomicRequest') | |
| 301 | request_handlers.register_lazy( | |
| 302 | 'readv', 'bzrlib.smart.vfs', 'ReadvRequest') | |
| 303 | request_handlers.register_lazy( | |
| 304 | 'rename', 'bzrlib.smart.vfs', 'RenameRequest') | |
| 2018.10.2
by v.ladeuil+lp at free gather_stats server side and request registration | 305 | request_handlers.register_lazy('Repository.gather_stats', | 
| 306 | 'bzrlib.smart.repository', | |
| 307 | 'SmartServerRepositoryGatherStats') | |
| 2018.5.37
by Andrew Bennetts Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names. | 308 | request_handlers.register_lazy( | 
| 2018.5.67
by Wouter van Heyst Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins) | 309 | 'Repository.get_revision_graph', 'bzrlib.smart.repository', 'SmartServerRepositoryGetRevisionGraph') | 
| 310 | request_handlers.register_lazy( | |
| 2018.5.40
by Robert Collins Implement a remote Repository.has_revision method. | 311 | 'Repository.has_revision', 'bzrlib.smart.repository', 'SmartServerRequestHasRevision') | 
| 312 | request_handlers.register_lazy( | |
| 2018.5.57
by Robert Collins Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil). | 313 | 'Repository.is_shared', 'bzrlib.smart.repository', 'SmartServerRepositoryIsShared') | 
| 314 | request_handlers.register_lazy( | |
| 2018.5.78
by Andrew Bennetts Implement RemoteRepository.lock_write/unlock to expect and send tokens over the | 315 | 'Repository.lock_write', 'bzrlib.smart.repository', 'SmartServerRepositoryLockWrite') | 
| 316 | request_handlers.register_lazy( | |
| 317 | 'Repository.unlock', 'bzrlib.smart.repository', 'SmartServerRepositoryUnlock') | |
| 318 | request_handlers.register_lazy( | |
| 2018.18.1
by Martin Pool Add stub Repository.tarball smart method | 319 | 'Repository.tarball', 'bzrlib.smart.repository', | 
| 320 | 'SmartServerRepositoryTarball') | |
| 321 | request_handlers.register_lazy( | |
| 2018.5.37
by Andrew Bennetts Make sure all the request handlers in bzrlib/smart/vfs.py have consistent names. | 322 | 'rmdir', 'bzrlib.smart.vfs', 'RmdirRequest') | 
| 323 | request_handlers.register_lazy( | |
| 324 | 'stat', 'bzrlib.smart.vfs', 'StatRequest') | |
| 2018.5.26
by Andrew Bennetts Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport. | 325 | request_handlers.register_lazy( | 
| 2018.5.95
by Andrew Bennetts Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes. | 326 | 'Transport.is_readonly', 'bzrlib.smart.request', 'SmartServerIsReadonly') | 
| 327 | request_handlers.register_lazy( | |
| 2018.5.163
by Andrew Bennetts Deal with various review comments from Robert. | 328 | 'BzrDir.open', 'bzrlib.smart.bzrdir', 'SmartServerRequestOpenBzrDir') |