/brz/remove-bazaar

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