/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

mention the requirement to install Dulwich.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
 
1
# Copyright (C) 2007-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
17
17
"""Converters, etc for going between Bazaar and Git ids."""
18
18
 
19
19
from bzrlib import errors, foreign
 
20
from bzrlib.inventory import ROOT_ID
20
21
from bzrlib.foreign import (
 
22
        ForeignVcs, 
 
23
        VcsMappingRegistry, 
21
24
        ForeignRevision,
22
25
        )
23
26
 
24
 
 
25
27
def escape_file_id(file_id):
26
28
    return file_id.replace('_', '__').replace(' ', '_s')
27
29
 
34
36
    """Class that maps between Git and Bazaar semantics."""
35
37
    experimental = False
36
38
 
37
 
    def revision_id_foreign_to_bzr(self, git_rev_id):
 
39
    def __init__(self):
 
40
        super(BzrGitMapping, self).__init__(foreign_git)
 
41
 
 
42
    def __eq__(self, other):
 
43
        return type(self) == type(other) and self.revid_prefix == other.revid_prefix
 
44
 
 
45
    @classmethod
 
46
    def revision_id_foreign_to_bzr(cls, git_rev_id):
38
47
        """Convert a git revision id handle to a Bazaar revision id."""
39
 
        return "%s:%s" % (self.revid_prefix, git_rev_id)
 
48
        return "%s:%s" % (cls.revid_prefix, git_rev_id)
40
49
 
41
 
    def revision_id_bzr_to_foreign(self, bzr_rev_id):
 
50
    @classmethod
 
51
    def revision_id_bzr_to_foreign(cls, bzr_rev_id):
42
52
        """Convert a Bazaar revision id to a git revision id handle."""
43
 
        if not bzr_rev_id.startswith("%s:" % self.revid_prefix):
44
 
            raise errors.InvalidRevisionId(bzr_rev_id, self)
45
 
        return bzr_rev_id[len(self.revid_prefix)+1:]
46
 
 
47
 
    def show_foreign_revid(self, foreign_revid):
48
 
        return { "git commit": foreign_revid }
 
53
        if not bzr_rev_id.startswith("%s:" % cls.revid_prefix):
 
54
            raise errors.InvalidRevisionId(bzr_rev_id, cls)
 
55
        return bzr_rev_id[len(cls.revid_prefix)+1:], cls()
49
56
 
50
57
    def generate_file_id(self, path):
 
58
        if path == "":
 
59
            return ROOT_ID
51
60
        return escape_file_id(path.encode('utf-8'))
52
61
 
53
62
    def import_commit(self, commit):
68
77
        return rev
69
78
 
70
79
 
71
 
class BzrGitMappingExperimental(BzrGitMapping):
 
80
class BzrGitMappingv1(BzrGitMapping):
 
81
    revid_prefix = 'git-v1'
 
82
    experimental = False
 
83
 
 
84
 
 
85
class BzrGitMappingExperimental(BzrGitMappingv1):
72
86
    revid_prefix = 'git-experimental'
73
87
    experimental = True
74
88
 
75
89
 
76
 
default_mapping = BzrGitMappingExperimental()
 
90
class GitMappingRegistry(VcsMappingRegistry):
 
91
 
 
92
    def revision_id_bzr_to_foreign(self, bzr_revid):
 
93
        if not bzr_revid.startswith("git-"):
 
94
            raise errors.InvalidRevisionId(bzr_revid, None)
 
95
        (mapping_version, git_sha) = bzr_revid.split(":", 1)
 
96
        mapping = self.get(mapping_version)
 
97
        return mapping.revision_id_bzr_to_foreign(bzr_revid)
 
98
 
 
99
    parse_revision_id = revision_id_bzr_to_foreign
 
100
 
 
101
 
 
102
mapping_registry = GitMappingRegistry()
 
103
mapping_registry.register_lazy('git-v1', "bzrlib.plugins.git.mapping",
 
104
                                   "BzrGitMappingv1")
 
105
mapping_registry.register_lazy('git-experimental', "bzrlib.plugins.git.mapping",
 
106
                                   "BzrGitMappingExperimental")
 
107
 
 
108
 
 
109
class ForeignGit(ForeignVcs):
 
110
    """Foreign Git."""
 
111
 
 
112
    def __init__(self):
 
113
        super(ForeignGit, self).__init__(mapping_registry)
 
114
 
 
115
    @classmethod
 
116
    def show_foreign_revid(cls, foreign_revid):
 
117
        return { "git commit": foreign_revid }
 
118
 
 
119
 
 
120
foreign_git = ForeignGit()
 
121
default_mapping = BzrGitMappingv1()
 
122
 
 
123
 
 
124
def inventory_to_tree_and_blobs(repo, mapping, revision_id):
 
125
    from dulwich.objects import Tree, Blob
 
126
    from bzrlib.inventory import InventoryDirectory, InventoryFile
 
127
    import stat
 
128
    stack = []
 
129
    cur = ""
 
130
    tree = Tree()
 
131
 
 
132
    inv = repo.get_inventory(revision_id)
 
133
 
 
134
    for path, entry in inv.iter_entries():
 
135
        while stack and not path.startswith(cur):
 
136
            tree.serialize()
 
137
            sha = tree.sha().hexdigest()
 
138
            yield sha, tree, path
 
139
            t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha)
 
140
            cur, tree = stack.pop()
 
141
            tree.add(*t)
 
142
 
 
143
        if type(entry) == InventoryDirectory:
 
144
            stack.append((cur, tree))
 
145
            cur = path
 
146
            tree = Tree()
 
147
 
 
148
        if type(entry) == InventoryFile:
 
149
            #FIXME: We can make potentially make this Lazy to avoid shaing lots of stuff
 
150
            # and having all these objects in memory at once
 
151
            blob = Blob()
 
152
            _, blob._text = repo.iter_files_bytes([(entry.file_id, revision_id, path)]).next()
 
153
            sha = blob.sha().hexdigest()
 
154
            yield sha, blob, path
 
155
 
 
156
            name = splitpath(path)[-1:][0].encode('UTF-8')
 
157
            mode = stat.S_IFREG | 0644
 
158
            if entry.executable:
 
159
                mode |= 0111
 
160
            tree.add(mode, name, sha)
 
161
 
 
162
    while len(stack) > 1:
 
163
        tree.serialize()
 
164
        sha = tree.sha().hexdigest()
 
165
        yield sha, tree, path
 
166
        t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha)
 
167
        cur, tree = stack.pop()
 
168
        tree.add(*t)
 
169
 
 
170
    tree.serialize()
 
171
    yield tree.sha().hexdigest(), tree, path
 
172
 
 
173
 
 
174
def revision_to_commit(rev, tree_sha, parent_lookup):
 
175
    """Turn a Bazaar revision in to a Git commit
 
176
 
 
177
    :param tree_sha: Tree sha for the commit
 
178
    :param parent_lookup: Function for looking up the GIT sha equiv of a bzr revision
 
179
    :return dulwich.objects.Commit represent the revision:
 
180
    """
 
181
    from dulwich.objects import Commit
 
182
    commit = Commit()
 
183
    commit._tree = tree_sha
 
184
    for p in rev.parent_ids:
 
185
        commit._parents.append(parent_lookup(p))
 
186
    commit._message = rev.message
 
187
    commit._committer = rev.committer
 
188
    if 'author' in rev.properties:
 
189
        commit._author = rev.properties['author']
 
190
    else:
 
191
        commit._author = rev.committer
 
192
    commit._commit_time = long(rev.timestamp)
 
193
    commit.serialize()
 
194
    return commit