/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4597.9.2 by Vincent Ladeuil
Merge bzr.dev into cleanup
1
# Copyright (C) 2007-2010 Canonical Ltd
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
16
6207.3.3 by jelmer at samba
Fix tests and the like.
17
"""Reconfigure a controldir into a new tree/branch/repository layout.
4509.3.38 by Martin Pool
Move reconfigure --stacked-on core code into reconfigure.py
18
19
Various types of reconfiguration operation are available either by
20
constructing a class or using a factory method on Reconfigure.
21
"""
22
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
23
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
24
from . import (
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
25
    branch,
6207.3.3 by jelmer at samba
Fix tests and the like.
26
    controldir,
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
27
    errors,
4509.3.38 by Martin Pool
Move reconfigure --stacked-on core code into reconfigure.py
28
    trace,
29
    ui,
30
    urlutils,
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
31
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
32
from .i18n import gettext
4509.3.38 by Martin Pool
Move reconfigure --stacked-on core code into reconfigure.py
33
34
# TODO: common base class for all reconfigure operations, making no
35
# assumptions about what kind of change will be done.
36
37
6734.1.17 by Jelmer Vernooij
Move format custom errors.
38
class BzrDirError(errors.BzrError):
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
39
40
    def __init__(self, controldir):
41
        display_url = urlutils.unescape_for_display(controldir.user_url,
42
                                                    'ascii')
6734.1.17 by Jelmer Vernooij
Move format custom errors.
43
        errors.BzrError.__init__(self, controldir=controldir,
44
                                 display_url=display_url)
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
45
46
47
class NoBindLocation(BzrDirError):
48
49
    _fmt = "No location could be found to bind to at %(display_url)s."
50
51
52
class UnsyncedBranches(BzrDirError):
53
54
    _fmt = ("'%(display_url)s' is not in sync with %(target_url)s.  See"
55
            " brz help sync-for-reconfigure.")
56
57
    def __init__(self, controldir, target_branch):
6744 by Jelmer Vernooij
Merge lp:~jelmer/brz/move-errors-knit.
58
        errors.BzrError.__init__(self, controldir)
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
59
        from . import urlutils
60
        self.target_url = urlutils.unescape_for_display(target_branch.base,
61
                                                        'ascii')
62
63
64
class AlreadyBranch(BzrDirError):
65
66
    _fmt = "'%(display_url)s' is already a branch."
67
68
69
class AlreadyTree(BzrDirError):
70
71
    _fmt = "'%(display_url)s' is already a tree."
72
73
74
class AlreadyCheckout(BzrDirError):
75
76
    _fmt = "'%(display_url)s' is already a checkout."
77
78
79
class AlreadyLightweightCheckout(BzrDirError):
80
81
    _fmt = "'%(display_url)s' is already a lightweight checkout."
82
83
84
class AlreadyUsingShared(BzrDirError):
85
86
    _fmt = "'%(display_url)s' is already using a shared repository."
87
88
89
class AlreadyStandalone(BzrDirError):
90
91
    _fmt = "'%(display_url)s' is already standalone."
92
93
94
class AlreadyWithTrees(BzrDirError):
95
96
    _fmt = ("Shared repository '%(display_url)s' already creates "
97
            "working trees.")
98
99
100
class AlreadyWithNoTrees(BzrDirError):
101
102
    _fmt = ("Shared repository '%(display_url)s' already doesn't create "
103
            "working trees.")
104
105
106
class ReconfigurationNotSupported(BzrDirError):
107
108
    _fmt = "Requested reconfiguration of '%(display_url)s' is not supported."
109
110
4509.3.38 by Martin Pool
Move reconfigure --stacked-on core code into reconfigure.py
111
class ReconfigureStackedOn(object):
112
    """Reconfigures a branch to be stacked on another branch."""
113
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
114
    def apply(self, controldir, stacked_on_url):
115
        branch = controldir.open_branch()
4509.3.38 by Martin Pool
Move reconfigure --stacked-on core code into reconfigure.py
116
        # it may be a path relative to the cwd or a url; the branch wants
117
        # a path relative to itself...
118
        on_url = urlutils.relative_url(branch.base,
7143.15.2 by Jelmer Vernooij
Run autopep8.
119
                                       urlutils.normalize_url(stacked_on_url))
7356.1.2 by Jelmer Vernooij
Use ExitStack in more places.
120
        with branch.lock_write():
4509.3.38 by Martin Pool
Move reconfigure --stacked-on core code into reconfigure.py
121
            branch.set_stacked_on_url(on_url)
122
            if not trace.is_quiet():
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
123
                ui.ui_factory.note(gettext(
124
                    "{0} is now stacked on {1}\n").format(
7143.15.2 by Jelmer Vernooij
Run autopep8.
125
                    branch.base, branch.get_stacked_on_url()))
4509.3.38 by Martin Pool
Move reconfigure --stacked-on core code into reconfigure.py
126
127
4509.3.39 by Martin Pool
Move reconfigure --unstacked to reconfigure.py
128
class ReconfigureUnstacked(object):
129
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
130
    def apply(self, controldir):
131
        branch = controldir.open_branch()
7356.1.2 by Jelmer Vernooij
Use ExitStack in more places.
132
        with branch.lock_write():
4509.3.39 by Martin Pool
Move reconfigure --unstacked to reconfigure.py
133
            branch.set_stacked_on_url(None)
134
            if not trace.is_quiet():
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
135
                ui.ui_factory.note(gettext(
136
                    "%s is now not stacked\n")
4509.3.39 by Martin Pool
Move reconfigure --unstacked to reconfigure.py
137
                    % (branch.base,))
138
139
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
140
class Reconfigure(object):
141
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
142
    def __init__(self, controldir, new_bound_location=None):
143
        self.controldir = controldir
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
144
        self.new_bound_location = new_bound_location
4509.1.1 by Jelmer Vernooij
Fix for unbound variable in reconfiguring lightweight checkout
145
        self.local_repository = None
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
146
        try:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
147
            self.repository = self.controldir.find_repository()
2796.2.7 by Aaron Bentley
Implement converting a lightweight checkout to a branch
148
        except errors.NoRepositoryPresent:
149
            self.repository = None
4324.2.1 by Jelmer Vernooij
Make sure class member local_repository of reconfigure is initialized.
150
            self.local_repository = None
3311.2.2 by Aaron Bentley
Flesh out to_sharing
151
        else:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
152
            if (self.repository.user_url == self.controldir.user_url):
3311.2.2 by Aaron Bentley
Flesh out to_sharing
153
                self.local_repository = self.repository
154
            else:
155
                self.local_repository = None
2796.2.7 by Aaron Bentley
Implement converting a lightweight checkout to a branch
156
        try:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
157
            branch = self.controldir.open_branch()
158
            if branch.user_url == controldir.user_url:
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
159
                self.local_branch = branch
160
                self.referenced_branch = None
161
            else:
162
                self.local_branch = None
163
                self.referenced_branch = branch
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
164
        except errors.NotBranchError:
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
165
            self.local_branch = None
2796.2.9 by Aaron Bentley
Ensure conversion from lightweight checkout works
166
            self.referenced_branch = None
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
167
        try:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
168
            self.tree = controldir.open_workingtree()
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
169
        except errors.NoWorkingTree:
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
170
            self.tree = None
2796.2.14 by Aaron Bentley
Updates from review
171
        self._unbind = False
172
        self._bind = False
173
        self._destroy_reference = False
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
174
        self._create_reference = False
175
        self._destroy_branch = False
2796.2.14 by Aaron Bentley
Updates from review
176
        self._create_branch = False
177
        self._destroy_tree = False
178
        self._create_tree = False
179
        self._create_repository = False
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
180
        self._destroy_repository = False
3983.3.7 by Marius Kruger
apply changes in apply again
181
        self._repository_trees = None
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
182
183
    @staticmethod
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
184
    def to_branch(controldir):
185
        """Return a Reconfiguration to convert this controldir into a branch
2796.2.16 by Aaron Bentley
Documentation updates from review
186
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
187
        :param controldir: The controldir to reconfigure
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
188
        :raise AlreadyBranch: if controldir is already a branch
2796.2.16 by Aaron Bentley
Documentation updates from review
189
        """
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
190
        reconfiguration = Reconfigure(controldir)
2796.2.15 by Aaron Bentley
More updates from review
191
        reconfiguration._plan_changes(want_tree=False, want_branch=True,
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
192
                                      want_bound=False, want_reference=False)
2796.2.14 by Aaron Bentley
Updates from review
193
        if not reconfiguration.changes_planned():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
194
            raise AlreadyBranch(controldir)
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
195
        return reconfiguration
196
197
    @staticmethod
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
198
    def to_tree(controldir):
199
        """Return a Reconfiguration to convert this controldir into a tree
2796.2.16 by Aaron Bentley
Documentation updates from review
200
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
201
        :param controldir: The controldir to reconfigure
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
202
        :raise AlreadyTree: if controldir is already a tree
2796.2.16 by Aaron Bentley
Documentation updates from review
203
        """
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
204
        reconfiguration = Reconfigure(controldir)
2796.2.15 by Aaron Bentley
More updates from review
205
        reconfiguration._plan_changes(want_tree=True, want_branch=True,
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
206
                                      want_bound=False, want_reference=False)
2796.2.14 by Aaron Bentley
Updates from review
207
        if not reconfiguration.changes_planned():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
208
            raise AlreadyTree(controldir)
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
209
        return reconfiguration
210
211
    @staticmethod
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
212
    def to_checkout(controldir, bound_location=None):
213
        """Return a Reconfiguration to convert this controldir into a checkout
2796.2.16 by Aaron Bentley
Documentation updates from review
214
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
215
        :param controldir: The controldir to reconfigure
2796.2.16 by Aaron Bentley
Documentation updates from review
216
        :param bound_location: The location the checkout should be bound to.
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
217
        :raise AlreadyCheckout: if controldir is already a checkout
2796.2.16 by Aaron Bentley
Documentation updates from review
218
        """
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
219
        reconfiguration = Reconfigure(controldir, bound_location)
2796.2.15 by Aaron Bentley
More updates from review
220
        reconfiguration._plan_changes(want_tree=True, want_branch=True,
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
221
                                      want_bound=True, want_reference=False)
2796.2.14 by Aaron Bentley
Updates from review
222
        if not reconfiguration.changes_planned():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
223
            raise AlreadyCheckout(controldir)
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
224
        return reconfiguration
225
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
226
    @classmethod
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
227
    def to_lightweight_checkout(klass, controldir, reference_location=None):
228
        """Make a Reconfiguration to convert controldir into a lightweight checkout
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
229
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
230
        :param controldir: The controldir to reconfigure
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
231
        :param bound_location: The location the checkout should be bound to.
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
232
        :raise AlreadyLightweightCheckout: if controldir is already a
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
233
            lightweight checkout
234
        """
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
235
        reconfiguration = klass(controldir, reference_location)
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
236
        reconfiguration._plan_changes(want_tree=True, want_branch=False,
237
                                      want_bound=False, want_reference=True)
238
        if not reconfiguration.changes_planned():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
239
            raise AlreadyLightweightCheckout(controldir)
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
240
        return reconfiguration
241
3311.2.1 by Aaron Bentley
Initial make-sharing functionality
242
    @classmethod
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
243
    def to_use_shared(klass, controldir):
3311.2.6 by Aaron Bentley
rename 'sharing' to 'use-shared'
244
        """Convert a standalone branch into a repository branch"""
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
245
        reconfiguration = klass(controldir)
3311.2.6 by Aaron Bentley
rename 'sharing' to 'use-shared'
246
        reconfiguration._set_use_shared(use_shared=True)
3311.2.2 by Aaron Bentley
Flesh out to_sharing
247
        if not reconfiguration.changes_planned():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
248
            raise AlreadyUsingShared(controldir)
3311.2.1 by Aaron Bentley
Initial make-sharing functionality
249
        return reconfiguration
250
3311.2.4 by Aaron Bentley
Implement conversion to standalone
251
    @classmethod
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
252
    def to_standalone(klass, controldir):
3311.2.6 by Aaron Bentley
rename 'sharing' to 'use-shared'
253
        """Convert a repository branch into a standalone branch"""
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
254
        reconfiguration = klass(controldir)
3311.2.6 by Aaron Bentley
rename 'sharing' to 'use-shared'
255
        reconfiguration._set_use_shared(use_shared=False)
3311.2.4 by Aaron Bentley
Implement conversion to standalone
256
        if not reconfiguration.changes_planned():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
257
            raise AlreadyStandalone(controldir)
3311.2.4 by Aaron Bentley
Implement conversion to standalone
258
        return reconfiguration
259
3921.4.2 by Matthew Fuller
Add support in Reconfigure for manipulating the repository setting for
260
    @classmethod
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
261
    def set_repository_trees(klass, controldir, with_trees):
3983.3.2 by Marius Kruger
make changes directly in set_repository_trees()
262
        """Adjust a repository's working tree presence default"""
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
263
        reconfiguration = klass(controldir)
3921.4.10 by Matthew Fuller
Stop trying to use _plan_changes() wholesale and just move all the
264
        if not reconfiguration.repository.is_shared():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
265
            raise ReconfigurationNotSupported(reconfiguration.controldir)
3983.3.2 by Marius Kruger
make changes directly in set_repository_trees()
266
        if with_trees and reconfiguration.repository.make_working_trees():
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
267
            raise AlreadyWithTrees(controldir)
7143.15.2 by Jelmer Vernooij
Run autopep8.
268
        elif (not with_trees and
269
              not reconfiguration.repository.make_working_trees()):
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
270
            raise AlreadyWithNoTrees(controldir)
3983.3.2 by Marius Kruger
make changes directly in set_repository_trees()
271
        else:
3983.3.7 by Marius Kruger
apply changes in apply again
272
            reconfiguration._repository_trees = with_trees
3921.4.2 by Matthew Fuller
Add support in Reconfigure for manipulating the repository setting for
273
        return reconfiguration
274
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
275
    def _plan_changes(self, want_tree, want_branch, want_bound,
3921.4.9 by Matthew Fuller
Back out _plan_changes() changes for trees frobbing. It's way more
276
                      want_reference):
2796.2.10 by Aaron Bentley
Ensure that shared repositories are used where possible
277
        """Determine which changes are needed to assume the configuration"""
3921.4.9 by Matthew Fuller
Back out _plan_changes() changes for trees frobbing. It's way more
278
        if not want_branch and not want_reference:
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
279
            raise ReconfigurationNotSupported(self.controldir)
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
280
        if want_branch and want_reference:
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
281
            raise ReconfigurationNotSupported(self.controldir)
2796.2.7 by Aaron Bentley
Implement converting a lightweight checkout to a branch
282
        if self.repository is None:
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
283
            if not want_reference:
284
                self._create_repository = True
285
        else:
5158.6.9 by Martin Pool
Simplify various code to use user_url
286
            if want_reference and (
7143.15.2 by Jelmer Vernooij
Run autopep8.
287
                    self.repository.user_url == self.controldir.user_url):
2796.2.25 by Aaron Bentley
Avoid destroying shared repositories
288
                if not self.repository.is_shared():
289
                    self._destroy_repository = True
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
290
        if self.referenced_branch is None:
291
            if want_reference:
292
                self._create_reference = True
2796.2.31 by Aaron Bentley
Fetch tags to reference branch when converting to checkout
293
                if self.local_branch is not None:
294
                    self._destroy_branch = True
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
295
        else:
296
            if not want_reference:
297
                self._destroy_reference = True
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
298
        if self.local_branch is None:
2796.2.15 by Aaron Bentley
More updates from review
299
            if want_branch is True:
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
300
                self._create_branch = True
301
                if want_bound:
302
                    self._bind = True
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
303
        else:
2796.2.15 by Aaron Bentley
More updates from review
304
            if want_bound:
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
305
                if self.local_branch.get_bound_location() is None:
2796.2.14 by Aaron Bentley
Updates from review
306
                    self._bind = True
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
307
            else:
308
                if self.local_branch.get_bound_location() is not None:
2796.2.14 by Aaron Bentley
Updates from review
309
                    self._unbind = True
2796.2.15 by Aaron Bentley
More updates from review
310
        if not want_tree and self.tree is not None:
2796.2.14 by Aaron Bentley
Updates from review
311
            self._destroy_tree = True
2796.2.15 by Aaron Bentley
More updates from review
312
        if want_tree and self.tree is None:
2796.2.14 by Aaron Bentley
Updates from review
313
            self._create_tree = True
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
314
3311.2.6 by Aaron Bentley
rename 'sharing' to 'use-shared'
315
    def _set_use_shared(self, use_shared=None):
316
        if use_shared is None:
3311.2.1 by Aaron Bentley
Initial make-sharing functionality
317
            return
3311.2.6 by Aaron Bentley
rename 'sharing' to 'use-shared'
318
        if use_shared:
3311.2.2 by Aaron Bentley
Flesh out to_sharing
319
            if self.local_repository is not None:
320
                self._destroy_repository = True
3311.2.4 by Aaron Bentley
Implement conversion to standalone
321
        else:
322
            if self.local_repository is None:
323
                self._create_repository = True
3311.2.1 by Aaron Bentley
Initial make-sharing functionality
324
2796.2.14 by Aaron Bentley
Updates from review
325
    def changes_planned(self):
2796.2.11 by Aaron Bentley
Cleanups
326
        """Return True if changes are planned, False otherwise"""
7143.15.2 by Jelmer Vernooij
Run autopep8.
327
        return (self._unbind or self._bind or self._destroy_tree or
328
                self._create_tree or self._destroy_reference or
329
                self._create_branch or self._create_repository or
330
                self._create_reference or self._destroy_repository)
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
331
332
    def _check(self):
2796.2.11 by Aaron Bentley
Cleanups
333
        """Raise if reconfiguration would destroy local changes"""
4721.3.2 by Vincent Ladeuil
Simplify mutable_tree.has_changes() and update call sites.
334
        if self._destroy_tree and self.tree.has_changes():
7143.15.2 by Jelmer Vernooij
Run autopep8.
335
            raise errors.UncommittedChanges(self.tree)
3338.1.1 by Aaron Bentley
Raise an error when converting a branch to a lightweight checkout loses data
336
        if self._create_reference and self.local_branch is not None:
337
            reference_branch = branch.Branch.open(self._select_bind_location())
7143.15.2 by Jelmer Vernooij
Run autopep8.
338
            if (reference_branch.last_revision()
339
                    != self.local_branch.last_revision()):
6744 by Jelmer Vernooij
Merge lp:~jelmer/brz/move-errors-knit.
340
                raise UnsyncedBranches(self.controldir, reference_branch)
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
341
342
    def _select_bind_location(self):
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
343
        """Select a location to bind or create a reference to.
2796.2.11 by Aaron Bentley
Cleanups
344
345
        Preference is:
346
        1. user specified location
347
        2. branch reference location (it's a kind of bind location)
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
348
        3. current bind location
349
        4. previous bind location (it was a good choice once)
350
        5. push location (it's writeable, so committable)
351
        6. parent location (it's pullable, so update-from-able)
2796.2.11 by Aaron Bentley
Cleanups
352
        """
353
        if self.new_bound_location is not None:
354
            return self.new_bound_location
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
355
        if self.local_branch is not None:
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
356
            bound = self.local_branch.get_bound_location()
357
            if bound is not None:
358
                return bound
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
359
            old_bound = self.local_branch.get_old_bound_location()
360
            if old_bound is not None:
361
                return old_bound
362
            push_location = self.local_branch.get_push_location()
363
            if push_location is not None:
364
                return push_location
365
            parent = self.local_branch.get_parent()
366
            if parent is not None:
367
                return parent
2796.2.9 by Aaron Bentley
Ensure conversion from lightweight checkout works
368
        elif self.referenced_branch is not None:
369
            return self.referenced_branch.base
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
370
        raise NoBindLocation(self.controldir)
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
371
372
    def apply(self, force=False):
2796.2.16 by Aaron Bentley
Documentation updates from review
373
        """Apply the reconfiguration
374
375
        :param force: If true, the reconfiguration is applied even if it will
376
            destroy local changes.
377
        :raise errors.UncommittedChanges: if the local tree is to be destroyed
378
            but contains uncommitted changes.
6734.1.16 by Jelmer Vernooij
Move reconfigure errors.
379
        :raise NoBindLocation: if no bind location was specified and
2796.2.16 by Aaron Bentley
Documentation updates from review
380
            none could be autodetected.
381
        """
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
382
        if not force:
383
            self._check()
2796.2.14 by Aaron Bentley
Updates from review
384
        if self._create_repository:
4297.4.5 by Martin von Gagern
Use repository format from exactly the same repository we want to fetch from.
385
            if self.local_branch and not self._destroy_branch:
386
                old_repo = self.local_branch.repository
387
            elif self._create_branch and self.referenced_branch is not None:
388
                old_repo = self.referenced_branch.repository
389
            else:
390
                old_repo = None
391
            if old_repo is not None:
392
                repository_format = old_repo._format
393
            else:
394
                repository_format = None
4297.4.3 by Martin von Gagern
Cleaner implementation of reconfigure.
395
            if repository_format is not None:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
396
                repo = repository_format.initialize(self.controldir)
4297.4.3 by Martin von Gagern
Cleaner implementation of reconfigure.
397
            else:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
398
                repo = self.controldir.create_repository()
3311.2.4 by Aaron Bentley
Implement conversion to standalone
399
            if self.local_branch and not self._destroy_branch:
400
                repo.fetch(self.local_branch.repository,
401
                           self.local_branch.last_revision())
2796.2.10 by Aaron Bentley
Ensure that shared repositories are used where possible
402
        else:
403
            repo = self.repository
2796.2.23 by Aaron Bentley
Add support for reconfiguring repositories into branches or trees
404
        if self._create_branch and self.referenced_branch is not None:
2796.2.10 by Aaron Bentley
Ensure that shared repositories are used where possible
405
            repo.fetch(self.referenced_branch.repository,
406
                       self.referenced_branch.last_revision())
2796.2.30 by Aaron Bentley
Reconfigure can safely be interrupted while fetching (#179316)
407
        if self._create_reference:
408
            reference_branch = branch.Branch.open(self._select_bind_location())
409
        if self._destroy_repository:
410
            if self._create_reference:
411
                reference_branch.repository.fetch(self.repository)
3311.2.1 by Aaron Bentley
Initial make-sharing functionality
412
            elif self.local_branch is not None and not self._destroy_branch:
5158.6.10 by Martin Pool
Update more code to use user_transport when it should
413
                up = self.local_branch.user_transport.clone('..')
6681.2.4 by Jelmer Vernooij
More renames.
414
                up_controldir = controldir.ControlDir.open_containing_from_transport(
6207.3.3 by jelmer at samba
Fix tests and the like.
415
                    up)[0]
6681.2.4 by Jelmer Vernooij
More renames.
416
                new_repo = up_controldir.find_repository()
3311.2.1 by Aaron Bentley
Initial make-sharing functionality
417
                new_repo.fetch(self.repository)
2796.2.23 by Aaron Bentley
Add support for reconfiguring repositories into branches or trees
418
        last_revision_info = None
2796.2.14 by Aaron Bentley
Updates from review
419
        if self._destroy_reference:
2796.2.23 by Aaron Bentley
Add support for reconfiguring repositories into branches or trees
420
            last_revision_info = self.referenced_branch.last_revision_info()
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
421
            self.controldir.destroy_branch()
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
422
        if self._destroy_branch:
2796.2.23 by Aaron Bentley
Add support for reconfiguring repositories into branches or trees
423
            last_revision_info = self.local_branch.last_revision_info()
2796.2.31 by Aaron Bentley
Fetch tags to reference branch when converting to checkout
424
            if self._create_reference:
425
                self.local_branch.tags.merge_to(reference_branch.tags)
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
426
            self.controldir.destroy_branch()
2796.2.14 by Aaron Bentley
Updates from review
427
        if self._create_branch:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
428
            local_branch = self.controldir.create_branch()
2796.2.23 by Aaron Bentley
Add support for reconfiguring repositories into branches or trees
429
            if last_revision_info is not None:
430
                local_branch.set_last_revision_info(*last_revision_info)
2796.2.32 by Aaron Bentley
Preserve tags converting from lightweight checkouts
431
            if self._destroy_reference:
432
                self.referenced_branch.tags.merge_to(local_branch.tags)
4273.1.18 by Aaron Bentley
Reconfigure preserves reference locations.
433
                self.referenced_branch.update_references(local_branch)
2796.2.9 by Aaron Bentley
Ensure conversion from lightweight checkout works
434
        else:
435
            local_branch = self.local_branch
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
436
        if self._create_reference:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
437
            self.controldir.set_branch_reference(reference_branch)
2796.2.14 by Aaron Bentley
Updates from review
438
        if self._destroy_tree:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
439
            self.controldir.destroy_workingtree()
2796.2.14 by Aaron Bentley
Updates from review
440
        if self._create_tree:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
441
            self.controldir.create_workingtree()
2796.2.14 by Aaron Bentley
Updates from review
442
        if self._unbind:
2796.2.3 by Aaron Bentley
Implement conversion to tree and checkout
443
            self.local_branch.unbind()
2796.2.14 by Aaron Bentley
Updates from review
444
        if self._bind:
2796.2.11 by Aaron Bentley
Cleanups
445
            bind_location = self._select_bind_location()
2796.2.9 by Aaron Bentley
Ensure conversion from lightweight checkout works
446
            local_branch.bind(branch.Branch.open(bind_location))
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
447
        if self._destroy_repository:
6653.6.1 by Jelmer Vernooij
Rename a number of attributes from bzrdir to controldir.
448
            self.controldir.destroy_repository()
3983.3.7 by Marius Kruger
apply changes in apply again
449
        if self._repository_trees is not None:
450
            repo.set_make_working_trees(self._repository_trees)