~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-09 13:52:06 UTC
  • mfrom: (6202.1.3 revno-revision)
  • Revision ID: pqm@pqm.ubuntu.com-20111009135206-t3utsln6mtzv9eut
(jelmer) Add a --revision argument to 'bzr revno'. (Jelmer Vernooij)

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
    do_catching_redirections,
56
56
    local,
57
57
    )
 
58
from bzrlib.i18n import gettext
58
59
""")
59
60
 
60
61
from bzrlib.trace import (
543
544
                    stacked=stacked)
544
545
        return result
545
546
 
546
 
 
547
 
 
548
547
    @staticmethod
549
548
    def create_branch_convenience(base, force_new_repo=False,
550
549
                                  force_new_tree=None, format=None,
634
633
            old_path = self.root_transport.abspath('.bzr')
635
634
            backup_dir = self._available_backup_name('backup.bzr')
636
635
            new_path = self.root_transport.abspath(backup_dir)
637
 
            ui.ui_factory.note('making backup of %s\n  to %s'
638
 
                               % (old_path, new_path,))
 
636
            ui.ui_factory.note(gettext('making backup of {0}\n  to {1}').format(
 
637
                urlutils.unescape_for_display(old_path, 'utf-8'),
 
638
                urlutils.unescape_for_display(new_path, 'utf-8')))
639
639
            self.root_transport.copy_tree('.bzr', backup_dir)
640
640
            return (old_path, new_path)
641
641
        finally:
656
656
            try:
657
657
                to_path = '.bzr.retired.%d' % i
658
658
                self.root_transport.rename('.bzr', to_path)
659
 
                note("renamed %s to %s"
660
 
                    % (self.root_transport.abspath('.bzr'), to_path))
 
659
                note(gettext("renamed {0} to {1}").format(
 
660
                    self.root_transport.abspath('.bzr'), to_path))
661
661
                return
662
662
            except (errors.TransportError, IOError, errors.PathError):
663
663
                i += 1
848
848
            redirected_transport = transport._redirected_to(e.source, e.target)
849
849
            if redirected_transport is None:
850
850
                raise errors.NotBranchError(base)
851
 
            note('%s is%s redirected to %s',
852
 
                 transport.base, e.permanently, redirected_transport.base)
 
851
            note(gettext('{0} is{1} redirected to {2}').format(
 
852
                 transport.base, e.permanently, redirected_transport.base))
853
853
            return redirected_transport
854
854
 
855
855
        try:
1146
1146
        """See BzrDir.can_convert_format()."""
1147
1147
        return True
1148
1148
 
1149
 
    def create_branch(self, name=None, repository=None):
 
1149
    def create_branch(self, name=None, repository=None,
 
1150
            append_revisions_only=None):
1150
1151
        """See BzrDir.create_branch."""
1151
1152
        return self._format.get_branch_format().initialize(self, name=name,
1152
 
                repository=repository)
 
1153
                repository=repository,
 
1154
                append_revisions_only=append_revisions_only)
1153
1155
 
1154
1156
    def destroy_branch(self, name=None):
1155
1157
        """See BzrDir.create_branch."""
1321
1323
        return config.TransportConfig(self.transport, 'control.conf')
1322
1324
 
1323
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
 
1324
1443
class BzrProber(controldir.Prober):
1325
1444
    """Prober for formats that use a .bzr/ control directory."""
1326
1445
 
1627
1746
 
1628
1747
    fixed_components = False
1629
1748
 
 
1749
    colocated_branches = False
 
1750
 
1630
1751
    def __init__(self):
1631
1752
        self._workingtree_format = None
1632
1753
        self._branch_format = None
1722
1843
                    new_repo_format = None
1723
1844
            if new_repo_format is not None:
1724
1845
                self.repository_format = new_repo_format
1725
 
                note('Source repository format does not support stacking,'
1726
 
                     ' using format:\n  %s',
 
1846
                note(gettext('Source repository format does not support stacking,'
 
1847
                     ' using format:\n  %s'),
1727
1848
                     new_repo_format.get_format_description())
1728
1849
 
1729
1850
        if not self.get_branch_format().supports_stacking():
1742
1863
            if new_branch_format is not None:
1743
1864
                # Does support stacking, use its format.
1744
1865
                self.set_branch_format(new_branch_format)
1745
 
                note('Source branch format does not support stacking,'
1746
 
                     ' using format:\n  %s',
 
1866
                note(gettext('Source branch format does not support stacking,'
 
1867
                     ' using format:\n  %s'),
1747
1868
                     new_branch_format.get_format_description())
1748
1869
 
1749
1870
    def get_converter(self, format=None):
1829
1950
controldir.ControlDirFormat._default_format = BzrDirMetaFormat1()
1830
1951
 
1831
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
 
1832
1981
class ConvertMetaToMeta(controldir.Converter):
1833
1982
    """Converts the components of metadirs."""
1834
1983
 
1853
2002
        else:
1854
2003
            if not isinstance(repo._format, self.target_format.repository_format.__class__):
1855
2004
                from bzrlib.repository import CopyConverter
1856
 
                ui.ui_factory.note('starting repository conversion')
 
2005
                ui.ui_factory.note(gettext('starting repository conversion'))
1857
2006
                converter = CopyConverter(self.target_format.repository_format)
1858
2007
                converter.convert(repo, pb)
1859
2008
        for branch in self.bzrdir.list_branches():
2032
2181
                                    possible_transports=[self._bzrdir.root_transport])
2033
2182
            if not self._require_stacking:
2034
2183
                # We have picked up automatic stacking somewhere.
2035
 
                note('Using default stacking branch %s at %s', self._stack_on,
2036
 
                    self._stack_on_pwd)
 
2184
                note(gettext('Using default stacking branch {0} at {1}').format(
 
2185
                    self._stack_on, self._stack_on_pwd))
2037
2186
        repository = self._bzrdir.create_repository(shared=shared)
2038
2187
        self._add_fallback(repository,
2039
2188
                           possible_transports=[self._bzrdir.transport])
2074
2223
         tree_format=None,
2075
2224
         hidden=False,
2076
2225
         experimental=False,
2077
 
         alias=False):
 
2226
         alias=False, bzrdir_format=None):
2078
2227
    """Register a metadir subformat.
2079
2228
 
2080
 
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
2081
 
    by the Repository/Branch/WorkingTreeformats.
 
2229
    These all use a meta bzrdir, but can be parameterized by the
 
2230
    Repository/Branch/WorkingTreeformats.
2082
2231
 
2083
2232
    :param repository_format: The fully-qualified repository format class
2084
2233
        name as a string.
2087
2236
    :param tree_format: Fully-qualified tree format class name as
2088
2237
        a string.
2089
2238
    """
 
2239
    if bzrdir_format is None:
 
2240
        bzrdir_format = BzrDirMetaFormat1
2090
2241
    # This should be expanded to support setting WorkingTree and Branch
2091
 
    # formats, once BzrDirMetaFormat1 supports that.
 
2242
    # formats, once the API supports that.
2092
2243
    def _load(full_name):
2093
2244
        mod_name, factory_name = full_name.rsplit('.', 1)
2094
2245
        try:
2101
2252
        return factory()
2102
2253
 
2103
2254
    def helper():
2104
 
        bd = BzrDirMetaFormat1()
 
2255
        bd = bzrdir_format()
2105
2256
        if branch_format is not None:
2106
2257
            bd.set_branch_format(_load(branch_format))
2107
2258
        if tree_format is not None:
2261
2412
    alias=False,
2262
2413
    )
2263
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
 
2264
2425
# And the development formats above will have aliased one of the following:
2265
2426
 
2266
2427
# Finally, the current format.
2287
2448
    help='Same as 2a.')
2288
2449
 
2289
2450
# The current format that is made on 'bzr init'.
2290
 
format_name = config.GlobalConfig().get_user_option('default_format')
2291
 
if format_name is None:
2292
 
    controldir.format_registry.set_default('2a')
2293
 
else:
2294
 
    controldir.format_registry.set_default(format_name)
 
2451
format_name = config.GlobalStack().get('default_format')
 
2452
controldir.format_registry.set_default(format_name)
2295
2453
 
2296
2454
# XXX 2010-08-20 JRV: There is still a lot of code relying on
2297
2455
# bzrlib.bzrdir.format_registry existing. When BzrDir.create/BzrDir.open/etc