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