/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

Add simple HACKING document.

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