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

Share more infrastructure between LocalGitDir and RemoteGitDir.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
from bzrlib import osutils, urlutils
18
17
from bzrlib.errors import InvalidRevisionId
19
 
from bzrlib.inventory import Inventory
20
18
from bzrlib.repository import InterRepository
21
19
from bzrlib.trace import info
22
20
 
23
 
from bzrlib.plugins.git import git
24
21
from bzrlib.plugins.git.repository import LocalGitRepository, GitRepository, GitFormat
25
22
from bzrlib.plugins.git.remote import RemoteGitRepository
26
23
 
27
 
from dulwich.objects import Commit
28
 
 
29
24
from cStringIO import StringIO
30
25
 
31
26
 
64
59
        return None
65
60
 
66
61
 
67
 
def import_git_blob(repo, mapping, path, blob, inv):
68
 
    """Import a git blob object into a bzr repository.
69
 
 
70
 
    :param repo: bzr repository
71
 
    :param path: Path in the tree
72
 
    :param blob: A git blob
73
 
    """
74
 
    file_id = mapping.generate_file_id(path)
75
 
    repo.texts.add_lines((file_id, blob.id),
76
 
        [], #FIXME 
77
 
        osutils.split_lines(blob.data))
78
 
    ie = inv.add_path(path, "file", file_id)
79
 
 
80
 
 
81
 
def import_git_tree(repo, mapping, path, tree, inv, lookup_object):
82
 
    """Import a git tree object into a bzr repository.
83
 
 
84
 
    :param repo: A Bzr repository object
85
 
    :param path: Path in the tree
86
 
    :param tree: A git tree object
87
 
    :param inv: Inventory object
88
 
    """
89
 
    file_id = mapping.generate_file_id(path)
90
 
    repo.texts.add_lines((file_id, tree.id),
91
 
        [], #FIXME 
92
 
        [])
93
 
    inv.add_path(path, "directory", file_id)
94
 
    for mode, name, hexsha in tree.entries():
95
 
        entry_kind = (mode & 0700000) / 0100000
96
 
        basename = name.decode("utf-8")
97
 
        if path == "":
98
 
            child_path = name
99
 
        else:
100
 
            child_path = urlutils.join(path, name)
101
 
        if entry_kind == 0:
102
 
            tree = lookup_object(hexsha)
103
 
            import_git_tree(repo, mapping, child_path, tree, inv, lookup_object)
104
 
        elif entry_kind == 1:
105
 
            blob = lookup_object(hexsha)
106
 
            import_git_blob(repo, mapping, child_path, blob, inv)
107
 
        else:
108
 
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
109
 
 
110
 
 
111
 
def import_git_objects(repo, mapping, object_iter):
112
 
    """Import a set of git objects into a bzr repository.
113
 
 
114
 
    :param repo: Bazaar repository
115
 
    :param mapping: Mapping to use
116
 
    :param object_iter: Iterator over Git objects.
117
 
    """
118
 
    # TODO: a more (memory-)efficient implementation of this
119
 
    objects = {}
120
 
    for o in object_iter:
121
 
        objects[o.id] = o
122
 
    root_trees = {}
123
 
    # Find and convert commit objects
124
 
    for o in objects.itervalues():
125
 
        if isinstance(o, Commit):
126
 
            rev = mapping.import_commit(o)
127
 
            root_trees[rev] = objects[o.tree]
128
 
    # Create the inventory objects
129
 
    for rev, root_tree in root_trees.iteritems():
130
 
        # We have to do this here, since we have to walk the tree and 
131
 
        # we need to make sure to import the blobs / trees with the riht 
132
 
        # path; this may involve adding them more than once.
133
 
        inv = Inventory()
134
 
        inv.revision_id = rev.revision_id
135
 
        def lookup_object(sha):
136
 
            if sha in objects:
137
 
                return objects[sha]
138
 
            return reconstruct_git_object(repo, mapping, sha)
139
 
        import_git_tree(repo, mapping, "", root_tree, inv, lookup_object)
140
 
        repo.add_revision(rev.revision_id, rev, inv)
141
 
 
142
 
 
143
 
def reconstruct_git_commit(repo, rev):
144
 
    raise NotImplementedError(self.reconstruct_git_commit)
145
 
 
146
 
 
147
 
def reconstruct_git_object(repo, mapping, sha):
148
 
    # Commit
149
 
    revid = mapping.revision_id_foreign_to_bzr(sha)
150
 
    try:
151
 
        rev = repo.get_revision(revid)
152
 
    except NoSuchRevision:
153
 
        pass
154
 
    else:
155
 
        return reconstruct_git_commit(rev)
156
 
 
157
 
    # TODO: Tree
158
 
    # TODO: Blob
159
 
    raise KeyError("No such object %s" % sha)
 
62
def import_git_object(repo, object):
 
63
    raise NotImplementedError(import_git_object)
160
64
 
161
65
 
162
66
class InterGitRepository(InterRepository):
189
93
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
190
94
        self.target.lock_write()
191
95
        try:
192
 
            self.target.start_write_group()
193
 
            try:
194
 
                import_git_objects(self.target, mapping,
195
 
                    iter(self.source.fetch_objects(determine_wants, graph_walker, 
196
 
                        progress)))
197
 
            finally:
198
 
                self.target.commit_write_group()
 
96
            for o in self.source.fetch_objects(determine_wants, graph_walker, progress):
 
97
                import_git_object(o)
199
98
        finally:
200
99
            self.target.unlock()
201
100
 
203
102
    def is_compatible(source, target):
204
103
        """Be compatible with GitRepository."""
205
104
        # FIXME: Also check target uses VersionedFile
206
 
        return (isinstance(source, LocalGitRepository) and 
207
 
                target.supports_rich_root())
 
105
        return isinstance(source, LocalGitRepository) and target.supports_rich_root()