~ubuntu-branches/ubuntu/oneiric/bzr-svn/oneiric

« back to all changes in this revision

Viewing changes to remote.py

  • Committer: Bazaar Package Importer
  • Author(s): Jelmer Vernooij
  • Date: 2011-08-26 19:47:18 UTC
  • mfrom: (1.1.31 upstream) (3.3.8 sid)
  • Revision ID: james.westby@ubuntu.com-20110826194718-iefslmdqyftcjyxx
Tags: 1.1.0-1
* New upstream release.
 + Fixes problems with sparse revision caches. LP: #795700, LP: #664085
 + Fixes test run against bzr 2.4.0. LP: #828381

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
from bzrlib import (
23
23
    errors,
 
24
    osutils,
24
25
    trace,
25
26
    )
26
27
from bzrlib.controldir import (
65
66
        return self.branch_push_result.old_revid
66
67
 
67
68
 
 
69
class UninitializableOnRemoteTransports(errors.UninitializableFormat):
 
70
 
 
71
    _fmt = "Format %(format)s can not be initialised on non-local transports."
 
72
 
 
73
 
68
74
class SvnRemoteFormat(ControlDirFormat):
69
75
    """Format for the Subversion smart server."""
70
76
 
71
77
    supports_workingtrees = False
 
78
    fixed_components = True
72
79
    _lock_class = TransportLock
73
80
 
74
81
    @property
90
97
            return SvnRemoteAccess(transport, self)
91
98
        except subvertpy.SubversionException, (_, num):
92
99
            if num in (subvertpy.ERR_RA_DAV_REQUEST_FAILED,
93
 
                       subvertpy.ERR_RA_DAV_NOT_VCC):
 
100
                       subvertpy.ERR_RA_DAV_NOT_VCC,
 
101
                       subvertpy.ERR_RA_LOCAL_REPOS_OPEN_FAILED):
94
102
                raise errors.NotBranchError(transport.base)
95
103
            if num == subvertpy.ERR_XML_MALFORMED:
96
104
                # This *could* be an indication of an actual corrupt
137
145
 
138
146
    def initialize_on_transport(self, transport):
139
147
        """See ControlDir.initialize_on_transport()."""
140
 
        from bzrlib import osutils
141
148
        from bzrlib.plugins.svn import lazy_check_versions
142
149
        lazy_check_versions()
143
150
        from bzrlib.transport.local import LocalTransport
145
152
        from subvertpy import repos
146
153
 
147
154
        if not isinstance(transport, LocalTransport):
148
 
            raise NotImplementedError(self.initialize,
149
 
                "Can't create Subversion Repositories/branches on "
150
 
                "non-local transports")
 
155
            raise UninitializableOnRemoteTransports(self)
151
156
 
152
157
        local_path = transport.local_abspath(".").rstrip("/").encode(osutils._fs_enc)
153
158
        assert type(local_path) == str
196
201
    def break_lock(self):
197
202
        pass
198
203
 
199
 
    def clone(self, url, revision_id=None, force_new_repo=False):
200
 
        """See ControlDir.clone().
 
204
    def clone_on_transport(self, transport, revision_id=None,
 
205
        force_new_repo=False, preserve_stacking=False, stacked_on=None,
 
206
        create_prefix=False, use_existing_dir=True, no_tree=False):
 
207
        """Clone this bzrdir and its contents to transport verbatim.
201
208
 
202
 
        Not supported on Subversion connections.
 
209
        :param transport: The transport for the location to produce the clone
 
210
            at.  If the target directory does not exist, it will be created.
 
211
        :param revision_id: The tip revision-id to use for any branch or
 
212
            working tree.  If not None, then the clone operation may tune
 
213
            itself to download less data.
 
214
        :param force_new_repo: Do not use a shared repository for the target,
 
215
                               even if one is available.
 
216
        :param preserve_stacking: When cloning a stacked branch, stack the
 
217
            new branch on top of the other branch's stacked-on branch.
 
218
        :param create_prefix: Create any missing directories leading up to
 
219
            to_transport.
 
220
        :param use_existing_dir: Use an existing directory if one exists.
 
221
        :param no_tree: If set to true prevents creation of a working tree.
203
222
        """
204
 
        raise NotImplementedError(SvnRemoteAccess.clone)
 
223
        if create_prefix:
 
224
            transport.create_prefix()
 
225
        if not use_existing_dir:
 
226
            transport.mkdir(".")
 
227
        target = SvnRemoteFormat().initialize_on_transport(transport)
 
228
        target_repo = target.open_repository()
 
229
        source_repo = self.open_repository()
 
230
        target_repo.fetch(source_repo, revision_id=revision_id)
 
231
        return target
205
232
 
206
233
    def sprout(self, url, revision_id=None, force_new_repo=False,
207
234
               recurse='down', possible_transports=None,
233
260
        if stacked:
234
261
            raise errors.IncompatibleRepositories(source_repository, result_repo)
235
262
        interrepo = InterRepository.get(source_repository, result_repo)
 
263
        if revision_id is None:
 
264
            revision_id = source_branch.last_revision()
236
265
        interrepo.fetch(revision_id=revision_id,
237
266
            project=source_branch.project, mapping=source_branch.mapping,
238
267
            target_is_empty=target_is_empty)
299
328
        """See ControlDir.needs_format_conversion()."""
300
329
        return not isinstance(self._format, format.__class__)
301
330
 
302
 
    def import_branch(self, source, stop_revision=None, overwrite=False):
 
331
    def import_branch(self, source, stop_revision=None, overwrite=False, name=None):
303
332
        """Create a new branch in this repository, possibly
304
333
        with the specified history, optionally importing revisions.
305
334
 
313
342
        try:
314
343
            if stop_revision is None:
315
344
                stop_revision = source.last_revision()
316
 
            target_branch_path = self._branch_path.strip("/")
 
345
            relpath = self._determine_relpath(name)
 
346
            target_branch_path = relpath.lstrip("/")
317
347
            repos = self.find_repository()
318
348
            repos.lock_write()
319
349
            try:
327
357
                    raise errors.NotBranchError(target_branch_path)
328
358
                inter.push_new_branch(layout, project, target_branch_path,
329
359
                        stop_revision, push_metadata=True, overwrite=overwrite)
330
 
                return self.open_branch()
 
360
                return self.open_branch(name)
331
361
            finally:
332
362
                repos.unlock()
333
363
        finally:
337
367
        from bzrlib.plugins.svn.errors import NoCustomBranchPaths
338
368
        repos = self.find_repository()
339
369
        layout = repos.get_layout()
 
370
        if branch_name is None and getattr(self, "_get_selected_branch", False):
 
371
            branch_name = self._get_selected_branch()
340
372
        if branch_name is None and layout.is_branch_or_tag(self._branch_path):
341
373
            return self._branch_path
342
374
        try:
 
375
            if branch_name is not None:
 
376
                branch_name = osutils.safe_utf8(branch_name)
343
377
            return layout.get_branch_path(branch_name, self._branch_path)
344
378
        except NoCustomBranchPaths:
345
 
            raise errors.NoColocatedBranchSupport(self)
 
379
            if branch_name is None:
 
380
                return self._branch_path
 
381
            else:
 
382
                raise errors.NoColocatedBranchSupport(layout)
346
383
 
347
384
    def create_branch(self, branch_name=None, repository=None, mapping=None):
348
385
        """See ControlDir.create_branch()."""
349
386
        from bzrlib.plugins.svn.branch import SvnBranch
 
387
        from bzrlib.plugins.svn.push import (
 
388
            check_dirs_exist,
 
389
            create_branch_container,
 
390
            create_branch_with_hidden_commit,
 
391
            )
350
392
        if repository is None:
351
393
            repository = self.find_repository()
352
394
 
353
 
        relpath = self._determine_relpath(branch_name)
 
395
        if mapping is None:
 
396
            mapping = repository.get_mapping()
 
397
 
 
398
        relpath = self._determine_relpath(branch_name).strip("/")
 
399
        if relpath == "":
 
400
            if repository.get_latest_revnum() > 0:
 
401
                # Bail out if there are already revisions in this repository
 
402
                raise errors.AlreadyBranchError(repository.transport.base)
 
403
            # TODO: Set NULL_REVISION in SVN_PROP_BZR_BRANCHING_SCHEME on rev0
 
404
        bp_parts = relpath.split("/")
 
405
        existing_bp_parts = check_dirs_exist(repository.transport, bp_parts,
 
406
            -1)
 
407
        if len(existing_bp_parts) == len(bp_parts) and relpath != "":
 
408
            raise errors.AlreadyBranchError(repository.transport.base)
 
409
        if len(existing_bp_parts) < len(bp_parts)-1:
 
410
            create_branch_container(repository.transport, relpath, "/".join(existing_bp_parts))
354
411
        if relpath != "":
355
 
            # TODO: Set NULL_REVISION in SVN_PROP_BZR_BRANCHING_SCHEME
356
 
            repository.transport.mkdir(relpath.strip("/"))
357
 
        elif repository.get_latest_revnum() > 0:
358
 
            # Bail out if there are already revisions in this repository
359
 
            raise errors.AlreadyBranchError(self.root_transport.base)
360
 
        if mapping is None:
361
 
            mapping = repository.get_mapping()
 
412
            create_branch_with_hidden_commit(repository, relpath, NULL_REVISION)
362
413
        return SvnBranch(repository, self, relpath, mapping)
363
414
 
364
415
    def open_branch(self, name=None, unsupported=True, ignore_fallbacks=False,
365
 
            mapping=None):
 
416
            mapping=None, branch_path=None, repository=None):
366
417
        """See ControlDir.open_branch()."""
367
418
        from bzrlib.plugins.svn.branch import SvnBranch
368
 
        relpath = self._determine_relpath(name)
369
 
        repos = self.find_repository()
 
419
        if branch_path is None:
 
420
            branch_path = self._determine_relpath(name)
 
421
        if repository is None:
 
422
            repository = self.find_repository()
370
423
        if mapping is None:
371
 
            mapping = repos.get_mapping()
372
 
        return SvnBranch(repos, self, relpath, mapping)
 
424
            mapping = repository.get_mapping()
 
425
        return SvnBranch(repository, self, branch_path, mapping)
373
426
 
374
427
    def create_repository(self, shared=False, format=None):
375
428
        """See ControlDir.create_repository."""
376
429
        return self.open_repository()
377
430
 
378
431
    def push_branch(self, source, revision_id=None, overwrite=False,
379
 
        remember=False, create_prefix=False):
 
432
        remember=False, create_prefix=False, name=None):
380
433
        ret = SubversionPushResult()
381
434
        ret.source_branch = source
382
435
        ret.workingtree_updated = None
383
436
        ret.stacked_on = None
384
437
        ret.master_branch = None
385
438
        try:
386
 
            target_branch = self.open_branch()
 
439
            target_branch = self.open_branch(name=name)
387
440
            if source.get_push_location() is None or remember:
388
441
                source.set_push_location(target_branch.base)
389
442
            ret.target_branch = target_branch
395
448
            finally:
396
449
                target_branch.unlock()
397
450
        except errors.NotBranchError:
398
 
            relpath = self._determine_relpath(None)
399
 
            ret.target_branch_path = "/%s" % relpath.lstrip("/")
400
451
            if create_prefix:
401
452
                self.root_transport.create_prefix()
402
453
            ret.target_branch = self.import_branch(source, revision_id,
403
454
                overwrite=overwrite)
 
455
            ret.target_branch_path = "/" + ret.target_branch.get_branch_path()
404
456
            ret.tag_conflicts = source.tags.merge_to(ret.target_branch.tags,
405
457
                overwrite)
406
458
            if source.get_push_location() is None or remember:
437
489
            self._config = SvnRepositoryConfig(self.root_transport.base,
438
490
                self.root_transport.get_uuid())
439
491
        return self._config
 
492
 
 
493
    def list_branches(self):
 
494
        repos = self.find_repository()
 
495
        layout = repos.get_layout()
 
496
        branches = []
 
497
        for project, bp, nick, has_props, revnum in layout.get_branches(repos,
 
498
                repos.get_latest_revnum()):
 
499
            branches.append(self.open_branch(branch_path=bp, repository=repos))
 
500
        return branches
 
501