/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
1
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
0.200.228 by Jelmer Vernooij
Split out map.
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
"""Map from Git sha's to Bazaar objects."""
18
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
19
from dulwich.objects import (
20
    Blob,
0.200.864 by Jelmer Vernooij
Cope with the first commit being pointless.
21
    Tree,
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
22
    sha_to_hex,
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
23
    )
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
24
from dulwich.object_store import (
0.200.457 by Jelmer Vernooij
Use BaseObjectStore.
25
    BaseObjectStore,
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
26
    )
0.200.249 by Jelmer Vernooij
Implement Tree.
27
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
28
from bzrlib import (
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
29
    errors,
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
30
    lru_cache,
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
31
    trace,
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
32
    ui,
0.200.773 by Jelmer Vernooij
Implement inventory_to_objects
33
    urlutils,
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
34
    )
0.200.541 by Jelmer Vernooij
Cope with NULL_REVISION.
35
from bzrlib.revision import (
36
    NULL_REVISION,
37
    )
0.200.1023 by Jelmer Vernooij
Set and verify testament.
38
from bzrlib.testament import(
39
    StrictTestament3,
40
    )
0.200.228 by Jelmer Vernooij
Split out map.
41
0.200.229 by Jelmer Vernooij
More work on converter.
42
from bzrlib.plugins.git.mapping import (
0.200.463 by Jelmer Vernooij
Support remote dpush (except for references).
43
    default_mapping,
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
44
    directory_to_tree,
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
45
    extract_unusual_modes,
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
46
    mapping_registry,
0.200.795 by Jelmer Vernooij
simplify sha extraction for blobs, process multiple blobs at once.
47
    symlink_to_blob,
0.200.229 by Jelmer Vernooij
More work on converter.
48
    )
0.200.938 by Jelmer Vernooij
Rename shamap to cache, as it can also do content caching now.
49
from bzrlib.plugins.git.cache import (
0.200.842 by Jelmer Vernooij
Allow content cache to be provided.
50
    from_repository as cache_from_repository,
0.200.231 by Jelmer Vernooij
Partially fix pull.
51
    )
52
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
53
import posixpath
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
54
import stat
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
55
0.200.228 by Jelmer Vernooij
Split out map.
56
0.200.452 by Jelmer Vernooij
Rename converter -> object_store, provide utility function for getting ObjectStore's.
57
def get_object_store(repo, mapping=None):
58
    git = getattr(repo, "_git", None)
59
    if git is not None:
60
        return git.object_store
61
    return BazaarObjectStore(repo, mapping)
62
63
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
64
MAX_TREE_CACHE_SIZE = 50 * 1024 * 1024
65
66
67
class LRUTreeCache(object):
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
68
69
    def __init__(self, repository):
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
70
        def approx_tree_size(tree):
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
71
            # Very rough estimate, 1k per inventory entry
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
72
            return len(tree.inventory) * 1024
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
73
        self.repository = repository
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
74
        self._cache = lru_cache.LRUSizeCache(max_size=MAX_TREE_CACHE_SIZE,
75
            after_cleanup_size=None, compute_size=approx_tree_size)
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
76
0.200.963 by Jelmer Vernooij
Add some tests for LRUTreeCache.
77
    def revision_tree(self, revid):
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
78
        try:
0.200.989 by Jelmer Vernooij
Add asserts.
79
            tree = self._cache[revid]
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
80
        except KeyError:
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
81
            tree = self.repository.revision_tree(revid)
82
            self.add(tree)
0.200.989 by Jelmer Vernooij
Add asserts.
83
        assert tree.get_revision_id() == tree.inventory.revision_id
84
        return tree
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
85
86
    def iter_revision_trees(self, revids):
0.200.989 by Jelmer Vernooij
Add asserts.
87
        trees = {}
88
        todo = []
89
        for revid in revids:
90
            try:
91
                tree = self._cache[revid]
92
            except KeyError:
93
                todo.append(revid)
94
            else:
95
                assert tree.get_revision_id() == revid
96
                assert tree.inventory.revision_id == revid
97
                trees[revid] = tree
98
        for tree in self.repository.revision_trees(todo):
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
99
            trees[tree.get_revision_id()] = tree
100
            self.add(tree)
101
        return (trees[r] for r in revids)
102
103
    def revision_trees(self, revids):
104
        return list(self.iter_revision_trees(revids))
105
106
    def add(self, tree):
107
        self._cache.add(tree.get_revision_id(), tree)
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
108
109
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
110
def _find_missing_bzr_revids(get_parent_map, want, have):
111
    """Find the revisions that have to be pushed.
112
113
    :param get_parent_map: Function that returns the parents for a sequence
114
        of revisions.
115
    :param want: Revisions the target wants
116
    :param have: Revisions the target already has
117
    :return: Set of revisions to fetch
118
    """
119
    pending = want - have
120
    processed = set()
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
121
    todo = set()
122
    while pending:
123
        processed.update(pending)
124
        next_map = get_parent_map(pending)
125
        next_pending = set()
126
        for item in next_map.iteritems():
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
127
            if item[0] in have:
128
                continue
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
129
            todo.add(item[0])
130
            next_pending.update(p for p in item[1] if p not in processed)
131
        pending = next_pending
132
    if NULL_REVISION in todo:
133
        todo.remove(NULL_REVISION)
134
    return todo
135
136
0.200.793 by Jelmer Vernooij
Make _check_expected_sha a global fn.
137
def _check_expected_sha(expected_sha, object):
0.200.797 by Jelmer Vernooij
Add docstring, fix formatting.
138
    """Check whether an object matches an expected SHA.
139
140
    :param expected_sha: None or expected SHA as either binary or as hex digest
141
    :param object: Object to verify
142
    """
0.200.793 by Jelmer Vernooij
Make _check_expected_sha a global fn.
143
    if expected_sha is None:
144
        return
145
    if len(expected_sha) == 40:
146
        if expected_sha != object.sha().hexdigest():
0.200.797 by Jelmer Vernooij
Add docstring, fix formatting.
147
            raise AssertionError("Invalid sha for %r: %s" % (object,
148
                expected_sha))
0.200.793 by Jelmer Vernooij
Make _check_expected_sha a global fn.
149
    elif len(expected_sha) == 20:
150
        if expected_sha != object.sha().digest():
0.200.797 by Jelmer Vernooij
Add docstring, fix formatting.
151
            raise AssertionError("Invalid sha for %r: %s" % (object,
152
                sha_to_hex(expected_sha)))
0.200.793 by Jelmer Vernooij
Make _check_expected_sha a global fn.
153
    else:
0.200.797 by Jelmer Vernooij
Add docstring, fix formatting.
154
        raise AssertionError("Unknown length %d for %r" % (len(expected_sha),
155
            expected_sha))
0.200.793 by Jelmer Vernooij
Make _check_expected_sha a global fn.
156
157
0.200.931 by Jelmer Vernooij
Update docstring, deal with kind changes appropriately in _tree_to_objects
158
def _tree_to_objects(tree, parent_trees, idmap, unusual_modes,
159
                     dummy_file_name=None):
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
160
    """Iterate over the objects that were introduced in a revision.
161
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
162
    :param idmap: id map
0.200.931 by Jelmer Vernooij
Update docstring, deal with kind changes appropriately in _tree_to_objects
163
    :param parent_trees: Parent revision trees
164
    :param unusual_modes: Unusual file modes dictionary
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
165
    :param dummy_file_name: File name to use for dummy files
166
        in empty directories. None to skip empty directories
0.200.837 by Jelmer Vernooij
Return inventory entries when creating git objects for a revision.
167
    :return: Yields (path, object, ie) entries
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
168
    """
169
    new_trees = {}
170
    new_blobs = []
171
    shamap = {}
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
172
    try:
173
        base_tree = parent_trees[0]
174
        other_parent_trees = parent_trees[1:]
175
    except IndexError:
176
        base_tree = tree._repository.revision_tree(NULL_REVISION)
177
        other_parent_trees = []
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
178
    def find_unchanged_parent_ie(ie, parent_trees):
179
        assert ie.kind in ("symlink", "file")
180
        for ptree in parent_trees:
181
            try:
182
                pie = ptree.inventory[ie.file_id]
183
            except errors.NoSuchId:
184
                pass
185
            else:
186
                if (pie.text_sha1 == ie.text_sha1 and 
187
                    pie.kind == ie.kind and
188
                    pie.symlink_target == ie.symlink_target):
189
                    return pie
190
        raise KeyError
0.200.965 by Jelmer Vernooij
Formatting fixes.
191
0.200.931 by Jelmer Vernooij
Update docstring, deal with kind changes appropriately in _tree_to_objects
192
    # Find all the changed blobs
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
193
    for (file_id, path, changed_content, versioned, parent, name, kind,
194
         executable) in tree.iter_changes(base_tree):
195
        if kind[1] == "file":
196
            ie = tree.inventory[file_id]
197
            if changed_content:
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
198
                try:
199
                    pie = find_unchanged_parent_ie(ie, other_parent_trees)
200
                except KeyError:
201
                    pass
202
                else:
0.252.40 by Jelmer Vernooij
Checks for roundtripping.
203
                    try:
204
                        shamap[ie.file_id] = idmap.lookup_blob_id(
205
                            pie.file_id, pie.revision)
206
                    except KeyError:
207
                        # no-change merge ?
208
                        blob = Blob()
209
                        blob.data = tree.get_file_text(ie.file_id)
210
                        shamap[ie.file_id] = blob.id
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
211
            if not file_id in shamap:
212
                new_blobs.append((path[1], ie))
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
213
            new_trees[posixpath.dirname(path[1])] = parent[1]
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
214
        elif kind[1] == "symlink":
215
            ie = tree.inventory[file_id]
216
            if changed_content:
217
                blob = symlink_to_blob(ie)
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
218
                shamap[file_id] = blob.id
219
                try:
220
                    find_unchanged_parent_ie(ie, other_parent_trees)
221
                except KeyError:
222
                    yield path[1], blob, ie
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
223
            new_trees[posixpath.dirname(path[1])] = parent[1]
0.250.3 by Jelmer Vernooij
Simplify..
224
        elif kind[1] not in (None, "directory"):
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
225
            raise AssertionError(kind[1])
0.200.1017 by Jelmer Vernooij
Cope with root moving.
226
        if (path[0] not in (None, "") and
227
            parent[0] in tree.inventory and
228
            tree.inventory[parent[0]].kind == "directory"):
0.200.931 by Jelmer Vernooij
Update docstring, deal with kind changes appropriately in _tree_to_objects
229
            # Removal
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
230
            new_trees[posixpath.dirname(path[0])] = parent[0]
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
231
    
0.200.931 by Jelmer Vernooij
Update docstring, deal with kind changes appropriately in _tree_to_objects
232
    # Fetch contents of the blobs that were changed
0.250.2 by Jelmer Vernooij
Make it work for evolution.
233
    for (path, ie), chunks in tree.iter_files_bytes(
234
        [(ie.file_id, (path, ie)) for (path, ie) in new_blobs]):
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
235
        obj = Blob()
0.200.851 by Jelmer Vernooij
Use blob.chunked.
236
        obj.chunked = chunks
0.200.837 by Jelmer Vernooij
Return inventory entries when creating git objects for a revision.
237
        yield path, obj, ie
238
        shamap[ie.file_id] = obj.id
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
239
0.200.879 by Jelmer Vernooij
Fix unusual modes.
240
    for path in unusual_modes:
241
        parent_path = posixpath.dirname(path)
242
        new_trees[parent_path] = tree.path2id(parent_path)
0.200.989 by Jelmer Vernooij
Add asserts.
243
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
244
    trees = {}
245
    while new_trees:
246
        items = new_trees.items()
247
        new_trees = {}
248
        for path, file_id in items:
0.200.931 by Jelmer Vernooij
Update docstring, deal with kind changes appropriately in _tree_to_objects
249
            parent_id = tree.inventory[file_id].parent_id
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
250
            if parent_id is not None:
251
                parent_path = urlutils.dirname(path)
252
                new_trees[parent_path] = parent_id
253
            trees[path] = file_id
254
0.200.808 by Jelmer Vernooij
Avoid recalculating tree shas we already have.
255
    def ie_to_hexsha(ie):
256
        try:
257
            return shamap[ie.file_id]
258
        except KeyError:
0.200.884 by Jelmer Vernooij
Cope with -0000 as timezone in Git commits.
259
            # FIXME: Should be the same as in parent
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
260
            if ie.kind in ("file", "symlink"):
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
261
                try:
262
                    return idmap.lookup_blob_id(ie.file_id, ie.revision)
263
                except KeyError:
264
                    # no-change merge ?
265
                    blob = Blob()
266
                    blob.data = tree.get_file_text(ie.file_id)
267
                    return blob.id
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
268
            elif ie.kind == "directory":
269
                # Not all cache backends store the tree information, 
270
                # calculate again from scratch
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
271
                ret = directory_to_tree(ie, ie_to_hexsha, unusual_modes,
272
                    dummy_file_name)
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
273
                if ret is None:
274
                    return ret
275
                return ret.id
276
            else:
277
                raise AssertionError
0.200.808 by Jelmer Vernooij
Avoid recalculating tree shas we already have.
278
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
279
    for path in sorted(trees.keys(), reverse=True):
0.250.1 by Jelmer Vernooij
Use iter_changes() rather than iterating over all contents of an inventory.
280
        ie = tree.inventory[trees[path]]
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
281
        assert ie.kind == "directory"
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
282
        obj = directory_to_tree(ie, ie_to_hexsha, unusual_modes,
283
            dummy_file_name)
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
284
        if obj is not None:
0.200.837 by Jelmer Vernooij
Return inventory entries when creating git objects for a revision.
285
            yield path, obj, ie
0.200.798 by Jelmer Vernooij
Split out _inventory_to_objects into a function.
286
            shamap[ie.file_id] = obj.id
287
288
0.200.457 by Jelmer Vernooij
Use BaseObjectStore.
289
class BazaarObjectStore(BaseObjectStore):
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
290
    """A Git-style object store backed onto a Bazaar repository."""
0.200.228 by Jelmer Vernooij
Split out map.
291
292
    def __init__(self, repository, mapping=None):
293
        self.repository = repository
294
        if mapping is None:
0.200.463 by Jelmer Vernooij
Support remote dpush (except for references).
295
            self.mapping = default_mapping
0.200.228 by Jelmer Vernooij
Split out map.
296
        else:
297
            self.mapping = mapping
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
298
        self._cache = cache_from_repository(repository)
0.254.40 by Jelmer Vernooij
Add content cache infrastructure.
299
        self._content_cache_types = ("tree")
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
300
        self.start_write_group = self._cache.idmap.start_write_group
301
        self.abort_write_group = self._cache.idmap.abort_write_group
302
        self.commit_write_group = self._cache.idmap.commit_write_group
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
303
        self.tree_cache = LRUTreeCache(self.repository)
0.200.228 by Jelmer Vernooij
Split out map.
304
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
305
    def _update_sha_map(self, stop_revision=None):
0.200.683 by Jelmer Vernooij
Lazier checking of which revisions need to be fetched.
306
        graph = self.repository.get_graph()
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
307
        if stop_revision is None:
0.200.683 by Jelmer Vernooij
Lazier checking of which revisions need to be fetched.
308
            heads = graph.heads(self.repository.all_revision_ids())
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
309
        else:
0.200.683 by Jelmer Vernooij
Lazier checking of which revisions need to be fetched.
310
            heads = set([stop_revision])
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
311
        missing_revids = self._cache.idmap.missing_revisions(heads)
0.200.683 by Jelmer Vernooij
Lazier checking of which revisions need to be fetched.
312
        while heads:
313
            parents = graph.get_parent_map(heads)
314
            todo = set()
315
            for p in parents.values():
0.200.684 by Jelmer Vernooij
Properly close write groups.
316
                todo.update([x for x in p if x not in missing_revids])
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
317
            heads = self._cache.idmap.missing_revisions(todo)
0.200.684 by Jelmer Vernooij
Properly close write groups.
318
            missing_revids.update(heads)
0.200.694 by Jelmer Vernooij
Avoid processing NULL_REVISION.
319
        if NULL_REVISION in missing_revids:
320
            missing_revids.remove(NULL_REVISION)
0.254.16 by Jelmer Vernooij
Add optimization preventing recursive index updating.
321
        missing_revids = self.repository.has_revisions(missing_revids)
322
        if not missing_revids:
323
            return
0.200.735 by Jelmer Vernooij
Use convenience functions for start/stop write groups.
324
        self.start_write_group()
0.200.231 by Jelmer Vernooij
Partially fix pull.
325
        try:
0.254.4 by Jelmer Vernooij
Merge trunk.
326
            pb = ui.ui_factory.nested_progress_bar()
327
            try:
328
                for i, revid in enumerate(graph.iter_topo_order(missing_revids)):
0.254.16 by Jelmer Vernooij
Add optimization preventing recursive index updating.
329
                    trace.mutter('processing %r', revid)
0.254.4 by Jelmer Vernooij
Merge trunk.
330
                    pb.update("updating git map", i, len(missing_revids))
331
                    self._update_sha_map_revision(revid)
332
            finally:
333
                pb.finished()
0.200.735 by Jelmer Vernooij
Use convenience functions for start/stop write groups.
334
        except:
335
            self.abort_write_group()
336
            raise
337
        else:
338
            self.commit_write_group()
0.200.229 by Jelmer Vernooij
More work on converter.
339
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
340
    def __iter__(self):
341
        self._update_sha_map()
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
342
        return iter(self._cache.idmap.sha1s())
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
343
0.200.1023 by Jelmer Vernooij
Set and verify testament.
344
    def _reconstruct_commit(self, rev, tree_sha, roundtrip, testament3_sha1):
0.238.7 by Jelmer Vernooij
Cope with ghosts a bit better.
345
        def parent_lookup(revid):
346
            try:
347
                return self._lookup_revision_sha1(revid)
348
            except errors.NoSuchRevision:
349
                return None
0.252.4 by Jelmer Vernooij
More work on roundtripping.
350
        return self.mapping.export_commit(rev, tree_sha, parent_lookup,
0.200.1023 by Jelmer Vernooij
Set and verify testament.
351
            roundtrip, testament3_sha1)
0.238.7 by Jelmer Vernooij
Cope with ghosts a bit better.
352
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
353
    def _create_fileid_map_blob(self, inv):
354
        # FIXME: This can probably be a lot more efficient, 
355
        # not all files necessarily have to be processed.
356
        file_ids = {}
357
        for (path, ie) in inv.iter_entries():
358
            if self.mapping.generate_file_id(path) != ie.file_id:
359
                file_ids[path] = ie.file_id
360
        return self.mapping.export_fileid_map(file_ids)
361
0.252.4 by Jelmer Vernooij
More work on roundtripping.
362
    def _revision_to_objects(self, rev, tree, roundtrip):
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
363
        """Convert a revision to a set of git objects.
364
365
        :param rev: Bazaar revision object
366
        :param tree: Bazaar revision tree
367
        :param roundtrip: Whether to roundtrip all Bazaar revision data
368
        """
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
369
        unusual_modes = extract_unusual_modes(rev)
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
370
        present_parents = self.repository.has_revisions(rev.parent_ids)
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
371
        parent_trees = self.tree_cache.revision_trees(
0.200.797 by Jelmer Vernooij
Add docstring, fix formatting.
372
            [p for p in rev.parent_ids if p in present_parents])
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
373
        root_tree = None
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
374
        for path, obj, ie in _tree_to_objects(tree, parent_trees,
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
375
                self._cache.idmap, unusual_modes, self.mapping.BZR_DUMMY_FILE):
0.200.773 by Jelmer Vernooij
Implement inventory_to_objects
376
            if path == "":
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
377
                root_tree = obj
0.252.34 by Jelmer Vernooij
Yield the proper object for the tree root.
378
                root_ie = ie
379
                # Don't yield just yet
380
            else:
381
                yield path, obj, ie
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
382
        if root_tree is None:
0.250.2 by Jelmer Vernooij
Make it work for evolution.
383
            # Pointless commit - get the tree sha elsewhere
0.200.864 by Jelmer Vernooij
Cope with the first commit being pointless.
384
            if not rev.parent_ids:
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
385
                root_tree = Tree()
0.200.864 by Jelmer Vernooij
Cope with the first commit being pointless.
386
            else:
387
                base_sha1 = self._lookup_revision_sha1(rev.parent_ids[0])
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
388
                root_tree = self[self[base_sha1].tree]
0.252.35 by Jelmer Vernooij
Ignore control files in inventories.
389
            root_ie = tree.inventory.root
0.200.915 by Jelmer Vernooij
Cope with the fact that the old format didn't export file ids.
390
        if roundtrip and self.mapping.BZR_FILE_IDS_FILE is not None:
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
391
            b = self._create_fileid_map_blob(tree.inventory)
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
392
            if b is not None:
393
                root_tree[self.mapping.BZR_FILE_IDS_FILE] = ((stat.S_IFREG | 0644), b.id)
394
                yield self.mapping.BZR_FILE_IDS_FILE, b, None
0.252.34 by Jelmer Vernooij
Yield the proper object for the tree root.
395
        yield "", root_tree, root_ie
0.200.1023 by Jelmer Vernooij
Set and verify testament.
396
        if roundtrip:
397
            testament3 = StrictTestament3(rev, tree.inventory)
398
            testament3_sha1 = testament3.as_sha1()
399
        else:
400
            testament3_sha1 = None
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
401
        commit_obj = self._reconstruct_commit(rev, root_tree.id,
0.200.1023 by Jelmer Vernooij
Set and verify testament.
402
            roundtrip=roundtrip, testament3_sha1=testament3_sha1)
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
403
        try:
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
404
            foreign_revid, mapping = mapping_registry.parse_revision_id(
405
                rev.revision_id)
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
406
        except errors.InvalidRevisionId:
407
            pass
408
        else:
0.200.794 by Jelmer Vernooij
Use _check_expected_sha rather than custom checks.
409
            _check_expected_sha(foreign_revid, commit_obj)
0.200.837 by Jelmer Vernooij
Return inventory entries when creating git objects for a revision.
410
        yield None, commit_obj, None
0.200.783 by Jelmer Vernooij
Move object generation into a separate function.
411
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
412
    def _get_updater(self, rev):
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
413
        return self._cache.get_updater(rev)
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
414
0.200.783 by Jelmer Vernooij
Move object generation into a separate function.
415
    def _update_sha_map_revision(self, revid):
416
        rev = self.repository.get_revision(revid)
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
417
        tree = self.tree_cache.revision_tree(rev.revision_id)
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
418
        updater = self._get_updater(rev)
0.252.4 by Jelmer Vernooij
More work on roundtripping.
419
        for path, obj, ie in self._revision_to_objects(rev, tree,
420
            roundtrip=True):
0.200.952 by Jelmer Vernooij
Write git pack files rather than loose objects.
421
            updater.add_object(obj, ie, path)
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
422
        commit_obj = updater.finish()
0.200.781 by Jelmer Vernooij
Return commit id after converting a revision.
423
        return commit_obj.id
0.200.229 by Jelmer Vernooij
More work on converter.
424
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
425
    def _reconstruct_blobs(self, keys):
0.200.698 by Jelmer Vernooij
Merge fixes for SHA1s of symlinks.
426
        """Return a Git Blob object from a fileid and revision stored in bzr.
427
428
        :param fileid: File id of the text
429
        :param revision: Revision of the text
430
        """
0.250.2 by Jelmer Vernooij
Make it work for evolution.
431
        stream = self.repository.iter_files_bytes(
432
            ((key[0], key[1], key) for key in keys))
0.200.856 by Jelmer Vernooij
Support reconstructing multiple blobs at the same time.
433
        for (fileid, revision, expected_sha), chunks in stream:
0.200.854 by Jelmer Vernooij
_get_blob -> _get_blobs.
434
            blob = Blob()
435
            blob.chunked = chunks
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
436
            if blob.id != expected_sha and blob.data == "":
0.200.854 by Jelmer Vernooij
_get_blob -> _get_blobs.
437
                # Perhaps it's a symlink ?
438
                tree = self.tree_cache.revision_tree(revision)
439
                entry = tree.inventory[fileid]
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
440
                if entry.kind == 'symlink':
441
                    blob = symlink_to_blob(entry)
0.200.854 by Jelmer Vernooij
_get_blob -> _get_blobs.
442
            _check_expected_sha(expected_sha, blob)
443
            yield blob
0.200.229 by Jelmer Vernooij
More work on converter.
444
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
445
    def _reconstruct_tree(self, fileid, revid, inv, unusual_modes,
446
        expected_sha=None):
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
447
        """Return a Git Tree object from a file id and a revision stored in bzr.
0.200.249 by Jelmer Vernooij
Implement Tree.
448
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
449
        :param fileid: fileid in the tree.
0.200.249 by Jelmer Vernooij
Implement Tree.
450
        :param revision: Revision of the tree.
451
        """
0.200.776 by Jelmer Vernooij
Remove unnecessary lookups.
452
        def get_ie_sha1(entry):
453
            if entry.kind == "directory":
0.200.808 by Jelmer Vernooij
Avoid recalculating tree shas we already have.
454
                try:
0.200.859 by Jelmer Vernooij
Trivial cleanups.
455
                    return self._cache.idmap.lookup_tree_id(entry.file_id,
456
                        revid)
0.200.812 by Jelmer Vernooij
Catch KeyError from lookup_tree as well - some caches (such as sqlite) don't store all trees, only some.
457
                except (NotImplementedError, KeyError):
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
458
                    obj = self._reconstruct_tree(entry.file_id, revid, inv,
0.200.808 by Jelmer Vernooij
Avoid recalculating tree shas we already have.
459
                        unusual_modes)
460
                    if obj is None:
461
                        return None
462
                    else:
463
                        return obj.id
0.200.776 by Jelmer Vernooij
Remove unnecessary lookups.
464
            elif entry.kind in ("file", "symlink"):
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
465
                try:
466
                    return self._cache.idmap.lookup_blob_id(entry.file_id,
467
                        entry.revision)
468
                except KeyError:
469
                    # no-change merge?
470
                    return self._reconstruct_blobs(
471
                        [(entry.file_id, entry.revision, None)]).next().id
0.200.776 by Jelmer Vernooij
Remove unnecessary lookups.
472
            else:
473
                raise AssertionError("unknown entry kind '%s'" % entry.kind)
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
474
        tree = directory_to_tree(inv[fileid], get_ie_sha1, unusual_modes,
475
            self.mapping.BZR_DUMMY_FILE)
0.200.915 by Jelmer Vernooij
Cope with the fact that the old format didn't export file ids.
476
        if (inv.root.file_id == fileid and
477
            self.mapping.BZR_FILE_IDS_FILE is not None):
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
478
            b = self._create_fileid_map_blob(inv)
479
            # If this is the root tree, add the file ids
480
            tree[self.mapping.BZR_FILE_IDS_FILE] = ((stat.S_IFREG | 0644), b.id)
0.200.793 by Jelmer Vernooij
Make _check_expected_sha a global fn.
481
        _check_expected_sha(expected_sha, tree)
0.200.249 by Jelmer Vernooij
Implement Tree.
482
        return tree
0.200.229 by Jelmer Vernooij
More work on converter.
483
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
484
    def get_parents(self, sha):
0.200.454 by Jelmer Vernooij
Use ObjectStore.find_missing_objects in server.
485
        """Retrieve the parents of a Git commit by SHA1.
486
487
        :param sha: SHA1 of the commit
488
        :raises: KeyError, NotCommitError
489
        """
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
490
        return self[sha].parents
491
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
492
    def _lookup_revision_sha1(self, revid):
0.200.449 by Jelmer Vernooij
Use BazaarObjectStore to find matching SHA1s for bzr revisions.
493
        """Return the SHA1 matching a Bazaar revision."""
0.200.891 by Jelmer Vernooij
Use ZERO_SHA constant where possible.
494
        from dulwich.protocol import ZERO_SHA
0.200.541 by Jelmer Vernooij
Cope with NULL_REVISION.
495
        if revid == NULL_REVISION:
0.200.891 by Jelmer Vernooij
Use ZERO_SHA constant where possible.
496
            return ZERO_SHA
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
497
        try:
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
498
            return self._cache.idmap.lookup_commit(revid)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
499
        except KeyError:
0.200.682 by Jelmer Vernooij
Avoid doing a full sha map update if we already know the SHA1.
500
            try:
501
                return mapping_registry.parse_revision_id(revid)[0]
502
            except errors.InvalidRevisionId:
0.252.47 by Jelmer Vernooij
Fix handling of HEAD refs.
503
                self.repository.lock_read()
504
                try:
505
                    self._update_sha_map(revid)
506
                finally:
507
                    self.repository.unlock()
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
508
                return self._cache.idmap.lookup_commit(revid)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
509
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
510
    def get_raw(self, sha):
0.200.454 by Jelmer Vernooij
Use ObjectStore.find_missing_objects in server.
511
        """Get the raw representation of a Git object by SHA1.
512
513
        :param sha: SHA1 of the git object
514
        """
0.200.566 by Jelmer Vernooij
Fix ObjectStore.get_raw() .
515
        obj = self[sha]
516
        return (obj.type, obj.as_raw_string())
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
517
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
518
    def __contains__(self, sha):
519
        # See if sha is in map
520
        try:
0.200.897 by Jelmer Vernooij
Make lookup_git_sha public.
521
            (type, type_data) = self.lookup_git_sha(sha)
0.200.568 by Jelmer Vernooij
Properly check that matching bzr objects exist.
522
            if type == "commit":
523
                return self.repository.has_revision(type_data[0])
524
            elif type == "blob":
0.200.964 by Jelmer Vernooij
Add some tests for object store.
525
                return self.repository.texts.has_key(type_data)
0.200.568 by Jelmer Vernooij
Properly check that matching bzr objects exist.
526
            elif type == "tree":
527
                return self.repository.has_revision(type_data[1])
528
            else:
529
                raise AssertionError("Unknown object type '%s'" % type)
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
530
        except KeyError:
531
            return False
532
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
533
    def lookup_git_shas(self, shas, update_map=True):
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
534
        from dulwich.protocol import ZERO_SHA
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
535
        ret = {}
536
        for sha in shas:
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
537
            if sha == ZERO_SHA:
0.200.985 by Jelmer Vernooij
Fix handling of ZERO_SHA in lookup_git_sha.
538
                ret[sha] = ("commit", (NULL_REVISION, None))
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
539
                continue
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
540
            try:
541
                ret[sha] = self._cache.idmap.lookup_git_sha(sha)
542
            except KeyError:
543
                if update_map:
544
                    # if not, see if there are any unconverted revisions and add
545
                    # them to the map, search for sha in map again
546
                    self._update_sha_map()
547
                    update_map = False
548
                    try:
549
                        ret[sha] = self._cache.idmap.lookup_git_sha(sha)
550
                    except KeyError:
551
                        pass
552
        return ret
553
554
    def lookup_git_sha(self, sha, update_map=True):
555
        return self.lookup_git_shas([sha], update_map=update_map)[sha]
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
556
557
    def __getitem__(self, sha):
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
558
        if self._cache.content_cache is not None:
0.200.840 by Jelmer Vernooij
Support using content cache.
559
            try:
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
560
                return self._cache.content_cache[sha]
0.200.840 by Jelmer Vernooij
Support using content cache.
561
            except KeyError:
562
                pass
0.200.897 by Jelmer Vernooij
Make lookup_git_sha public.
563
        (type, type_data) = self.lookup_git_sha(sha)
0.200.228 by Jelmer Vernooij
Split out map.
564
        # convert object to git object
0.200.229 by Jelmer Vernooij
More work on converter.
565
        if type == "commit":
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
566
            (revid, tree_sha) = type_data
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
567
            try:
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
568
                rev = self.repository.get_revision(revid)
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
569
            except errors.NoSuchRevision:
0.200.836 by Jelmer Vernooij
Allow content cache.
570
                trace.mutter('entry for %s %s in shamap: %r, but not found in '
571
                             'repository', type, sha, type_data)
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
572
                raise KeyError(sha)
0.252.22 by Jelmer Vernooij
Fix file id map (de)serialization.
573
            commit = self._reconstruct_commit(rev, tree_sha, roundtrip=True)
0.200.793 by Jelmer Vernooij
Make _check_expected_sha a global fn.
574
            _check_expected_sha(sha, commit)
0.200.785 by Jelmer Vernooij
Eliminate _get_commit.
575
            return commit
0.200.229 by Jelmer Vernooij
More work on converter.
576
        elif type == "blob":
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
577
            (fileid, revision) = type_data
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
578
            return self._reconstruct_blobs([(fileid, revision, sha)]).next()
0.200.229 by Jelmer Vernooij
More work on converter.
579
        elif type == "tree":
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
580
            (fileid, revid) = type_data
0.200.561 by Jelmer Vernooij
Cope with revisions pointed to by trees in the shamap disappearing.
581
            try:
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
582
                tree = self.tree_cache.revision_tree(revid)
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
583
                rev = self.repository.get_revision(revid)
0.200.561 by Jelmer Vernooij
Cope with revisions pointed to by trees in the shamap disappearing.
584
            except errors.NoSuchRevision:
585
                trace.mutter('entry for %s %s in shamap: %r, but not found in repository', type, sha, type_data)
586
                raise KeyError(sha)
0.200.556 by Jelmer Vernooij
Fix syntax error.
587
            unusual_modes = extract_unusual_modes(rev)
0.200.491 by Jelmer Vernooij
Cope with map for Tree objects becoming invalid.
588
            try:
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
589
                return self._reconstruct_tree(fileid, revid, tree.inventory,
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
590
                    unusual_modes, expected_sha=sha)
0.200.491 by Jelmer Vernooij
Cope with map for Tree objects becoming invalid.
591
            except errors.NoSuchRevision:
592
                raise KeyError(sha)
0.200.228 by Jelmer Vernooij
Split out map.
593
        else:
594
            raise AssertionError("Unknown object type '%s'" % type)
0.200.782 by Jelmer Vernooij
Add custom generate_pack_contents implementation.
595
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
596
    def generate_lossy_pack_contents(self, have, want, progress=None,
597
            get_tagged=None):
598
        return self.generate_pack_contents(have, want, progress, get_tagged,
599
            lossy=True)
600
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
601
    def generate_pack_contents(self, have, want, progress=None,
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
602
            get_tagged=None, lossy=False):
0.200.782 by Jelmer Vernooij
Add custom generate_pack_contents implementation.
603
        """Iterate over the contents of a pack file.
604
605
        :param have: List of SHA1s of objects that should not be sent
606
        :param want: List of SHA1s of objects that should be sent
607
        """
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
608
        processed = set()
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
609
        ret = self.lookup_git_shas(have + want)
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
610
        for commit_sha in have:
611
            try:
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
612
                (type, (revid, tree_sha)) = ret[commit_sha]
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
613
            except KeyError:
614
                pass
615
            else:
616
                assert type == "commit"
617
                processed.add(revid)
618
        pending = set()
619
        for commit_sha in want:
620
            if commit_sha in have:
621
                continue
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
622
            try:
623
                (type, (revid, tree_sha)) = ret[commit_sha]
624
            except KeyError:
625
                pass
626
            else:
627
                assert type == "commit"
628
                pending.add(revid)
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
629
630
        todo = _find_missing_bzr_revids(self.repository.get_parent_map, 
631
                                        pending, processed)
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
632
        trace.mutter('sending revisions %r', todo)
633
        ret = []
634
        pb = ui.ui_factory.nested_progress_bar()
635
        try:
636
            for i, revid in enumerate(todo):
637
                pb.update("generating git objects", i, len(todo))
638
                rev = self.repository.get_revision(revid)
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
639
                tree = self.tree_cache.revision_tree(revid)
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
640
                for path, obj, ie in self._revision_to_objects(rev, tree,
641
                    roundtrip=not lossy):
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
642
                    ret.append((obj, path))
643
        finally:
644
            pb.finished()
645
        return ret
0.251.1 by Jelmer Vernooij
Implement ObjectStore.add_{thin_,}pack.
646
647
    def add_thin_pack(self):
648
        import tempfile
649
        import os
650
        fd, path = tempfile.mkstemp(suffix=".pack")
651
        f = os.fdopen(fd, 'wb')
652
        def commit():
653
            from dulwich.pack import PackData, Pack
654
            from bzrlib.plugins.git.fetch import import_git_objects
655
            os.fsync(fd)
656
            f.close()
657
            if os.path.getsize(path) == 0:
658
                return
659
            pd = PackData(path)
660
            pd.create_index_v2(path[:-5]+".idx", self.object_store.get_raw)
661
662
            p = Pack(path[:-5])
663
            self.repository.lock_write()
664
            try:
665
                self.repository.start_write_group()
666
                try:
667
                    import_git_objects(self.repository, self.mapping, 
668
                        p.iterobjects(get_raw=self.get_raw),
669
                        self.object_store)
670
                except:
671
                    self.repository.abort_write_group()
672
                    raise
673
                else:
674
                    self.repository.commit_write_group()
675
            finally:
676
                self.repository.unlock()
677
        return f, commit
678
679
    # The pack isn't kept around anyway, so no point 
680
    # in treating full packs different from thin packs
681
    add_pack = add_thin_pack