~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree_4.py

  • Committer: Jelmer Vernooij
  • Date: 2011-04-19 10:42:59 UTC
  • mto: This revision was merged to the branch mainline in revision 5806.
  • Revision ID: jelmer@samba.org-20110419104259-g9exlcp1f5jdu3ci
Move Inventory._get_mutable_inventory -> mutable_inventory_from_tree.

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
 
53
from bzrlib.lock import LogicalLockResult
56
54
from bzrlib.mutabletree import needs_tree_write_lock
57
55
from bzrlib.osutils import (
58
56
    file_kind,
61
59
    realpath,
62
60
    safe_unicode,
63
61
    )
64
 
from bzrlib.trace import mutter
65
62
from bzrlib.transport.local import LocalTransport
66
 
from bzrlib.tree import InterTree
67
 
from bzrlib.tree import Tree
68
 
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
    )
69
72
 
70
73
 
71
74
class DirStateWorkingTree(WorkingTree3):
 
75
 
72
76
    def __init__(self, basedir,
73
77
                 branch,
74
78
                 _control_files=None,
84
88
        self._format = _format
85
89
        self.bzrdir = _bzrdir
86
90
        basedir = safe_unicode(basedir)
87
 
        mutter("opening working tree %r", basedir)
 
91
        trace.mutter("opening working tree %r", basedir)
88
92
        self._branch = branch
89
93
        self.basedir = realpath(basedir)
90
94
        # if branch is at our basedir and is a format 6 or less
368
372
        state = self.current_dirstate()
369
373
        if stat_value is None:
370
374
            try:
371
 
                stat_value = os.lstat(file_abspath)
 
375
                stat_value = osutils.lstat(file_abspath)
372
376
            except OSError, e:
373
377
                if e.errno == errno.ENOENT:
374
378
                    return None
477
481
            self._must_be_locked()
478
482
            if not path:
479
483
                path = self.id2path(file_id)
480
 
            mode = os.lstat(self.abspath(path)).st_mode
 
484
            mode = osutils.lstat(self.abspath(path)).st_mode
481
485
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
482
486
 
483
487
    def all_file_ids(self):
567
571
            return _mod_revision.NULL_REVISION
568
572
 
569
573
    def lock_read(self):
570
 
        """See Branch.lock_read, and WorkingTree.unlock."""
 
574
        """See Branch.lock_read, and WorkingTree.unlock.
 
575
 
 
576
        :return: A bzrlib.lock.LogicalLockResult.
 
577
        """
571
578
        self.branch.lock_read()
572
579
        try:
573
580
            self._control_files.lock_read()
586
593
        except:
587
594
            self.branch.unlock()
588
595
            raise
 
596
        return LogicalLockResult(self.unlock)
589
597
 
590
598
    def _lock_self_write(self):
591
599
        """This should be called after the branch is locked."""
606
614
        except:
607
615
            self.branch.unlock()
608
616
            raise
 
617
        return LogicalLockResult(self.unlock)
609
618
 
610
619
    def lock_tree_write(self):
611
 
        """See MutableTree.lock_tree_write, and WorkingTree.unlock."""
 
620
        """See MutableTree.lock_tree_write, and WorkingTree.unlock.
 
621
 
 
622
        :return: A bzrlib.lock.LogicalLockResult.
 
623
        """
612
624
        self.branch.lock_read()
613
 
        self._lock_self_write()
 
625
        return self._lock_self_write()
614
626
 
615
627
    def lock_write(self):
616
 
        """See MutableTree.lock_write, and WorkingTree.unlock."""
 
628
        """See MutableTree.lock_write, and WorkingTree.unlock.
 
629
 
 
630
        :return: A bzrlib.lock.LogicalLockResult.
 
631
        """
617
632
        self.branch.lock_write()
618
 
        self._lock_self_write()
 
633
        return self._lock_self_write()
619
634
 
620
635
    @needs_tree_write_lock
621
636
    def move(self, from_paths, to_dir, after=False):
1235
1250
        # have to change the legacy inventory too.
1236
1251
        if self._inventory is not None:
1237
1252
            for file_id in file_ids:
1238
 
                self._inventory.remove_recursive_id(file_id)
 
1253
                if self._inventory.has_id(file_id):
 
1254
                    self._inventory.remove_recursive_id(file_id)
1239
1255
 
1240
1256
    @needs_tree_write_lock
1241
1257
    def rename_one(self, from_rel, to_rel, after=False):
1242
1258
        """See WorkingTree.rename_one"""
1243
1259
        self.flush()
1244
 
        WorkingTree.rename_one(self, from_rel, to_rel, after)
 
1260
        super(DirStateWorkingTree, self).rename_one(from_rel, to_rel, after)
1245
1261
 
1246
1262
    @needs_tree_write_lock
1247
1263
    def apply_inventory_delta(self, changes):
1280
1296
            self._inventory = inv
1281
1297
        self.flush()
1282
1298
 
 
1299
    @needs_tree_write_lock
 
1300
    def reset_state(self, revision_ids=None):
 
1301
        """Reset the state of the working tree.
 
1302
 
 
1303
        This does a hard-reset to a last-known-good state. This is a way to
 
1304
        fix if something got corrupted (like the .bzr/checkout/dirstate file)
 
1305
        """
 
1306
        if revision_ids is None:
 
1307
            revision_ids = self.get_parent_ids()
 
1308
        if not revision_ids:
 
1309
            base_tree = self.branch.repository.revision_tree(
 
1310
                _mod_revision.NULL_REVISION)
 
1311
            trees = []
 
1312
        else:
 
1313
            trees = zip(revision_ids,
 
1314
                        self.branch.repository.revision_trees(revision_ids))
 
1315
            base_tree = trees[0][1]
 
1316
        state = self.current_dirstate()
 
1317
        # We don't support ghosts yet
 
1318
        state.set_state_from_scratch(base_tree.inventory, trees, [])
 
1319
 
1283
1320
 
1284
1321
class ContentFilterAwareSHA1Provider(dirstate.SHA1Provider):
1285
1322
 
1290
1327
        """See dirstate.SHA1Provider.sha1()."""
1291
1328
        filters = self.tree._content_filter_stack(
1292
1329
            self.tree.relpath(osutils.safe_unicode(abspath)))
1293
 
        return internal_size_sha_file_byname(abspath, filters)[1]
 
1330
        return _mod_filters.internal_size_sha_file_byname(abspath, filters)[1]
1294
1331
 
1295
1332
    def stat_and_sha1(self, abspath):
1296
1333
        """See dirstate.SHA1Provider.stat_and_sha1()."""
1300
1337
        try:
1301
1338
            statvalue = os.fstat(file_obj.fileno())
1302
1339
            if filters:
1303
 
                file_obj = filtered_input_file(file_obj, filters)
 
1340
                file_obj = _mod_filters.filtered_input_file(file_obj, filters)
1304
1341
            sha1 = osutils.size_sha_file(file_obj)[1]
1305
1342
        finally:
1306
1343
            file_obj.close()
1317
1354
    def _file_content_summary(self, path, stat_result):
1318
1355
        # This is to support the somewhat obsolete path_content_summary method
1319
1356
        # with content filtering: see
1320
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/415508>.
 
1357
        # <https://bugs.launchpad.net/bzr/+bug/415508>.
1321
1358
        #
1322
1359
        # If the dirstate cache is up to date and knows the hash and size,
1323
1360
        # return that.
1372
1409
 
1373
1410
class DirStateWorkingTreeFormat(WorkingTreeFormat3):
1374
1411
 
 
1412
    missing_parent_conflicts = True
 
1413
 
1375
1414
    def initialize(self, a_bzrdir, revision_id=None, from_branch=None,
1376
1415
                   accelerator_tree=None, hardlink=False):
1377
1416
        """See WorkingTreeFormat.initialize().
1572
1611
        return True
1573
1612
 
1574
1613
 
1575
 
class DirStateRevisionTree(Tree):
 
1614
class DirStateRevisionTree(InventoryTree):
1576
1615
    """A revision tree pulling the inventory from a dirstate.
1577
1616
    
1578
1617
    Note that this is one of the historical (ie revision) trees cached in the
1725
1764
                elif kind == 'directory':
1726
1765
                    parent_ies[(dirname + '/' + name).strip('/')] = inv_entry
1727
1766
                elif kind == 'symlink':
1728
 
                    inv_entry.executable = False
1729
 
                    inv_entry.text_size = None
1730
1767
                    inv_entry.symlink_target = utf8_decode(fingerprint)[0]
1731
1768
                elif kind == 'tree-reference':
1732
1769
                    inv_entry.reference_revision = fingerprint or None
1856
1893
    def is_executable(self, file_id, path=None):
1857
1894
        ie = self.inventory[file_id]
1858
1895
        if ie.kind != "file":
1859
 
            return None
 
1896
            return False
1860
1897
        return ie.executable
1861
1898
 
 
1899
    def is_locked(self):
 
1900
        return self._locked
 
1901
 
1862
1902
    def list_files(self, include_root=False, from_dir=None, recursive=True):
1863
1903
        # We use a standard implementation, because DirStateRevisionTree is
1864
1904
        # dealing with one of the parents of the current state
1877
1917
            yield path, 'V', entry.kind, entry.file_id, entry
1878
1918
 
1879
1919
    def lock_read(self):
1880
 
        """Lock the tree for a set of operations."""
 
1920
        """Lock the tree for a set of operations.
 
1921
 
 
1922
        :return: A bzrlib.lock.LogicalLockResult.
 
1923
        """
1881
1924
        if not self._locked:
1882
1925
            self._repository.lock_read()
1883
1926
            if self._dirstate._lock_token is None:
1884
1927
                self._dirstate.lock_read()
1885
1928
                self._dirstate_locked = True
1886
1929
        self._locked += 1
 
1930
        return LogicalLockResult(self.unlock)
1887
1931
 
1888
1932
    def _must_be_locked(self):
1889
1933
        if not self._locked: