/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 basic infrastructure for dpush.

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
 
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("__", "_")
20
33
 
21
34
 
22
35
class BzrGitMapping(foreign.VcsMapping):
23
36
    """Class that maps between Git and Bazaar semantics."""
24
37
    experimental = False
25
38
 
26
 
    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):
27
47
        """Convert a git revision id handle to a Bazaar revision id."""
28
 
        return "%s:%s" % (self.revid_prefix, git_rev_id)
 
48
        return "%s:%s" % (cls.revid_prefix, git_rev_id)
29
49
 
30
 
    def revision_id_bzr_to_foreign(self, bzr_rev_id):
 
50
    @classmethod
 
51
    def revision_id_bzr_to_foreign(cls, bzr_rev_id):
31
52
        """Convert a Bazaar revision id to a git revision id handle."""
32
 
        if not bzr_rev_id.startswith("%s:" % self.revid_prefix):
33
 
            raise errors.InvalidRevisionId(bzr_rev_id, self)
34
 
        return bzr_rev_id[len(self.revid_prefix)+1:]
35
 
 
36
 
    def show_foreign_revid(self, foreign_revid):
37
 
        return { "git commit": foreign_revid }
38
 
 
39
 
 
40
 
class BzrGitMappingExperimental(BzrGitMapping):
 
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
    def export_commit(self, rev, tree_sha):
 
80
        """Turn a Bazaar revision in to a Git commit
 
81
 
 
82
        :param tree_sha: HACK parameter (until we can retrieve this from the mapping)
 
83
        :return dulwich.objects.Commit represent the revision:
 
84
        """
 
85
        from dulwich.objects import Commit
 
86
        commit = Commit()
 
87
        commit._tree = tree_sha
 
88
        for p in rev.parent_ids:
 
89
            commit._parents.append(self.revision_id_bzr_to_foreign(p))
 
90
        commit._message = rev.message
 
91
        commit._committer = rev.committer
 
92
        if 'author' in rev.properties:
 
93
            commit._author = rev.properties['author']
 
94
        else:
 
95
            commit._author = rev.committer
 
96
        commit._commit_time = long(rev.timestamp)
 
97
        commit.serialize()
 
98
        return commit
 
99
 
 
100
 
 
101
class BzrGitMappingv1(BzrGitMapping):
 
102
    revid_prefix = 'git-v1'
 
103
    experimental = False
 
104
 
 
105
 
 
106
class BzrGitMappingExperimental(BzrGitMappingv1):
41
107
    revid_prefix = 'git-experimental'
42
108
    experimental = True
43
109
 
44
110
 
45
 
default_mapping = BzrGitMappingExperimental()
 
111
class GitMappingRegistry(VcsMappingRegistry):
 
112
 
 
113
    def revision_id_bzr_to_foreign(self, bzr_revid):
 
114
        if not bzr_revid.startswith("git-"):
 
115
            raise errors.InvalidRevisionId(bzr_revid, None)
 
116
        (mapping_version, git_sha) = bzr_revid.split(":", 1)
 
117
        mapping = self.get(mapping_version)
 
118
        return mapping.revision_id_bzr_to_foreign(bzr_revid)
 
119
 
 
120
    parse_revision_id = revision_id_bzr_to_foreign
 
121
 
 
122
 
 
123
mapping_registry = GitMappingRegistry()
 
124
mapping_registry.register_lazy('git-v1', "bzrlib.plugins.git.mapping",
 
125
                                   "BzrGitMappingv1")
 
126
mapping_registry.register_lazy('git-experimental', "bzrlib.plugins.git.mapping",
 
127
                                   "BzrGitMappingExperimental")
 
128
 
 
129
 
 
130
class ForeignGit(ForeignVcs):
 
131
    """Foreign Git."""
 
132
 
 
133
    def __init__(self):
 
134
        super(ForeignGit, self).__init__(mapping_registry)
 
135
 
 
136
    @classmethod
 
137
    def show_foreign_revid(cls, foreign_revid):
 
138
        return { "git commit": foreign_revid }
 
139
 
 
140
 
 
141
foreign_git = ForeignGit()
 
142
default_mapping = BzrGitMappingv1()