/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.226 by Jelmer Vernooij
Merge thin-pack work.
18
from bzrlib.errors import InvalidRevisionId, NoSuchRevision
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.169 by Jelmer Vernooij
Fix branch cloning.
24
from bzrlib.plugins.git.repository import (
25
        LocalGitRepository, 
26
        GitRepository, 
27
        GitFormat,
28
        )
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
29
from bzrlib.plugins.git.shamap import GitObjectConverter
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.193 by Jelmer Vernooij
Cope with newer *system* dulwich
32
import dulwich as git
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
33
from dulwich.client import SimpleFetchGraphWalker
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
34
from dulwich.objects import Commit
35
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
36
from cStringIO import StringIO
37
38
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
39
class BzrFetchGraphWalker(object):
0.200.196 by Jelmer Vernooij
Add simple tests and docstrings for GraphWalker.
40
    """GraphWalker implementation that uses a Bazaar repository."""
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
41
42
    def __init__(self, repository, mapping):
43
        self.repository = repository
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
44
        self.mapping = mapping
45
        self.done = set()
46
        self.heads = set(repository.all_revision_ids())
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
47
        self.parents = {}
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
48
0.200.196 by Jelmer Vernooij
Add simple tests and docstrings for GraphWalker.
49
    def __iter__(self):
50
        return iter(self.next, None)
51
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
52
    def ack(self, sha):
53
        revid = self.mapping.revision_id_foreign_to_bzr(sha)
54
        self.remove(revid)
55
56
    def remove(self, revid):
57
        self.done.add(revid)
0.200.177 by Jelmer Vernooij
Add git-import command.
58
        if revid in self.heads:
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
59
            self.heads.remove(revid)
60
        if revid in self.parents:
61
            for p in self.parents[revid]:
62
                self.remove(p)
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
63
64
    def next(self):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
65
        while self.heads:
66
            ret = self.heads.pop()
67
            ps = self.repository.get_parent_map([ret])[ret]
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
68
            self.parents[ret] = ps
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
69
            self.heads.update([p for p in ps if not p in self.done])
70
            try:
71
                self.done.add(ret)
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
72
                return self.mapping.revision_id_bzr_to_foreign(ret)[0]
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
73
            except InvalidRevisionId:
74
                pass
0.216.4 by Jelmer Vernooij
Add basic pack fetch infrastructure.
75
        return None
76
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
77
0.200.159 by Jelmer Vernooij
Fix branch tests.
78
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.
79
    """Import a git blob object into a bzr repository.
80
81
    :param repo: bzr repository
82
    :param path: Path in the tree
83
    :param blob: A git blob
84
    """
85
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
86
    text_revision = inv.revision_id
87
    repo.texts.add_lines((file_id, text_revision),
88
        [(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.
89
        osutils.split_lines(blob.data))
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
90
    ie = inv.add_path(path, "file", file_id)
0.200.158 by Jelmer Vernooij
fetch works \o/
91
    ie.revision = text_revision
92
    ie.text_size = len(blob.data)
93
    ie.text_sha1 = osutils.sha_string(blob.data)
0.200.159 by Jelmer Vernooij
Fix branch tests.
94
    ie.executable = executable
0.200.158 by Jelmer Vernooij
fetch works \o/
95
96
97
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.
98
    """Import a git tree object into a bzr repository.
99
100
    :param repo: A Bzr repository object
101
    :param path: Path in the tree
102
    :param tree: A git tree object
103
    :param inv: Inventory object
104
    """
105
    file_id = mapping.generate_file_id(path)
0.200.158 by Jelmer Vernooij
fetch works \o/
106
    text_revision = inv.revision_id
107
    repo.texts.add_lines((file_id, text_revision),
108
        [(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.
109
        [])
0.200.158 by Jelmer Vernooij
fetch works \o/
110
    ie = inv.add_path(path, "directory", file_id)
111
    ie.revision = text_revision
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
112
    for mode, name, hexsha in tree.entries():
113
        entry_kind = (mode & 0700000) / 0100000
114
        basename = name.decode("utf-8")
115
        if path == "":
116
            child_path = name
117
        else:
118
            child_path = urlutils.join(path, name)
119
        if entry_kind == 0:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
120
            tree = lookup_object(hexsha)
0.200.158 by Jelmer Vernooij
fetch works \o/
121
            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.
122
        elif entry_kind == 1:
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
123
            blob = lookup_object(hexsha)
0.200.159 by Jelmer Vernooij
Fix branch tests.
124
            fs_mode = mode & 0777
125
            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.
126
        else:
127
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
128
129
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
130
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
131
        pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
132
    """Import a set of git objects into a bzr repository.
133
134
    :param repo: Bazaar repository
135
    :param mapping: Mapping to use
136
    :param object_iter: Iterator over Git objects.
137
    """
138
    # TODO: a more (memory-)efficient implementation of this
0.200.158 by Jelmer Vernooij
fetch works \o/
139
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
140
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
141
    revisions = {}
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
142
    # Find and convert commit objects
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
143
    for o in object_iter.iterobjects():
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
144
        if isinstance(o, Commit):
145
            rev = mapping.import_commit(o)
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
146
            root_trees[rev.revision_id] = object_iter[o.tree]
0.200.158 by Jelmer Vernooij
fetch works \o/
147
            revisions[rev.revision_id] = rev
148
            graph.append((rev.revision_id, rev.parent_ids))
149
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
150
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
151
    for i, revid in enumerate(topo_sort(graph)):
152
        if pb is not None:
153
            pb.update("fetching revisions", i, len(graph))
154
        root_tree = root_trees[revid]
155
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
156
        # We have to do this here, since we have to walk the tree and 
157
        # we need to make sure to import the blobs / trees with the riht 
158
        # path; this may involve adding them more than once.
159
        inv = Inventory()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
160
        inv.revision_id = rev.revision_id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
161
        def lookup_object(sha):
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
162
            if sha in object_iter:
163
                return object_iter[sha]
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
164
            return target_git_object_retriever(sha)
0.200.158 by Jelmer Vernooij
fetch works \o/
165
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
0.200.170 by Jelmer Vernooij
Merge new dulwich.
166
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
167
            lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
168
        repo.add_revision(rev.revision_id, rev, inv)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
169
170
0.200.153 by Jelmer Vernooij
Merge new dulwich.
171
def reconstruct_git_object(repo, mapping, sha):
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
172
    import pdb; pdb.set_trace()
0.200.153 by Jelmer Vernooij
Merge new dulwich.
173
174
    # TODO: Tree
175
    # TODO: Blob
176
    raise KeyError("No such object %s" % sha)
177
178
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
179
class InterGitNonGitRepository(InterRepository):
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
180
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
181
    _matching_repo_format = GitFormat()
182
183
    @staticmethod
184
    def _get_repo_format_to_test():
185
        return None
186
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
187
    def copy_content(self, revision_id=None, pb=None):
188
        """See InterRepository.copy_content."""
189
        self.fetch(revision_id, pb, find_ghosts=False)
190
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
191
    def fetch_objects(self, determine_wants, mapping, pb=None):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
192
        def progress(text):
0.217.41 by John Carr
Don't fill screen with muttering
193
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
194
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
195
        create_pb = None
196
        if pb is None:
197
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
198
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
199
        
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
200
        try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
201
            self.target.lock_write()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
202
            try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
203
                self.target.start_write_group()
204
                try:
0.200.216 by Jelmer Vernooij
Use ObjectIterator interface.
205
                    objects_iter = self.source.fetch_objects(determine_wants, 
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
206
                                graph_walker, 
207
                                target_git_object_retriever.__getitem__, 
208
                                progress)
209
                    import_git_objects(self.target, mapping, objects_iter, 
210
                            target_git_object_retriever, pb)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
211
                finally:
212
                    self.target.commit_write_group()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
213
            finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
214
                self.target.unlock()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
215
        finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
216
            if create_pb:
217
                create_pb.finished()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
218
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
219
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
220
              mapping=None):
221
        if mapping is None:
222
            mapping = self.source.get_mapping()
223
        def determine_wants(heads):
224
            if revision_id is None:
225
                ret = heads.values()
226
            else:
227
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
228
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
229
        return self.fetch_objects(determine_wants, mapping, pb)
230
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
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.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
236
                target.supports_rich_root() and
237
                not isinstance(target, GitRepository))
238
239
240
class InterGitRepository(InterRepository):
241
242
    _matching_repo_format = GitFormat()
243
244
    @staticmethod
245
    def _get_repo_format_to_test():
246
        return None
247
248
    def copy_content(self, revision_id=None, pb=None):
249
        """See InterRepository.copy_content."""
250
        self.fetch(revision_id, pb, find_ghosts=False)
251
252
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
253
              mapping=None):
254
        if mapping is None:
255
            mapping = self.source.get_mapping()
256
        def progress(text):
257
            info("git: %s", text)
258
        r = self.target._git
259
        if revision_id is None:
260
            determine_wants = lambda x: [y for y in x.values() if not y in r.object_store]
261
        else:
0.200.195 by Jelmer Vernooij
Return mapping in revision_id_bzr_to_foreign() as required by the interface.
262
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
263
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
264
265
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
266
        f, commit = r.object_store.add_pack()
267
        try:
268
            self.source._git.fetch_pack(path, determine_wants, graphwalker, f.write, progress)
269
            f.close()
270
            commit()
271
        except:
272
            f.close()
273
            raise
274
275
    @staticmethod
276
    def is_compatible(source, target):
277
        """Be compatible with GitRepository."""
278
        return (isinstance(source, GitRepository) and 
279
                isinstance(target, GitRepository))