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