/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.1153 by Jelmer Vernooij
Import ZERO_SHA from dulwich.objects.
24
    ZERO_SHA,
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
25
    )
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
26
from dulwich.object_store import (
0.200.457 by Jelmer Vernooij
Use BaseObjectStore.
27
    BaseObjectStore,
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
28
    )
0.200.249 by Jelmer Vernooij
Implement Tree.
29
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
30
from bzrlib import (
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
31
    errors,
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
32
    lru_cache,
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
33
    trace,
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
34
    ui,
0.200.773 by Jelmer Vernooij
Implement inventory_to_objects
35
    urlutils,
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
36
    )
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
37
from bzrlib.lock import LogicalLockResult
0.200.541 by Jelmer Vernooij
Cope with NULL_REVISION.
38
from bzrlib.revision import (
39
    NULL_REVISION,
40
    )
0.200.1023 by Jelmer Vernooij
Set and verify testament.
41
from bzrlib.testament import(
42
    StrictTestament3,
43
    )
0.200.228 by Jelmer Vernooij
Split out map.
44
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
45
from bzrlib.plugins.git.cache import (
46
    from_repository as cache_from_repository,
47
    )
0.200.229 by Jelmer Vernooij
More work on converter.
48
from bzrlib.plugins.git.mapping import (
0.200.463 by Jelmer Vernooij
Support remote dpush (except for references).
49
    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.
50
    directory_to_tree,
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
51
    extract_unusual_modes,
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
52
    mapping_registry,
0.200.795 by Jelmer Vernooij
simplify sha extraction for blobs, process multiple blobs at once.
53
    symlink_to_blob,
0.200.229 by Jelmer Vernooij
More work on converter.
54
    )
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
55
from bzrlib.plugins.git.unpeel_map import (
56
    UnpeelMap,
0.200.231 by Jelmer Vernooij
Partially fix pull.
57
    )
58
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
59
import posixpath
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
60
import stat
0.200.878 by Jelmer Vernooij
Fix determining of unusual file modes.
61
0.200.228 by Jelmer Vernooij
Split out map.
62
0.200.452 by Jelmer Vernooij
Rename converter -> object_store, provide utility function for getting ObjectStore's.
63
def get_object_store(repo, mapping=None):
64
    git = getattr(repo, "_git", None)
65
    if git is not None:
0.200.1303 by Jelmer Vernooij
Fix locking.
66
        git.object_store.unlock = lambda: None
67
        git.object_store.lock_read = lambda: LogicalLockResult(lambda: None)
68
        git.object_store.lock_write = lambda: LogicalLockResult(lambda: None)
0.200.452 by Jelmer Vernooij
Rename converter -> object_store, provide utility function for getting ObjectStore's.
69
        return git.object_store
70
    return BazaarObjectStore(repo, mapping)
71
72
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
73
MAX_TREE_CACHE_SIZE = 50 * 1024 * 1024
74
75
76
class LRUTreeCache(object):
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
77
78
    def __init__(self, repository):
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
79
        def approx_tree_size(tree):
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
80
            # Very rough estimate, 1k per inventory entry
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
81
            return len(tree.inventory) * 1024
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
82
        self.repository = repository
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
83
        self._cache = lru_cache.LRUSizeCache(max_size=MAX_TREE_CACHE_SIZE,
84
            after_cleanup_size=None, compute_size=approx_tree_size)
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
85
0.200.963 by Jelmer Vernooij
Add some tests for LRUTreeCache.
86
    def revision_tree(self, revid):
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
87
        try:
0.200.989 by Jelmer Vernooij
Add asserts.
88
            tree = self._cache[revid]
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
89
        except KeyError:
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
90
            tree = self.repository.revision_tree(revid)
91
            self.add(tree)
0.200.989 by Jelmer Vernooij
Add asserts.
92
        assert tree.get_revision_id() == tree.inventory.revision_id
93
        return tree
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
94
95
    def iter_revision_trees(self, revids):
0.200.989 by Jelmer Vernooij
Add asserts.
96
        trees = {}
97
        todo = []
98
        for revid in revids:
99
            try:
100
                tree = self._cache[revid]
101
            except KeyError:
102
                todo.append(revid)
103
            else:
104
                assert tree.get_revision_id() == revid
105
                trees[revid] = tree
106
        for tree in self.repository.revision_trees(todo):
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
107
            trees[tree.get_revision_id()] = tree
108
            self.add(tree)
109
        return (trees[r] for r in revids)
110
111
    def revision_trees(self, revids):
112
        return list(self.iter_revision_trees(revids))
113
114
    def add(self, tree):
0.270.1 by Martin
Avoid the deprecated LRUSizeCache.add method
115
        self._cache[tree.get_revision_id()] = tree
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
116
117
0.200.1053 by Jelmer Vernooij
Fix find_missing_bzr_revids.
118
def _find_missing_bzr_revids(graph, want, have):
0.252.5 by Jelmer Vernooij
enable 'bzr push'.
119
    """Find the revisions that have to be pushed.
120
121
    :param get_parent_map: Function that returns the parents for a sequence
122
        of revisions.
123
    :param want: Revisions the target wants
124
    :param have: Revisions the target already has
125
    :return: Set of revisions to fetch
126
    """
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
127
    handled = set(have)
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
128
    todo = set()
0.200.1053 by Jelmer Vernooij
Fix find_missing_bzr_revids.
129
    for rev in want:
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
130
        extra_todo = graph.find_unique_ancestors(rev, handled)
131
        todo.update(extra_todo)
132
        handled.update(extra_todo)
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
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:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
187
                if (pie.text_sha1 == ie.text_sha1 and
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
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
0.200.1375 by Jelmer Vernooij
Avoid using deprecated Inventory.__contains.
228
            tree.has_id(parent[0]) and
0.200.1017 by Jelmer Vernooij
Cope with root moving.
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.1212 by Jelmer Vernooij
Support read locking object stores.
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.1290 by Jelmer Vernooij
Avoid storing all objects to push in memory.
290
class PackTupleIterable(object):
291
292
    def __init__(self, store):
293
        self.store = store
0.200.1432 by Jelmer Vernooij
Make sure object store is locked/unlocked.
294
        self.store.lock_read()
0.200.1290 by Jelmer Vernooij
Avoid storing all objects to push in memory.
295
        self.objects = {}
296
0.200.1432 by Jelmer Vernooij
Make sure object store is locked/unlocked.
297
    def __del__(self):
298
        self.store.unlock()
299
0.200.1290 by Jelmer Vernooij
Avoid storing all objects to push in memory.
300
    def add(self, sha, path):
301
        self.objects[sha] = path
302
303
    def __len__(self):
304
        return len(self.objects)
305
306
    def __iter__(self):
307
        return ((self.store[object_id], path) for (object_id, path) in
308
                self.objects.iteritems())
309
310
0.200.457 by Jelmer Vernooij
Use BaseObjectStore.
311
class BazaarObjectStore(BaseObjectStore):
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
312
    """A Git-style object store backed onto a Bazaar repository."""
0.200.228 by Jelmer Vernooij
Split out map.
313
314
    def __init__(self, repository, mapping=None):
315
        self.repository = repository
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
316
        self._map_updated = False
317
        self._locked = None
0.200.228 by Jelmer Vernooij
Split out map.
318
        if mapping is None:
0.200.463 by Jelmer Vernooij
Support remote dpush (except for references).
319
            self.mapping = default_mapping
0.200.228 by Jelmer Vernooij
Split out map.
320
        else:
321
            self.mapping = mapping
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
322
        self._cache = cache_from_repository(repository)
0.200.1291 by Jelmer Vernooij
add hook for updating to local git cache.
323
        self._content_cache_types = ("tree",)
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
324
        self.start_write_group = self._cache.idmap.start_write_group
325
        self.abort_write_group = self._cache.idmap.abort_write_group
326
        self.commit_write_group = self._cache.idmap.commit_write_group
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
327
        self.tree_cache = LRUTreeCache(self.repository)
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
328
        self.unpeel_map = UnpeelMap.from_repository(self.repository)
0.200.228 by Jelmer Vernooij
Split out map.
329
0.200.1319 by Jelmer Vernooij
Only update git cache during post-commit if parents are already in the cache.
330
    def _missing_revisions(self, revisions):
331
        return self._cache.idmap.missing_revisions(revisions)
332
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
333
    def _update_sha_map(self, stop_revision=None):
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
334
        if not self.is_locked():
335
            raise AssertionError()
336
        if self._map_updated:
337
            return
0.200.1264 by Jelmer Vernooij
Fix updating cache for single revision - don't consider it an update of the full cache.
338
        if (stop_revision is not None and
0.200.1319 by Jelmer Vernooij
Only update git cache during post-commit if parents are already in the cache.
339
            not self._missing_revisions([stop_revision])):
0.200.1264 by Jelmer Vernooij
Fix updating cache for single revision - don't consider it an update of the full cache.
340
            return
0.200.683 by Jelmer Vernooij
Lazier checking of which revisions need to be fetched.
341
        graph = self.repository.get_graph()
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
342
        if stop_revision is None:
0.200.1301 by Jelmer Vernooij
Avoid expensive get_parent_map call.
343
            all_revids = self.repository.all_revision_ids()
0.200.1319 by Jelmer Vernooij
Only update git cache during post-commit if parents are already in the cache.
344
            missing_revids = self._missing_revisions(all_revids)
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
345
        else:
0.200.683 by Jelmer Vernooij
Lazier checking of which revisions need to be fetched.
346
            heads = set([stop_revision])
0.200.1319 by Jelmer Vernooij
Only update git cache during post-commit if parents are already in the cache.
347
            missing_revids = self._missing_revisions(heads)
0.200.1301 by Jelmer Vernooij
Avoid expensive get_parent_map call.
348
            while heads:
349
                parents = graph.get_parent_map(heads)
350
                todo = set()
351
                for p in parents.values():
352
                    todo.update([x for x in p if x not in missing_revids])
0.200.1319 by Jelmer Vernooij
Only update git cache during post-commit if parents are already in the cache.
353
                heads = self._missing_revisions(todo)
0.200.1301 by Jelmer Vernooij
Avoid expensive get_parent_map call.
354
                missing_revids.update(heads)
0.200.694 by Jelmer Vernooij
Avoid processing NULL_REVISION.
355
        if NULL_REVISION in missing_revids:
356
            missing_revids.remove(NULL_REVISION)
0.254.16 by Jelmer Vernooij
Add optimization preventing recursive index updating.
357
        missing_revids = self.repository.has_revisions(missing_revids)
358
        if not missing_revids:
0.200.1264 by Jelmer Vernooij
Fix updating cache for single revision - don't consider it an update of the full cache.
359
            if stop_revision is None:
360
                self._map_updated = True
0.254.16 by Jelmer Vernooij
Add optimization preventing recursive index updating.
361
            return
0.200.735 by Jelmer Vernooij
Use convenience functions for start/stop write groups.
362
        self.start_write_group()
0.200.231 by Jelmer Vernooij
Partially fix pull.
363
        try:
0.254.4 by Jelmer Vernooij
Merge trunk.
364
            pb = ui.ui_factory.nested_progress_bar()
365
            try:
366
                for i, revid in enumerate(graph.iter_topo_order(missing_revids)):
0.254.16 by Jelmer Vernooij
Add optimization preventing recursive index updating.
367
                    trace.mutter('processing %r', revid)
0.254.4 by Jelmer Vernooij
Merge trunk.
368
                    pb.update("updating git map", i, len(missing_revids))
369
                    self._update_sha_map_revision(revid)
370
            finally:
371
                pb.finished()
0.200.1264 by Jelmer Vernooij
Fix updating cache for single revision - don't consider it an update of the full cache.
372
            if stop_revision is None:
373
                self._map_updated = True
0.200.735 by Jelmer Vernooij
Use convenience functions for start/stop write groups.
374
        except:
375
            self.abort_write_group()
376
            raise
377
        else:
378
            self.commit_write_group()
0.200.229 by Jelmer Vernooij
More work on converter.
379
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
380
    def __iter__(self):
381
        self._update_sha_map()
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
382
        return iter(self._cache.idmap.sha1s())
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
383
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
384
    def _reconstruct_commit(self, rev, tree_sha, roundtrip, verifiers):
385
        """Reconstruct a Commit object.
386
387
        :param rev: Revision object
388
        :param tree_sha: SHA1 of the root tree object
389
        :param roundtrip: Whether or not to roundtrip bzr metadata
390
        :param verifiers: Verifiers for the commits
391
        :return: Commit object
392
        """
0.238.7 by Jelmer Vernooij
Cope with ghosts a bit better.
393
        def parent_lookup(revid):
394
            try:
395
                return self._lookup_revision_sha1(revid)
396
            except errors.NoSuchRevision:
397
                return None
0.252.4 by Jelmer Vernooij
More work on roundtripping.
398
        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.
399
            roundtrip, verifiers)
0.238.7 by Jelmer Vernooij
Cope with ghosts a bit better.
400
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
401
    def _create_fileid_map_blob(self, inv):
402
        # FIXME: This can probably be a lot more efficient, 
403
        # not all files necessarily have to be processed.
404
        file_ids = {}
405
        for (path, ie) in inv.iter_entries():
406
            if self.mapping.generate_file_id(path) != ie.file_id:
407
                file_ids[path] = ie.file_id
408
        return self.mapping.export_fileid_map(file_ids)
409
0.252.4 by Jelmer Vernooij
More work on roundtripping.
410
    def _revision_to_objects(self, rev, tree, roundtrip):
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
411
        """Convert a revision to a set of git objects.
412
413
        :param rev: Bazaar revision object
414
        :param tree: Bazaar revision tree
415
        :param roundtrip: Whether to roundtrip all Bazaar revision data
416
        """
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
417
        unusual_modes = extract_unusual_modes(rev)
0.200.789 by Jelmer Vernooij
Cope with ghosts, cache inventories.
418
        present_parents = self.repository.has_revisions(rev.parent_ids)
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
419
        parent_trees = self.tree_cache.revision_trees(
0.200.797 by Jelmer Vernooij
Add docstring, fix formatting.
420
            [p for p in rev.parent_ids if p in present_parents])
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
421
        root_tree = None
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
422
        for path, obj, ie in _tree_to_objects(tree, parent_trees,
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
423
                self._cache.idmap, unusual_modes, self.mapping.BZR_DUMMY_FILE):
0.200.773 by Jelmer Vernooij
Implement inventory_to_objects
424
            if path == "":
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
425
                root_tree = obj
0.252.34 by Jelmer Vernooij
Yield the proper object for the tree root.
426
                root_ie = ie
427
                # Don't yield just yet
428
            else:
429
                yield path, obj, ie
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
430
        if root_tree is None:
0.250.2 by Jelmer Vernooij
Make it work for evolution.
431
            # Pointless commit - get the tree sha elsewhere
0.200.864 by Jelmer Vernooij
Cope with the first commit being pointless.
432
            if not rev.parent_ids:
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
433
                root_tree = Tree()
0.200.864 by Jelmer Vernooij
Cope with the first commit being pointless.
434
            else:
435
                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.
436
                root_tree = self[self[base_sha1].tree]
0.252.35 by Jelmer Vernooij
Ignore control files in inventories.
437
            root_ie = tree.inventory.root
0.200.915 by Jelmer Vernooij
Cope with the fact that the old format didn't export file ids.
438
        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.
439
            b = self._create_fileid_map_blob(tree.inventory)
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
440
            if b is not None:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
441
                root_tree[self.mapping.BZR_FILE_IDS_FILE] = (
442
                    (stat.S_IFREG | 0644), b.id)
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
443
                yield self.mapping.BZR_FILE_IDS_FILE, b, None
0.252.34 by Jelmer Vernooij
Yield the proper object for the tree root.
444
        yield "", root_tree, root_ie
0.200.1023 by Jelmer Vernooij
Set and verify testament.
445
        if roundtrip:
0.200.1195 by Jelmer Vernooij
Cope with new StrictTestament3 arguments.
446
            if getattr(StrictTestament3, "from_revision_tree", None):
447
                testament3 = StrictTestament3(rev, tree)
448
            else: # bzr < 2.4
449
                testament3 = StrictTestament3(rev, tree.inventory)
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
450
            verifiers = { "testament3-sha1": testament3.as_sha1() }
0.200.1023 by Jelmer Vernooij
Set and verify testament.
451
        else:
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
452
            verifiers = {}
0.252.43 by Jelmer Vernooij
Some refactoring, support proper file ids in revision deltas.
453
        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.
454
            roundtrip=roundtrip, verifiers=verifiers)
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
455
        try:
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
456
            foreign_revid, mapping = mapping_registry.parse_revision_id(
457
                rev.revision_id)
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
458
        except errors.InvalidRevisionId:
459
            pass
460
        else:
0.200.794 by Jelmer Vernooij
Use _check_expected_sha rather than custom checks.
461
            _check_expected_sha(foreign_revid, commit_obj)
0.200.837 by Jelmer Vernooij
Return inventory entries when creating git objects for a revision.
462
        yield None, commit_obj, None
0.200.783 by Jelmer Vernooij
Move object generation into a separate function.
463
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
464
    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.
465
        return self._cache.get_updater(rev)
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
466
0.200.783 by Jelmer Vernooij
Move object generation into a separate function.
467
    def _update_sha_map_revision(self, revid):
468
        rev = self.repository.get_revision(revid)
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
469
        tree = self.tree_cache.revision_tree(rev.revision_id)
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
470
        updater = self._get_updater(rev)
0.252.4 by Jelmer Vernooij
More work on roundtripping.
471
        for path, obj, ie in self._revision_to_objects(rev, tree,
472
            roundtrip=True):
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
473
            if isinstance(obj, Commit):
0.200.1195 by Jelmer Vernooij
Cope with new StrictTestament3 arguments.
474
                if getattr(StrictTestament3, "from_revision_tree", None):
475
                    testament3 = StrictTestament3(rev, tree)
476
                else: # bzr < 2.4
477
                    testament3 = StrictTestament3(rev, tree.inventory)
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
478
                ie = { "testament3-sha1": testament3.as_sha1() }
0.200.952 by Jelmer Vernooij
Write git pack files rather than loose objects.
479
            updater.add_object(obj, ie, path)
0.200.838 by Jelmer Vernooij
Add convenience object for updating the object store.
480
        commit_obj = updater.finish()
0.200.781 by Jelmer Vernooij
Return commit id after converting a revision.
481
        return commit_obj.id
0.200.229 by Jelmer Vernooij
More work on converter.
482
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
483
    def _reconstruct_blobs(self, keys):
0.200.698 by Jelmer Vernooij
Merge fixes for SHA1s of symlinks.
484
        """Return a Git Blob object from a fileid and revision stored in bzr.
485
486
        :param fileid: File id of the text
487
        :param revision: Revision of the text
488
        """
0.250.2 by Jelmer Vernooij
Make it work for evolution.
489
        stream = self.repository.iter_files_bytes(
490
            ((key[0], key[1], key) for key in keys))
0.200.856 by Jelmer Vernooij
Support reconstructing multiple blobs at the same time.
491
        for (fileid, revision, expected_sha), chunks in stream:
0.200.854 by Jelmer Vernooij
_get_blob -> _get_blobs.
492
            blob = Blob()
493
            blob.chunked = chunks
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
494
            if blob.id != expected_sha and blob.data == "":
0.200.854 by Jelmer Vernooij
_get_blob -> _get_blobs.
495
                # Perhaps it's a symlink ?
496
                tree = self.tree_cache.revision_tree(revision)
497
                entry = tree.inventory[fileid]
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
498
                if entry.kind == 'symlink':
499
                    blob = symlink_to_blob(entry)
0.200.854 by Jelmer Vernooij
_get_blob -> _get_blobs.
500
            _check_expected_sha(expected_sha, blob)
501
            yield blob
0.200.229 by Jelmer Vernooij
More work on converter.
502
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
503
    def _reconstruct_tree(self, fileid, revid, inv, unusual_modes,
504
        expected_sha=None):
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
505
        """Return a Git Tree object from a file id and a revision stored in bzr.
0.200.249 by Jelmer Vernooij
Implement Tree.
506
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
507
        :param fileid: fileid in the tree.
0.200.249 by Jelmer Vernooij
Implement Tree.
508
        :param revision: Revision of the tree.
509
        """
0.200.776 by Jelmer Vernooij
Remove unnecessary lookups.
510
        def get_ie_sha1(entry):
511
            if entry.kind == "directory":
0.200.808 by Jelmer Vernooij
Avoid recalculating tree shas we already have.
512
                try:
0.200.859 by Jelmer Vernooij
Trivial cleanups.
513
                    return self._cache.idmap.lookup_tree_id(entry.file_id,
514
                        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.
515
                except (NotImplementedError, KeyError):
0.200.855 by Jelmer Vernooij
_get_ -> _reconstruct_.
516
                    obj = self._reconstruct_tree(entry.file_id, revid, inv,
0.200.808 by Jelmer Vernooij
Avoid recalculating tree shas we already have.
517
                        unusual_modes)
518
                    if obj is None:
519
                        return None
520
                    else:
521
                        return obj.id
0.200.776 by Jelmer Vernooij
Remove unnecessary lookups.
522
            elif entry.kind in ("file", "symlink"):
0.200.868 by Jelmer Vernooij
Cope with no-change merges.
523
                try:
524
                    return self._cache.idmap.lookup_blob_id(entry.file_id,
525
                        entry.revision)
526
                except KeyError:
527
                    # no-change merge?
528
                    return self._reconstruct_blobs(
529
                        [(entry.file_id, entry.revision, None)]).next().id
0.200.776 by Jelmer Vernooij
Remove unnecessary lookups.
530
            else:
531
                raise AssertionError("unknown entry kind '%s'" % entry.kind)
0.252.30 by Jelmer Vernooij
Support creating dummy files for empty directories.
532
        tree = directory_to_tree(inv[fileid], get_ie_sha1, unusual_modes,
533
            self.mapping.BZR_DUMMY_FILE)
0.200.915 by Jelmer Vernooij
Cope with the fact that the old format didn't export file ids.
534
        if (inv.root.file_id == fileid and
535
            self.mapping.BZR_FILE_IDS_FILE is not None):
0.200.1223 by Jelmer Vernooij
Cope with empty directories.
536
            if tree is None:
537
                tree = Tree()
0.252.49 by Jelmer Vernooij
Avoid trying to set HEAD for remote branches.
538
            b = self._create_fileid_map_blob(inv)
539
            # If this is the root tree, add the file ids
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
540
            tree[self.mapping.BZR_FILE_IDS_FILE] = (
541
                (stat.S_IFREG | 0644), b.id)
0.200.1223 by Jelmer Vernooij
Cope with empty directories.
542
        if tree is not None:
543
            _check_expected_sha(expected_sha, tree)
0.200.249 by Jelmer Vernooij
Implement Tree.
544
        return tree
0.200.229 by Jelmer Vernooij
More work on converter.
545
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
546
    def get_parents(self, sha):
0.200.454 by Jelmer Vernooij
Use ObjectStore.find_missing_objects in server.
547
        """Retrieve the parents of a Git commit by SHA1.
548
549
        :param sha: SHA1 of the commit
550
        :raises: KeyError, NotCommitError
551
        """
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
552
        return self[sha].parents
553
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
554
    def _lookup_revision_sha1(self, revid):
0.200.449 by Jelmer Vernooij
Use BazaarObjectStore to find matching SHA1s for bzr revisions.
555
        """Return the SHA1 matching a Bazaar revision."""
0.200.541 by Jelmer Vernooij
Cope with NULL_REVISION.
556
        if revid == NULL_REVISION:
0.200.891 by Jelmer Vernooij
Use ZERO_SHA constant where possible.
557
            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.
558
        try:
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
559
            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.
560
        except KeyError:
0.200.682 by Jelmer Vernooij
Avoid doing a full sha map update if we already know the SHA1.
561
            try:
562
                return mapping_registry.parse_revision_id(revid)[0]
563
            except errors.InvalidRevisionId:
0.200.1264 by Jelmer Vernooij
Fix updating cache for single revision - don't consider it an update of the full cache.
564
                self._update_sha_map(revid)
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
565
                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.
566
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
567
    def get_raw(self, sha):
0.200.454 by Jelmer Vernooij
Use ObjectStore.find_missing_objects in server.
568
        """Get the raw representation of a Git object by SHA1.
569
570
        :param sha: SHA1 of the git object
571
        """
0.200.566 by Jelmer Vernooij
Fix ObjectStore.get_raw() .
572
        obj = self[sha]
573
        return (obj.type, obj.as_raw_string())
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
574
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
575
    def __contains__(self, sha):
576
        # See if sha is in map
577
        try:
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
578
            for (type, type_data) in self.lookup_git_sha(sha):
579
                if type == "commit":
580
                    if self.repository.has_revision(type_data[0]):
581
                        return True
582
                elif type == "blob":
583
                    if self.repository.texts.has_key(type_data):
584
                        return True
585
                elif type == "tree":
586
                    if self.repository.has_revision(type_data[1]):
587
                        return True
588
                else:
589
                    raise AssertionError("Unknown object type '%s'" % type)
0.200.568 by Jelmer Vernooij
Properly check that matching bzr objects exist.
590
            else:
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
591
                return False
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
592
        except KeyError:
593
            return False
594
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
595
    def lock_read(self):
596
        self._locked = 'r'
597
        self._map_updated = False
598
        self.repository.lock_read()
599
        return LogicalLockResult(self.unlock)
600
601
    def lock_write(self):
602
        self._locked = 'r'
603
        self._map_updated = False
604
        self.repository.lock_write()
605
        return LogicalLockResult(self.unlock)
606
607
    def is_locked(self):
608
        return (self._locked is not None)
609
610
    def unlock(self):
611
        self._locked = None
612
        self._map_updated = False
613
        self.repository.unlock()
614
615
    def lookup_git_shas(self, shas):
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
616
        ret = {}
617
        for sha in shas:
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
618
            if sha == ZERO_SHA:
0.200.1169 by Jelmer Vernooij
Fix some sha lookups.
619
                ret[sha] = [("commit", (NULL_REVISION, None, {}))]
0.200.969 by Jelmer Vernooij
Use tuples with bzr revid and git sha to avoid lookups.
620
                continue
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
621
            try:
0.261.3 by Jelmer Vernooij
Fix more tests.
622
                ret[sha] = list(self._cache.idmap.lookup_git_sha(sha))
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
623
            except KeyError:
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
624
                # if not, see if there are any unconverted revisions and
625
                # add them to the map, search for sha in map again
626
                self._update_sha_map()
627
                try:
628
                    ret[sha] = list(self._cache.idmap.lookup_git_sha(sha))
629
                except KeyError:
630
                    pass
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
631
        return ret
632
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
633
    def lookup_git_sha(self, sha):
634
        return self.lookup_git_shas([sha])[sha]
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
635
636
    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.
637
        if self._cache.content_cache is not None:
0.200.840 by Jelmer Vernooij
Support using content cache.
638
            try:
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
639
                return self._cache.content_cache[sha]
0.200.840 by Jelmer Vernooij
Support using content cache.
640
            except KeyError:
641
                pass
0.200.1169 by Jelmer Vernooij
Fix some sha lookups.
642
        for (kind, type_data) in self.lookup_git_sha(sha):
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
643
            # convert object to git object
0.200.1169 by Jelmer Vernooij
Fix some sha lookups.
644
            if kind == "commit":
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
645
                (revid, tree_sha, verifiers) = type_data
646
                try:
647
                    rev = self.repository.get_revision(revid)
648
                except errors.NoSuchRevision:
0.200.1341 by Jelmer Vernooij
Add check that callers don't try to look up NULL_REVISION.
649
                    if revid == NULL_REVISION:
650
                        raise AssertionError(
651
                            "should not try to look up NULL_REVISION")
0.200.1169 by Jelmer Vernooij
Fix some sha lookups.
652
                    trace.mutter('entry for %s %s in shamap: %r, but not '
653
                                 'found in repository', kind, sha, type_data)
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
654
                    raise KeyError(sha)
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
655
                commit = self._reconstruct_commit(rev, tree_sha,
656
                    roundtrip=True, verifiers=verifiers)
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
657
                _check_expected_sha(sha, commit)
658
                return commit
0.200.1169 by Jelmer Vernooij
Fix some sha lookups.
659
            elif kind == "blob":
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
660
                (fileid, revision) = type_data
0.200.1212 by Jelmer Vernooij
Support read locking object stores.
661
                blobs = self._reconstruct_blobs([(fileid, revision, sha)])
662
                return blobs.next()
0.200.1169 by Jelmer Vernooij
Fix some sha lookups.
663
            elif kind == "tree":
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
664
                (fileid, revid) = type_data
665
                try:
666
                    tree = self.tree_cache.revision_tree(revid)
667
                    rev = self.repository.get_revision(revid)
668
                except errors.NoSuchRevision:
0.200.1319 by Jelmer Vernooij
Only update git cache during post-commit if parents are already in the cache.
669
                    trace.mutter('entry for %s %s in shamap: %r, but not found in '
670
                        'repository', kind, sha, type_data)
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
671
                    raise KeyError(sha)
672
                unusual_modes = extract_unusual_modes(rev)
673
                try:
674
                    return self._reconstruct_tree(fileid, revid,
675
                        tree.inventory, unusual_modes, expected_sha=sha)
676
                except errors.NoSuchRevision:
677
                    raise KeyError(sha)
678
            else:
0.200.1169 by Jelmer Vernooij
Fix some sha lookups.
679
                raise AssertionError("Unknown object type '%s'" % kind)
0.200.228 by Jelmer Vernooij
Split out map.
680
        else:
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
681
            raise KeyError(sha)
0.200.782 by Jelmer Vernooij
Add custom generate_pack_contents implementation.
682
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
683
    def generate_lossy_pack_contents(self, have, want, progress=None,
684
            get_tagged=None):
685
        return self.generate_pack_contents(have, want, progress, get_tagged,
686
            lossy=True)
687
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
688
    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.
689
            get_tagged=None, lossy=False):
0.200.782 by Jelmer Vernooij
Add custom generate_pack_contents implementation.
690
        """Iterate over the contents of a pack file.
691
692
        :param have: List of SHA1s of objects that should not be sent
693
        :param want: List of SHA1s of objects that should be sent
694
        """
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
695
        processed = set()
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
696
        ret = self.lookup_git_shas(have + want)
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
697
        for commit_sha in have:
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
698
            commit_sha = self.unpeel_map.peel_tag(commit_sha, commit_sha)
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
699
            try:
0.200.1180 by Jelmer Vernooij
Some dpush fixes.
700
                for (type, type_data) in ret[commit_sha]:
701
                    assert type == "commit"
702
                    processed.add(type_data[0])
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
703
            except KeyError:
0.200.1292 by Jelmer Vernooij
Fix repeeling objects when determining what to send.
704
                trace.mutter("unable to find remote ref %s", commit_sha)
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
705
        pending = set()
706
        for commit_sha in want:
707
            if commit_sha in have:
708
                continue
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
709
            try:
0.200.1180 by Jelmer Vernooij
Some dpush fixes.
710
                for (type, type_data) in ret[commit_sha]:
711
                    assert type == "commit"
712
                    pending.add(type_data[0])
0.200.898 by Jelmer Vernooij
Optimize finding of git shas.
713
            except KeyError:
714
                pass
0.200.899 by Jelmer Vernooij
Add tests for find_missing_bzr_revids.
715
0.200.1053 by Jelmer Vernooij
Fix find_missing_bzr_revids.
716
        graph = self.repository.get_graph()
717
        todo = _find_missing_bzr_revids(graph, pending, processed)
0.200.1290 by Jelmer Vernooij
Avoid storing all objects to push in memory.
718
        ret = PackTupleIterable(self)
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
719
        pb = ui.ui_factory.nested_progress_bar()
720
        try:
721
            for i, revid in enumerate(todo):
722
                pb.update("generating git objects", i, len(todo))
0.200.1059 by Jelmer Vernooij
Fix graph tests.
723
                try:
724
                    rev = self.repository.get_revision(revid)
725
                except errors.NoSuchRevision:
726
                    continue
0.200.852 by Jelmer Vernooij
Cache trees rather than inventories.
727
                tree = self.tree_cache.revision_tree(revid)
0.252.37 by Jelmer Vernooij
Factor out some common code for finding refs to send.
728
                for path, obj, ie in self._revision_to_objects(rev, tree,
729
                    roundtrip=not lossy):
0.200.1290 by Jelmer Vernooij
Avoid storing all objects to push in memory.
730
                    ret.add(obj.id, path)
0.200.1298 by Jelmer Vernooij
Fix compatibility with newer versions of dulwich.
731
            return ret
0.200.787 by Jelmer Vernooij
Implement custom ObjectWalker.generate_pack_contents.
732
        finally:
733
            pb.finished()
0.251.1 by Jelmer Vernooij
Implement ObjectStore.add_{thin_,}pack.
734
735
    def add_thin_pack(self):
736
        import tempfile
737
        import os
738
        fd, path = tempfile.mkstemp(suffix=".pack")
739
        f = os.fdopen(fd, 'wb')
740
        def commit():
741
            from dulwich.pack import PackData, Pack
742
            from bzrlib.plugins.git.fetch import import_git_objects
743
            os.fsync(fd)
744
            f.close()
745
            if os.path.getsize(path) == 0:
746
                return
747
            pd = PackData(path)
748
            pd.create_index_v2(path[:-5]+".idx", self.object_store.get_raw)
749
750
            p = Pack(path[:-5])
751
            self.repository.lock_write()
752
            try:
753
                self.repository.start_write_group()
754
                try:
0.200.1289 by Jelmer Vernooij
Switch to dulwich 0.8.0.
755
                    import_git_objects(self.repository, self.mapping,
0.251.1 by Jelmer Vernooij
Implement ObjectStore.add_{thin_,}pack.
756
                        p.iterobjects(get_raw=self.get_raw),
757
                        self.object_store)
758
                except:
759
                    self.repository.abort_write_group()
760
                    raise
761
                else:
762
                    self.repository.commit_write_group()
763
            finally:
764
                self.repository.unlock()
765
        return f, commit
766
767
    # The pack isn't kept around anyway, so no point 
768
    # in treating full packs different from thin packs
769
    add_pack = add_thin_pack