/breezy-svn/trunk

To get this branch, use:
bzr branch https://code.breezy-vcs.org/breezy-svn/trunk
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# Copyright (C) 2005-2009 Jelmer Vernooij <jelmer@samba.org>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""Version 4 mappings."""

from __future__ import absolute_import

import urllib

from breezy import (
    errors,
    )

from breezy.plugins.svn import (
    mapping,
    )
from breezy.plugins.svn.errors import (
    InvalidFileId,
    )

supported_features = set()


class BzrSvnMappingv4(mapping.BzrSvnMappingFileProps,
        mapping.BzrSvnMappingRevProps, mapping.BzrSvnMapping):
    """Mapping between Subversion and Bazaar, introduced in bzr-svn 0.5.

    Tries to use revision properties when possible.

    TODO: Add variable with required features.
    """
    revid_prefix = b"svn-v4"
    upgrade_suffix = b"-svn4"
    experimental = False
    roundtripping = True
    can_use_revprops = True
    can_use_fileprops = True
    supports_hidden = True
    restricts_branch_paths = False
    parseable_file_ids = True

    def __init__(self):
        mapping.BzrSvnMapping.__init__(self)
        self.name = "v4"

    def __hash__(self):
        return hash(type(self))

    @classmethod
    def from_repository(cls, repository, _hinted_branch_path=None):
        return cls()

    @classmethod
    def from_revprops(cls, revprops):
        return cls()

    @classmethod
    def revision_id_bzr_to_foreign(cls, revid):
        assert isinstance(revid, str)

        if not revid.startswith(cls.revid_prefix):
            raise errors.InvalidRevisionId(revid, "")

        try:
            (version, uuid, branch_path, srevnum) = revid.split(":")
        except ValueError:
            raise errors.InvalidRevisionId(revid, "")

        branch_path = mapping.unescape_svn_path(branch_path)

        return (uuid, branch_path, int(srevnum)), cls()

    def revision_id_foreign_to_bzr(self, foreign_revid):
        (uuid, path, revnum) = foreign_revid
        assert isinstance(uuid, str)
        return b"svn-v4:%s:%s:%d" % (uuid, str(urllib.quote(path)), revnum)

    def generate_file_id(self, foreign_revid, inv_path):
        (uuid, branch, revnum) = foreign_revid
        return b"%d@%s:%s" % (
                revnum, uuid,
                mapping.escape_svn_path(
                    u"%s/%s" % (branch, inv_path)))

    def parse_file_id(self, fileid):
        try:
            (revnum_str, rest) = fileid.split("@", 1)
            revnum = int(revnum_str)
            (uuid, path_escaped) = rest.split(":", 1)
        except ValueError:
            raise InvalidFileId(fileid)
        path = mapping.unescape_svn_path(path_escaped).strip("/")
        return (uuid, revnum, path)

    def is_branch(self, branch_path):
        return True

    def is_tag(self, tag_path):
        return True

    def __eq__(self, other):
        return type(self) == type(other)

    def __ne__(self, other):
        return type(self) != type(other)

    def get_lhs_parent_fileprops(self, fileprops):
        return None

    def import_revision_revprops(self, svn_revprops, rev):
        if svn_revprops.has_key(mapping.SVN_REVPROP_BZR_REQUIRED_FEATURES):
            features = mapping.parse_required_features_property(
                svn_revprops[mapping.SVN_REVPROP_BZR_REQUIRED_FEATURES])
            assert features.issubset(supported_features), "missing feature: %r" % features.difference(supported_features)
        return mapping.BzrSvnMappingRevProps.import_revision_revprops(self,
            svn_revprops, rev)

    def import_revision_fileprops(self, fileprops, rev):
        if fileprops.has_key(mapping.SVN_PROP_BZR_REQUIRED_FEATURES):
            features = mapping.parse_required_features_property(
                fileprops[mapping.SVN_PROP_BZR_REQUIRED_FEATURES])
            assert features.issubset(supported_features), "missing feature: %r" % features.difference(supported_features)
        return mapping.BzrSvnMappingFileProps.import_revision_fileprops(self,
            fileprops, rev)

    def get_mandated_layout(self, repository):
        return None

    def is_bzr_revision_hidden_revprops(self, revprops):
        return revprops.has_key(mapping.SVN_REVPROP_BZR_HIDDEN)

    def is_bzr_revision_hidden_fileprops(self, changed_fileprops):
        return changed_fileprops.has_key(mapping.SVN_PROP_BZR_HIDDEN)

    def get_hidden_lhs_ancestors_count(self, fileprops):
        return int(fileprops.get(mapping.SVN_PROP_BZR_HIDDEN, "0"))

    def export_hidden_revprops(self, branch_root, revprops):
        revprops[mapping.SVN_REVPROP_BZR_HIDDEN] = ""
        revprops[mapping.SVN_REVPROP_BZR_ROOT] = branch_root

    def export_hidden_fileprops(self, fileprops):
        old_value = fileprops.get(mapping.SVN_PROP_BZR_HIDDEN, "0")
        fileprops[mapping.SVN_PROP_BZR_HIDDEN] = str(int(old_value)+1)

    def supports_tags(self):
        return True

    def export_revprop_redirect(self, revnum, fileprops):
        if not mapping.SVN_PROP_BZR_REVPROP_REDIRECT in fileprops:
            fileprops[mapping.SVN_PROP_BZR_REVPROP_REDIRECT] = str(revnum)

    def newer_than(self, other_mapping):
        if other_mapping.revid_prefix[:6] in (b"svn-v1", b"svn-v2", b"svn-v3"):
            return True
        return False