/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

Without ino and dev, we can't assume that the stat result won't accidentally be the same.

So instead, we force the content to be different.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2008 Canonical Ltd
2
 
#
3
 
# This program is free software; you can redistribute it and/or modify
4
 
# it under the terms of the GNU General Public License as published by
5
 
# the Free Software Foundation; either version 2 of the License, or
6
 
# (at your option) any later version.
7
 
#
8
 
# This program is distributed in the hope that it will be useful,
9
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 
# GNU General Public License for more details.
12
 
#
13
 
# You should have received a copy of the GNU General Public License
14
 
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 
 
17
 
"""Converters, etc for going between Bazaar and Git ids."""
18
 
 
19
 
from bzrlib import errors, foreign, urlutils
20
 
from bzrlib.inventory import ROOT_ID
21
 
from bzrlib.foreign import (
22
 
        ForeignVcs, 
23
 
        VcsMappingRegistry, 
24
 
        ForeignRevision,
25
 
        )
26
 
 
27
 
def escape_file_id(file_id):
28
 
    return file_id.replace('_', '__').replace(' ', '_s')
29
 
 
30
 
 
31
 
def unescape_file_id(file_id):
32
 
    return file_id.replace("_s", " ").replace("__", "_")
33
 
 
34
 
 
35
 
class BzrGitMapping(foreign.VcsMapping):
36
 
    """Class that maps between Git and Bazaar semantics."""
37
 
    experimental = False
38
 
 
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):
47
 
        """Convert a git revision id handle to a Bazaar revision id."""
48
 
        return "%s:%s" % (cls.revid_prefix, git_rev_id)
49
 
 
50
 
    @classmethod
51
 
    def revision_id_bzr_to_foreign(cls, bzr_rev_id):
52
 
        """Convert a Bazaar revision id to a git revision id handle."""
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()
56
 
 
57
 
    def generate_file_id(self, path):
58
 
        if path == "":
59
 
            return ROOT_ID
60
 
        return escape_file_id(path.encode('utf-8'))
61
 
 
62
 
    def import_commit(self, commit):
63
 
        """Convert a git commit to a bzr revision.
64
 
 
65
 
        :return: a `bzrlib.revision.Revision` object.
66
 
        """
67
 
        if commit is None:
68
 
            raise AssertionError("Commit object can't be None")
69
 
        rev = ForeignRevision(commit.id, self, self.revision_id_foreign_to_bzr(commit.id))
70
 
        rev.parent_ids = tuple([self.revision_id_foreign_to_bzr(p) for p in commit.parents])
71
 
        rev.message = commit.message.decode("utf-8", "replace")
72
 
        rev.committer = str(commit.committer).decode("utf-8", "replace")
73
 
        if commit.committer != commit.author:
74
 
            rev.properties['author'] = str(commit.author).decode("utf-8", "replace")
75
 
        rev.timestamp = commit.commit_time
76
 
        rev.timezone = 0
77
 
        return rev
78
 
 
79
 
 
80
 
class BzrGitMappingv1(BzrGitMapping):
81
 
    revid_prefix = 'git-v1'
82
 
    experimental = False
83
 
 
84
 
 
85
 
class BzrGitMappingExperimental(BzrGitMappingv1):
86
 
    revid_prefix = 'git-experimental'
87
 
    experimental = True
88
 
 
89
 
 
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
 
    # stack contains the set of trees that we haven't 
135
 
    # finished constructing
136
 
 
137
 
    for path, entry in inv.iter_entries():
138
 
        while stack and not path.startswith(cur):
139
 
            tree.serialize()
140
 
            sha = tree.sha().hexdigest()
141
 
            yield sha, tree, cur
142
 
            t = (stat.S_IFDIR, urlutils.basename(cur).encode('UTF-8'), sha)
143
 
            cur, tree = stack.pop()
144
 
            tree.add(*t)
145
 
 
146
 
        if type(entry) == InventoryDirectory:
147
 
            stack.append((cur, tree))
148
 
            cur = path
149
 
            tree = Tree()
150
 
 
151
 
        if type(entry) == InventoryFile:
152
 
            #FIXME: We can make potentially make this Lazy to avoid shaing lots of stuff
153
 
            # and having all these objects in memory at once
154
 
            blob = Blob()
155
 
            _, blob._text = repo.iter_files_bytes([(entry.file_id, entry.revision, path)]).next()
156
 
            sha = blob.sha().hexdigest()
157
 
            yield sha, blob, path
158
 
 
159
 
            name = urlutils.basename(path).encode("utf-8")
160
 
            mode = stat.S_IFREG | 0644
161
 
            if entry.executable:
162
 
                mode |= 0111
163
 
            tree.add(mode, name, sha)
164
 
 
165
 
    while len(stack) > 1:
166
 
        tree.serialize()
167
 
        sha = tree.sha().hexdigest()
168
 
        yield sha, tree, cur
169
 
        t = (stat.S_IFDIR, urlutils.basename(cur).encode('UTF-8'), sha)
170
 
        cur, tree = stack.pop()
171
 
        tree.add(*t)
172
 
 
173
 
    tree.serialize()
174
 
    yield tree.sha().hexdigest(), tree, cur
175
 
 
176
 
 
177
 
def revision_to_commit(rev, tree_sha, parent_lookup):
178
 
    """Turn a Bazaar revision in to a Git commit
179
 
 
180
 
    :param tree_sha: Tree sha for the commit
181
 
    :param parent_lookup: Function for looking up the GIT sha equiv of a bzr revision
182
 
    :return dulwich.objects.Commit represent the revision:
183
 
    """
184
 
    from dulwich.objects import Commit
185
 
    commit = Commit()
186
 
    commit._tree = tree_sha
187
 
    for p in rev.parent_ids:
188
 
        git_p = parent_lookup(p)
189
 
        if git_p is not None:
190
 
            commit._parents.append(git_p)
191
 
    commit._message = rev.message.encode("utf-8")
192
 
    commit._committer = rev.committer.encode("utf-8")
193
 
    commit._author = rev.get_apparent_author().encode("utf-8")
194
 
    commit._commit_time = long(rev.timestamp)
195
 
    commit.serialize()
196
 
    return commit