~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Patch Queue Manager
  • Date: 2011-10-05 14:12:34 UTC
  • mfrom: (6083.2.13 metadir-goes-colo)
  • Revision ID: pqm@pqm.ubuntu.com-20111005141234-pjarq2hlunfrrrse
(jelmer) Add 'development-colo' format which supports colocated branches.
 (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1323
1323
        return config.TransportConfig(self.transport, 'control.conf')
1324
1324
 
1325
1325
 
 
1326
class BzrDirMeta1Colo(BzrDirMeta1):
 
1327
    """BzrDirMeta1 with support for colocated branches.
 
1328
 
 
1329
    This format is experimental, and will eventually be merged back into
 
1330
    BzrDirMeta1.
 
1331
    """
 
1332
 
 
1333
    def __init__(self, _transport, _format):
 
1334
        super(BzrDirMeta1Colo, self).__init__(_transport, _format)
 
1335
        self.control_files = lockable_files.LockableFiles(_transport,
 
1336
            self._format._lock_file_name, self._format._lock_class)
 
1337
 
 
1338
    def _get_branch_path(self, name):
 
1339
        """Obtain the branch path to use.
 
1340
 
 
1341
        This uses the API specified branch name first, and then falls back to
 
1342
        the branch name specified in the URL. If neither of those is specified,
 
1343
        it uses the default branch.
 
1344
 
 
1345
        :param name: Optional branch name to use
 
1346
        :return: Relative path to branch, branch name
 
1347
        """
 
1348
        if name is None:
 
1349
            name = self._get_selected_branch()
 
1350
        if name is None:
 
1351
            return 'branch', None
 
1352
        return urlutils.join('branches', name), name
 
1353
 
 
1354
    def _read_branch_list(self):
 
1355
        """Read the branch list.
 
1356
 
 
1357
        :return: List of utf-8 encoded branch names.
 
1358
        """
 
1359
        try:
 
1360
            f = self.control_transport.get('branch-list')
 
1361
        except errors.NoSuchFile:
 
1362
            return []
 
1363
 
 
1364
        ret = []
 
1365
        try:
 
1366
            for name in f:
 
1367
                ret.append(name.rstrip("\n"))
 
1368
        finally:
 
1369
            f.close()
 
1370
        return ret
 
1371
 
 
1372
    def _write_branch_list(self, branches):
 
1373
        """Write out the branch list.
 
1374
 
 
1375
        :param branches: List of utf-8 branch names to write
 
1376
        """
 
1377
        self.transport.put_bytes('branch-list',
 
1378
            "".join([name+"\n" for name in branches]))
 
1379
 
 
1380
    def destroy_branch(self, name=None):
 
1381
        """See BzrDir.create_branch."""
 
1382
        path, name = self._get_branch_path(name)
 
1383
        if name is not None:
 
1384
            self.control_files.lock_write()
 
1385
            try:
 
1386
                branches = self._read_branch_list()
 
1387
                try:
 
1388
                    branches.remove(name)
 
1389
                except ValueError:
 
1390
                    raise errors.NotBranchError(name)
 
1391
                self._write_branch_list(name)
 
1392
            finally:
 
1393
                self.control_files.unlock()
 
1394
        self.transport.delete_tree(path)
 
1395
 
 
1396
    def list_branches(self):
 
1397
        """See ControlDir.list_branches."""
 
1398
        ret = []
 
1399
        # Default branch
 
1400
        try:
 
1401
            ret.append(self.open_branch())
 
1402
        except (errors.NotBranchError, errors.NoRepositoryPresent):
 
1403
            pass
 
1404
 
 
1405
        # colocated branches
 
1406
        ret.extend([self.open_branch(name) for name in
 
1407
                    self._read_branch_list()])
 
1408
 
 
1409
        return ret
 
1410
 
 
1411
    def get_branch_transport(self, branch_format, name=None):
 
1412
        """See BzrDir.get_branch_transport()."""
 
1413
        path, name = self._get_branch_path(name)
 
1414
        # XXX: this shouldn't implicitly create the directory if it's just
 
1415
        # promising to get a transport -- mbp 20090727
 
1416
        if branch_format is None:
 
1417
            return self.transport.clone(path)
 
1418
        try:
 
1419
            branch_format.get_format_string()
 
1420
        except NotImplementedError:
 
1421
            raise errors.IncompatibleFormat(branch_format, self._format)
 
1422
        if name is not None:
 
1423
            try:
 
1424
                self.transport.mkdir('branches', mode=self._get_mkdir_mode())
 
1425
            except errors.FileExists:
 
1426
                pass
 
1427
            branches = self._read_branch_list()
 
1428
            if not name in branches:
 
1429
                self.control_files.lock_write()
 
1430
                try:
 
1431
                    branches = self._read_branch_list()
 
1432
                    branches.append(name)
 
1433
                    self._write_branch_list(branches)
 
1434
                finally:
 
1435
                    self.control_files.unlock()
 
1436
        try:
 
1437
            self.transport.mkdir(path, mode=self._get_mkdir_mode())
 
1438
        except errors.FileExists:
 
1439
            pass
 
1440
        return self.transport.clone(path)
 
1441
 
 
1442
 
1326
1443
class BzrProber(controldir.Prober):
1327
1444
    """Prober for formats that use a .bzr/ control directory."""
1328
1445
 
1629
1746
 
1630
1747
    fixed_components = False
1631
1748
 
 
1749
    colocated_branches = False
 
1750
 
1632
1751
    def __init__(self):
1633
1752
        self._workingtree_format = None
1634
1753
        self._branch_format = None
1831
1950
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1832
1951
 
1833
1952
 
 
1953
class BzrDirMetaFormat1Colo(BzrDirMetaFormat1):
 
1954
    """BzrDirMeta1 format with support for colocated branches."""
 
1955
 
 
1956
    colocated_branches = True
 
1957
 
 
1958
    @classmethod
 
1959
    def get_format_string(cls):
 
1960
        """See BzrDirFormat.get_format_string()."""
 
1961
        return "Bazaar meta directory, format 1 (with colocated branches)\n"
 
1962
 
 
1963
    def get_format_description(self):
 
1964
        """See BzrDirFormat.get_format_description()."""
 
1965
        return "Meta directory format 1 with support for colocated branches"
 
1966
 
 
1967
    def _open(self, transport):
 
1968
        """See BzrDirFormat._open."""
 
1969
        # Create a new format instance because otherwise initialisation of new
 
1970
        # metadirs share the global default format object leading to alias
 
1971
        # problems.
 
1972
        format = BzrDirMetaFormat1Colo()
 
1973
        self._supply_sub_formats_to(format)
 
1974
        return BzrDirMeta1Colo(transport, format)
 
1975
 
 
1976
 
 
1977
BzrProber.formats.register(BzrDirMetaFormat1Colo.get_format_string(),
 
1978
    BzrDirMetaFormat1Colo)
 
1979
 
 
1980
 
1834
1981
class ConvertMetaToMeta(controldir.Converter):
1835
1982
    """Converts the components of metadirs."""
1836
1983
 
2076
2223
         tree_format=None,
2077
2224
         hidden=False,
2078
2225
         experimental=False,
2079
 
         alias=False):
 
2226
         alias=False, bzrdir_format=None):
2080
2227
    """Register a metadir subformat.
2081
2228
 
2082
 
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2083
 
    by the Repository/Branch/WorkingTreeformats.
 
2229
    These all use a meta bzrdir, but can be parameterized by the
 
2230
    Repository/Branch/WorkingTreeformats.
2084
2231
 
2085
2232
    :param repository_format: The fully-qualified repository format class
2086
2233
        name as a string.
2089
2236
    :param tree_format: Fully-qualified tree format class name as
2090
2237
        a string.
2091
2238
    """
 
2239
    if bzrdir_format is None:
 
2240
        bzrdir_format = BzrDirMetaFormat1
2092
2241
    # This should be expanded to support setting WorkingTree and Branch
2093
 
    # formats, once BzrDirMetaFormat1 supports that.
 
2242
    # formats, once the API supports that.
2094
2243
    def _load(full_name):
2095
2244
        mod_name, factory_name = full_name.rsplit('.', 1)
2096
2245
        try:
2103
2252
        return factory()
2104
2253
 
2105
2254
    def helper():
2106
 
        bd = BzrDirMetaFormat1()
 
2255
        bd = bzrdir_format()
2107
2256
        if branch_format is not None:
2108
2257
            bd.set_branch_format(_load(branch_format))
2109
2258
        if tree_format is not None:
2263
2412
    alias=False,
2264
2413
    )
2265
2414
 
 
2415
register_metadir(controldir.format_registry, 'development-colo',
 
2416
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
 
2417
    help='The 2a format with experimental support for colocated branches.\n',
 
2418
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
2419
    tree_format='bzrlib.workingtree_4.WorkingTreeFormat6',
 
2420
    experimental=False,
 
2421
    bzrdir_format=BzrDirMetaFormat1Colo,
 
2422
    )
 
2423
 
 
2424
 
2266
2425
# And the development formats above will have aliased one of the following:
2267
2426
 
2268
2427
# Finally, the current format.