/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
1
# Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
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
"""Foreign branch utilities."""
18
0.205.6 by Jelmer Vernooij
Import FakeControlFiles.
19
from bzrlib import errors, registry
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
20
from bzrlib.branch import Branch
0.205.7 by Jelmer Vernooij
Import dpush.
21
from bzrlib.commands import Command, Option
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
22
from bzrlib.errors import InvalidRevisionId
23
from bzrlib.revision import Revision
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
24
from bzrlib.trace import info
0.205.3 by Jelmer Vernooij
Fix import.
25
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
26
class VcsMapping(object):
27
    """Describes the mapping between the semantics of Bazaar and a foreign vcs.
28
29
    """
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
30
    # Whether this is an experimental mapping that is still open to changes.
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
31
    experimental = False
0.205.18 by Jelmer Vernooij
Add docstrings.
32
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
33
    # Whether this mapping supports exporting and importing all bzr semantics.
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
34
    roundtripping = False
0.205.18 by Jelmer Vernooij
Add docstrings.
35
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
36
    # Prefix used when importing native foreign revisions (not roundtripped) 
37
    # using this mapping.
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
38
    revid_prefix = None
39
0.205.9 by Jelmer Vernooij
Add abstract functions for converting revision ids between bzr and foreign vcses.
40
    def revision_id_bzr_to_foreign(self, bzr_revid):
41
        """Parse a bzr revision id and convert it to a foreign revid.
42
43
        :param bzr_revid: The bzr revision id (a string).
44
        :return: A foreign revision id, can be any sort of object.
45
        """
46
        raise NotImplementedError(self.revision_id_bzr_to_foreign)
47
48
    def revision_id_foreign_to_bzr(self, foreign_revid):
49
        """Parse a foreign revision id and convert it to a bzr revid.
50
51
        :param foreign_revid: Foreign revision id, can be any sort of object.
52
        :return: A bzr revision id.
53
        """
54
        raise NotImplementedError(self.revision_id_foreign_to_bzr)
55
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
56
    def show_foreign_revid(self, foreign_revid):
57
        """Prepare a foreign revision id for formatting using bzr log.
58
        
59
        :param foreign_revid: Foreign revision id.
60
        :return: Dictionary mapping string keys to string values.
61
        """
62
        return { }
63
0.205.1 by Jelmer Vernooij
Import utility functions for foreign branches.
64
65
class VcsMappingRegistry(registry.Registry):
66
    """Registry for Bazaar<->foreign VCS mappings.
67
    
68
    There should be one instance of this registry for every foreign VCS.
69
    """
70
71
    def register(self, key, factory, help):
72
        """Register a mapping between Bazaar and foreign VCS semantics.
73
74
        The factory must be a callable that takes one parameter: the key.
75
        It must produce an instance of VcsMapping when called.
76
        """
77
        registry.Registry.register(self, key, factory, help)
78
79
    def set_default(self, key):
80
        """Set the 'default' key to be a clone of the supplied key.
81
82
        This method must be called once and only once.
83
        """
84
        self._set_default_key(key)
85
86
    def get_default(self):
87
        """Convenience function for obtaining the default mapping to use."""
88
        return self.get(self._get_default_key())
89
0.205.6 by Jelmer Vernooij
Import FakeControlFiles.
90
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
91
class ForeignBranch(Branch):
0.205.18 by Jelmer Vernooij
Add docstrings.
92
    """Branch that exists in a foreign version control system."""
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
93
94
    def __init__(self, mapping):
95
        super(ForeignBranch, self).__init__()
96
        self.mapping = mapping
97
98
    def dpull(self, source, stop_revision=None):
0.205.18 by Jelmer Vernooij
Add docstrings.
99
        """Pull deltas from another branch.
100
101
        :note: This does not, like pull, retain the revision ids from 
102
        the source branch.
103
104
        :param source: Source branch
105
        :param stop_revision: Revision to pull, defaults to last revision.
106
        """
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
107
        raise NotImplementedError(self.pull)
108
109
0.205.6 by Jelmer Vernooij
Import FakeControlFiles.
110
class FakeControlFiles(object):
111
    """Dummy implementation of ControlFiles.
112
    
113
    This is required as some code relies on controlfiles being 
114
    available."""
115
    def get_utf8(self, name):
116
        raise errors.NoSuchFile(name)
117
118
    def get(self, name):
119
        raise errors.NoSuchFile(name)
120
121
    def break_lock(self):
122
        pass
123
0.205.7 by Jelmer Vernooij
Import dpush.
124
125
class cmd_dpush(Command):
0.205.8 by Jelmer Vernooij
Remove references to svn.
126
    """Push diffs into a foreign version control system without any 
127
    Bazaar-specific metadata.
0.205.7 by Jelmer Vernooij
Import dpush.
128
0.205.8 by Jelmer Vernooij
Remove references to svn.
129
    This will afterwards rebase the local Bazaar branch on the remote
0.205.7 by Jelmer Vernooij
Import dpush.
130
    branch unless the --no-rebase option is used, in which case 
131
    the two branches will be out of sync. 
132
    """
133
    takes_args = ['location?']
134
    takes_options = ['remember', Option('directory',
135
            help='Branch to push from, '
136
                 'rather than the one containing the working directory.',
137
            short_name='d',
138
            type=unicode,
139
            ),
140
            Option('no-rebase', help="Don't rebase after push")]
141
142
    def run(self, location=None, remember=False, directory=None, 
143
            no_rebase=False):
144
        from bzrlib import urlutils
145
        from bzrlib.bzrdir import BzrDir
146
        from bzrlib.errors import BzrCommandError, NoWorkingTree
147
        from bzrlib.workingtree import WorkingTree
148
149
        if directory is None:
150
            directory = "."
151
        try:
152
            source_wt = WorkingTree.open_containing(directory)[0]
153
            source_branch = source_wt.branch
154
        except NoWorkingTree:
155
            source_branch = Branch.open_containing(directory)[0]
156
            source_wt = None
157
        stored_loc = source_branch.get_push_location()
158
        if location is None:
159
            if stored_loc is None:
160
                raise BzrCommandError("No push location known or specified.")
161
            else:
162
                display_url = urlutils.unescape_for_display(stored_loc,
163
                        self.outf.encoding)
164
                self.outf.write("Using saved location: %s\n" % display_url)
165
                location = stored_loc
166
167
        bzrdir = BzrDir.open(location)
168
        target_branch = bzrdir.open_branch()
169
        target_branch.lock_write()
0.207.1 by Jelmer Vernooij
Add ForeignBranch class, make dpush fallback to regular push.
170
        if not isinstance(target_branch, ForeignBranch):
171
            info("target branch is not a foreign branch, using regular push.")
172
            target_branch.pull(source_branch)
173
            no_rebase = True
174
        else:
175
            revid_map = target_branch.dpull(source_branch)
0.205.7 by Jelmer Vernooij
Import dpush.
176
        # We successfully created the target, remember it
177
        if source_branch.get_push_location() is None or remember:
178
            source_branch.set_push_location(target_branch.base)
179
        if not no_rebase:
180
            _, old_last_revid = source_branch.last_revision_info()
181
            new_last_revid = revid_map[old_last_revid]
182
            if source_wt is not None:
183
                source_wt.pull(target_branch, overwrite=True, 
184
                               stop_revision=new_last_revid)
185
            else:
186
                source_branch.pull(target_branch, overwrite=True, 
187
                                   stop_revision=new_last_revid)
188
0.205.15 by Jelmer Vernooij
Add test_suite function.
189
def test_suite():
190
    from unittest import TestSuite
191
    from bzrlib.tests import TestUtil
192
    loader = TestUtil.TestLoader()
193
    suite = TestSuite()
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
194
    testmod_names = ['test_versionedfiles', ]
0.205.15 by Jelmer Vernooij
Add test_suite function.
195
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
196
    return suite
0.205.7 by Jelmer Vernooij
Import dpush.
197
0.205.18 by Jelmer Vernooij
Add docstrings.
198
0.207.2 by Jelmer Vernooij
Import escape commit message function.
199
def escape_commit_message(message):
200
    """Replace xml-incompatible control characters."""
201
    if message is None:
202
        return None
203
    import re
204
    # FIXME: RBC 20060419 this should be done by the revision
205
    # serialiser not by commit. Then we can also add an unescaper
206
    # in the deserializer and start roundtripping revision messages
207
    # precisely. See repository_implementations/test_repository.py
208
    
209
    # Python strings can include characters that can't be
210
    # represented in well-formed XML; escape characters that
211
    # aren't listed in the XML specification
212
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
213
    message, _ = re.subn(
214
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
215
        lambda match: match.group(0).encode('unicode_escape'),
216
        message)
217
    return message
218
0.205.19 by Jelmer Vernooij
import bzr-svn improvements.
219
220
class ForeignRevision(Revision):
221
    """A Revision from a Foreign repository. Remembers 
222
    information about foreign revision id and mapping.
223
224
    """
225
226
    def __init__(self, foreign_revid, mapping, *args, **kwargs):
227
        super(ForeignRevision, self).__init__(*args, **kwargs)
228
        self.foreign_revid = foreign_revid
229
        self.mapping = mapping
230
231
232
def show_foreign_properties(mapping_registry, rev):
233
    """Custom log displayer for foreign revision identifiers.
234
235
    :param rev: Revision object.
236
    """
237
    # Revision comes directly from a foreign repository
238
    if isinstance(rev, ForeignRevision):
239
        return rev.mapping.show_foreign_revid(rev.foreign_revid)
240
241
    # Revision was once imported from a foreign repository
242
    try:
243
        foreign_revid, mapping = mapping_registry.parse_revision_id(rev.revision_id)
244
    except InvalidRevisionId:
245
        return {}
246
247
    return mapping.show_foreign_revid(foreign_revid)
248
249