/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 mapping.py

Fix index creation when fetching from remote host.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2007 Canonical Ltd
 
2
# Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
 
3
# Copyright (C) 2008 John Carr
2
4
#
3
5
# This program is free software; you can redistribute it and/or modify
4
6
# it under the terms of the GNU General Public License as published by
16
18
 
17
19
"""Converters, etc for going between Bazaar and Git ids."""
18
20
 
19
 
from bzrlib import errors, foreign
20
 
from bzrlib.inventory import ROOT_ID
 
21
from bzrlib import (
 
22
    errors,
 
23
    foreign,
 
24
    urlutils,
 
25
    )
 
26
from bzrlib.inventory import (
 
27
    ROOT_ID,
 
28
    )
21
29
from bzrlib.foreign import (
22
 
        ForeignRevision,
23
 
        )
24
 
 
 
30
    ForeignVcs, 
 
31
    VcsMappingRegistry, 
 
32
    ForeignRevision,
 
33
    )
25
34
 
26
35
def escape_file_id(file_id):
27
36
    return file_id.replace('_', '__').replace(' ', '_s')
35
44
    """Class that maps between Git and Bazaar semantics."""
36
45
    experimental = False
37
46
 
38
 
    def revision_id_foreign_to_bzr(self, git_rev_id):
 
47
    def __init__(self):
 
48
        super(BzrGitMapping, self).__init__(foreign_git)
 
49
 
 
50
    def __eq__(self, other):
 
51
        return type(self) == type(other) and self.revid_prefix == other.revid_prefix
 
52
 
 
53
    @classmethod
 
54
    def revision_id_foreign_to_bzr(cls, git_rev_id):
39
55
        """Convert a git revision id handle to a Bazaar revision id."""
40
 
        return "%s:%s" % (self.revid_prefix, git_rev_id)
 
56
        return "%s:%s" % (cls.revid_prefix, git_rev_id)
41
57
 
42
 
    def revision_id_bzr_to_foreign(self, bzr_rev_id):
 
58
    @classmethod
 
59
    def revision_id_bzr_to_foreign(cls, bzr_rev_id):
43
60
        """Convert a Bazaar revision id to a git revision id handle."""
44
 
        if not bzr_rev_id.startswith("%s:" % self.revid_prefix):
45
 
            raise errors.InvalidRevisionId(bzr_rev_id, self)
46
 
        return bzr_rev_id[len(self.revid_prefix)+1:]
47
 
 
48
 
    def show_foreign_revid(self, foreign_revid):
49
 
        return { "git commit": foreign_revid }
 
61
        if not bzr_rev_id.startswith("%s:" % cls.revid_prefix):
 
62
            raise errors.InvalidRevisionId(bzr_rev_id, cls)
 
63
        return bzr_rev_id[len(cls.revid_prefix)+1:], cls()
50
64
 
51
65
    def generate_file_id(self, path):
 
66
        # Git paths are just bytestrings
 
67
        # We must just hope they are valid UTF-8..
 
68
        assert isinstance(path, str)
52
69
        if path == "":
53
70
            return ROOT_ID
54
 
        return escape_file_id(path.encode('utf-8'))
 
71
        return escape_file_id(path)
55
72
 
56
73
    def import_commit(self, commit):
57
74
        """Convert a git commit to a bzr revision.
71
88
        return rev
72
89
 
73
90
 
74
 
class BzrGitMappingExperimental(BzrGitMapping):
 
91
class BzrGitMappingv1(BzrGitMapping):
 
92
    revid_prefix = 'git-v1'
 
93
    experimental = False
 
94
 
 
95
 
 
96
class BzrGitMappingExperimental(BzrGitMappingv1):
75
97
    revid_prefix = 'git-experimental'
76
98
    experimental = True
77
99
 
78
100
 
79
 
default_mapping = BzrGitMappingExperimental()
 
101
class GitMappingRegistry(VcsMappingRegistry):
 
102
 
 
103
    def revision_id_bzr_to_foreign(self, bzr_revid):
 
104
        if not bzr_revid.startswith("git-"):
 
105
            raise errors.InvalidRevisionId(bzr_revid, None)
 
106
        (mapping_version, git_sha) = bzr_revid.split(":", 1)
 
107
        mapping = self.get(mapping_version)
 
108
        return mapping.revision_id_bzr_to_foreign(bzr_revid)
 
109
 
 
110
    parse_revision_id = revision_id_bzr_to_foreign
 
111
 
 
112
 
 
113
mapping_registry = GitMappingRegistry()
 
114
mapping_registry.register_lazy('git-v1', "bzrlib.plugins.git.mapping",
 
115
                                   "BzrGitMappingv1")
 
116
mapping_registry.register_lazy('git-experimental', "bzrlib.plugins.git.mapping",
 
117
                                   "BzrGitMappingExperimental")
 
118
 
 
119
 
 
120
class ForeignGit(ForeignVcs):
 
121
    """Foreign Git."""
 
122
 
 
123
    def __init__(self):
 
124
        super(ForeignGit, self).__init__(mapping_registry)
 
125
 
 
126
    @classmethod
 
127
    def show_foreign_revid(cls, foreign_revid):
 
128
        return { "git commit": foreign_revid }
 
129
 
 
130
 
 
131
foreign_git = ForeignGit()
 
132
default_mapping = BzrGitMappingv1()
 
133
 
 
134
 
 
135
def inventory_to_tree_and_blobs(repo, mapping, revision_id):
 
136
    from dulwich.objects import Tree, Blob
 
137
    from bzrlib.inventory import InventoryDirectory, InventoryFile
 
138
    import stat
 
139
    stack = []
 
140
    cur = ""
 
141
    tree = Tree()
 
142
 
 
143
    inv = repo.get_inventory(revision_id)
 
144
 
 
145
    # stack contains the set of trees that we haven't 
 
146
    # finished constructing
 
147
    for path, entry in inv.iter_entries():
 
148
        while stack and not path.startswith(cur):
 
149
            tree.serialize()
 
150
            sha = tree.sha().hexdigest()
 
151
            yield sha, tree, cur
 
152
            t = (stat.S_IFDIR, urlutils.basename(cur).encode('UTF-8'), sha)
 
153
            cur, tree = stack.pop()
 
154
            tree.add(*t)
 
155
 
 
156
        if type(entry) == InventoryDirectory:
 
157
            stack.append((cur, tree))
 
158
            cur = path
 
159
            tree = Tree()
 
160
 
 
161
        if type(entry) == InventoryFile:
 
162
            #FIXME: We can make potentially make this Lazy to avoid shaing lots of stuff
 
163
            # and having all these objects in memory at once
 
164
            blob = Blob()
 
165
            _, blob._text = repo.iter_files_bytes([(entry.file_id, entry.revision, path)]).next()
 
166
            sha = blob.sha().hexdigest()
 
167
            yield sha, blob, path
 
168
 
 
169
            name = urlutils.basename(path).encode("utf-8")
 
170
            mode = stat.S_IFREG | 0644
 
171
            if entry.executable:
 
172
                mode |= 0111
 
173
            tree.add(mode, name, sha)
 
174
 
 
175
    while len(stack) > 1:
 
176
        tree.serialize()
 
177
        sha = tree.sha().hexdigest()
 
178
        yield sha, tree, cur
 
179
        t = (stat.S_IFDIR, urlutils.basename(cur).encode('UTF-8'), sha)
 
180
        cur, tree = stack.pop()
 
181
        tree.add(*t)
 
182
 
 
183
    tree.serialize()
 
184
    yield tree.sha().hexdigest(), tree, cur
 
185
 
 
186
 
 
187
def revision_to_commit(rev, tree_sha, parent_lookup):
 
188
    """Turn a Bazaar revision in to a Git commit
 
189
 
 
190
    :param tree_sha: Tree sha for the commit
 
191
    :param parent_lookup: Function for looking up the GIT sha equiv of a bzr revision
 
192
    :return dulwich.objects.Commit represent the revision:
 
193
    """
 
194
    from dulwich.objects import Commit
 
195
    commit = Commit()
 
196
    commit._tree = tree_sha
 
197
    for p in rev.parent_ids:
 
198
        git_p = parent_lookup(p)
 
199
        if git_p is not None:
 
200
            assert len(git_p) == 40, "unexpected length for %r" % git_p
 
201
            commit._parents.append(git_p)
 
202
    commit._message = rev.message.encode("utf-8")
 
203
    commit._committer = rev.committer.encode("utf-8")
 
204
    commit._author = rev.get_apparent_authors()[0].encode("utf-8")
 
205
    commit._commit_time = long(rev.timestamp)
 
206
    commit.serialize()
 
207
    return commit