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