~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/memorytree.py

  • Committer: Aaron Bentley
  • Date: 2007-06-21 23:43:17 UTC
  • mto: (2520.5.2 bzr.mpbundle)
  • mto: This revision was merged to the branch mainline in revision 2631.
  • Revision ID: abentley@panoramicfeedback.com-20070621234317-5w3h8h36oe90sups
Implement new merge directive format

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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
"""MemoryTree object.
18
18
 
20
20
"""
21
21
 
22
22
 
23
 
import os
 
23
from copy import deepcopy
24
24
 
25
 
from bzrlib import (
26
 
    errors,
27
 
    mutabletree,
28
 
    osutils,
29
 
    revision as _mod_revision,
30
 
    )
 
25
from bzrlib import errors, mutabletree
31
26
from bzrlib.decorators import needs_read_lock, needs_write_lock
32
27
from bzrlib.osutils import sha_file
33
28
from bzrlib.mutabletree import needs_tree_write_lock
36
31
 
37
32
class MemoryTree(mutabletree.MutableTree):
38
33
    """A MemoryTree is a specialisation of MutableTree.
39
 
 
 
34
    
40
35
    It maintains nearly no state outside of read_lock and write_lock
41
36
    transactions. (it keeps a reference to the branch, and its last-revision
42
37
    only).
68
63
    @staticmethod
69
64
    def create_on_branch(branch):
70
65
        """Create a MemoryTree for branch, using the last-revision of branch."""
71
 
        revision_id = _mod_revision.ensure_null(branch.last_revision())
72
 
        return MemoryTree(branch, revision_id)
 
66
        return MemoryTree(branch, branch.last_revision())
73
67
 
74
68
    def _gather_kinds(self, files, kinds):
75
69
        """See MutableTree._gather_kinds.
76
 
 
 
70
        
77
71
        This implementation does not care about the file kind of
78
72
        missing files, so is a no-op.
79
73
        """
80
74
 
81
 
    def get_file(self, file_id, path=None):
 
75
    def get_file(self, file_id):
82
76
        """See Tree.get_file."""
83
 
        if path is None:
84
 
            path = self.id2path(file_id)
85
 
        return self._file_transport.get(path)
 
77
        return self._file_transport.get(self.id2path(file_id))
86
78
 
87
 
    def get_file_sha1(self, file_id, path=None, stat_value=None):
 
79
    def get_file_sha1(self, file_id, path=None):
88
80
        """See Tree.get_file_sha1()."""
89
81
        if path is None:
90
82
            path = self.id2path(file_id)
91
83
        stream = self._file_transport.get(path)
92
84
        return sha_file(stream)
93
85
 
94
 
    def get_root_id(self):
95
 
        return self.path2id('')
96
 
 
97
 
    def _comparison_data(self, entry, path):
98
 
        """See Tree._comparison_data."""
99
 
        if entry is None:
100
 
            return None, False, None
101
 
        return entry.kind, entry.executable, None
102
 
 
103
 
    @needs_tree_write_lock
104
 
    def rename_one(self, from_rel, to_rel):
105
 
        file_id = self.path2id(from_rel)
106
 
        to_dir, to_tail = os.path.split(to_rel)
107
 
        to_parent_id = self.path2id(to_dir)
108
 
        self._file_transport.move(from_rel, to_rel)
109
 
        self._inventory.rename(file_id, to_parent_id, to_tail)
110
 
 
111
 
    def path_content_summary(self, path):
112
 
        """See Tree.path_content_summary."""
113
 
        id = self.path2id(path)
114
 
        if id is None:
115
 
            return 'missing', None, None, None
116
 
        kind = self.kind(id)
117
 
        if kind == 'file':
118
 
            bytes = self._file_transport.get_bytes(path)
119
 
            size = len(bytes)
120
 
            executable = self._inventory[id].executable
121
 
            sha1 = None # no stat cache
122
 
            return (kind, size, executable, sha1)
123
 
        elif kind == 'directory':
124
 
            # memory tree does not support nested trees yet.
125
 
            return kind, None, None, None
126
 
        elif kind == 'symlink':
127
 
            raise NotImplementedError('symlink support')
128
 
        else:
129
 
            raise NotImplementedError('unknown kind')
130
 
 
131
 
    def _file_size(self, entry, stat_value):
132
 
        """See Tree._file_size."""
133
 
        if entry is None:
134
 
            return 0
135
 
        return entry.text_size
136
 
 
137
86
    @needs_read_lock
138
87
    def get_parent_ids(self):
139
88
        """See Tree.get_parent_ids.
211
160
 
212
161
    def _populate_from_branch(self):
213
162
        """Populate the in-tree state from the branch."""
214
 
        self._set_basis()
215
 
        if self._branch_revision_id == _mod_revision.NULL_REVISION:
 
163
        self._basis_tree = self.branch.repository.revision_tree(
 
164
            self._branch_revision_id)
 
165
        if self._branch_revision_id is None:
216
166
            self._parent_ids = []
217
167
        else:
218
168
            self._parent_ids = [self._branch_revision_id]
219
 
        self._inventory = self._basis_tree._inventory._get_mutable_inventory()
 
169
        self._inventory = deepcopy(self._basis_tree._inventory)
220
170
        self._file_transport = MemoryTransport()
221
171
        # TODO copy the revision trees content, or do it lazy, or something.
222
172
        inventory_entries = self._inventory.iter_entries()
274
224
 
275
225
    def set_parent_ids(self, revision_ids, allow_leftmost_as_ghost=False):
276
226
        """See MutableTree.set_parent_trees()."""
277
 
        for revision_id in revision_ids:
278
 
            _mod_revision.check_not_reserved_id(revision_id)
279
227
        if len(revision_ids) == 0:
280
228
            self._parent_ids = []
281
 
            self._branch_revision_id = _mod_revision.NULL_REVISION
 
229
            self._basis_tree = self.branch.repository.revision_tree(None)
282
230
        else:
283
231
            self._parent_ids = revision_ids
 
232
            self._basis_tree = self.branch.repository.revision_tree(
 
233
                                    revision_ids[0])
284
234
            self._branch_revision_id = revision_ids[0]
285
 
        self._allow_leftmost_as_ghost = allow_leftmost_as_ghost
286
 
        self._set_basis()
287
 
    
288
 
    def _set_basis(self):
289
 
        try:
290
 
            self._basis_tree = self.branch.repository.revision_tree(
291
 
                self._branch_revision_id)
292
 
        except errors.NoSuchRevision:
293
 
            if self._allow_leftmost_as_ghost:
294
 
                self._basis_tree = self.branch.repository.revision_tree(
295
 
                    _mod_revision.NULL_REVISION)
296
 
            else:
297
 
                raise
298
235
 
299
236
    def set_parent_trees(self, parents_list, allow_leftmost_as_ghost=False):
300
237
        """See MutableTree.set_parent_trees()."""
301
238
        if len(parents_list) == 0:
302
239
            self._parent_ids = []
303
 
            self._basis_tree = self.branch.repository.revision_tree(
304
 
                                   _mod_revision.NULL_REVISION)
 
240
            self._basis_tree = self.branch.repository.revision_tree(None)
305
241
        else:
306
242
            if parents_list[0][1] is None and not allow_leftmost_as_ghost:
307
243
                # a ghost in the left most parent
308
244
                raise errors.GhostRevisionUnusableHere(parents_list[0][0])
309
245
            self._parent_ids = [parent_id for parent_id, tree in parents_list]
310
 
            if parents_list[0][1] is None or parents_list[0][1] == 'null:':
311
 
                self._basis_tree = self.branch.repository.revision_tree(
312
 
                                       _mod_revision.NULL_REVISION)
 
246
            if parents_list[0][1] is None:
 
247
                self._basis_tree = self.branch.repository.revision_tree(None)
313
248
            else:
314
249
                self._basis_tree = parents_list[0][1]
315
250
            self._branch_revision_id = parents_list[0][0]