/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 tests.

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