/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to object_store.py

Avoid using file ids in object store code.

Merged from https://code.launchpad.net/~jelmer/brz-git/no-push-file-ids/+merge/342827

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
    )
32
32
from dulwich.pack import (
33
33
    pack_objects_to_data,
 
34
    PackData,
 
35
    Pack,
34
36
    )
35
37
 
36
38
from ... import (
37
39
    errors,
38
40
    lru_cache,
39
41
    trace,
 
42
    osutils,
40
43
    ui,
41
44
    urlutils,
42
45
    )
53
56
    )
54
57
from .mapping import (
55
58
    default_mapping,
56
 
    directory_to_tree,
 
59
    entry_mode,
57
60
    extract_unusual_modes,
58
61
    mapping_registry,
59
62
    symlink_to_blob,
168
171
            expected_sha))
169
172
 
170
173
 
 
174
def directory_to_tree(path, children, lookup_ie_sha1, unusual_modes, empty_file_name,
 
175
                      allow_empty=False):
 
176
    """Create a Git Tree object from a Bazaar directory.
 
177
 
 
178
    :param path: directory path
 
179
    :param children: Children inventory entries
 
180
    :param lookup_ie_sha1: Lookup the Git SHA1 for a inventory entry
 
181
    :param unusual_modes: Dictionary with unusual file modes by file ids
 
182
    :param empty_file_name: Name to use for dummy files in empty directories,
 
183
        None to ignore empty directories.
 
184
    """
 
185
    tree = Tree()
 
186
    for value in children:
 
187
        child_path = osutils.pathjoin(path, value.name)
 
188
        try:
 
189
            mode = unusual_modes[child_path]
 
190
        except KeyError:
 
191
            mode = entry_mode(value)
 
192
        hexsha = lookup_ie_sha1(child_path, value)
 
193
        if hexsha is not None:
 
194
            tree.add(value.name.encode("utf-8"), mode, hexsha)
 
195
    if not allow_empty and len(tree) == 0:
 
196
        # Only the root can be an empty tree
 
197
        if empty_file_name is not None:
 
198
            tree.add(empty_file_name, stat.S_IFREG | 0644, Blob().id)
 
199
        else:
 
200
            return None
 
201
    return tree
 
202
 
 
203
 
171
204
def _tree_to_objects(tree, parent_trees, idmap, unusual_modes,
172
205
                     dummy_file_name=None):
173
206
    """Iterate over the objects that were introduced in a revision.
181
214
    """
182
215
    dirty_dirs = set()
183
216
    new_blobs = []
 
217
    new_contents = {}
184
218
    shamap = {}
185
219
    try:
186
220
        base_tree = parent_trees[0]
217
251
                    pass
218
252
                else:
219
253
                    try:
220
 
                        shamap[file_id] = idmap.lookup_blob_id(
 
254
                        shamap[path[1]] = idmap.lookup_blob_id(
221
255
                            pfile_id, prevision)
222
256
                    except KeyError:
223
257
                        # no-change merge ?
224
258
                        blob = Blob()
225
259
                        blob.data = tree.get_file_text(path[1], file_id)
226
 
                        shamap[file_id] = blob.id
227
 
            if not file_id in shamap:
 
260
                        shamap[path[1]] = blob.id
 
261
            if not path[1] in shamap:
228
262
                new_blobs.append((path[1], file_id))
229
263
        elif kind[1] == "symlink":
230
264
            if changed_content:
231
265
                target = tree.get_symlink_target(path[1], file_id)
232
266
                blob = symlink_to_blob(target)
233
 
                shamap[file_id] = blob.id
 
267
                shamap[path[1]] = blob.id
234
268
                try:
235
269
                    find_unchanged_parent_ie(file_id, kind[1], target, other_parent_trees)
236
270
                except KeyError:
237
271
                    yield path[1], blob, (file_id, tree.get_file_revision(path[1], file_id))
238
 
        elif kind[1] not in (None, "directory"):
 
272
        elif kind[1] is None:
 
273
            shamap[path[1]] = None
 
274
        elif kind[1] != 'directory':
239
275
            raise AssertionError(kind[1])
240
 
        for p in parent:
241
 
            if p and tree.has_id(p) and tree.kind(tree.id2path(p)) == "directory":
242
 
                dirty_dirs.add(p)
 
276
        for p in path:
 
277
            if p is None:
 
278
                continue
 
279
            dirty_dirs.add(osutils.dirname(p))
243
280
 
244
281
    # Fetch contents of the blobs that were changed
245
282
    for (path, file_id), chunks in tree.iter_files_bytes(
247
284
        obj = Blob()
248
285
        obj.chunked = chunks
249
286
        yield path, obj, (file_id, tree.get_file_revision(path, file_id))
250
 
        shamap[file_id] = obj.id
 
287
        shamap[path] = obj.id
251
288
 
252
289
    for path in unusual_modes:
253
 
        parent_path = posixpath.dirname(path)
254
 
        file_id = tree.path2id(parent_path)
255
 
        if file_id is None:
256
 
            raise AssertionError("Unable to find file id for %r" % parent_path)
257
 
        dirty_dirs.add(file_id)
258
 
 
259
 
    try:
260
 
        inv = tree.root_inventory
261
 
    except AttributeError:
262
 
        inv = tree.inventory
263
 
 
264
 
    trees = {}
265
 
    while dirty_dirs:
266
 
        new_dirs = set()
267
 
        for file_id in dirty_dirs:
268
 
            if file_id is None or not inv.has_id(file_id):
269
 
                continue
270
 
            trees[inv.id2path(file_id)] = file_id
271
 
            ie = inv.get_entry(file_id)
272
 
            if ie.parent_id is not None:
273
 
                new_dirs.add(ie.parent_id)
274
 
        dirty_dirs = new_dirs
275
 
 
276
 
    def ie_to_hexsha(ie):
277
 
        try:
278
 
            return shamap[ie.file_id]
279
 
        except KeyError:
280
 
            # FIXME: Should be the same as in parent
281
 
            if ie.kind in ("file", "symlink"):
282
 
                try:
283
 
                    return idmap.lookup_blob_id(ie.file_id, ie.revision)
284
 
                except KeyError:
285
 
                    # no-change merge ?
286
 
                    blob = Blob()
287
 
                    path = tree.id2path(ie.file_id)
288
 
                    blob.data = tree.get_file_text(path, ie.file_id)
289
 
                    return blob.id
290
 
            elif ie.kind == "directory":
291
 
                # Not all cache backends store the tree information,
292
 
                # calculate again from scratch
293
 
                ret = directory_to_tree(ie.children, ie_to_hexsha,
294
 
                    unusual_modes, dummy_file_name, ie.parent_id is None)
295
 
                if ret is None:
296
 
                    return ret
297
 
                return ret.id
298
 
            else:
299
 
                raise AssertionError
300
 
 
301
 
    for path in sorted(trees.keys(), reverse=True):
302
 
        file_id = trees[path]
303
 
        if tree.kind(path, file_id) != 'directory':
304
 
            raise AssertionError
305
 
        ie = inv.get_entry(file_id)
306
 
        obj = directory_to_tree(ie.children, ie_to_hexsha, unusual_modes,
307
 
            dummy_file_name, path == "")
 
290
        dirty_dirs.add(posixpath.dirname(path))
 
291
 
 
292
    for dir in list(dirty_dirs):
 
293
        for parent in osutils.parent_directories(dir):
 
294
            if parent in dirty_dirs:
 
295
                break
 
296
            dirty_dirs.add(parent)
 
297
 
 
298
    def ie_to_hexsha(path, ie):
 
299
        # FIXME: Should be the same as in parent
 
300
        if ie.kind in ("file", "symlink"):
 
301
            try:
 
302
                return idmap.lookup_blob_id(ie.file_id, ie.revision)
 
303
            except KeyError:
 
304
                # no-change merge ?
 
305
                blob = Blob()
 
306
                blob.data = tree.get_file_text(path, ie.file_id)
 
307
                return blob.id
 
308
        elif ie.kind == "directory":
 
309
            # Not all cache backends store the tree information,
 
310
            # calculate again from scratch
 
311
            ret = directory_to_tree(path, ie.children.values(), ie_to_hexsha,
 
312
                unusual_modes, dummy_file_name, ie.parent_id is None)
 
313
            if ret is None:
 
314
                return ret
 
315
            return ret.id
 
316
        else:
 
317
            raise AssertionError
 
318
 
 
319
    for path in sorted(dirty_dirs, reverse=True):
 
320
        if tree.kind(path) != 'directory':
 
321
            raise AssertionError
 
322
 
 
323
        obj = Tree()
 
324
        for value in tree.iter_child_entries(path):
 
325
            child_path = osutils.pathjoin(path, value.name)
 
326
            try:
 
327
                mode = unusual_modes[child_path]
 
328
            except KeyError:
 
329
                mode = entry_mode(value)
 
330
            try:
 
331
                hexsha = shamap[child_path]
 
332
            except KeyError:
 
333
                hexsha = ie_to_hexsha(child_path, value)
 
334
            if hexsha is not None:
 
335
                obj.add(value.name.encode("utf-8"), mode, hexsha)
 
336
 
 
337
        if len(obj) == 0:
 
338
            obj = None
 
339
 
308
340
        if obj is not None:
309
 
            yield path, obj, (file_id, )
310
 
            shamap[file_id] = obj.id
 
341
            yield path, obj, (tree.path2id(path), tree.get_revision_id())
 
342
            shamap[path] = obj.id
311
343
 
312
344
 
313
345
class PackTupleIterable(object):
457
489
            else:
458
490
                base_sha1 = self._lookup_revision_sha1(rev.parent_ids[0])
459
491
                root_tree = self[self[base_sha1].tree]
460
 
            root_key_data = (tree.get_root_id(), )
 
492
            root_key_data = (tree.get_root_id(), tree.get_revision_id())
461
493
        if not lossy and self.mapping.BZR_FILE_IDS_FILE is not None:
462
494
            b = self._create_fileid_map_blob(tree)
463
495
            if b is not None:
524
556
        :param fileid: fileid in the tree.
525
557
        :param revision: Revision of the tree.
526
558
        """
527
 
        def get_ie_sha1(entry):
 
559
        def get_ie_sha1(path, entry):
528
560
            if entry.kind == "directory":
529
561
                try:
530
562
                    return self._cache.idmap.lookup_tree_id(entry.file_id,
549
581
                return self._lookup_revision_sha1(entry.reference_revision)
550
582
            else:
551
583
                raise AssertionError("unknown entry kind '%s'" % entry.kind)
552
 
        try:
553
 
            inv = bzr_tree.root_inventory
554
 
        except AttributeError:
555
 
            inv = bzr_tree.inventory
556
 
        tree = directory_to_tree(inv.get_entry(fileid).children,
 
584
        path = bzr_tree.id2path(fileid)
 
585
        tree = directory_to_tree(
 
586
                path,
 
587
                bzr_tree.iter_child_entries(path),
557
588
                get_ie_sha1, unusual_modes, self.mapping.BZR_DUMMY_FILE,
558
589
                bzr_tree.get_root_id() == fileid)
559
590
        if (bzr_tree.get_root_id() == fileid and
768
799
        fd, path = tempfile.mkstemp(suffix=".pack")
769
800
        f = os.fdopen(fd, 'wb')
770
801
        def commit():
771
 
            from dulwich.pack import PackData, Pack
772
802
            from .fetch import import_git_objects
773
803
            os.fsync(fd)
774
804
            f.close()