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