/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
1
# Copyright (C) 2008 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
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
16
17
"""CommitHandlers that build and save revisions & their inventories."""
18
19
20
from bzrlib import (
21
    errors,
22
    generate_ids,
23
    inventory,
24
    osutils,
25
    revision,
26
    )
27
from bzrlib.plugins.fastimport import helpers, processor
28
29
0.81.2 by Ian Clatworthy
refactor InventoryCommitHandler general stuff into parent class
30
class GenericCommitHandler(processor.CommitHandler):
31
    """Base class for Bazaar CommitHandlers."""
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
32
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
33
    def __init__(self, command, cache_mgr, rev_store, verbose=False):
0.81.2 by Ian Clatworthy
refactor InventoryCommitHandler general stuff into parent class
34
        super(GenericCommitHandler, self).__init__(command)
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
35
        self.cache_mgr = cache_mgr
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
36
        self.rev_store = rev_store
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
37
        self.verbose = verbose
38
39
    def pre_process_files(self):
40
        """Prepare for committing."""
41
        self.revision_id = self.gen_revision_id()
42
        # cache of texts for this commit, indexed by file-id
43
        self.lines_for_commit = {}
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
44
        if self.rev_store.expects_rich_root():
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
45
            self.lines_for_commit[inventory.ROOT_ID] = []
46
47
        # Track the heads and get the real parent list
48
        parents = self.cache_mgr.track_heads(self.command)
49
50
        # Convert the parent commit-ids to bzr revision-ids
51
        if parents:
52
            self.parents = [self.cache_mgr.revision_ids[p]
53
                for p in parents]
54
        else:
55
            self.parents = []
56
        self.debug("%s id: %s, parents: %s", self.command.id,
57
            self.revision_id, str(self.parents))
58
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
59
        # Keep the basis inventory. This needs to be treated as read-only.
60
        if len(self.parents) == 0:
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
61
            self.basis_inventory = self.init_inventory()
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
62
        else:
63
            self.basis_inventory = self.get_inventory(self.parents[0])
64
        self.inventory_root = self.basis_inventory.root
65
66
        # directory-path -> inventory-entry for current inventory
67
        self.directory_entries = dict(self.basis_inventory.directories())
68
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
69
    def init_inventory(self):
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
70
        """Generate an inventory for a parentless revision."""
71
        inv = inventory.Inventory(revision_id=self.revision_id)
72
        if self.rev_store.expects_rich_root():
73
            # The very first root needs to have the right revision
74
            inv.root.revision = self.revision_id
75
        return inv
76
77
    def get_inventory(self, revision_id):
78
        """Get the inventory for a revision id."""
79
        try:
80
            inv = self.cache_mgr.inventories[revision_id]
81
        except KeyError:
82
            if self.verbose:
83
                self.note("get_inventory cache miss for %s", revision_id)
84
            # Not cached so reconstruct from the RevisionStore
85
            inv = self.rev_store.get_inventory(revision_id)
86
            self.cache_mgr.inventories[revision_id] = inv
87
        return inv
88
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
89
    def _get_lines(self, file_id):
90
        """Get the lines for a file-id."""
91
        return self.lines_for_commit[file_id]
92
93
    def _get_inventories(self, revision_ids):
94
        """Get the inventories for revision-ids.
95
        
96
        This is a callback used by the RepositoryStore to
97
        speed up inventory reconstruction.
98
        """
99
        present = []
100
        inventories = []
101
        # If an inventory is in the cache, we assume it was
102
        # successfully loaded into the revision store
103
        for revision_id in revision_ids:
104
            try:
105
                inv = self.cache_mgr.inventories[revision_id]
106
                present.append(revision_id)
107
            except KeyError:
108
                if self.verbose:
109
                    self.note("get_inventories cache miss for %s", revision_id)
110
                # Not cached so reconstruct from the revision store
111
                try:
112
                    inv = self.get_inventory(revision_id)
113
                    present.append(revision_id)
114
                except:
115
                    inv = self.init_inventory()
116
                self.cache_mgr.inventories[revision_id] = inv
117
            inventories.append(inv)
118
        return present, inventories
119
0.81.2 by Ian Clatworthy
refactor InventoryCommitHandler general stuff into parent class
120
    def bzr_file_id_and_new(self, path):
121
        """Get a Bazaar file identifier and new flag for a path.
122
        
123
        :return: file_id, is_new where
124
          is_new = True if the file_id is newly created
125
        """
126
        try:
127
            id = self.cache_mgr.file_ids[path]
128
            return id, False
129
        except KeyError:
130
            id = generate_ids.gen_file_id(path)
131
            self.cache_mgr.file_ids[path] = id
132
            self.debug("Generated new file id %s for '%s'", id, path)
133
            return id, True
134
135
    def bzr_file_id(self, path):
136
        """Get a Bazaar file identifier for a path."""
137
        return self.bzr_file_id_and_new(path)[0]
138
139
    def gen_revision_id(self):
140
        """Generate a revision id.
141
142
        Subclasses may override this to produce deterministic ids say.
143
        """
144
        committer = self.command.committer
145
        # Perhaps 'who' being the person running the import is ok? If so,
146
        # it might be a bit quicker and give slightly better compression?
147
        who = "%s <%s>" % (committer[0],committer[1])
148
        timestamp = committer[2]
149
        return generate_ids.gen_revision_id(who, timestamp)
150
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
151
    def build_revision(self):
152
        rev_props = {}
153
        committer = self.command.committer
154
        who = "%s <%s>" % (committer[0],committer[1])
155
        author = self.command.author
156
        if author is not None:
157
            author_id = "%s <%s>" % (author[0],author[1])
158
            if author_id != who:
159
                rev_props['author'] = author_id
160
        return revision.Revision(
161
           timestamp=committer[2],
162
           timezone=committer[3],
163
           committer=who,
164
           message=helpers.escape_commit_message(self.command.message),
165
           revision_id=self.revision_id,
166
           properties=rev_props,
167
           parent_ids=self.parents)
0.81.2 by Ian Clatworthy
refactor InventoryCommitHandler general stuff into parent class
168
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
169
    def _modify_item(self, path, kind, is_executable, data, inv):
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
170
        """Add to or change an item in the inventory."""
171
        # Create the new InventoryEntry
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
172
        basename, parent_ie = self._ensure_directory(path, inv)
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
173
        file_id = self.bzr_file_id(path)
174
        ie = inventory.make_entry(kind, basename, parent_ie.file_id, file_id)
175
        ie.revision = self.revision_id
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
176
        if kind == 'file':
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
177
            ie.executable = is_executable
178
            lines = osutils.split_lines(data)
179
            ie.text_sha1 = osutils.sha_strings(lines)
180
            ie.text_size = sum(map(len, lines))
181
            self.lines_for_commit[file_id] = lines
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
182
        elif kind == 'symlink':
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
183
            ie.symlink_target = data.encode('utf8')
184
            # There are no lines stored for a symlink so
185
            # make sure the cache used by get_lines knows that
186
            self.lines_for_commit[file_id] = []
187
        else:
188
            raise errors.BzrError("Cannot import items of kind '%s' yet" %
189
                (kind,))
190
        # Record it
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
191
        if file_id in inv:
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
192
            old_ie = inv[file_id]
193
            if old_ie.kind == 'directory':
194
                self.record_delete(path, old_ie)
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
195
            self.record_changed(path, ie, parent_ie)
196
        else:
197
            self.record_new(path, ie)
198
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
199
    def _ensure_directory(self, path, inv):
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
200
        """Ensure that the containing directory exists for 'path'"""
201
        dirname, basename = osutils.split(path)
202
        if dirname == '':
203
            # the root node doesn't get updated
204
            return basename, self.inventory_root
205
        try:
206
            ie = self.directory_entries[dirname]
207
        except KeyError:
208
            # We will create this entry, since it doesn't exist
209
            pass
210
        else:
211
            return basename, ie
212
213
        # No directory existed, we will just create one, first, make sure
214
        # the parent exists
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
215
        dir_basename, parent_ie = self._ensure_directory(dirname, inv)
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
216
        dir_file_id = self.bzr_file_id(dirname)
217
        ie = inventory.entry_factory['directory'](dir_file_id,
218
            dir_basename, parent_ie.file_id)
219
        ie.revision = self.revision_id
220
        self.directory_entries[dirname] = ie
221
        # There are no lines stored for a directory so
222
        # make sure the cache used by get_lines knows that
223
        self.lines_for_commit[dir_file_id] = []
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
224
225
        # It's possible that a file or symlink with that file-id
226
        # already exists. If it does, we need to delete it.
227
        if dir_file_id in inv:
228
            self.record_delete(dirname, ie)
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
229
        self.record_new(dirname, ie)
230
        return basename, ie
231
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
232
    def _delete_item(self, path, inv):
233
        file_id = inv.path2id(path)
234
        ie = inv[file_id]
0.81.9 by Ian Clatworthy
refactor delete_item
235
        self.record_delete(path, ie)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
236
237
    def _copy_item(self, src_path, dest_path, inv):
238
        if not self.parents:
239
            self.warning("ignoring copy of %s to %s - no parent revisions",
240
                src_path, dest_path)
241
            return
242
        file_id = inv.path2id(src_path)
243
        if file_id is None:
244
            self.warning("ignoring copy of %s to %s - source does not exist",
245
                src_path, dest_path)
246
            return
247
        ie = inv[file_id]
248
        kind = ie.kind
249
        if kind == 'file':
250
            content = self.rev_store.get_file_text(self.parents[0], file_id)
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
251
            self._modify_item(dest_path, kind, ie.executable, content, inv)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
252
        elif kind == 'symlink':
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
253
            self._modify_item(dest_path, kind, False, ie.symlink_target, inv)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
254
        else:
255
            self.warning("ignoring copy of %s %s - feature not yet supported",
256
                kind, path)
257
258
    def _rename_item(self, old_path, new_path, inv):
0.81.8 by Ian Clatworthy
refactor rename_item
259
        file_id = inv.path2id(old_path)
260
        ie = inv[file_id]
261
        rev_id = ie.revision
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
262
        new_file_id = inv.path2id(new_path)
263
        if new_file_id is not None:
0.81.9 by Ian Clatworthy
refactor delete_item
264
            self.record_delete(new_path, inv[new_file_id])
0.81.8 by Ian Clatworthy
refactor rename_item
265
        self.record_rename(old_path, new_path, file_id, ie)
266
        self.cache_mgr.rename_path(old_path, new_path)
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
267
0.81.8 by Ian Clatworthy
refactor rename_item
268
        # The revision-id for this entry will be/has been updated and
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
269
        # that means the loader then needs to know what the "new" text is.
270
        # We therefore must go back to the revision store to get it.
0.81.8 by Ian Clatworthy
refactor rename_item
271
        lines = self.rev_store.get_file_lines(rev_id, file_id)
272
        self.lines_for_commit[file_id] = lines
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
273
274
    def _delete_all_items(self, inv):
275
        for name, root_item in inv.root.children.iteritems():
276
            inv.remove_recursive_id(root_item.file_id)
277
0.81.2 by Ian Clatworthy
refactor InventoryCommitHandler general stuff into parent class
278
279
class InventoryCommitHandler(GenericCommitHandler):
0.81.3 by Ian Clatworthy
enhance RevisionLoader to try inventory deltas & decide on rich-roots
280
    """A CommitHandler that builds and saves full inventories."""
0.81.2 by Ian Clatworthy
refactor InventoryCommitHandler general stuff into parent class
281
282
    def pre_process_files(self):
283
        super(InventoryCommitHandler, self).pre_process_files()
284
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
285
        # Seed the inventory from the previous one
286
        if len(self.parents) == 0:
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
287
            self.inventory = self.basis_inventory
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
288
        else:
289
            # TODO: Shallow copy - deep inventory copying is expensive
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
290
            self.inventory = self.basis_inventory.copy()
291
        self.inventory_root = self.inventory.root
292
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
293
        # directory-path -> inventory-entry for current inventory
294
        self.directory_entries = dict(self.inventory.directories())
295
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
296
        # Initialise the inventory revision info as required
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
297
        if self.rev_store.expects_rich_root():
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
298
            self.inventory.revision_id = self.revision_id
299
        else:
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
300
            # In this revision store, root entries have no knit or weave.
301
            # When serializing out to disk and back in, root.revision is
302
            # always the new revision_id.
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
303
            self.inventory.root.revision = self.revision_id
304
305
    def post_process_files(self):
306
        """Save the revision."""
307
        self.cache_mgr.inventories[self.revision_id] = self.inventory
0.81.2 by Ian Clatworthy
refactor InventoryCommitHandler general stuff into parent class
308
        rev = self.build_revision()
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
309
        self.rev_store.load(rev, self.inventory, None,
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
310
            lambda file_id: self._get_lines(file_id),
311
            lambda revision_ids: self._get_inventories(revision_ids))
312
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
313
    def record_new(self, path, ie):
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
314
        try:
315
            self.inventory.add(ie)
316
        except errors.DuplicateFileId:
317
            # Directory already exists as a file or symlink
318
            del self.inventory[ie.file_id]
319
            # Try again
320
            self.inventory.add(ie)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
321
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
322
    def record_changed(self, path, ie, parent_ie):
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
323
        # HACK: no API for this (del+add does more than it needs to)
324
        self.inventory._byid[ie.file_id] = ie
325
        parent_ie.children[ie.name] = ie
326
0.81.9 by Ian Clatworthy
refactor delete_item
327
    def record_delete(self, path, ie):
328
        self.inventory.remove_recursive_id(ie.file_id)
0.81.8 by Ian Clatworthy
refactor rename_item
329
330
    def record_rename(self, old_path, new_path, file_id, ie):
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
331
        new_basename, new_parent_ie = self._ensure_directory(new_path,
332
            self.inventory)
0.81.8 by Ian Clatworthy
refactor rename_item
333
        new_parent_id = new_parent_ie.file_id
334
        self.inventory.rename(file_id, new_parent_id, new_basename)
335
        self.inventory[file_id].revision = self.revision_id
336
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
337
    def _delete_item(self, path):
338
        # NOTE: I'm retaining this method for now, instead of using the
339
        # one in the superclass, because it's taken quite a lot of tweaking
340
        # to cover all the edge cases seen in the wild. Long term, it can
341
        # probably go once the higher level method does "warn_unless_in_merges"
342
        # and handles all the various special cases ...
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
343
        fileid = self.bzr_file_id(path)
344
        dirname, basename = osutils.split(path)
345
        if (fileid in self.inventory and
346
            isinstance(self.inventory[fileid], inventory.InventoryDirectory)):
347
            for child_path in self.inventory[fileid].children.keys():
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
348
                self._delete_item(osutils.pathjoin(path, child_path))
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
349
        try:
350
            if self.inventory.id2path(fileid) == path:
351
                del self.inventory[fileid]
352
            else:
353
                # already added by some other name?
354
                if dirname in self.cache_mgr.file_ids:
355
                    parent_id = self.cache_mgr.file_ids[dirname]
356
                    del self.inventory[parent_id].children[basename]
357
        except KeyError:
358
            self._warn_unless_in_merges(fileid, path)
359
        except errors.NoSuchId:
360
            self._warn_unless_in_merges(fileid, path)
361
        except AttributeError, ex:
362
            if ex.args[0] == 'children':
363
                # A directory has changed into a file and then one
364
                # of it's children is being deleted!
365
                self._warn_unless_in_merges(fileid, path)
366
            else:
367
                raise
368
        try:
369
            self.cache_mgr.delete_path(path)
370
        except KeyError:
371
            pass
372
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
373
    def _warn_unless_in_merges(self, fileid, path):
374
        if len(self.parents) <= 1:
375
            return
376
        for parent in self.parents[1:]:
377
            if fileid in self.get_inventory(parent):
378
                return
379
        self.warning("ignoring delete of %s as not in parent inventories", path)
380
381
    def modify_handler(self, filecmd):
382
        if filecmd.dataref is not None:
383
            data = self.cache_mgr.fetch_blob(filecmd.dataref)
384
        else:
385
            data = filecmd.data
386
        self.debug("modifying %s", filecmd.path)
387
        self._modify_item(filecmd.path, filecmd.kind,
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
388
            filecmd.is_executable, data, self.inventory)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
389
390
    def delete_handler(self, filecmd):
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
391
        self.debug("deleting %s", filecmd.path)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
392
        self._delete_item(filecmd.path)
393
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
394
    def copy_handler(self, filecmd):
395
        src_path = filecmd.src_path
396
        dest_path = filecmd.dest_path
397
        self.debug("copying %s to %s", src_path, dest_path)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
398
        self._copy_item(src_path, dest_path, self.inventory)
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
399
400
    def rename_handler(self, filecmd):
401
        old_path = filecmd.old_path
402
        new_path = filecmd.new_path
403
        self.debug("renaming %s to %s", old_path, new_path)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
404
        self._rename_item(old_path, new_path, self.inventory)
0.81.1 by Ian Clatworthy
move GenericCommitHandler into its own module in prep for a delta-based one
405
406
    def deleteall_handler(self, filecmd):
407
        self.debug("deleting all files (and also all directories)")
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
408
        self._delete_all_items(self.inventory)
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
409
410
411
class DeltaCommitHandler(GenericCommitHandler):
412
    """A CommitHandler that builds and saves inventory deltas."""
413
414
    def pre_process_files(self):
415
        super(DeltaCommitHandler, self).pre_process_files()
416
        self.delta = []
417
418
    def post_process_files(self):
419
        """Save the revision."""
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
420
        #for path, entry in self.basis_inventory.iter_entries_by_dir():
421
        #    print "ie for %s:\n%r" % (path, entry)
422
        #print "delta:\n%r" % (self.delta,)
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
423
        rev = self.build_revision()
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
424
        inv = self.rev_store.load_using_delta(rev, self.basis_inventory,
425
            self.delta, None,
426
            lambda file_id: self._get_lines(file_id),
427
            lambda revision_ids: self._get_inventories(revision_ids))
0.81.5 by Ian Clatworthy
basic DeltaCommitHandler generating deltas
428
        self.cache_mgr.inventories[self.revision_id] = inv
429
430
    def record_new(self, path, ie):
431
        self.delta.append((None, path, ie.file_id, ie))
432
433
    def record_changed(self, path, ie, parent_ie=None):
434
        self.delta.append((path, path, ie.file_id, ie))
435
0.81.9 by Ian Clatworthy
refactor delete_item
436
    def record_delete(self, path, ie):
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
437
        self.delta.append((path, None, ie.file_id, None))
438
        if ie.kind == 'directory':
439
            for child_path, entry in \
440
                self.basis_inventory.iter_entries_by_dir(from_dir=ie):
441
                #print "deleting child %s" % child_path
442
                self.delta.append((child_path, None, entry.file_id, None))
0.81.8 by Ian Clatworthy
refactor rename_item
443
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
444
    def record_rename(self, old_path, new_path, file_id, old_ie):
445
        new_ie = old_ie.copy()
446
        new_basename, new_parent_ie = self._ensure_directory(new_path,
447
            self.basis_inventory)
448
        new_ie.name = new_basename
449
        new_ie.parent_id = new_parent_ie.file_id
450
        new_ie.revision = self.revision_id
451
        self.delta.append((old_path, new_path, file_id, new_ie))
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
452
453
    def modify_handler(self, filecmd):
454
        if filecmd.dataref is not None:
455
            data = self.cache_mgr.fetch_blob(filecmd.dataref)
456
        else:
457
            data = filecmd.data
458
        self.debug("modifying %s", filecmd.path)
459
        self._modify_item(filecmd.path, filecmd.kind,
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
460
            filecmd.is_executable, data, self.basis_inventory)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
461
462
    def delete_handler(self, filecmd):
463
        self.debug("deleting %s", filecmd.path)
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
464
        self._delete_item(filecmd.path, self.basis_inventory)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
465
466
    def copy_handler(self, filecmd):
467
        src_path = filecmd.src_path
468
        dest_path = filecmd.dest_path
469
        self.debug("copying %s to %s", src_path, dest_path)
0.81.10 by Ian Clatworthy
get DeltaCommitHandler passing all tests
470
        self._copy_item(src_path, dest_path, self.basis_inventory)
0.81.6 by Ian Clatworthy
basic DeltaCommitHandler mostly going bar rename
471
472
    def rename_handler(self, filecmd):
473
        old_path = filecmd.old_path
474
        new_path = filecmd.new_path
475
        self.debug("renaming %s to %s", old_path, new_path)
476
        self._rename_item(old_path, new_path, self.basis_inventory)
477
478
    def deleteall_handler(self, filecmd):
479
        self.debug("deleting all files (and also all directories)")
480
        # I'm not 100% sure this will work in the delta case.
481
        # But clearing out the basis inventory so that everything
482
        # is added sounds ok in theory ...
483
        # We grab a copy as the basis is likely to be cached and
484
        # we don't want to destroy the cached version
485
        self.basis_inventory = self.basis_inventory.copy()
486
        self._delete_all_items(self.basis_inventory)