~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Robert Collins
  • Date: 2009-03-27 04:10:25 UTC
  • mfrom: (4208 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4216.
  • Revision ID: robertc@robertcollins.net-20090327041025-rgutx4q03xo4pq6l
Resolve NEWS conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
# TODO: At some point, handle upgrades by just passing the whole request
18
18
# across to run on the server.
153
153
        except errors.UnknownSmartMethod:
154
154
            medium._remember_remote_is_before((1, 13))
155
155
            return self._vfs_cloning_metadir(require_stacking=require_stacking)
 
156
        except errors.UnknownErrorFromSmartServer, err:
 
157
            if err.error_tuple != ('BranchReference',):
 
158
                raise
 
159
            # We need to resolve the branch reference to determine the
 
160
            # cloning_metadir.  This causes unnecessary RPCs to open the
 
161
            # referenced branch (and bzrdir, etc) but only when the caller
 
162
            # didn't already resolve the branch reference.
 
163
            referenced_branch = self.open_branch()
 
164
            return referenced_branch.bzrdir.cloning_metadir()
156
165
        if len(response) != 3:
157
166
            raise errors.UnexpectedSmartServerResponse(response)
158
167
        control_name, repo_name, branch_info = response
256
265
        """See BzrDir._get_tree_branch()."""
257
266
        return None, self.open_branch()
258
267
 
259
 
    def open_branch(self, _unsupported=False):
 
268
    def open_branch(self, _unsupported=False, ignore_fallbacks=False):
260
269
        if _unsupported:
261
270
            raise NotImplementedError('unsupported flag support not implemented yet.')
262
271
        if self._next_open_branch_result is not None:
268
277
        if response[0] == 'ref':
269
278
            # a branch reference, use the existing BranchReference logic.
270
279
            format = BranchReferenceFormat()
271
 
            return format.open(self, _found=True, location=response[1])
 
280
            return format.open(self, _found=True, location=response[1],
 
281
                ignore_fallbacks=ignore_fallbacks)
272
282
        branch_format_name = response[1]
273
283
        if not branch_format_name:
274
284
            branch_format_name = None
275
285
        format = RemoteBranchFormat(network_name=branch_format_name)
276
 
        return RemoteBranch(self, self.find_repository(), format=format)
 
286
        return RemoteBranch(self, self.find_repository(), format=format,
 
287
            setup_stacking=not ignore_fallbacks)
277
288
 
278
289
    def _open_repo_v1(self, path):
279
290
        verb = 'BzrDir.find_repository'
690
701
        self._ensure_real()
691
702
        return self._real_repository._generate_text_key_index()
692
703
 
693
 
    @symbol_versioning.deprecated_method(symbol_versioning.one_four)
694
 
    def get_revision_graph(self, revision_id=None):
695
 
        """See Repository.get_revision_graph()."""
696
 
        return self._get_revision_graph(revision_id)
697
 
 
698
704
    def _get_revision_graph(self, revision_id):
699
705
        """Private method for using with old (< 1.2) servers to fallback."""
700
706
        if revision_id is None:
833
839
        if not self._lock_mode:
834
840
            self._lock_mode = 'r'
835
841
            self._lock_count = 1
836
 
            self._unstacked_provider.enable_cache(cache_misses=False)
 
842
            self._unstacked_provider.enable_cache(cache_misses=True)
837
843
            if self._real_repository is not None:
838
844
                self._real_repository.lock_read()
839
845
        else:
1193
1199
            # We already found out that the server can't understand
1194
1200
            # Repository.get_parent_map requests, so just fetch the whole
1195
1201
            # graph.
1196
 
            # XXX: Note that this will issue a deprecation warning. This is ok
1197
 
            # :- its because we're working with a deprecated server anyway, and
1198
 
            # the user will almost certainly have seen a warning about the
1199
 
            # server version already.
1200
 
            rg = self.get_revision_graph()
 
1202
            #
 
1203
            # Note that this reads the whole graph, when only some keys are
 
1204
            # wanted.  On this old server there's no way (?) to get them all
 
1205
            # in one go, and the user probably will have seen a warning about
 
1206
            # the server being old anyhow.
 
1207
            rg = self._get_revision_graph(None)
1201
1208
            # There is an api discrepency between get_parent_map and
1202
1209
            # get_revision_graph. Specifically, a "key:()" pair in
1203
1210
            # get_revision_graph just means a node has no parents. For
1234
1241
        # TODO: Manage this incrementally to avoid covering the same path
1235
1242
        # repeatedly. (The server will have to on each request, but the less
1236
1243
        # work done the better).
 
1244
        #
 
1245
        # Negative caching notes:
 
1246
        # new server sends missing when a request including the revid
 
1247
        # 'include-missing:' is present in the request.
 
1248
        # missing keys are serialised as missing:X, and we then call
 
1249
        # provider.note_missing(X) for-all X
1237
1250
        parents_map = self._unstacked_provider.get_cached_map()
1238
1251
        if parents_map is None:
1239
1252
            # Repository is not locked, so there's no cache.
1240
1253
            parents_map = {}
 
1254
        # start_set is all the keys in the cache
1241
1255
        start_set = set(parents_map)
 
1256
        # result set is all the references to keys in the cache
1242
1257
        result_parents = set()
1243
1258
        for parents in parents_map.itervalues():
1244
1259
            result_parents.update(parents)
1245
1260
        stop_keys = result_parents.difference(start_set)
 
1261
        # We don't need to send ghosts back to the server as a position to
 
1262
        # stop either.
 
1263
        stop_keys.difference_update(self._unstacked_provider.missing_keys)
1246
1264
        included_keys = start_set.intersection(result_parents)
1247
1265
        start_set.difference_update(included_keys)
1248
1266
        recipe = ('manual', start_set, stop_keys, len(parents_map))
1253
1271
                raise ValueError(
1254
1272
                    "key %r not a plain string" % (key,))
1255
1273
        verb = 'Repository.get_parent_map'
1256
 
        args = (path,) + tuple(keys)
 
1274
        args = (path, 'include-missing:') + tuple(keys)
1257
1275
        try:
1258
1276
            response = self._call_with_body_bytes_expecting_body(
1259
1277
                verb, args, body)
1269
1287
            # To avoid having to disconnect repeatedly, we keep track of the
1270
1288
            # fact the server doesn't understand remote methods added in 1.2.
1271
1289
            medium._remember_remote_is_before((1, 2))
1272
 
            return self.get_revision_graph(None)
 
1290
            # Recurse just once and we should use the fallback code.
 
1291
            return self._get_parent_map_rpc(keys)
1273
1292
        response_tuple, response_handler = response
1274
1293
        if response_tuple[0] not in ['ok']:
1275
1294
            response_handler.cancel_read_body()
1286
1305
                if len(d) > 1:
1287
1306
                    revision_graph[d[0]] = d[1:]
1288
1307
                else:
1289
 
                    # No parents - so give the Graph result (NULL_REVISION,).
1290
 
                    revision_graph[d[0]] = (NULL_REVISION,)
 
1308
                    # No parents:
 
1309
                    if d[0].startswith('missing:'):
 
1310
                        revid = d[0][8:]
 
1311
                        self._unstacked_provider.note_missing_key(revid)
 
1312
                    else:
 
1313
                        # no parents - so give the Graph result
 
1314
                        # (NULL_REVISION,).
 
1315
                        revision_graph[d[0]] = (NULL_REVISION,)
1291
1316
            return revision_graph
1292
1317
 
1293
1318
    @needs_read_lock
1296
1321
        return self._real_repository.get_signature_text(revision_id)
1297
1322
 
1298
1323
    @needs_read_lock
1299
 
    @symbol_versioning.deprecated_method(symbol_versioning.one_three)
1300
 
    def get_revision_graph_with_ghosts(self, revision_ids=None):
1301
 
        self._ensure_real()
1302
 
        return self._real_repository.get_revision_graph_with_ghosts(
1303
 
            revision_ids=revision_ids)
1304
 
 
1305
 
    @needs_read_lock
1306
1324
    def get_inventory_xml(self, revision_id):
1307
1325
        self._ensure_real()
1308
1326
        return self._real_repository.get_inventory_xml(revision_id)
1743
1761
    def network_name(self):
1744
1762
        return self._network_name
1745
1763
 
1746
 
    def open(self, a_bzrdir):
1747
 
        return a_bzrdir.open_branch()
 
1764
    def open(self, a_bzrdir, ignore_fallbacks=False):
 
1765
        return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
1748
1766
 
1749
1767
    def _vfs_initialize(self, a_bzrdir):
1750
1768
        # Initialisation when using a local bzrdir object, or a non-vfs init