/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.115.12 by John Arbash Meinel
Add a bunch of direct tests for the _TreeShim interface.
1
# Copyright (C) 2008, 2009 Canonical Ltd
0.64.5 by Ian Clatworthy
first cut at generic processing method
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
0.64.334 by Jelmer Vernooij
Remove old FSF address. Thanks Dan Callaghan.
14
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
0.64.5 by Ian Clatworthy
first cut at generic processing method
15
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
16
"""An abstraction of a repository providing just the bits importing needs."""
0.64.5 by Ian Clatworthy
first cut at generic processing method
17
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
18
from __future__ import absolute_import
19
6855.4.8 by Jelmer Vernooij
Fix some more tests.
20
from io import BytesIO
0.64.5 by Ian Clatworthy
first cut at generic processing method
21
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
22
from ... import (
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
23
    errors,
24
    graph as _mod_graph,
25
    lru_cache,
26
    osutils,
27
    revision as _mod_revision,
28
    trace,
29
    )
6670.4.1 by Jelmer Vernooij
Update imports.
30
from ...bzr import (
31
    knit,
32
    inventory,
33
    )
0.64.6 by Ian Clatworthy
generic processing method working for one revision in one branch
34
35
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
36
class _TreeShim(object):
37
    """Fake a Tree implementation.
38
39
    This implements just enough of the tree api to make commit builder happy.
40
    """
41
0.115.7 by John Arbash Meinel
Fall back to the repository for cases where the content is not present in the stream yet.
42
    def __init__(self, repo, basis_inv, inv_delta, content_provider):
43
        self._repo = repo
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
44
        self._content_provider = content_provider
45
        self._basis_inv = basis_inv
46
        self._inv_delta = inv_delta
47
        self._new_info_by_id = dict([(file_id, (new_path, ie))
48
                                    for _, new_path, file_id, ie in inv_delta])
49
50
    def id2path(self, file_id):
51
        if file_id in self._new_info_by_id:
52
            new_path = self._new_info_by_id[file_id][0]
53
            if new_path is None:
0.115.12 by John Arbash Meinel
Add a bunch of direct tests for the _TreeShim interface.
54
                raise errors.NoSuchId(self, file_id)
55
            return new_path
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
56
        return self._basis_inv.id2path(file_id)
57
58
    def path2id(self, path):
0.115.12 by John Arbash Meinel
Add a bunch of direct tests for the _TreeShim interface.
59
        # CommitBuilder currently only requires access to the root id. We don't
60
        # build a map of renamed files, etc. One possibility if we ever *do*
61
        # need more than just root, is to defer to basis_inv.path2id() and then
62
        # check if the file_id is in our _new_info_by_id dict. And in that
63
        # case, return _new_info_by_id[file_id][0]
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
64
        if path != '':
65
            raise NotImplementedError(_TreeShim.path2id)
66
        # TODO: Handle root renames?
67
        return self._basis_inv.root.file_id
68
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
69
    def get_file_with_stat(self, path, file_id=None):
70
        content = self.get_file_text(path, file_id)
6855.4.8 by Jelmer Vernooij
Fix some more tests.
71
        sio = BytesIO(content)
0.123.16 by Jelmer Vernooij
Support get_file_text in _TreeShim.
72
        return sio, None
73
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
74
    def get_file_text(self, path, file_id=None):
75
        if file_id is None:
76
            file_id = self.path2id(path)
0.115.7 by John Arbash Meinel
Fall back to the repository for cases where the content is not present in the stream yet.
77
        try:
0.123.16 by Jelmer Vernooij
Support get_file_text in _TreeShim.
78
            return self._content_provider(file_id)
0.115.7 by John Arbash Meinel
Fall back to the repository for cases where the content is not present in the stream yet.
79
        except KeyError:
80
            # The content wasn't shown as 'new'. Just validate this fact
81
            assert file_id not in self._new_info_by_id
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
82
            old_ie = self._basis_inv.get_entry(file_id)
0.115.7 by John Arbash Meinel
Fall back to the repository for cases where the content is not present in the stream yet.
83
            old_text_key = (file_id, old_ie.revision)
84
            stream = self._repo.texts.get_record_stream([old_text_key],
85
                                                        'unordered', True)
7018.3.10 by Jelmer Vernooij
Consistent return values in PreviewTree.list_files.
86
            return next(stream).get_bytes_as('fulltext')
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
87
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
88
    def get_symlink_target(self, path, file_id=None):
89
        if file_id is None:
90
            file_id = self.path2id(path)
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
91
        if file_id in self._new_info_by_id:
92
            ie = self._new_info_by_id[file_id][1]
93
            return ie.symlink_target
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
94
        return self._basis_inv.get_entry(file_id).symlink_target
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
95
6809.4.1 by Jelmer Vernooij
Swap file_id and path arguments for get_reference_revision and get_nested_tree.
96
    def get_reference_revision(self, path, file_id=None):
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
97
        raise NotImplementedError(_TreeShim.get_reference_revision)
98
99
    def _delta_to_iter_changes(self):
100
        """Convert the inv_delta into an iter_changes repr."""
101
        # iter_changes is:
102
        #   (file_id,
103
        #    (old_path, new_path),
104
        #    content_changed,
105
        #    (old_versioned, new_versioned),
106
        #    (old_parent_id, new_parent_id),
107
        #    (old_name, new_name),
108
        #    (old_kind, new_kind),
109
        #    (old_exec, new_exec),
110
        #   )
111
        basis_inv = self._basis_inv
112
        for old_path, new_path, file_id, ie in self._inv_delta:
0.115.12 by John Arbash Meinel
Add a bunch of direct tests for the _TreeShim interface.
113
            # Perf: Would this be faster if we did 'if file_id in basis_inv'?
114
            # Since the *very* common case is that the file already exists, it
115
            # probably is better to optimize for that
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
116
            try:
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
117
                old_ie = basis_inv.get_entry(file_id)
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
118
            except errors.NoSuchId:
119
                old_ie = None
0.115.6 by John Arbash Meinel
We need to handle when the object has been deleted.
120
                if ie is None:
121
                    raise AssertionError('How is both old and new None?')
122
                    change = (file_id,
123
                        (old_path, new_path),
124
                        False,
125
                        (False, False),
126
                        (None, None),
127
                        (None, None),
128
                        (None, None),
129
                        (None, None),
130
                        )
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
131
                change = (file_id,
132
                    (old_path, new_path),
133
                    True,
134
                    (False, True),
135
                    (None, ie.parent_id),
136
                    (None, ie.name),
137
                    (None, ie.kind),
138
                    (None, ie.executable),
139
                    )
140
            else:
0.115.6 by John Arbash Meinel
We need to handle when the object has been deleted.
141
                if ie is None:
142
                    change = (file_id,
143
                        (old_path, new_path),
144
                        True,
145
                        (True, False),
146
                        (old_ie.parent_id, None),
147
                        (old_ie.name, None),
148
                        (old_ie.kind, None),
149
                        (old_ie.executable, None),
150
                        )
151
                else:
152
                    content_modified = (ie.text_sha1 != old_ie.text_sha1
153
                                        or ie.text_size != old_ie.text_size)
0.115.7 by John Arbash Meinel
Fall back to the repository for cases where the content is not present in the stream yet.
154
                    # TODO: ie.kind != old_ie.kind
0.115.12 by John Arbash Meinel
Add a bunch of direct tests for the _TreeShim interface.
155
                    # TODO: symlinks changing targets, content_modified?
0.115.6 by John Arbash Meinel
We need to handle when the object has been deleted.
156
                    change = (file_id,
157
                        (old_path, new_path),
158
                        content_modified,
159
                        (True, True),
160
                        (old_ie.parent_id, ie.parent_id),
161
                        (old_ie.name, ie.name),
162
                        (old_ie.kind, ie.kind),
163
                        (old_ie.executable, ie.executable),
164
                        )
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
165
            yield change
166
167
7027.2.3 by Jelmer Vernooij
Drop old RevisionStore implementation.
168
class RevisionStore(object):
0.64.5 by Ian Clatworthy
first cut at generic processing method
169
0.64.48 by Ian Clatworthy
one revision loader instance
170
    def __init__(self, repo):
0.64.5 by Ian Clatworthy
first cut at generic processing method
171
        """An object responsible for loading revisions into a repository.
172
173
        NOTE: Repository locking is not managed by this class. Clients
174
        should take a write lock, call load() multiple times, then release
175
        the lock.
176
177
        :param repository: the target repository
0.64.48 by Ian Clatworthy
one revision loader instance
178
        """
179
        self.repo = repo
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
180
        self._graph = None
181
        self._use_known_graph = True
0.84.8 by Ian Clatworthy
ensure the chk stuff is only used on formats actually supporting it
182
        self._supports_chks = getattr(repo._format, 'supports_chks', False)
0.81.3 by Ian Clatworthy
enhance RevisionLoader to try inventory deltas & decide on rich-roots
183
184
    def expects_rich_root(self):
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
185
        """Does this store expect inventories with rich roots?"""
0.81.3 by Ian Clatworthy
enhance RevisionLoader to try inventory deltas & decide on rich-roots
186
        return self.repo.supports_rich_root()
0.64.48 by Ian Clatworthy
one revision loader instance
187
0.84.4 by Ian Clatworthy
improved-but-not-yet-working CHKInventory support
188
    def init_inventory(self, revision_id):
189
        """Generate an inventory for a parentless revision."""
0.84.8 by Ian Clatworthy
ensure the chk stuff is only used on formats actually supporting it
190
        if self._supports_chks:
0.84.4 by Ian Clatworthy
improved-but-not-yet-working CHKInventory support
191
            inv = self._init_chk_inventory(revision_id, inventory.ROOT_ID)
192
        else:
193
            inv = inventory.Inventory(revision_id=revision_id)
0.84.6 by Ian Clatworthy
set maximum_size & key_width for initial parent_id_basename_to_file_id map
194
            if self.expects_rich_root():
195
                # The very first root needs to have the right revision
196
                inv.root.revision = revision_id
0.84.4 by Ian Clatworthy
improved-but-not-yet-working CHKInventory support
197
        return inv
198
199
    def _init_chk_inventory(self, revision_id, root_id):
200
        """Generate a CHKInventory for a parentless revision."""
6670.4.3 by Jelmer Vernooij
Fix more imports.
201
        from ...bzr import chk_map
0.84.4 by Ian Clatworthy
improved-but-not-yet-working CHKInventory support
202
        # Get the creation parameters
0.84.8 by Ian Clatworthy
ensure the chk stuff is only used on formats actually supporting it
203
        chk_store = self.repo.chk_bytes
0.84.4 by Ian Clatworthy
improved-but-not-yet-working CHKInventory support
204
        serializer = self.repo._format._serializer
205
        search_key_name = serializer.search_key_name
206
        maximum_size = serializer.maximum_size
207
208
        # Maybe the rest of this ought to be part of the CHKInventory API?
209
        inv = inventory.CHKInventory(search_key_name)
210
        inv.revision_id = revision_id
211
        inv.root_id = root_id
212
        search_key_func = chk_map.search_key_registry.get(search_key_name)
213
        inv.id_to_entry = chk_map.CHKMap(chk_store, None, search_key_func)
214
        inv.id_to_entry._root_node.set_maximum_size(maximum_size)
0.64.151 by Ian Clatworthy
parent_id_to_basename_index is no longer a serializer attribute - always required now
215
        inv.parent_id_basename_to_file_id = chk_map.CHKMap(chk_store,
216
            None, search_key_func)
217
        inv.parent_id_basename_to_file_id._root_node.set_maximum_size(
218
            maximum_size)
219
        inv.parent_id_basename_to_file_id._root_node._key_width = 2
0.84.4 by Ian Clatworthy
improved-but-not-yet-working CHKInventory support
220
        return inv
221
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
222
    def get_inventory(self, revision_id):
223
        """Get a stored inventory."""
224
        return self.repo.get_inventory(revision_id)
225
226
    def get_file_text(self, revision_id, file_id):
227
        """Get the text stored for a file in a given revision."""
228
        revtree = self.repo.revision_tree(revision_id)
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
229
        path = revtree.id2path(file_id)
230
        return revtree.get_file_text(path, file_id)
0.81.4 by Ian Clatworthy
generalise RevisionLoader to RevisionStore as a repo abstraction
231
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
232
    def get_file_lines(self, revision_id, file_id):
233
        """Get the lines stored for a file in a given revision."""
0.64.156 by Ian Clatworthy
minor revision_store clean-ups
234
        revtree = self.repo.revision_tree(revision_id)
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
235
        path = revtree.id2path(file_id)
236
        return osutils.split_lines(revtree.get_file_text(path, file_id))
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
237
0.85.2 by Ian Clatworthy
improve per-file graph generation
238
    def start_new_revision(self, revision, parents, parent_invs):
239
        """Init the metadata needed for get_parents_and_revision_for_entry().
240
241
        :param revision: a Revision object
242
        """
243
        self._current_rev_id = revision.revision_id
244
        self._rev_parents = parents
245
        self._rev_parent_invs = parent_invs
246
        # We don't know what the branch will be so there's no real BranchConfig.
247
        # That means we won't be triggering any hooks and that's a good thing.
248
        # Without a config though, we must pass in the committer below so that
249
        # the commit builder doesn't try to look up the config.
250
        config = None
251
        # We can't use self.repo.get_commit_builder() here because it starts a
252
        # new write group. We want one write group around a batch of imports
253
        # where the default batch size is currently 10000. IGC 20090312
254
        self._commit_builder = self.repo._commit_builder_class(self.repo,
255
            parents, config, timestamp=revision.timestamp,
256
            timezone=revision.timezone, committer=revision.committer,
257
            revprops=revision.properties, revision_id=revision.revision_id)
258
259
    def get_parents_and_revision_for_entry(self, ie):
260
        """Get the parents and revision for an inventory entry.
7027.2.1 by Jelmer Vernooij
Port fastimport to python3.
261
0.85.2 by Ian Clatworthy
improve per-file graph generation
262
        :param ie: the inventory entry
263
        :return parents, revision_id where
0.64.160 by Ian Clatworthy
make per-file parents tuples and fix text loading in chk formats
264
            parents is the tuple of parent revision_ids for the per-file graph
0.85.2 by Ian Clatworthy
improve per-file graph generation
265
            revision_id is the revision_id to use for this entry
266
        """
267
        # Check for correct API usage
268
        if self._current_rev_id is None:
269
            raise AssertionError("start_new_revision() must be called"
270
                " before get_parents_and_revision_for_entry()")
271
        if ie.revision != self._current_rev_id:
272
            raise AssertionError("start_new_revision() registered a different"
273
                " revision (%s) to that in the inventory entry (%s)" %
274
                (self._current_rev_id, ie.revision))
275
276
        # Find the heads. This code is lifted from
277
        # repository.CommitBuilder.record_entry_contents().
278
        parent_candidate_entries = ie.parent_candidates(self._rev_parent_invs)
279
        head_set = self._commit_builder._heads(ie.file_id,
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
280
            list(parent_candidate_entries))
0.85.2 by Ian Clatworthy
improve per-file graph generation
281
        heads = []
282
        for inv in self._rev_parent_invs:
6883.7.11 by Jelmer Vernooij
Avoid has_id.
283
            try:
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
284
                old_rev = inv.get_entry(ie.file_id).revision
6883.7.11 by Jelmer Vernooij
Avoid has_id.
285
            except errors.NoSuchId:
286
                pass
287
            else:
0.85.2 by Ian Clatworthy
improve per-file graph generation
288
                if old_rev in head_set:
6915.4.2 by Jelmer Vernooij
Remove __getitem__ and __iter__ from Inventory.
289
                    rev_id = inv.get_entry(ie.file_id).revision
0.64.161 by Ian Clatworthy
fix per-graph parent handling for adds and renames
290
                    heads.append(rev_id)
291
                    head_set.remove(rev_id)
0.85.2 by Ian Clatworthy
improve per-file graph generation
292
293
        # Find the revision to use. If the content has not changed
294
        # since the parent, record the parent's revision.
0.64.161 by Ian Clatworthy
fix per-graph parent handling for adds and renames
295
        if len(heads) == 0:
296
            return (), ie.revision
0.85.2 by Ian Clatworthy
improve per-file graph generation
297
        parent_entry = parent_candidate_entries[heads[0]]
298
        changed = False
299
        if len(heads) > 1:
300
            changed = True
0.64.161 by Ian Clatworthy
fix per-graph parent handling for adds and renames
301
        elif (parent_entry.name != ie.name or parent_entry.kind != ie.kind or
7027.2.1 by Jelmer Vernooij
Port fastimport to python3.
302
            parent_entry.parent_id != ie.parent_id):
0.85.2 by Ian Clatworthy
improve per-file graph generation
303
            changed = True
304
        elif ie.kind == 'file':
305
            if (parent_entry.text_sha1 != ie.text_sha1 or
306
                parent_entry.executable != ie.executable):
307
                changed = True
308
        elif ie.kind == 'symlink':
309
            if parent_entry.symlink_target != ie.symlink_target:
310
                changed = True
311
        if changed:
312
            rev_id = ie.revision
313
        else:
314
            rev_id = parent_entry.revision
0.64.160 by Ian Clatworthy
make per-file parents tuples and fix text loading in chk formats
315
        return tuple(heads), rev_id
0.85.2 by Ian Clatworthy
improve per-file graph generation
316
0.64.171 by Ian Clatworthy
use inv deltas by default for all formats now: --classic to get old algorithm for packs
317
    def load_using_delta(self, rev, basis_inv, inv_delta, signature,
0.85.2 by Ian Clatworthy
improve per-file graph generation
318
        text_provider, parents_provider, inventories_provider=None):
0.64.171 by Ian Clatworthy
use inv deltas by default for all formats now: --classic to get old algorithm for packs
319
        """Load a revision by applying a delta to a (CHK)Inventory.
0.84.13 by Ian Clatworthy
smarter RevisionStore.chk_load()
320
321
        :param rev: the Revision
0.64.171 by Ian Clatworthy
use inv deltas by default for all formats now: --classic to get old algorithm for packs
322
        :param basis_inv: the basis Inventory or CHKInventory
0.84.13 by Ian Clatworthy
smarter RevisionStore.chk_load()
323
        :param inv_delta: the inventory delta
324
        :param signature: signing information
325
        :param text_provider: a callable expecting a file_id parameter
326
            that returns the text for that file-id
0.85.2 by Ian Clatworthy
improve per-file graph generation
327
        :param parents_provider: a callable expecting a file_id parameter
328
            that return the list of parent-ids for that file-id
0.84.13 by Ian Clatworthy
smarter RevisionStore.chk_load()
329
        :param inventories_provider: a callable expecting a repository and
330
            a list of revision-ids, that returns:
331
              * the list of revision-ids present in the repository
332
              * the list of inventories for the revision-id's,
333
                including an empty inventory for the missing revisions
334
            If None, a default implementation is provided.
335
        """
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
336
        # TODO: set revision_id = rev.revision_id
337
        builder = self.repo._commit_builder_class(self.repo,
338
            parents=rev.parent_ids, config=None, timestamp=rev.timestamp,
339
            timezone=rev.timezone, committer=rev.committer,
340
            revprops=rev.properties, revision_id=rev.revision_id)
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
341
        if self._graph is None and self._use_known_graph:
0.64.290 by Jelmer Vernooij
Avoid use of Repository.revisions, which may not be set.
342
            if (getattr(_mod_graph, 'GraphThunkIdsToKeys', None) and
343
                getattr(_mod_graph.GraphThunkIdsToKeys, "add_node", None) and
344
                getattr(self.repo, "get_known_graph_ancestry", None)):
345
                self._graph = self.repo.get_known_graph_ancestry(
346
                    rev.parent_ids)
347
            else:
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
348
                self._use_known_graph = False
349
        if self._graph is not None:
0.116.2 by John Arbash Meinel
Some debugging code. It looks like the main bugs involve files that are deleted and restored.
350
            orig_heads = builder._heads
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
351
            def thunked_heads(file_id, revision_ids):
352
                # self._graph thinks in terms of keys, not ids, so translate
353
                # them
0.116.2 by John Arbash Meinel
Some debugging code. It looks like the main bugs involve files that are deleted and restored.
354
                # old_res = orig_heads(file_id, revision_ids)
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
355
                if len(revision_ids) < 2:
0.116.2 by John Arbash Meinel
Some debugging code. It looks like the main bugs involve files that are deleted and restored.
356
                    res = set(revision_ids)
357
                else:
0.64.290 by Jelmer Vernooij
Avoid use of Repository.revisions, which may not be set.
358
                    res = set(self._graph.heads(revision_ids))
0.116.2 by John Arbash Meinel
Some debugging code. It looks like the main bugs involve files that are deleted and restored.
359
                # if old_res != res:
360
                #     import pdb; pdb.set_trace()
361
                return res
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
362
            builder._heads = thunked_heads
0.84.13 by Ian Clatworthy
smarter RevisionStore.chk_load()
363
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
364
        if rev.parent_ids:
365
            basis_rev_id = rev.parent_ids[0]
366
        else:
367
            basis_rev_id = _mod_revision.NULL_REVISION
0.115.7 by John Arbash Meinel
Fall back to the repository for cases where the content is not present in the stream yet.
368
        tree = _TreeShim(self.repo, basis_inv, inv_delta, text_provider)
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
369
        changes = tree._delta_to_iter_changes()
370
        for (file_id, path, fs_hash) in builder.record_iter_changes(
371
                tree, basis_rev_id, changes):
372
            # So far, we don't *do* anything with the result
0.84.13 by Ian Clatworthy
smarter RevisionStore.chk_load()
373
            pass
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
374
        builder.finish_inventory()
6628.1.2 by Jelmer Vernooij
Fix imports, move exporter.py, drop explorer metadata.
375
        # TODO: This is working around a bug in the breezy code base.
0.115.5 by John Arbash Meinel
Found a bug in CommitBuilder.finish_inventory().
376
        # 'builder.finish_inventory()' ends up doing:
377
        # self.inv_sha1 = self.repository.add_inventory_by_delta(...)
378
        # However, add_inventory_by_delta returns (sha1, inv)
379
        # And we *want* to keep a handle on both of those objects
380
        if isinstance(builder.inv_sha1, tuple):
381
            builder.inv_sha1, builder.new_inventory = builder.inv_sha1
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
382
        # This is a duplicate of Builder.commit() since we already have the
383
        # Revision object, and we *don't* want to call commit_write_group()
384
        rev.inv_sha1 = builder.inv_sha1
6690.2.2 by Jelmer Vernooij
Drop support for bzr < 2.5.
385
        config = builder._config_stack
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
386
        builder.repository.add_revision(builder._new_revision_id, rev,
6700.2.4 by Jelmer Vernooij
Fix test.
387
            builder.revision_tree().root_inventory)
0.116.1 by John Arbash Meinel
Use the new KnownGraph.add_node() functionality.
388
        if self._graph is not None:
389
            # TODO: Use StaticTuple and .intern() for these things
0.64.290 by Jelmer Vernooij
Avoid use of Repository.revisions, which may not be set.
390
            self._graph.add_node(builder._new_revision_id, rev.parent_ids)
0.84.13 by Ian Clatworthy
smarter RevisionStore.chk_load()
391
392
        if signature is not None:
0.115.4 by John Arbash Meinel
(broken) Start working towards using CommitBuilder rather than using a custom implementation.
393
            raise AssertionError('signatures not guaranteed yet')
0.64.290 by Jelmer Vernooij
Avoid use of Repository.revisions, which may not be set.
394
            self.repo.add_signature_text(rev.revision_id, signature)
6643.1.1 by Jelmer Vernooij
Fix fastimport tests now that RevisionTree.inventory has been removed.
395
        return builder.revision_tree().root_inventory
0.84.13 by Ian Clatworthy
smarter RevisionStore.chk_load()
396
0.81.7 by Ian Clatworthy
merge import tests and tweaks to make them pass
397
    def get_file_lines(self, revision_id, file_id):
6634.2.1 by Martin
Apply 2to3 next fixer and make compatible
398
        record = next(self.repo.texts.get_record_stream([(file_id, revision_id)],
399
            'unordered', True))
0.74.1 by John Arbash Meinel
Change the rename code to create a new text entry.
400
        if record.storage_kind == 'absent':
401
            raise errors.RevisionNotPresent(record.key, self.repo)
402
        return osutils.split_lines(record.get_bytes_as('fulltext'))