/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

Move conversion functions to mapping, use fetch_objects() from repository if present.

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
    stack = []
 
126
    cur = ""
 
127
    tree = Tree()
 
128
 
 
129
    inv = repo.get_inventory(revision_id)
 
130
 
 
131
    for path, entry in inv.iter_entries():
 
132
        while stack and not path.startswith(cur):
 
133
            tree.serialize()
 
134
            sha = tree.sha().hexdigest()
 
135
            yield sha, tree, path
 
136
            t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha)
 
137
            cur, tree = stack.pop()
 
138
            tree.add(*t)
 
139
 
 
140
        if type(entry) == InventoryDirectory:
 
141
            stack.append((cur, tree))
 
142
            cur = path
 
143
            tree = Tree()
 
144
 
 
145
        if type(entry) == InventoryFile:
 
146
            #FIXME: We can make potentially make this Lazy to avoid shaing lots of stuff
 
147
            # and having all these objects in memory at once
 
148
            blob = Blob()
 
149
            _, blob._text = repo.iter_files_bytes([(entry.file_id, revision_id, path)]).next()
 
150
            sha = blob.sha().hexdigest()
 
151
            yield sha, blob, path
 
152
 
 
153
            name = splitpath(path)[-1:][0].encode('UTF-8')
 
154
            mode = stat.S_IFREG | 0644
 
155
            if entry.executable:
 
156
                mode |= 0111
 
157
            tree.add(mode, name, sha)
 
158
 
 
159
    while len(stack) > 1:
 
160
        tree.serialize()
 
161
        sha = tree.sha().hexdigest()
 
162
        yield sha, tree, path
 
163
        t = (stat.S_IFDIR, splitpath(cur)[-1:][0].encode('UTF-8'), sha)
 
164
        cur, tree = stack.pop()
 
165
        tree.add(*t)
 
166
 
 
167
    tree.serialize()
 
168
    yield tree.sha().hexdigest(), tree, path
 
169
 
 
170
 
 
171
def revision_to_commit(rev, tree_sha, parent_lookup):
 
172
    """Turn a Bazaar revision in to a Git commit
 
173
 
 
174
    :param tree_sha: Tree sha for the commit
 
175
    :param parent_lookup: Function for looking up the GIT sha equiv of a bzr revision
 
176
    :return dulwich.objects.Commit represent the revision:
 
177
    """
 
178
    from dulwich.objects import Commit
 
179
    commit = Commit()
 
180
    commit._tree = tree_sha
 
181
    for p in rev.parent_ids:
 
182
        commit._parents.append(parent_lookup(p))
 
183
    commit._message = rev.message
 
184
    commit._committer = rev.committer
 
185
    if 'author' in rev.properties:
 
186
        commit._author = rev.properties['author']
 
187
    else:
 
188
        commit._author = rev.committer
 
189
    commit._commit_time = long(rev.timestamp)
 
190
    commit.serialize()
 
191
    return commit