~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/memorytree.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2011-05-04 12:10:51 UTC
  • mfrom: (5819.1.4 777007-developer-doc)
  • Revision ID: pqm@pqm.ubuntu.com-20110504121051-aovlsmqiivjmc4fc
(jelmer) Small fixes to developer documentation. (Jonathan Riddell)

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""MemoryTree object.
18
18
 
20
20
"""
21
21
 
22
22
 
23
 
from copy import deepcopy
 
23
import os
24
24
 
25
 
from bzrlib import errors, mutabletree
26
 
from bzrlib.decorators import needs_read_lock, needs_write_lock
 
25
from bzrlib import (
 
26
    errors,
 
27
    mutabletree,
 
28
    revision as _mod_revision,
 
29
    )
 
30
from bzrlib.decorators import needs_read_lock
 
31
from bzrlib.inventory import Inventory
27
32
from bzrlib.osutils import sha_file
28
33
from bzrlib.mutabletree import needs_tree_write_lock
29
34
from bzrlib.transport.memory import MemoryTransport
30
35
 
31
36
 
32
 
class MemoryTree(mutabletree.MutableTree):
 
37
class MemoryTree(mutabletree.MutableInventoryTree):
33
38
    """A MemoryTree is a specialisation of MutableTree.
34
 
    
 
39
 
35
40
    It maintains nearly no state outside of read_lock and write_lock
36
41
    transactions. (it keeps a reference to the branch, and its last-revision
37
42
    only).
45
50
        self._locks = 0
46
51
        self._lock_mode = None
47
52
 
 
53
    def is_control_filename(self, filename):
 
54
        # Memory tree doesn't have any control filenames
 
55
        return False
 
56
 
48
57
    @needs_tree_write_lock
49
58
    def _add(self, files, ids, kinds):
50
59
        """See MutableTree._add."""
63
72
    @staticmethod
64
73
    def create_on_branch(branch):
65
74
        """Create a MemoryTree for branch, using the last-revision of branch."""
66
 
        return MemoryTree(branch, branch.last_revision())
 
75
        revision_id = _mod_revision.ensure_null(branch.last_revision())
 
76
        return MemoryTree(branch, revision_id)
67
77
 
68
78
    def _gather_kinds(self, files, kinds):
69
79
        """See MutableTree._gather_kinds.
70
 
        
 
80
 
71
81
        This implementation does not care about the file kind of
72
82
        missing files, so is a no-op.
73
83
        """
74
84
 
75
 
    def get_file(self, file_id):
 
85
    def get_file(self, file_id, path=None):
76
86
        """See Tree.get_file."""
77
 
        return self._file_transport.get(self.id2path(file_id))
 
87
        if path is None:
 
88
            path = self.id2path(file_id)
 
89
        return self._file_transport.get(path)
78
90
 
79
 
    def get_file_sha1(self, file_id, path=None):
 
91
    def get_file_sha1(self, file_id, path=None, stat_value=None):
80
92
        """See Tree.get_file_sha1()."""
81
93
        if path is None:
82
94
            path = self.id2path(file_id)
83
95
        stream = self._file_transport.get(path)
84
96
        return sha_file(stream)
85
97
 
 
98
    def get_root_id(self):
 
99
        return self.path2id('')
 
100
 
 
101
    def _comparison_data(self, entry, path):
 
102
        """See Tree._comparison_data."""
 
103
        if entry is None:
 
104
            return None, False, None
 
105
        return entry.kind, entry.executable, None
 
106
 
 
107
    @needs_tree_write_lock
 
108
    def rename_one(self, from_rel, to_rel):
 
109
        file_id = self.path2id(from_rel)
 
110
        to_dir, to_tail = os.path.split(to_rel)
 
111
        to_parent_id = self.path2id(to_dir)
 
112
        self._file_transport.move(from_rel, to_rel)
 
113
        self._inventory.rename(file_id, to_parent_id, to_tail)
 
114
 
 
115
    def path_content_summary(self, path):
 
116
        """See Tree.path_content_summary."""
 
117
        id = self.path2id(path)
 
118
        if id is None:
 
119
            return 'missing', None, None, None
 
120
        kind = self.kind(id)
 
121
        if kind == 'file':
 
122
            bytes = self._file_transport.get_bytes(path)
 
123
            size = len(bytes)
 
124
            executable = self._inventory[id].executable
 
125
            sha1 = None # no stat cache
 
126
            return (kind, size, executable, sha1)
 
127
        elif kind == 'directory':
 
128
            # memory tree does not support nested trees yet.
 
129
            return kind, None, None, None
 
130
        elif kind == 'symlink':
 
131
            raise NotImplementedError('symlink support')
 
132
        else:
 
133
            raise NotImplementedError('unknown kind')
 
134
 
 
135
    def _file_size(self, entry, stat_value):
 
136
        """See Tree._file_size."""
 
137
        if entry is None:
 
138
            return 0
 
139
        return entry.text_size
 
140
 
86
141
    @needs_read_lock
87
142
    def get_parent_ids(self):
88
143
        """See Tree.get_parent_ids.
99
154
    def is_executable(self, file_id, path=None):
100
155
        return self._inventory[file_id].executable
101
156
 
 
157
    def kind(self, file_id):
 
158
        return self._inventory[file_id].kind
 
159
 
102
160
    def mkdir(self, path, file_id=None):
103
161
        """See MutableTree.mkdir()."""
104
162
        self.add(path, file_id, 'directory')
157
215
 
158
216
    def _populate_from_branch(self):
159
217
        """Populate the in-tree state from the branch."""
160
 
        self._basis_tree = self.branch.repository.revision_tree(
161
 
            self._branch_revision_id)
162
 
        if self._branch_revision_id is None:
 
218
        self._set_basis()
 
219
        if self._branch_revision_id == _mod_revision.NULL_REVISION:
163
220
            self._parent_ids = []
164
221
        else:
165
222
            self._parent_ids = [self._branch_revision_id]
166
 
        self._inventory = deepcopy(self._basis_tree._inventory)
 
223
        self._inventory = Inventory(None, self._basis_tree.get_revision_id())
167
224
        self._file_transport = MemoryTransport()
168
225
        # TODO copy the revision trees content, or do it lazy, or something.
169
 
        inventory_entries = self._inventory.iter_entries()
 
226
        inventory_entries = self._basis_tree.iter_entries_by_dir()
170
227
        for path, entry in inventory_entries:
 
228
            self._inventory.add(entry.copy())
171
229
            if path == '':
172
230
                continue
173
231
            if entry.kind == 'directory':
219
277
            else:
220
278
                raise errors.NoSuchId(self, file_id)
221
279
 
 
280
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
 
281
        """See MutableTree.set_parent_trees()."""
 
282
        for revision_id in revision_ids:
 
283
            _mod_revision.check_not_reserved_id(revision_id)
 
284
        if len(revision_ids) == 0:
 
285
            self._parent_ids = []
 
286
            self._branch_revision_id = _mod_revision.NULL_REVISION
 
287
        else:
 
288
            self._parent_ids = revision_ids
 
289
            self._branch_revision_id = revision_ids[0]
 
290
        self._allow_leftmost_as_ghost = allow_leftmost_as_ghost
 
291
        self._set_basis()
 
292
    
 
293
    def _set_basis(self):
 
294
        try:
 
295
            self._basis_tree = self.branch.repository.revision_tree(
 
296
                self._branch_revision_id)
 
297
        except errors.NoSuchRevision:
 
298
            if self._allow_leftmost_as_ghost:
 
299
                self._basis_tree = self.branch.repository.revision_tree(
 
300
                    _mod_revision.NULL_REVISION)
 
301
            else:
 
302
                raise
 
303
 
222
304
    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
223
305
        """See MutableTree.set_parent_trees()."""
224
306
        if len(parents_list) == 0:
225
307
            self._parent_ids = []
226
 
            self._basis_tree = self.branch.repository.revisiontree(None)
 
308
            self._basis_tree = self.branch.repository.revision_tree(
 
309
                                   _mod_revision.NULL_REVISION)
227
310
        else:
228
311
            if parents_list[0][1] is None and not allow_leftmost_as_ghost:
229
312
                # a ghost in the left most parent
230
313
                raise errors.GhostRevisionUnusableHere(parents_list[0][0])
231
314
            self._parent_ids = [parent_id for parent_id, tree in parents_list]
232
 
            if parents_list[0][1] is None:
233
 
                self._basis_tree = self.branch.repository.revisiontree(None)
 
315
            if parents_list[0][1] is None or parents_list[0][1] == 'null:':
 
316
                self._basis_tree = self.branch.repository.revision_tree(
 
317
                                       _mod_revision.NULL_REVISION)
234
318
            else:
235
319
                self._basis_tree = parents_list[0][1]
236
320
            self._branch_revision_id = parents_list[0][0]