/brz/remove-bazaar

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