~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: Martin Pool
  • Date: 2010-01-31 15:28:41 UTC
  • mto: (4999.3.1 apport)
  • mto: This revision was merged to the branch mainline in revision 5002.
  • Revision ID: mbp@sourcefrog.net-20100131152841-uak92h8motai6xqo
Don't write crash reports if apport is configured to ignore them

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
46
46
    )
47
47
""")
48
48
 
49
 
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
 
49
from bzrlib.decorators import needs_read_lock, needs_write_lock
50
50
from bzrlib.hooks import HookPoint, Hooks
51
51
from bzrlib.inter import InterObject
52
 
from bzrlib.lock import _RelockDebugMixin
53
52
from bzrlib import registry
54
53
from bzrlib.symbol_versioning import (
55
54
    deprecated_in,
167
166
        """
168
167
        control = bzrdir.BzrDir.open(base, _unsupported,
169
168
                                     possible_transports=possible_transports)
170
 
        return control.open_branch(unsupported=_unsupported)
 
169
        return control.open_branch(_unsupported)
171
170
 
172
171
    @staticmethod
173
 
    def open_from_transport(transport, name=None, _unsupported=False):
 
172
    def open_from_transport(transport, _unsupported=False):
174
173
        """Open the branch rooted at transport"""
175
174
        control = bzrdir.BzrDir.open_from_transport(transport, _unsupported)
176
 
        return control.open_branch(name=name, unsupported=_unsupported)
 
175
        return control.open_branch(_unsupported)
177
176
 
178
177
    @staticmethod
179
178
    def open_containing(url, possible_transports=None):
217
216
    def _get_fallback_repository(self, url):
218
217
        """Get the repository we fallback to at url."""
219
218
        url = urlutils.join(self.base, url)
220
 
        a_branch = Branch.open(url,
 
219
        a_bzrdir = bzrdir.BzrDir.open(url,
221
220
            possible_transports=[self.bzrdir.root_transport])
222
 
        return a_branch.repository
 
221
        return a_bzrdir.open_branch().repository
223
222
 
224
223
    def _get_tags_bytes(self):
225
224
        """Get the bytes of a serialised tags dict.
447
446
        # start_revision_id.
448
447
        if self._merge_sorted_revisions_cache is None:
449
448
            last_revision = self.last_revision()
450
 
            known_graph = self.repository.get_known_graph_ancestry(
451
 
                [last_revision])
 
449
            last_key = (last_revision,)
 
450
            known_graph = self.repository.revisions.get_known_graph_ancestry(
 
451
                [last_key])
452
452
            self._merge_sorted_revisions_cache = known_graph.merge_sort(
453
 
                last_revision)
 
453
                last_key)
454
454
        filtered = self._filter_merge_sorted_revisions(
455
455
            self._merge_sorted_revisions_cache, start_revision_id,
456
456
            stop_revision_id, stop_rule)
457
 
        # Make sure we don't return revisions that are not part of the
458
 
        # start_revision_id ancestry.
459
 
        filtered = self._filter_non_ancestors(filtered)
460
457
        if direction == 'reverse':
461
458
            return filtered
462
459
        if direction == 'forward':
505
502
                left_parent = stop_rev.parent_ids[0]
506
503
            else:
507
504
                left_parent = _mod_revision.NULL_REVISION
508
 
            # left_parent is the actual revision we want to stop logging at,
509
 
            # since we want to show the merged revisions after the stop_rev too
510
 
            reached_stop_revision_id = False
511
 
            revision_id_whitelist = []
512
505
            for node in rev_iter:
513
506
                rev_id = node.key[-1]
514
507
                if rev_id == left_parent:
515
 
                    # reached the left parent after the stop_revision
516
508
                    return
517
 
                if (not reached_stop_revision_id or
518
 
                        rev_id in revision_id_whitelist):
519
 
                    yield (rev_id, node.merge_depth, node.revno,
 
509
                yield (rev_id, node.merge_depth, node.revno,
520
510
                       node.end_of_merge)
521
 
                    if reached_stop_revision_id or rev_id == stop_revision_id:
522
 
                        # only do the merged revs of rev_id from now on
523
 
                        rev = self.repository.get_revision(rev_id)
524
 
                        if rev.parent_ids:
525
 
                            reached_stop_revision_id = True
526
 
                            revision_id_whitelist.extend(rev.parent_ids)
527
511
        else:
528
512
            raise ValueError('invalid stop_rule %r' % stop_rule)
529
513
 
530
 
    def _filter_non_ancestors(self, rev_iter):
531
 
        # If we started from a dotted revno, we want to consider it as a tip
532
 
        # and don't want to yield revisions that are not part of its
533
 
        # ancestry. Given the order guaranteed by the merge sort, we will see
534
 
        # uninteresting descendants of the first parent of our tip before the
535
 
        # tip itself.
536
 
        first = rev_iter.next()
537
 
        (rev_id, merge_depth, revno, end_of_merge) = first
538
 
        yield first
539
 
        if not merge_depth:
540
 
            # We start at a mainline revision so by definition, all others
541
 
            # revisions in rev_iter are ancestors
542
 
            for node in rev_iter:
543
 
                yield node
544
 
 
545
 
        clean = False
546
 
        whitelist = set()
547
 
        pmap = self.repository.get_parent_map([rev_id])
548
 
        parents = pmap.get(rev_id, [])
549
 
        if parents:
550
 
            whitelist.update(parents)
551
 
        else:
552
 
            # If there is no parents, there is nothing of interest left
553
 
 
554
 
            # FIXME: It's hard to test this scenario here as this code is never
555
 
            # called in that case. -- vila 20100322
556
 
            return
557
 
 
558
 
        for (rev_id, merge_depth, revno, end_of_merge) in rev_iter:
559
 
            if not clean:
560
 
                if rev_id in whitelist:
561
 
                    pmap = self.repository.get_parent_map([rev_id])
562
 
                    parents = pmap.get(rev_id, [])
563
 
                    whitelist.remove(rev_id)
564
 
                    whitelist.update(parents)
565
 
                    if merge_depth == 0:
566
 
                        # We've reached the mainline, there is nothing left to
567
 
                        # filter
568
 
                        clean = True
569
 
                else:
570
 
                    # A revision that is not part of the ancestry of our
571
 
                    # starting revision.
572
 
                    continue
573
 
            yield (rev_id, merge_depth, revno, end_of_merge)
574
 
 
575
514
    def leave_lock_in_place(self):
576
515
        """Tell this branch object not to release the physical lock when this
577
516
        object is unlocked.
1150
1089
        params = ChangeBranchTipParams(
1151
1090
            self, old_revno, new_revno, old_revid, new_revid)
1152
1091
        for hook in hooks:
1153
 
            hook(params)
 
1092
            try:
 
1093
                hook(params)
 
1094
            except errors.TipChangeRejected:
 
1095
                raise
 
1096
            except Exception:
 
1097
                exc_info = sys.exc_info()
 
1098
                hook_name = Branch.hooks.get_hook_name(hook)
 
1099
                raise errors.HookFailed(
 
1100
                    'pre_change_branch_tip', hook_name, exc_info)
1154
1101
 
1155
1102
    @needs_write_lock
1156
1103
    def update(self):
1364
1311
        if lightweight:
1365
1312
            format = self._get_checkout_format()
1366
1313
            checkout = format.initialize_on_transport(t)
1367
 
            from_branch = BranchReferenceFormat().initialize(checkout, 
1368
 
                target_branch=self)
 
1314
            from_branch = BranchReferenceFormat().initialize(checkout, self)
1369
1315
        else:
1370
1316
            format = self._get_checkout_format()
1371
1317
            checkout_branch = bzrdir.BzrDir.create_branch_convenience(
1413
1359
    def supports_tags(self):
1414
1360
        return self._format.supports_tags()
1415
1361
 
1416
 
    def automatic_tag_name(self, revision_id):
1417
 
        """Try to automatically find the tag name for a revision.
1418
 
 
1419
 
        :param revision_id: Revision id of the revision.
1420
 
        :return: A tag name or None if no tag name could be determined.
1421
 
        """
1422
 
        for hook in Branch.hooks['automatic_tag_name']:
1423
 
            ret = hook(self, revision_id)
1424
 
            if ret is not None:
1425
 
                return ret
1426
 
        return None
1427
 
 
1428
1362
    def _check_if_descendant_or_diverged(self, revision_a, revision_b, graph,
1429
1363
                                         other_branch):
1430
1364
        """Ensure that revision_b is a descendant of revision_a.
1494
1428
        return not (self == other)
1495
1429
 
1496
1430
    @classmethod
1497
 
    def find_format(klass, a_bzrdir, name=None):
 
1431
    def find_format(klass, a_bzrdir):
1498
1432
        """Return the format for the branch object in a_bzrdir."""
1499
1433
        try:
1500
 
            transport = a_bzrdir.get_branch_transport(None, name=name)
1501
 
            format_string = transport.get_bytes("format")
 
1434
            transport = a_bzrdir.get_branch_transport(None)
 
1435
            format_string = transport.get("format").read()
1502
1436
            return klass._formats[format_string]
1503
1437
        except errors.NoSuchFile:
1504
 
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
 
1438
            raise errors.NotBranchError(path=transport.base)
1505
1439
        except KeyError:
1506
1440
            raise errors.UnknownFormatError(format=format_string, kind='branch')
1507
1441
 
1543
1477
        """Return the short format description for this format."""
1544
1478
        raise NotImplementedError(self.get_format_description)
1545
1479
 
1546
 
    def _initialize_helper(self, a_bzrdir, utf8_files, name=None,
1547
 
                           lock_type='metadir', set_format=True):
 
1480
    def _initialize_helper(self, a_bzrdir, utf8_files, lock_type='metadir',
 
1481
                           set_format=True):
1548
1482
        """Initialize a branch in a bzrdir, with specified files
1549
1483
 
1550
1484
        :param a_bzrdir: The bzrdir to initialize the branch in
1551
1485
        :param utf8_files: The files to create as a list of
1552
1486
            (filename, content) tuples
1553
 
        :param name: Name of colocated branch to create, if any
1554
1487
        :param set_format: If True, set the format with
1555
1488
            self.get_format_string.  (BzrBranch4 has its format set
1556
1489
            elsewhere)
1557
1490
        :return: a branch in this format
1558
1491
        """
1559
1492
        mutter('creating branch %r in %s', self, a_bzrdir.transport.base)
1560
 
        branch_transport = a_bzrdir.get_branch_transport(self, name=name)
 
1493
        branch_transport = a_bzrdir.get_branch_transport(self)
1561
1494
        lock_map = {
1562
1495
            'metadir': ('lock', lockdir.LockDir),
1563
1496
            'branch4': ('branch-lock', lockable_files.TransportLock),
1584
1517
        finally:
1585
1518
            if lock_taken:
1586
1519
                control_files.unlock()
1587
 
        return self.open(a_bzrdir, name, _found=True)
 
1520
        return self.open(a_bzrdir, _found=True)
1588
1521
 
1589
 
    def initialize(self, a_bzrdir, name=None):
1590
 
        """Create a branch of this format in a_bzrdir.
1591
 
        
1592
 
        :param name: Name of the colocated branch to create.
1593
 
        """
 
1522
    def initialize(self, a_bzrdir):
 
1523
        """Create a branch of this format in a_bzrdir."""
1594
1524
        raise NotImplementedError(self.initialize)
1595
1525
 
1596
1526
    def is_supported(self):
1626
1556
        """
1627
1557
        raise NotImplementedError(self.network_name)
1628
1558
 
1629
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
 
1559
    def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):
1630
1560
        """Return the branch object for a_bzrdir
1631
1561
 
1632
1562
        :param a_bzrdir: A BzrDir that contains a branch.
1633
 
        :param name: Name of colocated branch to open
1634
1563
        :param _found: a private parameter, do not use it. It is used to
1635
1564
            indicate if format probing has already be done.
1636
1565
        :param ignore_fallbacks: when set, no fallback branches will be opened
1744
1673
            "multiple hooks installed for transform_fallback_location, "
1745
1674
            "all are called with the url returned from the previous hook."
1746
1675
            "The order is however undefined.", (1, 9), None))
1747
 
        self.create_hook(HookPoint('automatic_tag_name',
1748
 
            "Called to determine an automatic tag name for a revision."
1749
 
            "automatic_tag_name is called with (branch, revision_id) and "
1750
 
            "should return a tag name or None if no tag name could be "
1751
 
            "determined. The first non-None tag name returned will be used.",
1752
 
            (2, 2), None))
1753
 
 
1754
1676
 
1755
1677
 
1756
1678
# install the default hooks into the Branch class.
1807
1729
        """See BranchFormat.get_format_description()."""
1808
1730
        return "Branch format 4"
1809
1731
 
1810
 
    def initialize(self, a_bzrdir, name=None):
 
1732
    def initialize(self, a_bzrdir):
1811
1733
        """Create a branch of this format in a_bzrdir."""
1812
1734
        utf8_files = [('revision-history', ''),
1813
1735
                      ('branch-name', ''),
1814
1736
                      ]
1815
 
        return self._initialize_helper(a_bzrdir, utf8_files, name=name,
 
1737
        return self._initialize_helper(a_bzrdir, utf8_files,
1816
1738
                                       lock_type='branch4', set_format=False)
1817
1739
 
1818
1740
    def __init__(self):
1823
1745
        """The network name for this format is the control dirs disk label."""
1824
1746
        return self._matchingbzrdir.get_format_string()
1825
1747
 
1826
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
 
1748
    def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):
1827
1749
        """See BranchFormat.open()."""
1828
1750
        if not _found:
1829
1751
            # we are being called directly and must probe.
1831
1753
        return BzrBranch(_format=self,
1832
1754
                         _control_files=a_bzrdir._control_files,
1833
1755
                         a_bzrdir=a_bzrdir,
1834
 
                         name=name,
1835
1756
                         _repository=a_bzrdir.open_repository())
1836
1757
 
1837
1758
    def __str__(self):
1852
1773
        """
1853
1774
        return self.get_format_string()
1854
1775
 
1855
 
    def open(self, a_bzrdir, name=None, _found=False, ignore_fallbacks=False):
 
1776
    def open(self, a_bzrdir, _found=False, ignore_fallbacks=False):
1856
1777
        """See BranchFormat.open()."""
1857
1778
        if not _found:
1858
 
            format = BranchFormat.find_format(a_bzrdir, name=name)
 
1779
            format = BranchFormat.find_format(a_bzrdir)
1859
1780
            if format.__class__ != self.__class__:
1860
1781
                raise AssertionError("wrong format %r found for %r" %
1861
1782
                    (format, self))
1862
1783
        try:
1863
 
            transport = a_bzrdir.get_branch_transport(None, name=name)
 
1784
            transport = a_bzrdir.get_branch_transport(None)
1864
1785
            control_files = lockable_files.LockableFiles(transport, 'lock',
1865
1786
                                                         lockdir.LockDir)
1866
1787
            return self._branch_class()(_format=self,
1867
1788
                              _control_files=control_files,
1868
 
                              name=name,
1869
1789
                              a_bzrdir=a_bzrdir,
1870
1790
                              _repository=a_bzrdir.find_repository(),
1871
1791
                              ignore_fallbacks=ignore_fallbacks)
1872
1792
        except errors.NoSuchFile:
1873
 
            raise errors.NotBranchError(path=transport.base, bzrdir=a_bzrdir)
 
1793
            raise errors.NotBranchError(path=transport.base)
1874
1794
 
1875
1795
    def __init__(self):
1876
1796
        super(BranchFormatMetadir, self).__init__()
1905
1825
        """See BranchFormat.get_format_description()."""
1906
1826
        return "Branch format 5"
1907
1827
 
1908
 
    def initialize(self, a_bzrdir, name=None):
 
1828
    def initialize(self, a_bzrdir):
1909
1829
        """Create a branch of this format in a_bzrdir."""
1910
1830
        utf8_files = [('revision-history', ''),
1911
1831
                      ('branch-name', ''),
1912
1832
                      ]
1913
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
 
1833
        return self._initialize_helper(a_bzrdir, utf8_files)
1914
1834
 
1915
1835
    def supports_tags(self):
1916
1836
        return False
1938
1858
        """See BranchFormat.get_format_description()."""
1939
1859
        return "Branch format 6"
1940
1860
 
1941
 
    def initialize(self, a_bzrdir, name=None):
 
1861
    def initialize(self, a_bzrdir):
1942
1862
        """Create a branch of this format in a_bzrdir."""
1943
1863
        utf8_files = [('last-revision', '0 null:\n'),
1944
1864
                      ('branch.conf', ''),
1945
1865
                      ('tags', ''),
1946
1866
                      ]
1947
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
 
1867
        return self._initialize_helper(a_bzrdir, utf8_files)
1948
1868
 
1949
1869
    def make_tags(self, branch):
1950
1870
        """See bzrlib.branch.BranchFormat.make_tags()."""
1968
1888
        """See BranchFormat.get_format_description()."""
1969
1889
        return "Branch format 8"
1970
1890
 
1971
 
    def initialize(self, a_bzrdir, name=None):
 
1891
    def initialize(self, a_bzrdir):
1972
1892
        """Create a branch of this format in a_bzrdir."""
1973
1893
        utf8_files = [('last-revision', '0 null:\n'),
1974
1894
                      ('branch.conf', ''),
1975
1895
                      ('tags', ''),
1976
1896
                      ('references', '')
1977
1897
                      ]
1978
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
 
1898
        return self._initialize_helper(a_bzrdir, utf8_files)
1979
1899
 
1980
1900
    def __init__(self):
1981
1901
        super(BzrBranchFormat8, self).__init__()
2004
1924
    This format was introduced in bzr 1.6.
2005
1925
    """
2006
1926
 
2007
 
    def initialize(self, a_bzrdir, name=None):
 
1927
    def initialize(self, a_bzrdir):
2008
1928
        """Create a branch of this format in a_bzrdir."""
2009
1929
        utf8_files = [('last-revision', '0 null:\n'),
2010
1930
                      ('branch.conf', ''),
2011
1931
                      ('tags', ''),
2012
1932
                      ]
2013
 
        return self._initialize_helper(a_bzrdir, utf8_files, name)
 
1933
        return self._initialize_helper(a_bzrdir, utf8_files)
2014
1934
 
2015
1935
    def _branch_class(self):
2016
1936
        return BzrBranch7
2051
1971
    def get_reference(self, a_bzrdir):
2052
1972
        """See BranchFormat.get_reference()."""
2053
1973
        transport = a_bzrdir.get_branch_transport(None)
2054
 
        return transport.get_bytes('location')
 
1974
        return transport.get('location').read()
2055
1975
 
2056
1976
    def set_reference(self, a_bzrdir, to_branch):
2057
1977
        """See BranchFormat.set_reference()."""
2058
1978
        transport = a_bzrdir.get_branch_transport(None)
2059
1979
        location = transport.put_bytes('location', to_branch.base)
2060
1980
 
2061
 
    def initialize(self, a_bzrdir, name=None, target_branch=None):
 
1981
    def initialize(self, a_bzrdir, target_branch=None):
2062
1982
        """Create a branch of this format in a_bzrdir."""
2063
1983
        if target_branch is None:
2064
1984
            # this format does not implement branch itself, thus the implicit
2065
1985
            # creation contract must see it as uninitializable
2066
1986
            raise errors.UninitializableFormat(self)
2067
1987
        mutter('creating branch reference in %s', a_bzrdir.transport.base)
2068
 
        branch_transport = a_bzrdir.get_branch_transport(self, name=name)
 
1988
        branch_transport = a_bzrdir.get_branch_transport(self)
2069
1989
        branch_transport.put_bytes('location',
2070
1990
            target_branch.bzrdir.root_transport.base)
2071
1991
        branch_transport.put_bytes('format', self.get_format_string())
2072
1992
        return self.open(
2073
 
            a_bzrdir, name, _found=True,
 
1993
            a_bzrdir, _found=True,
2074
1994
            possible_transports=[target_branch.bzrdir.root_transport])
2075
1995
 
2076
1996
    def __init__(self):
2083
2003
        def clone(to_bzrdir, revision_id=None,
2084
2004
            repository_policy=None):
2085
2005
            """See Branch.clone()."""
2086
 
            return format.initialize(to_bzrdir, target_branch=a_branch)
 
2006
            return format.initialize(to_bzrdir, a_branch)
2087
2007
            # cannot obey revision_id limits when cloning a reference ...
2088
2008
            # FIXME RBC 20060210 either nuke revision_id for clone, or
2089
2009
            # emit some sort of warning/error to the caller ?!
2090
2010
        return clone
2091
2011
 
2092
 
    def open(self, a_bzrdir, name=None, _found=False, location=None,
 
2012
    def open(self, a_bzrdir, _found=False, location=None,
2093
2013
             possible_transports=None, ignore_fallbacks=False):
2094
2014
        """Return the branch that the branch reference in a_bzrdir points at.
2095
2015
 
2096
2016
        :param a_bzrdir: A BzrDir that contains a branch.
2097
 
        :param name: Name of colocated branch to open, if any
2098
2017
        :param _found: a private parameter, do not use it. It is used to
2099
2018
            indicate if format probing has already be done.
2100
2019
        :param ignore_fallbacks: when set, no fallback branches will be opened
2105
2024
        :param possible_transports: An optional reusable transports list.
2106
2025
        """
2107
2026
        if not _found:
2108
 
            format = BranchFormat.find_format(a_bzrdir, name=name)
 
2027
            format = BranchFormat.find_format(a_bzrdir)
2109
2028
            if format.__class__ != self.__class__:
2110
2029
                raise AssertionError("wrong format %r found for %r" %
2111
2030
                    (format, self))
2113
2032
            location = self.get_reference(a_bzrdir)
2114
2033
        real_bzrdir = bzrdir.BzrDir.open(
2115
2034
            location, possible_transports=possible_transports)
2116
 
        result = real_bzrdir.open_branch(name=name, 
2117
 
            ignore_fallbacks=ignore_fallbacks)
 
2035
        result = real_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2118
2036
        # this changes the behaviour of result.clone to create a new reference
2119
2037
        # rather than a copy of the content of the branch.
2120
2038
        # I did not use a proxy object because that needs much more extensive
2154
2072
    _legacy_formats[0].network_name(), _legacy_formats[0].__class__)
2155
2073
 
2156
2074
 
2157
 
class BzrBranch(Branch, _RelockDebugMixin):
 
2075
class BzrBranch(Branch):
2158
2076
    """A branch stored in the actual filesystem.
2159
2077
 
2160
2078
    Note that it's "local" in the context of the filesystem; it doesn't
2166
2084
    :ivar repository: Repository for this branch.
2167
2085
    :ivar base: The url of the base directory for this branch; the one
2168
2086
        containing the .bzr directory.
2169
 
    :ivar name: Optional colocated branch name as it exists in the control
2170
 
        directory.
2171
2087
    """
2172
2088
 
2173
2089
    def __init__(self, _format=None,
2174
 
                 _control_files=None, a_bzrdir=None, name=None,
2175
 
                 _repository=None, ignore_fallbacks=False):
 
2090
                 _control_files=None, a_bzrdir=None, _repository=None,
 
2091
                 ignore_fallbacks=False):
2176
2092
        """Create new branch object at a particular location."""
2177
2093
        if a_bzrdir is None:
2178
2094
            raise ValueError('a_bzrdir must be supplied')
2179
2095
        else:
2180
2096
            self.bzrdir = a_bzrdir
2181
2097
        self._base = self.bzrdir.transport.clone('..').base
2182
 
        self.name = name
2183
2098
        # XXX: We should be able to just do
2184
2099
        #   self.base = self.bzrdir.root_transport.base
2185
2100
        # but this does not quite work yet -- mbp 20080522
2192
2107
        Branch.__init__(self)
2193
2108
 
2194
2109
    def __str__(self):
2195
 
        if self.name is None:
2196
 
            return '%s(%r)' % (self.__class__.__name__, self.base)
2197
 
        else:
2198
 
            return '%s(%r,%r)' % (self.__class__.__name__, self.base, self.name)
 
2110
        return '%s(%r)' % (self.__class__.__name__, self.base)
2199
2111
 
2200
2112
    __repr__ = __str__
2201
2113
 
2212
2124
        return self.control_files.is_locked()
2213
2125
 
2214
2126
    def lock_write(self, token=None):
2215
 
        if not self.is_locked():
2216
 
            self._note_lock('w')
2217
2127
        # All-in-one needs to always unlock/lock.
2218
2128
        repo_control = getattr(self.repository, 'control_files', None)
2219
2129
        if self.control_files == repo_control or not self.is_locked():
2220
 
            self.repository._warn_if_deprecated(self)
2221
2130
            self.repository.lock_write()
2222
2131
            took_lock = True
2223
2132
        else:
2230
2139
            raise
2231
2140
 
2232
2141
    def lock_read(self):
2233
 
        if not self.is_locked():
2234
 
            self._note_lock('r')
2235
2142
        # All-in-one needs to always unlock/lock.
2236
2143
        repo_control = getattr(self.repository, 'control_files', None)
2237
2144
        if self.control_files == repo_control or not self.is_locked():
2238
 
            self.repository._warn_if_deprecated(self)
2239
2145
            self.repository.lock_read()
2240
2146
            took_lock = True
2241
2147
        else:
2247
2153
                self.repository.unlock()
2248
2154
            raise
2249
2155
 
2250
 
    @only_raises(errors.LockNotHeld, errors.LockBroken)
2251
2156
    def unlock(self):
2252
2157
        try:
2253
2158
            self.control_files.unlock()