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