/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-02-15 01:34:16 UTC
  • mto: (0.436.139 foreign)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20090215013416-mmu844aamvlqefey
Fix typo.

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