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