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