/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

  • Committer: John Arbash Meinel
  • Date: 2011-04-22 14:12:22 UTC
  • mfrom: (5809 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5836.
  • Revision ID: john@arbash-meinel.com-20110422141222-nx2j0hbkihcb8j16
Merge newer bzr.dev and resolve conflicts.
Try to write some documentation about how the _dirblock_state works.
Fix up the tests so that they pass again.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
 
1
# Copyright (C) 2007-2011 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
31
31
import errno
32
32
import stat
33
33
 
34
 
import bzrlib
35
34
from bzrlib import (
36
35
    bzrdir,
37
36
    cache_utf8,
38
37
    debug,
39
38
    dirstate,
40
39
    errors,
 
40
    filters as _mod_filters,
41
41
    generate_ids,
42
42
    osutils,
43
43
    revision as _mod_revision,
46
46
    transform,
47
47
    views,
48
48
    )
49
 
import bzrlib.branch
50
 
import bzrlib.ui
51
49
""")
52
50
 
53
51
from bzrlib.decorators import needs_read_lock, needs_write_lock
54
 
from bzrlib.filters import filtered_input_file, internal_size_sha_file_byname
55
52
from bzrlib.inventory import Inventory, ROOT_ID, entry_factory
56
53
from bzrlib.lock import LogicalLockResult
57
54
from bzrlib.mutabletree import needs_tree_write_lock
62
59
    realpath,
63
60
    safe_unicode,
64
61
    )
65
 
from bzrlib.trace import mutter
66
62
from bzrlib.transport.local import LocalTransport
67
 
from bzrlib.tree import InterTree
68
 
from bzrlib.tree import Tree
69
 
from bzrlib.workingtree import WorkingTree, WorkingTree3, WorkingTreeFormat3
 
63
from bzrlib.tree import (
 
64
    InterTree,
 
65
    InventoryTree,
 
66
    )
 
67
from bzrlib.workingtree import (
 
68
    WorkingTree,
 
69
    WorkingTree3,
 
70
    WorkingTreeFormat3,
 
71
    )
70
72
 
71
73
 
72
74
class DirStateWorkingTree(WorkingTree3):
 
75
 
73
76
    def __init__(self, basedir,
74
77
                 branch,
75
78
                 _control_files=None,
85
88
        self._format = _format
86
89
        self.bzrdir = _bzrdir
87
90
        basedir = safe_unicode(basedir)
88
 
        mutter("opening working tree %r", basedir)
 
91
        trace.mutter("opening working tree %r", basedir)
89
92
        self._branch = branch
90
93
        self.basedir = realpath(basedir)
91
94
        # if branch is at our basedir and is a format 6 or less
219
222
        local_path = self.bzrdir.get_workingtree_transport(None
220
223
            ).local_abspath('dirstate')
221
224
        self._dirstate = dirstate.DirState.on_file(local_path,
222
 
            self._sha1_provider())
 
225
            self._sha1_provider(), self._worth_saving_limit())
223
226
        return self._dirstate
224
227
 
225
228
    def _sha1_provider(self):
234
237
        else:
235
238
            return None
236
239
 
 
240
    def _worth_saving_limit(self):
 
241
        """How many hash changes are ok before we must save the dirstate.
 
242
 
 
243
        :return: an integer. -1 means never save.
 
244
        """
 
245
        # XXX: In the future, we could return -1 for logical read-only
 
246
        # operations like status. For now, just use a small number.
 
247
        return 10
 
248
 
237
249
    def filter_unversioned_files(self, paths):
238
250
        """Filter out paths that are versioned.
239
251
 
369
381
        state = self.current_dirstate()
370
382
        if stat_value is None:
371
383
            try:
372
 
                stat_value = os.lstat(file_abspath)
 
384
                stat_value = osutils.lstat(file_abspath)
373
385
            except OSError, e:
374
386
                if e.errno == errno.ENOENT:
375
387
                    return None
478
490
            self._must_be_locked()
479
491
            if not path:
480
492
                path = self.id2path(file_id)
481
 
            mode = os.lstat(self.abspath(path)).st_mode
 
493
            mode = osutils.lstat(self.abspath(path)).st_mode
482
494
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
483
495
 
484
496
    def all_file_ids(self):
850
862
                rollback_rename()
851
863
                raise
852
864
            result.append((from_rel, to_rel))
853
 
            state._dirblock_state = dirstate.DirState.IN_MEMORY_MODIFIED
 
865
            state._mark_modified()
854
866
            self._make_dirty(reset_inventory=False)
855
867
 
856
868
        return result
1247
1259
        # have to change the legacy inventory too.
1248
1260
        if self._inventory is not None:
1249
1261
            for file_id in file_ids:
1250
 
                self._inventory.remove_recursive_id(file_id)
 
1262
                if self._inventory.has_id(file_id):
 
1263
                    self._inventory.remove_recursive_id(file_id)
1251
1264
 
1252
1265
    @needs_tree_write_lock
1253
1266
    def rename_one(self, from_rel, to_rel, after=False):
1254
1267
        """See WorkingTree.rename_one"""
1255
1268
        self.flush()
1256
 
        WorkingTree.rename_one(self, from_rel, to_rel, after)
 
1269
        super(DirStateWorkingTree, self).rename_one(from_rel, to_rel, after)
1257
1270
 
1258
1271
    @needs_tree_write_lock
1259
1272
    def apply_inventory_delta(self, changes):
1292
1305
            self._inventory = inv
1293
1306
        self.flush()
1294
1307
 
 
1308
    @needs_tree_write_lock
 
1309
    def reset_state(self, revision_ids=None):
 
1310
        """Reset the state of the working tree.
 
1311
 
 
1312
        This does a hard-reset to a last-known-good state. This is a way to
 
1313
        fix if something got corrupted (like the .bzr/checkout/dirstate file)
 
1314
        """
 
1315
        if revision_ids is None:
 
1316
            revision_ids = self.get_parent_ids()
 
1317
        if not revision_ids:
 
1318
            base_tree = self.branch.repository.revision_tree(
 
1319
                _mod_revision.NULL_REVISION)
 
1320
            trees = []
 
1321
        else:
 
1322
            trees = zip(revision_ids,
 
1323
                        self.branch.repository.revision_trees(revision_ids))
 
1324
            base_tree = trees[0][1]
 
1325
        state = self.current_dirstate()
 
1326
        # We don't support ghosts yet
 
1327
        state.set_state_from_scratch(base_tree.inventory, trees, [])
 
1328
 
1295
1329
 
1296
1330
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1297
1331
 
1302
1336
        """See dirstate.SHA1Provider.sha1()."""
1303
1337
        filters = self.tree._content_filter_stack(
1304
1338
            self.tree.relpath(osutils.safe_unicode(abspath)))
1305
 
        return internal_size_sha_file_byname(abspath, filters)[1]
 
1339
        return _mod_filters.internal_size_sha_file_byname(abspath, filters)[1]
1306
1340
 
1307
1341
    def stat_and_sha1(self, abspath):
1308
1342
        """See dirstate.SHA1Provider.stat_and_sha1()."""
1312
1346
        try:
1313
1347
            statvalue = os.fstat(file_obj.fileno())
1314
1348
            if filters:
1315
 
                file_obj = filtered_input_file(file_obj, filters)
 
1349
                file_obj = _mod_filters.filtered_input_file(file_obj, filters)
1316
1350
            sha1 = osutils.size_sha_file(file_obj)[1]
1317
1351
        finally:
1318
1352
            file_obj.close()
1329
1363
    def _file_content_summary(self, path, stat_result):
1330
1364
        # This is to support the somewhat obsolete path_content_summary method
1331
1365
        # with content filtering: see
1332
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/415508>.
 
1366
        # <https://bugs.launchpad.net/bzr/+bug/415508>.
1333
1367
        #
1334
1368
        # If the dirstate cache is up to date and knows the hash and size,
1335
1369
        # return that.
1384
1418
 
1385
1419
class DirStateWorkingTreeFormat(WorkingTreeFormat3):
1386
1420
 
 
1421
    missing_parent_conflicts = True
 
1422
 
1387
1423
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1388
1424
                   accelerator_tree=None, hardlink=False):
1389
1425
        """See WorkingTreeFormat.initialize().
1584
1620
        return True
1585
1621
 
1586
1622
 
1587
 
class DirStateRevisionTree(Tree):
 
1623
class DirStateRevisionTree(InventoryTree):
1588
1624
    """A revision tree pulling the inventory from a dirstate.
1589
1625
    
1590
1626
    Note that this is one of the historical (ie revision) trees cached in the
1609
1645
    def annotate_iter(self, file_id,
1610
1646
                      default_revision=_mod_revision.CURRENT_REVISION):
1611
1647
        """See Tree.annotate_iter"""
1612
 
        text_key = (file_id, self.inventory[file_id].revision)
 
1648
        text_key = (file_id, self.get_file_revision(file_id))
1613
1649
        annotations = self._repository.texts.annotate(text_key)
1614
1650
        return [(key[-1], line) for (key, line) in annotations]
1615
1651
 
1737
1773
                elif kind == 'directory':
1738
1774
                    parent_ies[(dirname + '/' + name).strip('/')] = inv_entry
1739
1775
                elif kind == 'symlink':
1740
 
                    inv_entry.executable = False
1741
 
                    inv_entry.text_size = None
1742
1776
                    inv_entry.symlink_target = utf8_decode(fingerprint)[0]
1743
1777
                elif kind == 'tree-reference':
1744
1778
                    inv_entry.reference_revision = fingerprint or None
1781
1815
            return parent_details[1]
1782
1816
        return None
1783
1817
 
 
1818
    @needs_read_lock
 
1819
    def get_file_revision(self, file_id):
 
1820
        return self.inventory[file_id].revision
 
1821
 
1784
1822
    def get_file(self, file_id, path=None):
1785
1823
        return StringIO(self.get_file_text(file_id))
1786
1824
 
1868
1906
    def is_executable(self, file_id, path=None):
1869
1907
        ie = self.inventory[file_id]
1870
1908
        if ie.kind != "file":
1871
 
            return None
 
1909
            return False
1872
1910
        return ie.executable
1873
1911
 
1874
1912
    def is_locked(self):