/brz/remove-bazaar

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