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