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