/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.264 by Jelmer Vernooij
Add more tests.
136
    shagitmap.add_entry(tree.sha().hexdigest(), "tree",
0.200.261 by Jelmer Vernooij
More formatting fixes.
137
        (file_id, text_revision))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
138
    for mode, name, hexsha in tree.entries():
139
        entry_kind = (mode & 0700000) / 0100000
140
        basename = name.decode("utf-8")
141
        if path == "":
142
            child_path = name
143
        else:
144
            child_path = urlutils.join(path, name)
0.200.264 by Jelmer Vernooij
Add more tests.
145
        obj = lookup_object(hexsha)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
146
        if entry_kind == 0:
0.200.264 by Jelmer Vernooij
Add more tests.
147
            import_git_tree(texts, mapping, child_path, obj, inv, parent_invs,
148
                shagitmap, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
149
        elif entry_kind == 1:
0.200.159 by Jelmer Vernooij
Fix branch tests.
150
            fs_mode = mode & 0777
0.200.264 by Jelmer Vernooij
Add more tests.
151
            import_git_blob(texts, mapping, child_path, obj, inv, parent_invs,
152
                shagitmap, bool(fs_mode & 0111))
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
153
        else:
154
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
155
156
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
157
def import_git_objects(repo, mapping, object_iter, target_git_object_retriever, 
158
        pb=None):
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
159
    """Import a set of git objects into a bzr repository.
160
161
    :param repo: Bazaar repository
162
    :param mapping: Mapping to use
163
    :param object_iter: Iterator over Git objects.
164
    """
165
    # TODO: a more (memory-)efficient implementation of this
0.200.158 by Jelmer Vernooij
fetch works \o/
166
    graph = []
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
167
    root_trees = {}
0.200.158 by Jelmer Vernooij
fetch works \o/
168
    revisions = {}
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
169
    # Find and convert commit objects
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
170
    for o in object_iter.iterobjects():
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
171
        if isinstance(o, Commit):
172
            rev = mapping.import_commit(o)
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
173
            root_trees[rev.revision_id] = object_iter[o.tree]
0.200.158 by Jelmer Vernooij
fetch works \o/
174
            revisions[rev.revision_id] = rev
175
            graph.append((rev.revision_id, rev.parent_ids))
0.200.261 by Jelmer Vernooij
More formatting fixes.
176
            target_git_object_retriever._idmap.add_entry(o.sha().hexdigest(),
177
                "commit", (rev.revision_id, o._tree))
0.200.158 by Jelmer Vernooij
fetch works \o/
178
    # Order the revisions
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
179
    # Create the inventory objects
0.200.158 by Jelmer Vernooij
fetch works \o/
180
    for i, revid in enumerate(topo_sort(graph)):
181
        if pb is not None:
182
            pb.update("fetching revisions", i, len(graph))
183
        root_tree = root_trees[revid]
184
        rev = revisions[revid]
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
185
        # We have to do this here, since we have to walk the tree and 
186
        # we need to make sure to import the blobs / trees with the riht 
187
        # path; this may involve adding them more than once.
188
        inv = Inventory()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
189
        inv.revision_id = rev.revision_id
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
190
        def lookup_object(sha):
0.200.217 by Jelmer Vernooij
Avoid reading everything into memory when accessing objects.
191
            if sha in object_iter:
192
                return object_iter[sha]
0.200.230 by Jelmer Vernooij
Implement sha cache.
193
            return target_git_object_retriever[sha]
0.200.158 by Jelmer Vernooij
fetch works \o/
194
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
0.200.261 by Jelmer Vernooij
More formatting fixes.
195
        import_git_tree(repo.texts, mapping, "", root_tree, inv, parent_invs, 
0.200.264 by Jelmer Vernooij
Add more tests.
196
            target_git_object_retriever._idmap, lookup_object)
0.200.151 by Jelmer Vernooij
Support converting git objects to bzr objects.
197
        repo.add_revision(rev.revision_id, rev, inv)
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
198
199
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
200
class InterGitNonGitRepository(InterRepository):
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
201
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
202
    _matching_repo_format = GitFormat()
203
204
    @staticmethod
205
    def _get_repo_format_to_test():
206
        return None
207
0.200.135 by Jelmer Vernooij
Add stub for fetching data.
208
    def copy_content(self, revision_id=None, pb=None):
209
        """See InterRepository.copy_content."""
210
        self.fetch(revision_id, pb, find_ghosts=False)
211
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
212
    def fetch_objects(self, determine_wants, mapping, pb=None):
0.200.140 by Jelmer Vernooij
Support negotiating with remote git repository and receiving pack.
213
        def progress(text):
0.217.41 by John Carr
Don't fill screen with muttering
214
            pb.update("git: %s" % text.rstrip("\r\n"), 0, 0)
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
215
        graph_walker = BzrFetchGraphWalker(self.target, mapping)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
216
        create_pb = None
217
        if pb is None:
218
            create_pb = pb = ui.ui_factory.nested_progress_bar()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
219
        target_git_object_retriever = GitObjectConverter(self.target, mapping)
220
        
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
221
        try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
222
            self.target.lock_write()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
223
            try:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
224
                self.target.start_write_group()
225
                try:
0.200.216 by Jelmer Vernooij
Use ObjectIterator interface.
226
                    objects_iter = self.source.fetch_objects(determine_wants, 
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
227
                                graph_walker, 
228
                                target_git_object_retriever.__getitem__, 
229
                                progress)
230
                    import_git_objects(self.target, mapping, objects_iter, 
231
                            target_git_object_retriever, pb)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
232
                finally:
233
                    self.target.commit_write_group()
0.200.157 by Jelmer Vernooij
Fix some bit of fetching.
234
            finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
235
                self.target.unlock()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
236
        finally:
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
237
            if create_pb:
238
                create_pb.finished()
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
239
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
240
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
241
              mapping=None, fetch_spec=None):
0.200.247 by Jelmer Vernooij
Fix git-import.
242
        self.fetch_refs(revision_id=revision_id, pb=pb, find_ghosts=find_ghosts,
243
                mapping=mapping, fetch_spec=fetch_spec)
244
245
    def fetch_refs(self, revision_id=None, pb=None, find_ghosts=False, 
246
              mapping=None, fetch_spec=None):
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
247
        if mapping is None:
248
            mapping = self.source.get_mapping()
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
249
        if revision_id is not None:
250
            interesting_heads = [revision_id]
251
        elif fetch_spec is not None:
252
            interesting_heads = fetch_spec.heads
253
        else:
254
            interesting_heads = None
0.200.247 by Jelmer Vernooij
Fix git-import.
255
        self._refs = {}
256
        def determine_wants(refs):
257
            self._refs = refs
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
258
            if interesting_heads is None:
0.200.247 by Jelmer Vernooij
Fix git-import.
259
                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.
260
            else:
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
261
                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.
262
            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.
263
        self.fetch_objects(determine_wants, mapping, pb)
264
        return self._refs
0.200.225 by Jelmer Vernooij
Implement custom InterBranch to support fetching from remote git branches.
265
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
266
    @staticmethod
267
    def is_compatible(source, target):
268
        """Be compatible with GitRepository."""
269
        # FIXME: Also check target uses VersionedFile
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
270
        return (isinstance(source, GitRepository) and 
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
271
                target.supports_rich_root() and
272
                not isinstance(target, GitRepository))
273
274
275
class InterGitRepository(InterRepository):
276
277
    _matching_repo_format = GitFormat()
278
279
    @staticmethod
280
    def _get_repo_format_to_test():
281
        return None
282
283
    def copy_content(self, revision_id=None, pb=None):
284
        """See InterRepository.copy_content."""
285
        self.fetch(revision_id, pb, find_ghosts=False)
286
287
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
288
              mapping=None, fetch_spec=None):
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
289
        if mapping is None:
290
            mapping = self.source.get_mapping()
291
        def progress(text):
0.200.261 by Jelmer Vernooij
More formatting fixes.
292
            trace.info("git: %s", text)
0.200.175 by Jelmer Vernooij
Add optimized handling when fetching from git to git.
293
        r = self.target._git
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
294
        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.
295
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
296
        elif fetch_spec is not None:
297
            args = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in fetch_spec.heads]
0.200.247 by Jelmer Vernooij
Fix git-import.
298
        if fetch_spec is None and revision_id is None:
299
            determine_wants = r.object_store.determine_wants_all
0.226.2 by Jelmer Vernooij
Cope with new fetch_spec argument.
300
        else:
0.200.247 by Jelmer Vernooij
Fix git-import.
301
            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.
302
303
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)
304
        f, commit = r.object_store.add_pack()
305
        try:
306
            self.source._git.fetch_pack(path, determine_wants, graphwalker, f.write, progress)
307
            f.close()
308
            commit()
309
        except:
310
            f.close()
311
            raise
312
313
    @staticmethod
314
    def is_compatible(source, target):
315
        """Be compatible with GitRepository."""
316
        return (isinstance(source, GitRepository) and 
317
                isinstance(target, GitRepository))