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