/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: 2009-07-20 06:06:22 UTC
  • mto: This revision was merged to the branch mainline in revision 4553.
  • Revision ID: robertc@robertcollins.net-20090720060622-ey7a2b2cegan37yh
Change the tree transform test_first_commit test to set a root id in the new tree, and workaround an apparent bug in TreeTransform._determine_path.

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 
46
 
            metadata, push only those semantics of the revision that can be 
47
 
            natively represented in this branch.
48
 
 
49
 
        :param source: Source branch
50
 
        :param stop_revision: Revision to pull, defaults to last revision.
51
 
        :return: Revision id map and file id map
52
 
        """
53
 
        raise NotImplementedError(self.dpull)
54
 
 
55
 
 
56
 
class FakeControlFiles(object):
57
 
    """Dummy implementation of ControlFiles.
58
 
    
59
 
    This is required as some code relies on controlfiles being 
60
 
    available."""
61
 
    def get_utf8(self, name):
62
 
        raise errors.NoSuchFile(name)
63
 
 
64
 
    def get(self, name):
65
 
        raise errors.NoSuchFile(name)
66
 
 
67
 
    def break_lock(self):
68
 
        pass
69
 
 
70
 
 
71
 
class cmd_dpush(Command):
72
 
    """Push diffs into a foreign version control system without any 
73
 
    Bazaar-specific metadata.
74
 
 
75
 
    This will afterwards rebase the local Bazaar branch on the remote
76
 
    branch unless the --no-rebase option is used, in which case 
77
 
    the two branches will be out of sync. 
78
 
    """
79
 
    takes_args = ['location?']
80
 
    takes_options = ['remember', Option('directory',
81
 
            help='Branch to push from, '
82
 
                 'rather than the one containing the working directory.',
83
 
            short_name='d',
84
 
            type=unicode,
85
 
            ),
86
 
            Option('no-rebase', help="Don't rebase after push")]
87
 
 
88
 
    def run(self, location=None, remember=False, directory=None, 
89
 
            no_rebase=False):
90
 
        from bzrlib import urlutils
91
 
        from bzrlib.bzrdir import BzrDir
92
 
        from bzrlib.errors import BzrCommandError, NoWorkingTree
93
 
        from bzrlib.trace import info
94
 
        from bzrlib.workingtree import WorkingTree
95
 
        from upgrade import update_workingtree_fileids
96
 
 
97
 
        if directory is None:
98
 
            directory = "."
99
 
        try:
100
 
            source_wt = WorkingTree.open_containing(directory)[0]
101
 
            source_branch = source_wt.branch
102
 
        except NoWorkingTree:
103
 
            source_branch = Branch.open_containing(directory)[0]
104
 
            source_wt = None
105
 
        stored_loc = source_branch.get_push_location()
106
 
        if location is None:
107
 
            if stored_loc is None:
108
 
                raise BzrCommandError("No push location known or specified.")
109
 
            else:
110
 
                display_url = urlutils.unescape_for_display(stored_loc,
111
 
                        self.outf.encoding)
112
 
                self.outf.write("Using saved location: %s\n" % display_url)
113
 
                location = stored_loc
114
 
 
115
 
        bzrdir = BzrDir.open(location)
116
 
        target_branch = bzrdir.open_branch()
117
 
        target_branch.lock_write()
118
 
        try:
119
 
            if not isinstance(target_branch, ForeignBranch):
120
 
                info("target branch is not a foreign branch, using regular push.")
121
 
                target_branch.pull(source_branch)
122
 
                no_rebase = True
123
 
            else:
124
 
                revid_map = target_branch.dpull(source_branch)
125
 
            # We successfully created the target, remember it
126
 
            if source_branch.get_push_location() is None or remember:
127
 
                source_branch.set_push_location(target_branch.base)
128
 
            if not no_rebase:
129
 
                _, old_last_revid = source_branch.last_revision_info()
130
 
                new_last_revid = revid_map[old_last_revid]
131
 
                if source_wt is not None:
132
 
                    source_wt.pull(target_branch, overwrite=True, 
133
 
                                   stop_revision=new_last_revid)
134
 
                    source_wt.lock_write()
135
 
                    try:
136
 
                        update_workingtree_fileids(source_wt, 
137
 
                            source_wt.branch.repository.revision_tree(old_last_revid),
138
 
                            source_wt.branch.repository.revision_tree(new_last_revid))
139
 
                    finally:
140
 
                        source_wt.unlock()
141
 
                else:
142
 
                    source_branch.pull(target_branch, overwrite=True, 
143
 
                                       stop_revision=new_last_revid)
144
 
        finally:
145
 
            target_branch.unlock()
146
 
 
147
 
def test_suite():
148
 
    from unittest import TestSuite
149
 
    from bzrlib.tests import TestUtil
150
 
    loader = TestUtil.TestLoader()
151
 
    suite = TestSuite()
152
 
    testmod_names = ['test_versionedfiles', ]
153
 
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
154
 
    return suite
155
 
 
156
 
 
157
 
def escape_commit_message(message):
158
 
    """Replace xml-incompatible control characters."""
159
 
    if message is None:
160
 
        return None
161
 
    import re
162
 
    # FIXME: RBC 20060419 this should be done by the revision
163
 
    # serialiser not by commit. Then we can also add an unescaper
164
 
    # in the deserializer and start roundtripping revision messages
165
 
    # precisely. See repository_implementations/test_repository.py
166
 
    
167
 
    # Python strings can include characters that can't be
168
 
    # represented in well-formed XML; escape characters that
169
 
    # aren't listed in the XML specification
170
 
    # (http://www.w3.org/TR/REC-xml/#NT-Char).
171
 
    message, _ = re.subn(
172
 
        u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]+',
173
 
        lambda match: match.group(0).encode('unicode_escape'),
174
 
        message)
175
 
    return message
176
 
 
177