/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to fetch.py

Merge thin-pack work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
 
1
# Copyright (C) 2008 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
from cStringIO import StringIO
18
 
import dulwich as git
19
 
from dulwich.client import (
20
 
    SimpleFetchGraphWalker,
21
 
    )
22
 
from dulwich.objects import (
23
 
    Commit,
24
 
    )
25
 
 
26
 
from bzrlib import (
27
 
    osutils,
28
 
    trace,
29
 
    ui,
30
 
    urlutils,
31
 
    )
32
 
from bzrlib.errors import (
33
 
    InvalidRevisionId,
34
 
    NoSuchRevision,
35
 
    )
36
 
from bzrlib.inventory import (
37
 
    Inventory,
38
 
    )
39
 
from bzrlib.repository import (
40
 
    InterRepository,
41
 
    )
 
17
from bzrlib import osutils, ui, urlutils
 
18
from bzrlib.errors import InvalidRevisionId, NoSuchRevision
 
19
from bzrlib.inventory import Inventory
 
20
from bzrlib.repository import InterRepository
 
21
from bzrlib.trace import info
42
22
from bzrlib.tsort import topo_sort
43
23
 
44
 
from bzrlib.plugins.git.converter import (
45
 
    GitObjectConverter,
46
 
    )
47
24
from bzrlib.plugins.git.repository import (
48
 
    LocalGitRepository, 
49
 
    GitRepository, 
50
 
    GitFormat,
51
 
    )
52
 
from bzrlib.plugins.git.remote import (
53
 
    RemoteGitRepository,
54
 
    )
 
25
        LocalGitRepository, 
 
26
        GitRepository, 
 
27
        GitFormat,
 
28
        )
 
29
from bzrlib.plugins.git.shamap import GitObjectConverter
 
30
from bzrlib.plugins.git.remote import RemoteGitRepository
 
31
 
 
32
import dulwich as git
 
33
from dulwich.client import SimpleFetchGraphWalker
 
34
from dulwich.objects import Commit
 
35
 
 
36
from cStringIO import StringIO
55
37
 
56
38
 
57
39
class BzrFetchGraphWalker(object):
93
75
        return None
94
76
 
95
77
 
96
 
def import_git_blob(texts, mapping, path, blob, inv, parent_invs, shagitmap,
97
 
    executable):
 
78
def import_git_blob(repo, mapping, path, blob, inv, parent_invs, executable):
98
79
    """Import a git blob object into a bzr repository.
99
80
 
100
 
    :param texts: VersionedFiles to add to
 
81
    :param repo: bzr repository
101
82
    :param path: Path in the tree
102
83
    :param blob: A git blob
103
84
    """
104
85
    file_id = mapping.generate_file_id(path)
105
86
    text_revision = inv.revision_id
106
 
    assert file_id is not None
107
 
    assert text_revision is not None
108
 
    texts.add_lines((file_id, text_revision),
 
87
    repo.texts.add_lines((file_id, text_revision),
109
88
        [(file_id, p[file_id].revision) for p in parent_invs if file_id in p],
110
89
        osutils.split_lines(blob.data))
111
90
    ie = inv.add_path(path, "file", file_id)
113
92
    ie.text_size = len(blob.data)
114
93
    ie.text_sha1 = osutils.sha_string(blob.data)
115
94
    ie.executable = executable
116
 
    shagitmap.add_entry(blob.sha().hexdigest(), "blob",
117
 
        (ie.file_id, ie.revision))
118
 
 
119
 
 
120
 
def import_git_tree(texts, mapping, path, tree, inv, parent_invs, shagitmap,
121
 
    lookup_object):
 
95
 
 
96
 
 
97
def import_git_tree(repo, mapping, path, tree, inv, parent_invs, lookup_object):
122
98
    """Import a git tree object into a bzr repository.
123
99
 
124
 
    :param texts: VersionedFiles object to add to
 
100
    :param repo: A Bzr repository object
125
101
    :param path: Path in the tree
126
102
    :param tree: A git tree object
127
103
    :param inv: Inventory object
128
104
    """
129
105
    file_id = mapping.generate_file_id(path)
130
106
    text_revision = inv.revision_id
131
 
    texts.add_lines((file_id, text_revision),
 
107
    repo.texts.add_lines((file_id, text_revision),
132
108
        [(file_id, p[file_id].revision) for p in parent_invs if file_id in p],
133
109
        [])
134
110
    ie = inv.add_path(path, "directory", file_id)
135
111
    ie.revision = text_revision
136
 
    shagitmap.add_entry(tree.id, "tree", (file_id, text_revision))
137
112
    for mode, name, hexsha in tree.entries():
138
113
        entry_kind = (mode & 0700000) / 0100000
139
114
        basename = name.decode("utf-8")
141
116
            child_path = name
142
117
        else:
143
118
            child_path = urlutils.join(path, name)
144
 
        obj = lookup_object(hexsha)
145
119
        if entry_kind == 0:
146
 
            import_git_tree(texts, mapping, child_path, obj, inv, parent_invs,
147
 
                shagitmap, lookup_object)
 
120
            tree = lookup_object(hexsha)
 
121
            import_git_tree(repo, mapping, child_path, tree, inv, parent_invs, lookup_object)
148
122
        elif entry_kind == 1:
 
123
            blob = lookup_object(hexsha)
149
124
            fs_mode = mode & 0777
150
 
            import_git_blob(texts, mapping, child_path, obj, inv, parent_invs,
151
 
                shagitmap, bool(fs_mode & 0111))
 
125
            import_git_blob(repo, mapping, child_path, blob, inv, parent_invs, bool(fs_mode & 0111))
152
126
        else:
153
127
            raise AssertionError("Unknown blob kind, perms=%r." % (mode,))
154
128
 
172
146
            root_trees[rev.revision_id] = object_iter[o.tree]
173
147
            revisions[rev.revision_id] = rev
174
148
            graph.append((rev.revision_id, rev.parent_ids))
175
 
            target_git_object_retriever._idmap.add_entry(o.sha().hexdigest(),
176
 
                "commit", (rev.revision_id, o._tree))
177
149
    # Order the revisions
178
150
    # Create the inventory objects
179
151
    for i, revid in enumerate(topo_sort(graph)):
189
161
        def lookup_object(sha):
190
162
            if sha in object_iter:
191
163
                return object_iter[sha]
192
 
            return target_git_object_retriever[sha]
 
164
            return target_git_object_retriever(sha)
193
165
        parent_invs = [repo.get_inventory(r) for r in rev.parent_ids]
194
 
        import_git_tree(repo.texts, mapping, "", root_tree, inv, parent_invs, 
195
 
            target_git_object_retriever._idmap, lookup_object)
 
166
        import_git_tree(repo, mapping, "", root_tree, inv, parent_invs, 
 
167
            lookup_object)
196
168
        repo.add_revision(rev.revision_id, rev, inv)
197
169
 
198
170
 
 
171
def reconstruct_git_object(repo, mapping, sha):
 
172
    import pdb; pdb.set_trace()
 
173
 
 
174
    # TODO: Tree
 
175
    # TODO: Blob
 
176
    raise KeyError("No such object %s" % sha)
 
177
 
 
178
 
199
179
class InterGitNonGitRepository(InterRepository):
200
180
 
201
181
    _matching_repo_format = GitFormat()
237
217
                create_pb.finished()
238
218
 
239
219
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
240
 
              mapping=None, fetch_spec=None):
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):
 
220
              mapping=None):
246
221
        if mapping is None:
247
222
            mapping = self.source.get_mapping()
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
254
 
        self._refs = {}
255
 
        def determine_wants(refs):
256
 
            self._refs = refs
257
 
            if interesting_heads is None:
258
 
                ret = [sha for (ref, sha) in refs.iteritems() if not ref.endswith("^{}")]
 
223
        def determine_wants(heads):
 
224
            if revision_id is None:
 
225
                ret = heads.values()
259
226
            else:
260
 
                ret = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in interesting_heads]
 
227
                ret = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
261
228
            return [rev for rev in ret if not self.target.has_revision(mapping.revision_id_foreign_to_bzr(rev))]
262
 
        self.fetch_objects(determine_wants, mapping, pb)
263
 
        return self._refs
 
229
        return self.fetch_objects(determine_wants, mapping, pb)
264
230
 
265
231
    @staticmethod
266
232
    def is_compatible(source, target):
284
250
        self.fetch(revision_id, pb, find_ghosts=False)
285
251
 
286
252
    def fetch(self, revision_id=None, pb=None, find_ghosts=False, 
287
 
              mapping=None, fetch_spec=None):
 
253
              mapping=None):
288
254
        if mapping is None:
289
255
            mapping = self.source.get_mapping()
290
256
        def progress(text):
291
 
            trace.info("git: %s", text)
 
257
            info("git: %s", text)
292
258
        r = self.target._git
293
 
        if revision_id is not None:
 
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:
294
262
            args = [mapping.revision_id_bzr_to_foreign(revision_id)[0]]
295
 
        elif fetch_spec is not None:
296
 
            args = [mapping.revision_id_bzr_to_foreign(revid)[0] for revid in fetch_spec.heads]
297
 
        if fetch_spec is None and revision_id is None:
298
 
            determine_wants = r.object_store.determine_wants_all
299
 
        else:
300
263
            determine_wants = lambda x: [y for y in args if not y in r.object_store]
301
264
 
302
265
        graphwalker = SimpleFetchGraphWalker(r.heads().values(), r.get_parents)