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

  • Committer: Robert Collins
  • Date: 2006-09-04 08:00:00 UTC
  • mto: (1981.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 1982.
  • Revision ID: robertc@robertcollins.net-20060904080000-1152da5eed765694
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
 
19
 
from bzrlib.branch import Branch
20
 
from bzrlib.commands import Command, Option
21
 
from bzrlib.repository import Repository
22
 
from bzrlib.revision import Revision
23
 
from bzrlib.lazy_import import lazy_import
24
 
lazy_import(globals(), """
25
 
from bzrlib import (
26
 
    errors,
27
 
    log,
28
 
    osutils,
29
 
    registry,
30
 
    )
31
 
""")
32
 
 
33
 
 
34
 
class ForeignBranch(Branch):
35
 
    """Branch that exists in a foreign version control system."""
36
 
 
37
 
    def __init__(self, mapping):
38
 
        self.mapping = mapping
39
 
        super(ForeignBranch, self).__init__()
40
 
 
41
 
    def dpull(self, source, stop_revision=None):
42
 
        """Pull deltas from another branch.
43
 
 
44
 
        :note: This does not, like pull, retain the revision ids from 
45
 
        the source branch and will, rather than adding bzr-specific metadata,
46
 
        push only those semantics of the revision that can be natively 
47
 
        represented in this branch.
48
 
 
49
 
        :param source: Source branch
50
 
        :param stop_revision: Revision to pull, defaults to last revision.
51
 
        """
52
 
        raise NotImplementedError(self.pull)
53
 
 
54
 
 
55
 
class ForeignRepository(Repository):
56
 
 
57
 
    def has_foreign_revision(self, foreign_revid):
58
 
        raise NotImplementedError(self.has_foreign_revision)
59
 
 
60
 
    def all_revision_ids(self, mapping=None):
61
 
        raise NotImplementedError(self.all_revision_ids)
62
 
 
63
 
    def get_mapping(self):
64
 
        raise NotImplementedError(self.get_mapping)
65
 
 
66
 
    def get_inventory_xml(self, revision_id):
67
 
        """See Repository.get_inventory_xml()."""
68
 
        return self.serialise_inventory(self.get_inventory(revision_id))
69
 
 
70
 
    def get_inventory_sha1(self, revision_id):
71
 
        """Get the sha1 for the XML representation of an inventory.
72
 
 
73
 
        :param revision_id: Revision id of the inventory for which to return 
74
 
         the SHA1.
75
 
        :return: XML string
76
 
        """
77
 
 
78
 
        return osutils.sha_string(self.get_inventory_xml(revision_id))
79
 
 
80
 
    def get_revision_xml(self, revision_id):
81
 
        """Return the XML representation of a revision.
82
 
 
83
 
        :param revision_id: Revision for which to return the XML.
84
 
        :return: XML string
85
 
        """
86
 
        return self._serializer.write_revision_to_string(self.get_revision(revision_id))
87
 
 
88
 
 
89
 
 
90
 
class FakeControlFiles(object):
91
 
    """Dummy implementation of ControlFiles.
92
 
    
93
 
    This is required as some code relies on controlfiles being 
94
 
    available."""
95
 
    def get_utf8(self, name):
96
 
        raise errors.NoSuchFile(name)
97
 
 
98
 
    def get(self, name):
99
 
        raise errors.NoSuchFile(name)
100
 
 
101
 
    def break_lock(self):
102
 
        pass
103
 
 
104
 
 
105
 
class cmd_dpush(Command):
106
 
    """Push diffs into a foreign version control system without any 
107
 
    Bazaar-specific metadata.
108
 
 
109
 
    This will afterwards rebase the local Bazaar branch on the remote
110
 
    branch unless the --no-rebase option is used, in which case 
111
 
    the two branches will be out of sync. 
112
 
    """
113
 
    takes_args = ['location?']
114
 
    takes_options = ['remember', Option('directory',
115
 
            help='Branch to push from, '
116
 
                 'rather than the one containing the working directory.',
117
 
            short_name='d',
118
 
            type=unicode,
119
 
            ),
120
 
            Option('no-rebase', help="Don't rebase after push")]
121
 
 
122
 
    def run(self, location=None, remember=False, directory=None, 
123
 
            no_rebase=False):
124
 
        from bzrlib import urlutils
125
 
        from bzrlib.bzrdir import BzrDir
126
 
        from bzrlib.errors import BzrCommandError, NoWorkingTree
127
 
        from bzrlib.trace import info
128
 
        from bzrlib.workingtree import WorkingTree
129
 
 
130
 
        if directory is None:
131
 
            directory = "."
132
 
        try:
133
 
            source_wt = WorkingTree.open_containing(directory)[0]
134
 
            source_branch = source_wt.branch
135
 
        except NoWorkingTree:
136
 
            source_branch = Branch.open_containing(directory)[0]
137
 
            source_wt = None
138
 
        stored_loc = source_branch.get_push_location()
139
 
        if location is None:
140
 
            if stored_loc is None:
141
 
                raise BzrCommandError("No push location known or specified.")
142
 
            else:
143
 
                display_url = urlutils.unescape_for_display(stored_loc,
144
 
                        self.outf.encoding)
145
 
                self.outf.write("Using saved location: %s\n" % display_url)
146
 
                location = stored_loc
147
 
 
148
 
        bzrdir = BzrDir.open(location)
149
 
        target_branch = bzrdir.open_branch()
150
 
        target_branch.lock_write()
151
 
        if not isinstance(target_branch, ForeignBranch):
152
 
            info("target branch is not a foreign branch, using regular push.")
153
 
            target_branch.pull(source_branch)
154
 
            no_rebase = True
155
 
        else:
156
 
            revid_map = target_branch.dpull(source_branch)
157
 
        # We successfully created the target, remember it
158
 
        if source_branch.get_push_location() is None or remember:
159
 
            source_branch.set_push_location(target_branch.base)
160
 
        if not no_rebase:
161
 
            _, old_last_revid = source_branch.last_revision_info()
162
 
            new_last_revid = revid_map[old_last_revid]
163
 
            if source_wt is not None:
164
 
                source_wt.pull(target_branch, overwrite=True, 
165
 
                               stop_revision=new_last_revid)
166
 
            else:
167
 
                source_branch.pull(target_branch, overwrite=True, 
168
 
                                   stop_revision=new_last_revid)
169
 
 
170
 
def test_suite():
171
 
    from unittest import TestSuite
172
 
    from bzrlib.tests import TestUtil
173
 
    loader = TestUtil.TestLoader()
174
 
    suite = TestSuite()
175
 
    testmod_names = ['test_versionedfiles', ]
176
 
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
177
 
    return suite
178
 
 
179
 
 
180
 
def escape_commit_message(message):
181
 
    """Replace xml-incompatible control characters."""
182
 
    if message is None:
183
 
        return None
184
 
    import re
185
 
    # FIXME: RBC 20060419 this should be done by the revision
186
 
    # serialiser not by commit. Then we can also add an unescaper
187
 
    # in the deserializer and start roundtripping revision messages
188
 
    # precisely. See repository_implementations/test_repository.py
189
 
    
190
 
    # Python strings can include characters that can't be
191
 
    # represented in well-formed XML; escape characters that
192
 
    # aren't listed in the XML specification
193
 
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
194
 
    message, _ = re.subn(
195
 
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
196
 
        lambda match: match.group(0).encode('unicode_escape'),
197
 
        message)
198
 
    return message
199
 
 
200