/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-14 18:17:35 UTC
  • mto: (0.436.139 foreign)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20090314181735-i2u2gb2lv6iyy2no
Add keys to virtual VersionedFiles.

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