/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 __init__.py

  • Committer: Jelmer Vernooij
  • Date: 2009-03-19 16:43:56 UTC
  • mto: (0.436.139 foreign)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20090319164356-iwxw3x3ntre7fjxc
Fix formatting.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008-2009 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
 
 
19
from bzrlib import (
 
20
    errors,
 
21
    )
 
22
from bzrlib.branch import (
 
23
    Branch,
 
24
    )
 
25
from bzrlib.commands import (
 
26
    Command,
 
27
    Option,
 
28
    )
 
29
 
 
30
 
 
31
class ForeignBranch(Branch):
 
32
    """Branch that exists in a foreign version control system."""
 
33
 
 
34
    def __init__(self, mapping):
 
35
        self.mapping = mapping
 
36
        super(ForeignBranch, self).__init__()
 
37
 
 
38
    def dpull(self, source, stop_revision=None):
 
39
        """Pull deltas from another branch.
 
40
 
 
41
        :note: This does not, like pull, retain the revision ids from 
 
42
            the source branch and will, rather than adding bzr-specific 
 
43
            metadata, push only those semantics of the revision that can be 
 
44
            natively represented in this branch.
 
45
 
 
46
        :param source: Source branch
 
47
        :param stop_revision: Revision to pull, defaults to last revision.
 
48
        :return: Revision id map and file id map
 
49
        """
 
50
        raise NotImplementedError(self.dpull)
 
51
 
 
52
 
 
53
class FakeControlFiles(object):
 
54
    """Dummy implementation of ControlFiles.
 
55
    
 
56
    This is required as some code relies on controlfiles being 
 
57
    available."""
 
58
    def get_utf8(self, name):
 
59
        raise errors.NoSuchFile(name)
 
60
 
 
61
    def get(self, name):
 
62
        raise errors.NoSuchFile(name)
 
63
 
 
64
    def break_lock(self):
 
65
        pass
 
66
 
 
67
 
 
68
class cmd_dpush(Command):
 
69
    """Push diffs into a foreign branch without any bzr-specific metadata.
 
70
 
 
71
    This will afterwards rebase the local Bazaar branch on the remote
 
72
    branch unless the --no-rebase option is used, in which case 
 
73
    the two branches will be out of sync. 
 
74
    """
 
75
    takes_args = ['location?']
 
76
    takes_options = ['remember', Option('directory',
 
77
            help='Branch to push from, '
 
78
                 'rather than the one containing the working directory.',
 
79
            short_name='d',
 
80
            type=unicode,
 
81
            ),
 
82
            Option("idmap-file", help="Write map with old and new revision ids.", type=str),
 
83
            Option('no-rebase', help="Don't rebase after push")]
 
84
 
 
85
    def run(self, location=None, remember=False, directory=None, 
 
86
            no_rebase=False, idmap_file=None):
 
87
        from bzrlib import urlutils
 
88
        from bzrlib.bzrdir import BzrDir
 
89
        from bzrlib.errors import BzrCommandError, NoWorkingTree
 
90
        from bzrlib.inventory import Inventory
 
91
        from bzrlib.revision import NULL_REVISION
 
92
        from bzrlib.trace import info
 
93
        from bzrlib.workingtree import WorkingTree
 
94
        from upgrade import update_workinginv_fileids
 
95
 
 
96
        def get_inv(wt, revid):
 
97
            if revid == NULL_REVISION:
 
98
                return Inventory()
 
99
            else:
 
100
                return wt.branch.repository.get_inventory(revid)
 
101
 
 
102
        if directory is None:
 
103
            directory = "."
 
104
        try:
 
105
            source_wt = WorkingTree.open_containing(directory)[0]
 
106
            source_branch = source_wt.branch
 
107
        except NoWorkingTree:
 
108
            source_branch = Branch.open_containing(directory)[0]
 
109
            source_wt = None
 
110
        stored_loc = source_branch.get_push_location()
 
111
        if location is None:
 
112
            if stored_loc is None:
 
113
                raise BzrCommandError("No push location known or specified.")
 
114
            else:
 
115
                display_url = urlutils.unescape_for_display(stored_loc,
 
116
                        self.outf.encoding)
 
117
                self.outf.write("Using saved location: %s\n" % display_url)
 
118
                location = stored_loc
 
119
 
 
120
        bzrdir = BzrDir.open(location)
 
121
        target_branch = bzrdir.open_branch()
 
122
        target_branch.lock_write()
 
123
        try:
 
124
            if getattr(target_branch, "dpull", None) is None:
 
125
                info("target branch is not a foreign branch, using regular push.")
 
126
                target_branch.pull(source_branch)
 
127
                no_rebase = True
 
128
            else:
 
129
                revid_map = target_branch.dpull(source_branch)
 
130
                if idmap_file:
 
131
                    f = open(idmap_file, "w")
 
132
                    try:
 
133
                        f.write("".join(["%s\t%s\n" % item for item in revid_map.iteritems()]))
 
134
                    finally:
 
135
                        f.close()
 
136
            # We successfully created the target, remember it
 
137
            if source_branch.get_push_location() is None or remember:
 
138
                source_branch.set_push_location(target_branch.base)
 
139
            if not no_rebase:
 
140
                _, old_last_revid = source_branch.last_revision_info()
 
141
                new_last_revid = revid_map[old_last_revid]
 
142
                if source_wt is not None:
 
143
                    source_wt.pull(target_branch, overwrite=True, 
 
144
                                   stop_revision=new_last_revid)
 
145
                    source_wt.lock_write()
 
146
                    try:
 
147
                        update_workinginv_fileids(source_wt, 
 
148
                            get_inv(source_wt, old_last_revid), 
 
149
                            get_inv(source_wt, new_last_revid))
 
150
                    finally:
 
151
                        source_wt.unlock()
 
152
                else:
 
153
                    source_branch.pull(target_branch, overwrite=True, 
 
154
                                       stop_revision=new_last_revid)
 
155
        finally:
 
156
            target_branch.unlock()
 
157
 
 
158
 
 
159
class cmd_foreign_mapping_upgrade(Command):
 
160
    """Upgrade revisions mapped from a foreign version control system.
 
161
    
 
162
    This will change the identity of revisions whose parents 
 
163
    were mapped from revisions in the other version control system.
 
164
 
 
165
    You are recommended to run "bzr check" in the local repository 
 
166
    after running this command.
 
167
    """
 
168
    aliases = ['svn-upgrade']
 
169
    takes_args = ['from_repository?']
 
170
    takes_options = ['verbose', 
 
171
            Option("idmap-file", help="Write map with old and new revision ids.", type=str)]
 
172
 
 
173
    def run(self, from_repository=None, verbose=False, idmap_file=None):
 
174
        from upgrade import upgrade_branch, upgrade_workingtree
 
175
        from bzrlib.branch import Branch
 
176
        from bzrlib.errors import NoWorkingTree, BzrCommandError
 
177
        from bzrlib.repository import Repository
 
178
        from bzrlib.trace import info
 
179
        from bzrlib.workingtree import WorkingTree
 
180
        try:
 
181
            wt_to = WorkingTree.open(".")
 
182
            branch_to = wt_to.branch
 
183
        except NoWorkingTree:
 
184
            wt_to = None
 
185
            branch_to = Branch.open(".")
 
186
 
 
187
        stored_loc = branch_to.get_parent()
 
188
        if from_repository is None:
 
189
            if stored_loc is None:
 
190
                raise BzrCommandError("No pull location known or"
 
191
                                             " specified.")
 
192
            else:
 
193
                import bzrlib.urlutils as urlutils
 
194
                display_url = urlutils.unescape_for_display(stored_loc,
 
195
                        self.outf.encoding)
 
196
                self.outf.write("Using saved location: %s\n" % display_url)
 
197
                from_repository = Branch.open(stored_loc).repository
 
198
        else:
 
199
            from_repository = Repository.open(from_repository)
 
200
 
 
201
        vcs = getattr(from_repository, "vcs", None)
 
202
        if vcs is None:
 
203
            raise BzrCommandError("Repository at %s is not a foreign repository.a" % from_repository.base)
 
204
 
 
205
        new_mapping = from_repository.get_mapping()
 
206
 
 
207
        if wt_to is not None:
 
208
            renames = upgrade_workingtree(wt_to, from_repository, 
 
209
                                          new_mapping=new_mapping,
 
210
                                          allow_changes=True, verbose=verbose)
 
211
        else:
 
212
            renames = upgrade_branch(branch_to, from_repository, 
 
213
                                     new_mapping=new_mapping,
 
214
                                     allow_changes=True, verbose=verbose)
 
215
 
 
216
        if renames == {}:
 
217
            info("Nothing to do.")
 
218
 
 
219
        if idmap_file is not None:
 
220
            f = open(idmap_file, 'w')
 
221
            try:
 
222
                for oldid, newid in renames.iteritems():
 
223
                    f.write("%s\t%s\n" % (oldid, newid))
 
224
            finally:
 
225
                f.close()
 
226
 
 
227
        if wt_to is not None:
 
228
            wt_to.set_last_revision(branch_to.last_revision())
 
229
 
 
230
 
 
231
def test_suite():
 
232
    from unittest import TestSuite
 
233
    from bzrlib.tests import TestUtil
 
234
    loader = TestUtil.TestLoader()
 
235
    suite = TestSuite()
 
236
    testmod_names = ['test_versionedfiles', ]
 
237
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
 
238
    return suite
 
239
 
 
240
 
 
241
def escape_commit_message(message):
 
242
    """Replace xml-incompatible control characters."""
 
243
    if message is None:
 
244
        return None
 
245
    import re
 
246
    # FIXME: RBC 20060419 this should be done by the revision
 
247
    # serialiser not by commit. Then we can also add an unescaper
 
248
    # in the deserializer and start roundtripping revision messages
 
249
    # precisely. See repository_implementations/test_repository.py
 
250
    
 
251
    # Python strings can include characters that can't be
 
252
    # represented in well-formed XML; escape characters that
 
253
    # aren't listed in the XML specification
 
254
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
 
255
    message, _ = re.subn(
 
256
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
 
257
        lambda match: match.group(0).encode('unicode_escape'),
 
258
        message)
 
259
    return message
 
260
 
 
261