~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree_4.py

  • Committer: Jelmer Vernooij
  • Date: 2012-02-01 19:18:09 UTC
  • mfrom: (6459 +trunk)
  • mto: This revision was merged to the branch mainline in revision 6460.
  • Revision ID: jelmer@samba.org-20120201191809-xn340a5i5v4fqsfu
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
WorkingTree.open(dir).
23
23
"""
24
24
 
 
25
from __future__ import absolute_import
 
26
 
25
27
from cStringIO import StringIO
26
28
import os
27
29
import sys
34
36
from bzrlib import (
35
37
    bzrdir,
36
38
    cache_utf8,
 
39
    config,
37
40
    conflicts as _mod_conflicts,
38
41
    debug,
39
42
    dirstate,
54
57
from bzrlib.lock import LogicalLockResult
55
58
from bzrlib.lockable_files import LockableFiles
56
59
from bzrlib.lockdir import LockDir
57
 
from bzrlib.mutabletree import needs_tree_write_lock
 
60
from bzrlib.mutabletree import (
 
61
    MutableTree,
 
62
    needs_tree_write_lock,
 
63
    )
58
64
from bzrlib.osutils import (
59
65
    file_kind,
60
66
    isdir,
70
76
from bzrlib.workingtree import (
71
77
    InventoryWorkingTree,
72
78
    WorkingTree,
73
 
    WorkingTreeFormat,
 
79
    WorkingTreeFormatMetaDir,
74
80
    )
75
81
 
76
82
 
77
83
class DirStateWorkingTree(InventoryWorkingTree):
78
84
 
79
 
    _DEFAULT_WORTH_SAVING_LIMIT = 10
80
 
 
81
85
    def __init__(self, basedir,
82
86
                 branch,
83
87
                 _control_files=None,
251
255
 
252
256
        :return: an integer. -1 means never save.
253
257
        """
254
 
        config = self.branch.get_config()
255
 
        val = config.get_user_option('bzr.workingtree.worth_saving_limit')
256
 
        if val is None:
257
 
            val = self._DEFAULT_WORTH_SAVING_LIMIT
258
 
        else:
259
 
            try:
260
 
                val = int(val)
261
 
            except ValueError, e:
262
 
                trace.warning('Invalid config value for'
263
 
                              ' "bzr.workingtree.worth_saving_limit"'
264
 
                              ' value %r is not an integer.'
265
 
                              % (val,))
266
 
                val = self._DEFAULT_WORTH_SAVING_LIMIT
267
 
        return val
 
258
        conf = self.get_config_stack()
 
259
        return conf.get('bzr.workingtree.worth_saving_limit')
268
260
 
269
261
    def filter_unversioned_files(self, paths):
270
262
        """Filter out paths that are versioned.
488
480
            return False # Missing entries are not executable
489
481
        return entry[1][0][3] # Executable?
490
482
 
491
 
    if not osutils.supports_executable():
492
 
        def is_executable(self, file_id, path=None):
493
 
            """Test if a file is executable or not.
 
483
    def is_executable(self, file_id, path=None):
 
484
        """Test if a file is executable or not.
494
485
 
495
 
            Note: The caller is expected to take a read-lock before calling this.
496
 
            """
 
486
        Note: The caller is expected to take a read-lock before calling this.
 
487
        """
 
488
        if not self._supports_executable():
497
489
            entry = self._get_entry(file_id=file_id, path=path)
498
490
            if entry == (None, None):
499
491
                return False
500
492
            return entry[1][0][3]
501
 
 
502
 
        _is_executable_from_path_and_stat = \
503
 
            _is_executable_from_path_and_stat_from_basis
504
 
    else:
505
 
        def is_executable(self, file_id, path=None):
506
 
            """Test if a file is executable or not.
507
 
 
508
 
            Note: The caller is expected to take a read-lock before calling this.
509
 
            """
 
493
        else:
510
494
            self._must_be_locked()
511
495
            if not path:
512
496
                path = self.id2path(file_id)
981
965
                    all_versioned = False
982
966
                    break
983
967
            if not all_versioned:
984
 
                raise errors.PathsNotVersionedError(paths)
 
968
                raise errors.PathsNotVersionedError(
 
969
                    [p.decode('utf-8') for p in paths])
985
970
        # -- remove redundancy in supplied paths to prevent over-scanning --
986
971
        search_paths = osutils.minimum_path_selection(paths)
987
972
        # sketch:
1036
1021
            found_dir_names = set(dir_name_id[:2] for dir_name_id in found)
1037
1022
            for dir_name in split_paths:
1038
1023
                if dir_name not in found_dir_names:
1039
 
                    raise errors.PathsNotVersionedError(paths)
 
1024
                    raise errors.PathsNotVersionedError(
 
1025
                        [p.decode('utf-8') for p in paths])
1040
1026
 
1041
1027
        for dir_name_id, trees_info in found.iteritems():
1042
1028
            for index in search_indexes:
1163
1149
                # _make_delta if we can't get the RevisionTree
1164
1150
                pass
1165
1151
            else:
1166
 
                delta = rev_tree.inventory._make_delta(basis_tree.inventory)
 
1152
                delta = rev_tree.inventory._make_delta(
 
1153
                    basis_tree.inventory)
1167
1154
                dirstate.update_basis_by_delta(delta, rev_id)
1168
1155
                updated = True
1169
1156
        if not updated:
1458
1445
        return views.PathBasedViews(self)
1459
1446
 
1460
1447
 
1461
 
class DirStateWorkingTreeFormat(WorkingTreeFormat):
 
1448
class DirStateWorkingTreeFormat(WorkingTreeFormatMetaDir):
1462
1449
 
1463
1450
    missing_parent_conflicts = True
1464
1451
 
1494
1481
        control_files = self._open_control_files(a_bzrdir)
1495
1482
        control_files.create_lock()
1496
1483
        control_files.lock_write()
1497
 
        transport.put_bytes('format', self.get_format_string(),
 
1484
        transport.put_bytes('format', self.as_string(),
1498
1485
            mode=a_bzrdir._get_file_mode())
1499
1486
        if from_branch is not None:
1500
1487
            branch = from_branch
1560
1547
                transform.build_tree(basis, wt, accelerator_tree,
1561
1548
                                     hardlink=hardlink,
1562
1549
                                     delta_from_tree=delta_from_tree)
 
1550
                for hook in MutableTree.hooks['post_build_tree']:
 
1551
                    hook(wt)
1563
1552
            finally:
1564
1553
                basis.unlock()
1565
1554
        finally:
1609
1598
        """Overrideable method to get a bzrdir for testing."""
1610
1599
        # please test against something that will let us do tree references
1611
1600
        return bzrdir.format_registry.make_bzrdir(
1612
 
            'dirstate-with-subtree')
 
1601
            'development-subtree')
1613
1602
 
1614
1603
    _matchingbzrdir = property(__get_matchingbzrdir)
1615
1604
 
1620
1609
    This format:
1621
1610
        - exists within a metadir controlling .bzr
1622
1611
        - includes an explicit version marker for the workingtree control
1623
 
          files, separate from the BzrDir format
 
1612
          files, separate from the ControlDir format
1624
1613
        - modifies the hash cache format
1625
1614
        - is new in bzr 0.15
1626
1615
        - uses a LockDir to guard access to it.
1630
1619
 
1631
1620
    _tree_class = WorkingTree4
1632
1621
 
1633
 
    def get_format_string(self):
 
1622
    @classmethod
 
1623
    def get_format_string(cls):
1634
1624
        """See WorkingTreeFormat.get_format_string()."""
1635
1625
        return "Bazaar Working Tree Format 4 (bzr 0.15)\n"
1636
1626
 
1647
1637
 
1648
1638
    _tree_class = WorkingTree5
1649
1639
 
1650
 
    def get_format_string(self):
 
1640
    @classmethod
 
1641
    def get_format_string(cls):
1651
1642
        """See WorkingTreeFormat.get_format_string()."""
1652
1643
        return "Bazaar Working Tree Format 5 (bzr 1.11)\n"
1653
1644
 
1667
1658
 
1668
1659
    _tree_class = WorkingTree6
1669
1660
 
1670
 
    def get_format_string(self):
 
1661
    @classmethod
 
1662
    def get_format_string(cls):
1671
1663
        """See WorkingTreeFormat.get_format_string()."""
1672
1664
        return "Bazaar Working Tree Format 6 (bzr 1.14)\n"
1673
1665
 
1861
1853
        # Make sure the file exists
1862
1854
        entry = self._get_entry(file_id, path=path)
1863
1855
        if entry == (None, None): # do we raise?
1864
 
            return None
 
1856
            raise errors.NoSuchId(self, file_id)
1865
1857
        parent_index = self._get_parent_index()
1866
1858
        last_changed_revision = entry[1][parent_index][4]
1867
1859
        try:
1880
1872
 
1881
1873
    @needs_read_lock
1882
1874
    def get_file_revision(self, file_id):
1883
 
        return self.inventory[file_id].revision
 
1875
        inv, inv_file_id = self._unpack_file_id(file_id)
 
1876
        return inv[inv_file_id].revision
1884
1877
 
1885
1878
    def get_file(self, file_id, path=None):
1886
1879
        return StringIO(self.get_file_text(file_id))
1887
1880
 
1888
1881
    def get_file_size(self, file_id):
1889
1882
        """See Tree.get_file_size"""
1890
 
        return self.inventory[file_id].text_size
 
1883
        inv, inv_file_id = self._unpack_file_id(file_id)
 
1884
        return inv[inv_file_id].text_size
1891
1885
 
1892
1886
    def get_file_text(self, file_id, path=None):
1893
1887
        _, content = list(self.iter_files_bytes([(file_id, None)]))[0]
1894
1888
        return ''.join(content)
1895
1889
 
1896
1890
    def get_reference_revision(self, file_id, path=None):
1897
 
        return self.inventory[file_id].reference_revision
 
1891
        inv, inv_file_id = self._unpack_file_id(file_id)
 
1892
        return inv[inv_file_id].reference_revision
1898
1893
 
1899
1894
    def iter_files_bytes(self, desired_files):
1900
1895
        """See Tree.iter_files_bytes.
1954
1949
 
1955
1950
    def path_content_summary(self, path):
1956
1951
        """See Tree.path_content_summary."""
1957
 
        id = self.inventory.path2id(path)
1958
 
        if id is None:
 
1952
        inv, inv_file_id = self._path2inv_file_id(path)
 
1953
        if inv_file_id is None:
1959
1954
            return ('missing', None, None, None)
1960
 
        entry = self._inventory[id]
 
1955
        entry = inv[inv_file_id]
1961
1956
        kind = entry.kind
1962
1957
        if kind == 'file':
1963
1958
            return (kind, entry.text_size, entry.executable, entry.text_sha1)
1967
1962
            return (kind, None, None, None)
1968
1963
 
1969
1964
    def is_executable(self, file_id, path=None):
1970
 
        ie = self.inventory[file_id]
 
1965
        inv, inv_file_id = self._unpack_file_id(file_id)
 
1966
        ie = inv[inv_file_id]
1971
1967
        if ie.kind != "file":
1972
1968
            return False
1973
1969
        return ie.executable
1978
1974
    def list_files(self, include_root=False, from_dir=None, recursive=True):
1979
1975
        # We use a standard implementation, because DirStateRevisionTree is
1980
1976
        # dealing with one of the parents of the current state
1981
 
        inv = self._get_inventory()
1982
1977
        if from_dir is None:
 
1978
            inv = self.inventory
1983
1979
            from_dir_id = None
1984
1980
        else:
1985
 
            from_dir_id = inv.path2id(from_dir)
 
1981
            inv, from_dir_id = self._path2inv_file_id(from_dir)
1986
1982
            if from_dir_id is None:
1987
1983
                # Directory not versioned
1988
1984
                return
2186
2182
                path_entries = state._entries_for_path(path)
2187
2183
                if not path_entries:
2188
2184
                    # this specified path is not present at all: error
2189
 
                    not_versioned.append(path)
 
2185
                    not_versioned.append(path.decode('utf-8'))
2190
2186
                    continue
2191
2187
                found_versioned = False
2192
2188
                # for each id at this path
2200
2196
                if not found_versioned:
2201
2197
                    # none of the indexes was not 'absent' at all ids for this
2202
2198
                    # path.
2203
 
                    not_versioned.append(path)
 
2199
                    not_versioned.append(path.decode('utf-8'))
2204
2200
            if len(not_versioned) > 0:
2205
2201
                raise errors.PathsNotVersionedError(not_versioned)
2206
2202
        # -- remove redundancy in supplied specific_files to prevent over-scanning --
2273
2269
    def update_format(self, tree):
2274
2270
        """Change the format marker."""
2275
2271
        tree._transport.put_bytes('format',
2276
 
            self.target_format.get_format_string(),
 
2272
            self.target_format.as_string(),
2277
2273
            mode=tree.bzrdir._get_file_mode())
2278
2274
 
2279
2275
 
2296
2292
    def update_format(self, tree):
2297
2293
        """Change the format marker."""
2298
2294
        tree._transport.put_bytes('format',
2299
 
            self.target_format.get_format_string(),
 
2295
            self.target_format.as_string(),
2300
2296
            mode=tree.bzrdir._get_file_mode())
2301
2297
 
2302
2298
 
2325
2321
    def update_format(self, tree):
2326
2322
        """Change the format marker."""
2327
2323
        tree._transport.put_bytes('format',
2328
 
            self.target_format.get_format_string(),
 
2324
            self.target_format.as_string(),
2329
2325
            mode=tree.bzrdir._get_file_mode())