/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 converter.py

Fix tests now that the tree import function returns a tuple.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009 Canonical Ltd
 
1
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
16
16
 
17
17
"""Map from Git sha's to Bazaar objects."""
18
18
 
19
 
import bzrlib
20
 
 
21
 
from bzrlib import ui
22
 
 
23
 
from bzrlib.errors import NoSuchRevision
 
19
from dulwich.objects import (
 
20
    Blob,
 
21
    Tree,
 
22
    )
 
23
import stat
 
24
 
 
25
from bzrlib import (
 
26
    errors,
 
27
    ui,
 
28
    )
24
29
 
25
30
from bzrlib.plugins.git.mapping import (
26
31
    inventory_to_tree_and_blobs,
 
32
    mapping_registry,
27
33
    revision_to_commit,
28
34
    )
29
 
from bzrlib.plugins.git.shamap import GitShaMap
30
 
 
31
 
from dulwich.objects import (
32
 
    Blob,
 
35
from bzrlib.plugins.git.shamap import (
 
36
    SqliteGitShaMap,
33
37
    )
34
38
 
35
39
 
36
 
class GitObjectConverter(object):
 
40
class BazaarObjectStore(object):
 
41
    """A Git-style object store backed onto a Bazaar repository."""
37
42
 
38
43
    def __init__(self, repository, mapping=None):
39
44
        self.repository = repository
41
46
            self.mapping = self.repository.get_mapping()
42
47
        else:
43
48
            self.mapping = mapping
44
 
        self._idmap = GitShaMap(self.repository._transport)
 
49
        self._idmap = SqliteGitShaMap(self.repository._transport)
45
50
 
46
51
    def _update_sha_map(self):
47
52
        all_revids = self.repository.all_revision_ids()
48
53
        graph = self.repository.get_graph()
49
54
        present_revids = set(self._idmap.revids())
 
55
        missing_revids = [revid for revid in graph.iter_topo_order(all_revids) if revid not in present_revids]
50
56
        pb = ui.ui_factory.nested_progress_bar()
51
57
        try:
52
 
            for i, revid in enumerate(graph.iter_topo_order(all_revids)):
53
 
                if revid in present_revids:
54
 
                    continue
55
 
                pb.update("updating git map", i, len(all_revids))
 
58
            for i, revid in enumerate(missing_revids):
 
59
                pb.update("updating git map", i, len(missing_revids))
56
60
                self._update_sha_map_revision(revid)
57
61
        finally:
 
62
            self._idmap.commit()
58
63
            pb.finished()
59
64
 
60
65
    def _update_sha_map_revision(self, revid):
61
66
        inv = self.repository.get_inventory(revid)
62
 
        objects = inventory_to_tree_and_blobs(self.repository, self.mapping, revid)
 
67
        objects = inventory_to_tree_and_blobs(self.repository, self.mapping,
 
68
            revid)
63
69
        for sha, o, path in objects:
64
70
            if path == "":
65
71
                tree_sha = sha
66
72
            ie = inv[inv.path2id(path)]
67
73
            if ie.kind in ("file", "symlink"):
68
 
                self._idmap.add_entry(sha, "blob", (ie.file_id, ie.revision))
 
74
                git_kind = "blob"
 
75
            elif ie.kind == "directory":
 
76
                git_kind = "tree"
69
77
            else:
70
 
                self._idmap.add_entry(sha, "tree", (ie.file_id, ie.revision))
 
78
                raise AssertionError()
 
79
            self._idmap.add_entry(sha, git_kind, (ie.file_id, ie.revision))
71
80
        rev = self.repository.get_revision(revid)
72
 
        commit_obj = revision_to_commit(rev, tree_sha, self._idmap._parent_lookup)
73
 
        self._idmap.add_entry(commit_obj.sha().hexdigest(), "commit", (revid, tree_sha))
 
81
        commit_obj = revision_to_commit(rev, tree_sha,
 
82
            self._idmap._parent_lookup)
 
83
        try:
 
84
            foreign_revid, mapping = mapping_registry.parse_revision_id(revid)
 
85
        except errors.InvalidRevisionId:
 
86
            pass
 
87
        else:
 
88
            if foreign_revid != commit_obj.id:
 
89
                raise AssertionError("recreated git commit had different sha1: expected %s, got %s" % (foreign_revid, commit_obj.id))
 
90
        self._idmap.add_entry(commit_obj.id, "commit", (revid, tree_sha))
74
91
 
75
92
    def _get_blob(self, fileid, revision):
76
 
        text = self.repository.texts.get_record_stream([(fileid, revision)], "unordered", True).next().get_bytes_as("fulltext")
 
93
        """Return a Git Blob object from a fileid and revision stored in bzr.
 
94
        
 
95
        :param fileid: File id of the text
 
96
        :param revision: Revision of the text
 
97
        """
 
98
        text = self.repository.texts.get_record_stream([(fileid, revision)],
 
99
            "unordered", True).next().get_bytes_as("fulltext")
77
100
        blob = Blob()
78
101
        blob._text = text
79
102
        return blob
80
103
 
81
 
    def _get_tree(self, fileid, revid):
82
 
        raise NotImplementedError(self._get_tree)
 
104
    def _get_tree(self, fileid, revid, inv=None):
 
105
        """Return a Git Tree object from a file id and a revision stored in bzr.
 
106
 
 
107
        :param fileid: fileid in the tree.
 
108
        :param revision: Revision of the tree.
 
109
        """
 
110
        if inv is None:
 
111
            inv = self.repository.get_inventory(revid)
 
112
        tree = Tree()
 
113
        for name, ie in inv[fileid].children.iteritems():
 
114
            if ie.kind == "directory":
 
115
                subtree = self._get_tree(ie.file_id, revid, inv)
 
116
                tree.add(stat.S_IFDIR, name.encode('UTF-8'), subtree.id)
 
117
            elif ie.kind == "file":
 
118
                blob = self._get_blob(ie.file_id, ie.revision)
 
119
                mode = stat.S_IFREG | 0644
 
120
                if ie.executable:
 
121
                    mode |= 0111
 
122
                tree.add(mode, name.encode('UTF-8'), blob.id)
 
123
            elif ie.kind == "symlink":
 
124
                raise AssertionError("Symlinks not yet supported")
 
125
        tree.serialize()
 
126
        return tree
83
127
 
84
128
    def _get_commit(self, revid, tree_sha):
85
129
        rev = self.repository.get_revision(revid)
86
130
        return revision_to_commit(rev, tree_sha, self._idmap._parent_lookup)
87
131
 
 
132
    def get_raw(self, sha):
 
133
        obj = self[sha]
 
134
        assert obj.id == sha
 
135
        return obj._text
 
136
 
88
137
    def __getitem__(self, sha):
89
138
        # See if sha is in map
90
139
        try: