/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
1
# Copyright (C) 2008 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
0.200.158 by Jelmer Vernooij
fetch works \o/
17
from bzrlib import osutils, ui, urlutils
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
18
from bzrlib.errors import InvalidRevisionId
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
19
from bzrlib.inventory import Inventory
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
20
from bzrlib.repository import InterRepository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
21
from bzrlib.trace import info
0.200.158 by Jelmer Vernooij
fetch works \o/
22
from bzrlib.tsort import topo_sort
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
23
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
24
from bzrlib.plugins.git import git
0.200.169 by Jelmer Vernooij
Fix branch cloning.
25
from bzrlib.plugins.git.repository import (
26
        LocalGitRepository, 
27
        GitRepository, 
28
        GitFormat,
29
        )
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
30
from bzrlib.plugins.git.remote import RemoteGitRepository
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
31
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
32
from dulwich.objects import Commit
33
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
34
from cStringIO import StringIO
35
36
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
37
class BzrFetchGraphWalker(object):
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
38
39
    def __init__(self, repository, mapping):
40
        self.repository = repository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
41
        self.mapping = mapping
42
        self.done = set()
43
        self.heads = set(repository.all_revision_ids())
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
44
        self.parents = {}
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
45
46
    def ack(self, sha):
47
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
48
        self.remove(revid)
49
50
    def remove(self, revid):
51
        self.done.add(revid)
52
        if ref in self.heads:
53
            self.heads.remove(revid)
54
        if revid in self.parents:
55
            for p in self.parents[revid]:
56
                self.remove(p)
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
57
58
    def next(self):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
59
        while self.heads:
60
            ret = self.heads.pop()
61
            ps = self.repository.get_parent_map([ret])[ret]
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
62
            self.parents[ret] = ps
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
63
            self.heads.update([p for p in ps if not p in self.done])
64
            try:
65
                self.done.add(ret)
66
                return self.mapping.revision_id_bzr_to_foreign(ret)
67
            except InvalidRevisionId:
68
                pass
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
69
        return None
70
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
71
0.200.159 by Jelmer Vernooij
Fix branch tests.
72
def import_git_blob(repo, mapping, path, blob, inv, parent_invs, executable):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
73
    """Import a git blob object into a bzr repository.
74
75
    :param repo: bzr repository
76
    :param path: Path in the tree
77
    :param blob: A git blob
78
    """
79
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
80
    text_revision = inv.revision_id
81
    repo.texts.add_lines((file_id, text_revision),
82
        [(file_id, p[file_id].revision) for p in parent_invs if file_id in p],
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
83
        osutils.split_lines(blob.data))
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
84
    ie = inv.add_path(path, "file", file_id)
0.200.158 by Jelmer Vernooij
fetch works \o/
85
    ie.revision = text_revision
86
    ie.text_size = len(blob.data)
87
    ie.text_sha1 = osutils.sha_string(blob.data)
0.200.159 by Jelmer Vernooij
Fix branch tests.
88
    ie.executable = executable
0.200.158 by Jelmer Vernooij
fetch works \o/
89
90
91
def import_git_tree(repo, mapping, path, tree, inv, parent_invs, lookup_object):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
92
    """Import a git tree object into a bzr repository.
93
94
    :param repo: A Bzr repository object
95
    :param path: Path in the tree
96
    :param tree: A git tree object
97
    :param inv: Inventory object
98
    """
99
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
100
    text_revision = inv.revision_id
101
    repo.texts.add_lines((file_id, text_revision),
102
        [(file_id, p[file_id].revision) for p in parent_invs if file_id in p],
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
103
        [])
0.200.158 by Jelmer Vernooij
fetch works \o/
104
    ie = inv.add_path(path, "directory", file_id)
105
    ie.revision = text_revision
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
106
    for mode, name, hexsha in tree.entries():
107
        entry_kind = (mode & 0700000) / 0100000
108
        basename = name.decode("utf-8")
109
        if path == "":
110
            child_path = name
111
        else:
112
            child_path = urlutils.join(path, name)
113
        if entry_kind == 0:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
114
            tree = lookup_object(hexsha)
0.200.158 by Jelmer Vernooij
fetch works \o/
115
            import_git_tree(repo, mapping, child_path, tree, inv, parent_invs, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
116
        elif entry_kind == 1:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
117
            blob = lookup_object(hexsha)
0.200.159 by Jelmer Vernooij
Fix branch tests.
118
            fs_mode = mode & 0777
119
            import_git_blob(repo, mapping, child_path, blob, inv, parent_invs, bool(fs_mode & 0111))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
120
        else:
121
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
122
123
0.200.158 by Jelmer Vernooij
fetch works \o/
124
def import_git_objects(repo, mapping, object_iter, pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
125
    """Import a set of git objects into a bzr repository.
126
127
    :param repo: Bazaar repository
128
    :param mapping: Mapping to use
129
    :param object_iter: Iterator over Git objects.
130
    """
131
    # TODO: a more (memory-)efficient implementation of this
132
    objects = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
133
    for i, o in enumerate(object_iter):
134
        if pb is not None:
135
            pb.update("fetching objects", i) 
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
136
        objects[o.id] = o
0.200.158 by Jelmer Vernooij
fetch works \o/
137
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
138
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
139
    revisions = {}
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
140
    # Find and convert commit objects
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
141
    for o in objects.itervalues():
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
142
        if isinstance(o, Commit):
143
            rev = mapping.import_commit(o)
0.200.158 by Jelmer Vernooij
fetch works \o/
144
            root_trees[rev.revision_id] = objects[o.tree]
145
            revisions[rev.revision_id] = rev
146
            graph.append((rev.revision_id, rev.parent_ids))
147
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
148
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
149
    for i, revid in enumerate(topo_sort(graph)):
150
        if pb is not None:
151
            pb.update("fetching revisions", i, len(graph))
152
        root_tree = root_trees[revid]
153
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
154
        # We have to do this here, since we have to walk the tree and 
155
        # we need to make sure to import the blobs / trees with the riht 
156
        # path; this may involve adding them more than once.
157
        inv = Inventory()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
158
        inv.revision_id = rev.revision_id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
159
        def lookup_object(sha):
0.200.153 by Jelmer Vernooij
Merge new dulwich.
160
            if sha in objects:
161
                return objects[sha]
162
            return reconstruct_git_object(repo, mapping, sha)
0.200.158 by Jelmer Vernooij
fetch works \o/
163
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
164
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
165
        repo.add_revision(rev.revision_id, rev, inv)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
166
167
0.200.153 by Jelmer Vernooij
Merge new dulwich.
168
def reconstruct_git_commit(repo, rev):
169
    raise NotImplementedError(self.reconstruct_git_commit)
170
171
172
def reconstruct_git_object(repo, mapping, sha):
173
    # Commit
174
    revid = mapping.revision_id_foreign_to_bzr(sha)
175
    try:
176
        rev = repo.get_revision(revid)
177
    except NoSuchRevision:
178
        pass
179
    else:
180
        return reconstruct_git_commit(rev)
181
182
    # TODO: Tree
183
    # TODO: Blob
184
    raise KeyError("No such object %s" % sha)
185
186
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
187
class InterGitRepository(InterRepository):
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
188
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
189
    _matching_repo_format = GitFormat()
190
191
    @staticmethod
192
    def _get_repo_format_to_test():
193
        return None
194
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
195
    def copy_content(self, revision_id=None, pb=None):
196
        """See InterRepository.copy_content."""
197
        self.fetch(revision_id, pb, find_ghosts=False)
198
199
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
200
              mapping=None):
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
201
        if mapping is None:
202
            mapping = self.source.get_mapping()
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
203
        def progress(text):
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
204
            pb.note("git: %s", text)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
205
        def determine_wants(heads):
206
            if revision_id is None:
207
                ret = heads.values()
208
            else:
209
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)]
0.200.147 by Jelmer Vernooij
Merge new dulwich; fetching objects from local repository works now; they aren't converted yet though.
210
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
211
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
212
        create_pb = None
213
        if pb is None:
214
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
215
        try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
216
            self.target.lock_write()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
217
            try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
218
                self.target.start_write_group()
219
                try:
220
                    import_git_objects(self.target, mapping,
221
                        iter(self.source.fetch_objects(determine_wants, graph_walker, 
222
                            progress)), pb)
223
                finally:
224
                    self.target.commit_write_group()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
225
            finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
226
                self.target.unlock()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
227
        finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
228
            if create_pb:
229
                create_pb.finished()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
230
231
    @staticmethod
232
    def is_compatible(source, target):
233
        """Be compatible with GitRepository."""
234
        # FIXME: Also check target uses VersionedFile
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
235
        return (isinstance(source, GitRepository) and 
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
236
                target.supports_rich_root())