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