/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/workingtree_4.py

Add bzrlib.pyutils, which has get_named_object, a wrapper around __import__.

This is used to replace various ad hoc implementations of the same logic,
notably the version used in registry's _LazyObjectGetter which had a bug when
getting a module without also getting a member.  And of course, this new
function has unit tests, unlike the replaced code.

This also adds a KnownHooksRegistry subclass to provide a more natural home for
some other logic.

I'm not thrilled about the name of the new module or the new functions, but it's
hard to think of good names for such generic functionality.

Show diffs side-by-side

added added

removed removed

Lines of Context:
53
53
from bzrlib.decorators import needs_read_lock, needs_write_lock
54
54
from bzrlib.filters import filtered_input_file, internal_size_sha_file_byname
55
55
from bzrlib.inventory import Inventory, ROOT_ID, entry_factory
 
56
from bzrlib.lock import LogicalLockResult
56
57
from bzrlib.mutabletree import needs_tree_write_lock
57
58
from bzrlib.osutils import (
58
59
    file_kind,
567
568
            return _mod_revision.NULL_REVISION
568
569
 
569
570
    def lock_read(self):
570
 
        """See Branch.lock_read, and WorkingTree.unlock."""
 
571
        """See Branch.lock_read, and WorkingTree.unlock.
 
572
 
 
573
        :return: A bzrlib.lock.LogicalLockResult.
 
574
        """
571
575
        self.branch.lock_read()
572
576
        try:
573
577
            self._control_files.lock_read()
586
590
        except:
587
591
            self.branch.unlock()
588
592
            raise
 
593
        return LogicalLockResult(self.unlock)
589
594
 
590
595
    def _lock_self_write(self):
591
596
        """This should be called after the branch is locked."""
606
611
        except:
607
612
            self.branch.unlock()
608
613
            raise
 
614
        return LogicalLockResult(self.unlock)
609
615
 
610
616
    def lock_tree_write(self):
611
 
        """See MutableTree.lock_tree_write, and WorkingTree.unlock."""
 
617
        """See MutableTree.lock_tree_write, and WorkingTree.unlock.
 
618
 
 
619
        :return: A bzrlib.lock.LogicalLockResult.
 
620
        """
612
621
        self.branch.lock_read()
613
 
        self._lock_self_write()
 
622
        return self._lock_self_write()
614
623
 
615
624
    def lock_write(self):
616
 
        """See MutableTree.lock_write, and WorkingTree.unlock."""
 
625
        """See MutableTree.lock_write, and WorkingTree.unlock.
 
626
 
 
627
        :return: A bzrlib.lock.LogicalLockResult.
 
628
        """
617
629
        self.branch.lock_write()
618
 
        self._lock_self_write()
 
630
        return self._lock_self_write()
619
631
 
620
632
    @needs_tree_write_lock
621
633
    def move(self, from_paths, to_dir, after=False):
1235
1247
        # have to change the legacy inventory too.
1236
1248
        if self._inventory is not None:
1237
1249
            for file_id in file_ids:
1238
 
                self._inventory.remove_recursive_id(file_id)
 
1250
                if self._inventory.has_id(file_id):
 
1251
                    self._inventory.remove_recursive_id(file_id)
1239
1252
 
1240
1253
    @needs_tree_write_lock
1241
1254
    def rename_one(self, from_rel, to_rel, after=False):
1317
1330
    def _file_content_summary(self, path, stat_result):
1318
1331
        # This is to support the somewhat obsolete path_content_summary method
1319
1332
        # with content filtering: see
1320
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/415508>.
 
1333
        # <https://bugs.launchpad.net/bzr/+bug/415508>.
1321
1334
        #
1322
1335
        # If the dirstate cache is up to date and knows the hash and size,
1323
1336
        # return that.
1725
1738
                elif kind == 'directory':
1726
1739
                    parent_ies[(dirname + '/' + name).strip('/')] = inv_entry
1727
1740
                elif kind == 'symlink':
1728
 
                    inv_entry.executable = False
1729
 
                    inv_entry.text_size = None
1730
1741
                    inv_entry.symlink_target = utf8_decode(fingerprint)[0]
1731
1742
                elif kind == 'tree-reference':
1732
1743
                    inv_entry.reference_revision = fingerprint or None
1859
1870
            return None
1860
1871
        return ie.executable
1861
1872
 
 
1873
    def is_locked(self):
 
1874
        return self._locked
 
1875
 
1862
1876
    def list_files(self, include_root=False, from_dir=None, recursive=True):
1863
1877
        # We use a standard implementation, because DirStateRevisionTree is
1864
1878
        # dealing with one of the parents of the current state
1877
1891
            yield path, 'V', entry.kind, entry.file_id, entry
1878
1892
 
1879
1893
    def lock_read(self):
1880
 
        """Lock the tree for a set of operations."""
 
1894
        """Lock the tree for a set of operations.
 
1895
 
 
1896
        :return: A bzrlib.lock.LogicalLockResult.
 
1897
        """
1881
1898
        if not self._locked:
1882
1899
            self._repository.lock_read()
1883
1900
            if self._dirstate._lock_token is None:
1884
1901
                self._dirstate.lock_read()
1885
1902
                self._dirstate_locked = True
1886
1903
        self._locked += 1
 
1904
        return LogicalLockResult(self.unlock)
1887
1905
 
1888
1906
    def _must_be_locked(self):
1889
1907
        if not self._locked: