~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/memorytree.py

  • Committer: John Arbash Meinel
  • Date: 2012-09-19 07:58:27 UTC
  • mfrom: (6437.63.9 2.5)
  • mto: This revision was merged to the branch mainline in revision 6563.
  • Revision ID: john@arbash-meinel.com-20120919075827-36b2b042kiaps0d3
Merge bzr-2.5.2 into trunk to get the fixes for ConnectionReset.

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
 
19
19
See MemoryTree for more details.
20
20
"""
21
21
 
22
 
 
23
 
from copy import deepcopy
24
 
 
25
 
from bzrlib import errors, mutabletree
26
 
from bzrlib.decorators import needs_read_lock, needs_write_lock
 
22
from __future__ import absolute_import
 
23
 
 
24
import os
 
25
 
 
26
from bzrlib import (
 
27
    errors,
 
28
    mutabletree,
 
29
    revision as _mod_revision,
 
30
    )
 
31
from bzrlib.decorators import needs_read_lock
 
32
from bzrlib.inventory import Inventory
27
33
from bzrlib.osutils import sha_file
28
34
from bzrlib.mutabletree import needs_tree_write_lock
29
35
from bzrlib.transport.memory import MemoryTransport
30
36
 
31
37
 
32
 
class MemoryTree(mutabletree.MutableTree):
 
38
class MemoryTree(mutabletree.MutableInventoryTree):
33
39
    """A MemoryTree is a specialisation of MutableTree.
34
 
    
 
40
 
35
41
    It maintains nearly no state outside of read_lock and write_lock
36
42
    transactions. (it keeps a reference to the branch, and its last-revision
37
43
    only).
45
51
        self._locks = 0
46
52
        self._lock_mode = None
47
53
 
 
54
    def get_config_stack(self):
 
55
        return self.branch.get_config_stack()
 
56
 
 
57
    def is_control_filename(self, filename):
 
58
        # Memory tree doesn't have any control filenames
 
59
        return False
 
60
 
48
61
    @needs_tree_write_lock
49
62
    def _add(self, files, ids, kinds):
50
63
        """See MutableTree._add."""
63
76
    @staticmethod
64
77
    def create_on_branch(branch):
65
78
        """Create a MemoryTree for branch, using the last-revision of branch."""
66
 
        return MemoryTree(branch, branch.last_revision())
 
79
        revision_id = _mod_revision.ensure_null(branch.last_revision())
 
80
        return MemoryTree(branch, revision_id)
67
81
 
68
82
    def _gather_kinds(self, files, kinds):
69
83
        """See MutableTree._gather_kinds.
70
 
        
 
84
 
71
85
        This implementation does not care about the file kind of
72
86
        missing files, so is a no-op.
73
87
        """
74
88
 
75
 
    def get_file(self, file_id):
 
89
    def get_file(self, file_id, path=None):
76
90
        """See Tree.get_file."""
77
 
        return self._file_transport.get(self.id2path(file_id))
 
91
        if path is None:
 
92
            path = self.id2path(file_id)
 
93
        return self._file_transport.get(path)
78
94
 
79
 
    def get_file_sha1(self, file_id, path=None):
 
95
    def get_file_sha1(self, file_id, path=None, stat_value=None):
80
96
        """See Tree.get_file_sha1()."""
81
97
        if path is None:
82
98
            path = self.id2path(file_id)
83
99
        stream = self._file_transport.get(path)
84
100
        return sha_file(stream)
85
101
 
 
102
    def get_root_id(self):
 
103
        return self.path2id('')
 
104
 
 
105
    def _comparison_data(self, entry, path):
 
106
        """See Tree._comparison_data."""
 
107
        if entry is None:
 
108
            return None, False, None
 
109
        return entry.kind, entry.executable, None
 
110
 
 
111
    @needs_tree_write_lock
 
112
    def rename_one(self, from_rel, to_rel):
 
113
        file_id = self.path2id(from_rel)
 
114
        to_dir, to_tail = os.path.split(to_rel)
 
115
        to_parent_id = self.path2id(to_dir)
 
116
        self._file_transport.move(from_rel, to_rel)
 
117
        self._inventory.rename(file_id, to_parent_id, to_tail)
 
118
 
 
119
    def path_content_summary(self, path):
 
120
        """See Tree.path_content_summary."""
 
121
        id = self.path2id(path)
 
122
        if id is None:
 
123
            return 'missing', None, None, None
 
124
        kind = self.kind(id)
 
125
        if kind == 'file':
 
126
            bytes = self._file_transport.get_bytes(path)
 
127
            size = len(bytes)
 
128
            executable = self._inventory[id].executable
 
129
            sha1 = None # no stat cache
 
130
            return (kind, size, executable, sha1)
 
131
        elif kind == 'directory':
 
132
            # memory tree does not support nested trees yet.
 
133
            return kind, None, None, None
 
134
        elif kind == 'symlink':
 
135
            raise NotImplementedError('symlink support')
 
136
        else:
 
137
            raise NotImplementedError('unknown kind')
 
138
 
 
139
    def _file_size(self, entry, stat_value):
 
140
        """See Tree._file_size."""
 
141
        if entry is None:
 
142
            return 0
 
143
        return entry.text_size
 
144
 
86
145
    @needs_read_lock
87
146
    def get_parent_ids(self):
88
147
        """See Tree.get_parent_ids.
160
219
 
161
220
    def _populate_from_branch(self):
162
221
        """Populate the in-tree state from the branch."""
163
 
        self._basis_tree = self.branch.repository.revision_tree(
164
 
            self._branch_revision_id)
165
 
        if self._branch_revision_id is None:
 
222
        self._set_basis()
 
223
        if self._branch_revision_id == _mod_revision.NULL_REVISION:
166
224
            self._parent_ids = []
167
225
        else:
168
226
            self._parent_ids = [self._branch_revision_id]
169
 
        self._inventory = deepcopy(self._basis_tree._inventory)
 
227
        self._inventory = Inventory(None, self._basis_tree.get_revision_id())
170
228
        self._file_transport = MemoryTransport()
171
229
        # TODO copy the revision trees content, or do it lazy, or something.
172
 
        inventory_entries = self._inventory.iter_entries()
 
230
        inventory_entries = self._basis_tree.iter_entries_by_dir()
173
231
        for path, entry in inventory_entries:
 
232
            self._inventory.add(entry.copy())
174
233
            if path == '':
175
234
                continue
176
235
            if entry.kind == 'directory':
224
283
 
225
284
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
226
285
        """See MutableTree.set_parent_trees()."""
 
286
        for revision_id in revision_ids:
 
287
            _mod_revision.check_not_reserved_id(revision_id)
227
288
        if len(revision_ids) == 0:
228
289
            self._parent_ids = []
229
 
            self._basis_tree = self.branch.repository.revision_tree(None)
 
290
            self._branch_revision_id = _mod_revision.NULL_REVISION
230
291
        else:
231
292
            self._parent_ids = revision_ids
232
 
            self._basis_tree = self.branch.repository.revision_tree(
233
 
                                    revision_ids[0])
234
293
            self._branch_revision_id = revision_ids[0]
 
294
        self._allow_leftmost_as_ghost = allow_leftmost_as_ghost
 
295
        self._set_basis()
 
296
    
 
297
    def _set_basis(self):
 
298
        try:
 
299
            self._basis_tree = self.branch.repository.revision_tree(
 
300
                self._branch_revision_id)
 
301
        except errors.NoSuchRevision:
 
302
            if self._allow_leftmost_as_ghost:
 
303
                self._basis_tree = self.branch.repository.revision_tree(
 
304
                    _mod_revision.NULL_REVISION)
 
305
            else:
 
306
                raise
235
307
 
236
308
    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
237
309
        """See MutableTree.set_parent_trees()."""
238
310
        if len(parents_list) == 0:
239
311
            self._parent_ids = []
240
 
            self._basis_tree = self.branch.repository.revision_tree(None)
 
312
            self._basis_tree = self.branch.repository.revision_tree(
 
313
                                   _mod_revision.NULL_REVISION)
241
314
        else:
242
315
            if parents_list[0][1] is None and not allow_leftmost_as_ghost:
243
316
                # a ghost in the left most parent
244
317
                raise errors.GhostRevisionUnusableHere(parents_list[0][0])
245
318
            self._parent_ids = [parent_id for parent_id, tree in parents_list]
246
 
            if parents_list[0][1] is None:
247
 
                self._basis_tree = self.branch.repository.revision_tree(None)
 
319
            if parents_list[0][1] is None or parents_list[0][1] == 'null:':
 
320
                self._basis_tree = self.branch.repository.revision_tree(
 
321
                                       _mod_revision.NULL_REVISION)
248
322
            else:
249
323
                self._basis_tree = parents_list[0][1]
250
324
            self._branch_revision_id = parents_list[0][0]